"Gabriel Ravier" <[email protected]> wrote:
Please don't FULL QUOTE!
> On 8/13/21 8:58 PM, Stefan Kanthak wrote:
>> Hi,
>>
>> compile the following naive implementation of nextafter() for AMD64:
>>
>> JFTR: ignore the aliasing casts, they don't matter here!
>>
>> $ cat repro.c
[...]
> Shouldn't this kind of stuff go to the Bugzilla ?
I don't mind if you or someone else take it there.
If you do so, here's one for the road:
$ cat alternate.c
double nextafter(double from, double to)
{
if (from == to)
return to;
if ((from != from) || (to != to))
return from + to;
if (from == 0.0)
return to < 0.0 ? -0x1.0p-1074 : 0x1.0p-1074;
unsigned long long ull = *(unsigned long long *) &from;
if ((from > to) == (from > 0.0))
ull--;
else
ull++;
return *(double *) &ull;
}
$ gcc -m64 -o- -O3 -S alternate.c
nextafter:
ucomisd %xmm0, %xmm1 # sets PF if comparands are unordered,
# i.e. at least one is a NaN
jnp .L20 # OUCH: this branch is unlikely taken!
.L13: # reached only if at least one
# argument is a NaN!
ucomisd %xmm0, %xmm0 # OUCH: SUPERFLUOUS!
jnp .L21 # OUCH: SUPERFLUOUS!
.L14:
addsd %xmm1, %xmm0
ret
.L21: # reached only if at least one
# argument is a NaN!
ucomisd %xmm1, %xmm1 # OUCH: SUPERFLUOUS!
jp .L14 # OUCH: SUPERFLUOUS!
pxor %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jnp .L22 # OUCH: SUPERFLUOUS!
# xmm0 can't be NaN here!
# OUCH: and if it were, this branch
# would unlikely be taken!
.L8:
comisd %xmm0, %xmm1
movq %xmm0, %rdx
leaq -1(%rdx), %rax
seta %r8b
comisd %xmm0, %xmm2
seta %cl
addq $1, %rdx
cmpb %cl, %r8b
cmovne %rdx, %rax
movq %rax, %xmm0
ret
.L20:
jne .L13
movapd %xmm1, %xmm0
ret
.L22:
jne .L8
movabsq $-9223372036854775808, %rdx
movq %xmm1, %rax
andq %rdx, %rax
orq $1, %rax
movq %rax, %xmm0
ret
Stefan