c++ - 了解 std::isnan 的编译结果

标签 c++ gcc optimization x86 ieee-754

我一直认为,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)在第二个版本中?

最佳答案

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

关于c++ - 了解 std::isnan 的编译结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51294168/

相关文章:

c++ - 字符常量数组为空,即使已为其分配值 [C++]

c++ - 错误:使用已删除的函数 boost::shared_mutex::shared_mutex

c++ - 通过自定义宏构造 boost::fusion::map(以及更多)

c++ - 异常运行 boost asio ssl 示例

c++ - 为什么 c++ string == (equality) 运算符比手动逐个检查字符快得多?

linux - 如何减小生成的二进制文件的大小?

c++ - 继承虚基类的构造函数

c - 程序集中局部变量的大小

javascript - 不必要的 for 循环迭代会影响速度吗?

python - 如何改进这个重度嵌套的 for 循环?