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.