Why can't (! A &&! B) optimize a single TEST statement?

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

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

The compiler really 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 he use a single TEST statement to save branches and instructions?

+4
source share
2 answers

Due to short circuit rating .

if(!A && !B)

Pay attention to the code above.

If A is true (not 0), !A && !B becomes 0(FALSE). That's right, you do not need to check the value of B. It must skip (jump over) 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.

A 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).
+2

Source: https://habr.com/ru/post/1653277/


All Articles