I always assumed, that there is practically no difference between testing for NAN
via
x!=x
or
std::isnan(x)
However, gcc provides different assemblers for both versions (live on godbolt.org):
;x!=x:
ucomisd %xmm0, %xmm0
movl $1, %edx
setne %al
cmovp %edx, %eax
ret
;std::isnan(x)
ucomisd %xmm0, %xmm0
setp %al
ret
However, I'm struggling to understand both version. My naive try to compile std::isnan(x)
would be:
ucomisd %xmm0, %xmm0
setne %al ;return true when not equal
ret
but I must be missing something.
Probably, there is missed optimization in the x!=x
-version (Edit: it is probably a regression in gcc-8.1).
My question is, why is the parity flag (setp
, PF=1
) and not the equal flag (setne
, ZF=0
) used in the second version?