I believe your example doesn't take into account that the values can be NaN which compares false in all situations. If you allow the compiler to optimize without supporting NaN (-ffast-math), I think it generates the code you want: https://godbolt.org/z/1ra7zcsnd
--matt On Sat, Aug 21, 2021 at 1:59 PM Stefan Kanthak <stefan.kant...@nexgo.de> wrote: > 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 > -- Matt (he/him)