Jun Ryung Ju
Jun Ryung Ju

Reputation: 61

Why can't if( !A && !B ) optimize to a single TEST instruction?

if( !A && !B ) seems like it should compile to

mov    eax, dword ptr[esp + A_offset]
test   eax, dword ptr[esp + B_offset]
jne    ~~~~~~~~~~

The compiler actually generates

mov    eax, dword ptr[esp + A_offset]
test   eax, eax
jne    ~~~~~~~~~~
mov    eax, dword ptr[esp + B_offset]
test   eax, eax
jne    ~~~~~~~~~~

See dump here

8B 45 F8             mov         eax,dword ptr [b]  
83 7D FC 00          cmp         dword ptr [a],0  
75 04                jne         main+32h (0A71072h)  
85 C0                test        eax,eax  
75 00                jne         main+32h (0A71072h)   

Why doesn't it use a single TEST instruction to save branches and instructions?

Upvotes: 4

Views: 172

Answers (2)

Because of the short-circuit evaluation.

if(!A && !B)

Let's pay attention to code above.

If A is truthy(not 0), !A && !B becomes 0(FALSE). Right, you don't have to check the value of the B. It should skip(jump) the code-block for the if statement.

mov eax, dword ptr[esp + A_offset]
test eax, eax   ; If `A & A`
jne ~~~~~~~~~~  ; is not 0(If A is not 0), skip this if-codeblock.
mov eax, dword ptr[esp + B_offset] ; Otherwise,
test eax, eax   ; If `B & B`
jne ~~~~~~~~~~  ; is not 0(If B is not 0), skip this if-codeblock.
......          ; Both A and B are 0, and `!A && !B` is `1(TRUE)`! Run the if-codeblock.

Plus:

It seems your code is wrong..?

mov eax, dword ptr[esp + A_offset]
mov ebx, dword ptr[esp + B_offset]
test eax, ebx  ; `A & B`
jne ~~~~~~~~~~ ; If `A & B != 0`, skip this code-block for the if statement.
...... ; In other words, this code-block will be run when `A & B == 0`,
       ; which will be `TRUE` when A is 1(0b00000001) and B is 2(0b00000010).

Upvotes: 2

Serge
Serge

Reputation: 6095

No. The test instruction performs bitwise AND of the operands and set flags according to the result, see https://en.wikipedia.org/wiki/TEST_(x86_instruction).

So the code generated by compiler is correct.

Upvotes: 2

Related Questions