Weak optimzation for x86 for some small constants

Gunther Piez gpiez@web.de
Thu Oct 2 14:16:00 GMT 2003


Hello,

the function

int f(int x) {
    if (x & 0x1fff0)
        return 1;
    else
        return 0;
}

compiled with '-O2 -fomit-framepointer' for a x86, yields

	xor    %eax,%eax
 	testl  $0x1fff0,0x4(%esp,1)
 	setne  %al
 	ret

This is ok (at least for me). But if I change the constant 0x1fff0 to 0xfff0, 
f() now looks like

	mov    0x4(%esp,1),%eax
	and    $0xfffffff0,%eax
	test   %ax,%ax          <----- this is very ugly
	setne  %al
	movzbl %al,%eax
	ret

I suspect, the compiler wants to use the three bytes saving 'and imm8,%eax' 
instruction, but this doesn't make up for the additional 6 bytes it needs 
elsewhere. And the partial register read after a register write probably 
causes a stall, at least the second version did run 20% slower in a short 
test. This stays if the function gets inlined (actually i stumbled accross it 
while reviewing a inline function), and it is in both gcc-3.3.1 and 3.4.

Is this a bug?

Gunther



More information about the Gcc mailing list