了解std :: isnan的编译结果 [英] Understanding compilation result for std::isnan
问题描述
我一直以为,通过
测试NAN
实际上几乎没有区别
-
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
但是,我正在努力理解这两个版本.我天真的尝试编译std::isnan(x)
是:
ucomisd %xmm0, %xmm0
setne %al ;return true when not equal
ret
但我一定想念一些东西.
x!=x
版本中可能缺少优化(它可能是 setp
,PF=1
),而不是使用等于标志( setne
,ZF=0
)在第二版中?
x!=x
的结果归因于 ucomisd
运行方式的误解由@指出tkausl.该操作的结果可以是:
unordered < > ==
ZF 1 0 0 1
PF 1 0 1 0
CF 1 1 0 0
对于ucomisd %xmm0, %xmm
,只有结果无序"和"=="是可能的.
NaN
的情况是无序的,对此ZF的设置与==
的情况相同.因此,我们可以使用标志PF
和CF
来区分两个可能的结果.
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?
The result of x!=x
is due to a regression introduced to gcc-8, clang produces the same assembler for both versions.
My misunderstanding about the way ucomisd
is functioning was pointed out by @tkausl. The result of this operation can be:
unordered < > ==
ZF 1 0 0 1
PF 1 0 1 0
CF 1 1 0 0
In the case of ucomisd %xmm0, %xmm
only the outcomes "unordered" and "==" are possible.
The case of NaN
is unordered and for this ZF is set the same as in the case of ==
. Thus we can use the flags PF
and CF
to differentiate between two possible outcomes.
这篇关于了解std :: isnan的编译结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!