Hi, the following snippet is from the nextafter() function of <http://www.netlib.no/netlib/toms/722>
--- repro.c --- #define Zero 0.0 double nextafter(double argx, double argy) { double z = argx; if (isnan(argx) || isnan(argy)) return argx + argy; if (argx == argy) return argx; if (argx != Zero) if (((argx < Zero) && (argx < argy)) || ((argx > Zero) && (argx > argy))) z += 1.0; else z -= 1.0; return z; } --- EOF --- I expect that GCC knows DeMorgan's rules and is able to simplify/optimize the last if-statement to if ((argx < Zero) == (argx < argy)) Unfortunately GCC fails to do so: see the lines from label .L20: to label L7 $ gcc -m64 -O3 -o- -S ... nextafter: ucomisd %xmm1, %xmm0 jp .L19 pxor %xmm2, %xmm2 movl $1, %edx ucomisd %xmm2, %xmm0 setp %al cmovne %edx, %eax testb %al, %al je .L3 ucomisd %xmm1, %xmm0 setp %al cmove %eax, %edx testb %dl, %dl jne .L20 .L3: ret .L20: comisd %xmm0, %xmm2 ja .L21 .L4: comisd %xmm2, %xmm0 jbe .L7 comisd %xmm1, %xmm0 jbe .L7 .L6: addsd .LC1(%rip), %xmm0 ret .L21: comisd %xmm0, %xmm1 ja .L6 jmp .L4 .L7: subsd .LC1(%rip), %xmm0 ret .L19: addsd %xmm1, %xmm0 ret .LC1: .long 0 .long 1072693248 Stefan