;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版本中可能缺少优化(它可能是 gcc-8.1中的回归.我的问题是,为什么设置奇偶校验标志( setp ,PF=1),而不是使用等于标志( setne ,ZF=0)在第二版中?解决方案 x!=x的结果归因于 gcc-8引入了回归,clang为这两个版本生成了相同的汇编程序.我对 ucomisd 运行方式的误解由@指出tkausl.该操作的结果可以是: unordered < > ==ZF 1 0 0 1PF 1 0 1 0CF 1 1 0 0对于ucomisd %xmm0, %xmm,只有结果无序"和"=="是可能的. NaN的情况是无序的,对此ZF的设置与==的情况相同.因此,我们可以使用标志PF和CF来区分两个可能的结果.I always assumed, that there is practically no difference between testing for NAN viax!=xorstd::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 retHowever, 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 retbut 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 1PF 1 0 1 0CF 1 1 0 0In 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的编译结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
06-05 10:47