This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: x86 code generation question


On Thu, 29 Apr 2004, Paul Koning wrote:

> Testing...
> 
> #define sel(x,y,s) ((s) ? (y) : (x))
> 
> int test (int x, int y, int s)
> {
>     return sel(x,y,s);
> }
> 
> gcc -O2 -march=i686 -S test.c
> 
> produces
> 
> 	.file	"test.c"
> 	.text
> 	.p2align 4,,15
> .globl test
> 	.type	test, @function
> test:
> 	pushl	%ebp
> 	movl	%esp, %ebp
> 	movl	16(%ebp), %edx
> 	movl	12(%ebp), %eax
> 	testl	%edx, %edx
> 	cmove	8(%ebp), %eax
> 	popl	%ebp
> 	ret
> 
> So indeed the conditional move does happen.  It may be that you didn't
> see it because you didn't ask for optimization, or didn't specify the
> CPU type and ended up with i386 by default.
> 
> This was with GCC 3.3.2.
> 
>      paul
> 

So let me come back to my previous example for a moment. If we have
  #define sel(x, y, s) ((x) + (((y) - (x)) & (-(s))))
and
  y = sel(3, 7, (x > 11));
Then what the compiler should see (after all appropriate reductions) is:
  y = 3 + (4 & -(x > 11));
Thus, when we compile with no optimizations, and it has the conditional 
move available, why does gcc choose to instead generate assembly with a 
jump instead of conditional move? It seems like a conscious choice (given 
that straightforward generation of the code will yield no jumps), and one 
that makes the code worse off in the end.

Tested with GCC 3.2.3 -

-Vadim


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]