了解std :: isnan的编译结果

时间:2018-07-11 21:07:33

标签: c++ gcc optimization x86 ieee-754

我一直认为,通过{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)。

我的问题是,为什么第二个版本中不使用奇偶校验标志(setpPF=1)和相等标志(setneZF=0)? / p>

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设置的情况与==的情况相同。因此,我们可以使用标记PFCF来区分两个可能的结果。