flags: -O2 -ffast-math -march=i686 -fomit-frame-pointer double signum_dbl_gcc( double x ) { if ( x < 0.0 ) return -1.0; if ( x > 0.0 ) return 1.0; return 0.0; }
.LC1: .long 3212836864 signum_dbl_gcc: fldz fldl 4(%esp) fcomip %st(1), %st jb .L11 fld1 fcmovbe %st(1), %st fstp %st(1) ret .L11: fstp %st(0) flds .LC1 ret int signum_int_gcc( int x ) { if ( x < 0 ) return -1; if ( x > 0 ) return 1; return 0; } signum_int_gcc: cmpl $0, 4(%esp) movl $-1, %eax jl .L15 setne %al movzbl %al, %eax .L15: ret custom version without branches. double signum_user_dbl( double x ) { asm volatile ( "fld1 \n\t" "fchs \n\t" "fld1 \n\t" "fldz \n\t" "fucomi %%st(3) \n\t" "fcmovnbe %%st(2), %%st(0) \n\t" "fcmovb %%st(1), %%st(0) \n\t" "fstp %%st(1) \n\t" "fstp %%st(1) \n\t" "fstp %%st(1) \n\t" : "=t" (x) : "0" (x) ); return x; } int signum_user_int( int x ) { int retval; asm volatile ( "xor %%al, %%al \n\t" "mov $-1, %%cl \n\t" "mov $1, %%dl \n\t" "cmp $0, %1 \n\t" "cmovl %%ecx, %%eax \n\t" "cmovg %%edx, %%eax \n\t" "movsx %%al, %%eax \n\t" : "=a" (retval) : "m" (x) ); return retval; } -- Summary: missed optimization / lack of conditional moves Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: pluto at agmk dot net GCC build triplet: i686-pld-linux GCC host triplet: i686-pld-linux GCC target triplet: i686-pld-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26914