Understanding compilation result for std::isnan

痴心易碎 提交于 2019-12-08 16:14:21

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/51294168/understanding-compilation-result-for-stdisnan

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!