https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111655

--- Comment #5 from Paul Eggert <eggert at cs dot ucla.edu> ---
> I am thinking this is all under specified really ...
Although it is indeed unspecified whether 0.0/0.0 yields -NaN or +NaN, it is
well understood that negating a floating point value flips its sign bit. The
original test case demonstrates that gcc -O2 currently mishandles this, as that
test case negates a floating point value but the sign bit remains unchanged.

Old GCC and Clang handle this correctly, as do the other non-GCC compilers that
I checked. As far as I know, only recentish gcc gets this wrong, and even then
only when optimization is enabled.

Here is a sharper example of the bug:

  int
  main ()
  {
    double x = 0.0 / 0.0;
    return !__builtin_signbit (x) == !__builtin_signbit(-x);
  }

This should return 0 no matter what X's value is, but it returns 1 with recent
gcc -O2 on x86-64.


> The match pattern which causes the issue:
> (simplify
>  /* signbit(x) -> 0 if x is nonnegative.  */
>  (SIGNBIT tree_expr_nonnegative_p@0)
>  { integer_zero_node; })
I don't see anything wrong with that match pattern.

I speculate that what's wrong is that GCC incorrectly thinks that 0.0/0.0 is
nonnegative. Although it's tempting to say that the sign bit of a division is
the exclusive OR of the sign bits of its operands, evidently this is not true
on x86-64 when NaNs are involved.

Reply via email to