代码之家  ›  专栏  ›  技术社区  ›  ead

了解STD:ISSN编译结果

  •  9
  • ead  · 技术社区  · 6 年前

    我一直认为,测试 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::ISNANN(X) 将是:

      ucomisd %xmm0, %xmm0
      setne %al   ;return true when not equal
      ret
    

    但我一定错过了什么。

    可能,在 X!= X -版本(编辑:可能是 regression in gcc-8.1 )

    我的问题是,为什么是均等标志( setp , PF=1 )而不是平等的旗帜( setne , ZF=0 )在第二个版本中使用?

    1 回复  |  直到 6 年前
        1
  •  2
  •   ead    6 年前

    结果 x!=x 是由于 regression introduced to gcc-8 ,clang为两个版本生成相同的汇编程序。

    我对路的误解 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 区分两种可能的结果。