我一直认为,通过{p>测试NAN
之间几乎没有区别
x!=x
或
std::isnan(x)
但是,gcc为两个版本(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
但是,我正在努力理解这两个版本。我天真的尝试编译std::isnan(x)
是:
ucomisd %xmm0, %xmm0
setne %al ;return true when not equal
ret
但我一定想念一些东西。
在x!=x
版本中可能缺少优化(编辑:它可能是regression in gcc-8.1)。
答案 0 :(得分:2)
x!=x
的结果归因于regression introduced to gcc-8,clang为这两个版本生成相同的汇编程序。
@tkausl指出了我对ucomisd
运作方式的误解。该操作的结果可以是:
unordered < > ==
ZF 1 0 0 1
PF 1 0 1 0
CF 1 1 0 0
对于ucomisd %xmm0, %xmm
,只有结果“无序”和“ ==”是可能的。
NaN
的情况是无序的,为此ZF设置的情况与==
的情况相同。因此,我们可以使用标记PF
和CF
来区分两个可能的结果。