ead*_*ead 9 c++ optimization x86 gcc ieee-754
我一直认为,测试NANvia 之间几乎没有区别
x!=x要么
std::isnan(x)但是,gcc为这两个版本提供了不同的汇编程序(在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
Run Code Online (Sandbox Code Playgroud)
但是,我很难理解这两个版本.我天真的尝试编译std::isnan(x)将是:
ucomisd %xmm0, %xmm0
setne %al ;return true when not equal
ret
Run Code Online (Sandbox Code Playgroud)
但我必须遗漏一些东西.
结果x!=x是由于gcc-8 引入的回归,clang 为两个版本生成相同的汇编程序。
ucomisd@tkausl 指出了我对运行方式的误解。该操作的结果可以是:
unordered < > ==
ZF 1 0 0 1
PF 1 0 1 0
CF 1 1 0 0
Run Code Online (Sandbox Code Playgroud)
ucomisd %xmm0, %xmm在只有结果“无序”和“==”的情况下是可能的。
的情况NaN是无序的,并且该 ZF 的设置与 的情况相同==。因此,我们可以使用标志PF和CF来区分两种可能的结果。