了解std :: isnan的编译结果 [英] Understanding compilation result for std::isnan

查看:175
本文介绍了了解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的设置与==的情况相同.因此,我们可以使用标志PFCF来区分两个可能的结果.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆