This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: x86 code generation question
- From: Vadim Lobanov <vadim at cs dot washington dot edu>
- To: Paul Koning <pkoning at equallogic dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 29 Apr 2004 14:38:00 -0700 (PDT)
- Subject: 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