On(c)e more: optimizer failure
Matt Godbolt
matt@godbolt.org
Sat Aug 21 19:06:18 GMT 2021
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.kanthak@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)
More information about the Gcc
mailing list