https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63387
Bug ID: 63387
Summary: Optimize pairs of isnan() calls into a single
isunordered()
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: other
Assignee: unassigned at gcc dot gnu.org
Reporter: jzwinck at gmail dot com
Whenever a program does (isnan(x) || isnan(y)), GCC 4.7 and 4.9 in the best
case emits code like this on x86-64:
ucomisd %xmm0, %xmm0 ; set parity flag if x is NAN
setp %dl ; copy parity flag to %edx
ucomisd %xmm1, %xmm1 ; set parity flag if y is NAN
setp %al ; copy parity flag to %eax
orl %edx, %eax ; OR one byte of each result into a full-width register
This is suboptimal because ucomisd already has the effect of checking if
*either* of its operands is NAN, so this code is equivalent:
xorl %eax, %eax
ucomisd %xmm1, %xmm0
setp %al
And indeed that's what you get if you help GCC along by calling isunordered(x,
y) instead. But no one thinks to do that, because isnan() is much more widely
used and it isn't an obvious thing at the source level to change pairs of
isnan() calls to isunordered(). So the optimizer should do it.
Someone already suggested that in GCC 5 it might be as simple as this (which
seems correct and safe to me):
(simplify (or (unordered @0 @0) (unordered @1 @1)) (unordered @0 @1))
A discussion of this issue is here:
http://stackoverflow.com/questions/26053934/is-it-feasible-to-add-this-optimization-to-gcc