int c = 4;
int p = 5;

if (p & (1 << c))

gcc -S:

movl    -4(%rbp), %eax   /* eax holds the variable c  */
movl    -8(%rbp), %edx   /* and edx holds p  */
movl    %eax, %ecx       /* tmp(ecx) = c  */
sarl    %cl, %edx        /* edx(p) >>= c  */
movl    %edx, %eax       /* eax = p shifted right by c */
andl    $1, %eax         /* eax(p shifted right by c) &= 1  */
testl   %eax, %eax       /* test if p is 0  */
... jumps and such ...

As you can see, GCC for some reason converted my code to:

p >>= c;
p &= 1
if (p != 0)

Something fishy is going on here or I am missing something... It kinda made the operation backwards, although I had brackets around the 1 << c so it should've done it separately then AND it with p correct?

Can someone explain why did GCC do this? Is it some sort of optimization (I had no optimization enabled when I compiled this, so doubt it) Or is it how it should be done in assembly?

2 Answers 2

(1<<c) set the fifth bit. == 0x10 (==16 dec)

p & (1<<c)

The condition here is: "Is the 5th bit set in the variable p?"

To achieve this test you can shift p right by 4 and ask "is the lowest bit set?" so your code has been converted to if((p>>4) & 0x1)

Which is the same thing.

run gcc -S -O3 and the same logic collapses to

btl %edi, %esi
jc  .L4

It is likely some sort of optimization. Not all optimizations must be explicitly enabled. The safest ones will be enabled unless explicitly disabled, which seems to be the case here. Running the following command on my system shows 47 optimizations enabled by default:

gcc -Q --help=optimizers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.