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

            Bug ID: 112449
           Summary: Arithmetic operations can produce signaling NaNs
           Product: gcc
           Version: 13.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: post+gcc at ralfj dot de
  Target Milestone: ---

According to the IEEE 754 specification, the output of an arithmetic operation
can never be a signaling NaN. However, GCC performs optimizations that turn `x
* 1.0` into just `x`, and if `x` is a signaling NaN, that means that the
multiplication will now (seem to) return a signaling NaN. (proof of GCC
performing that transformation: https://godbolt.org/z/scPhn1d8s)

It is very common for C compilers to violate this IEEE 754 requirement, but it
does open the door to a great many questions. Since GCC evidently does not seem
to implement the original IEEE 754 semantics, it would be great to have some
documentation on what exactly GCC *does* implement, and in particular under
which conditions operations are allowed to return a signaling NaN.

So currently, GCC is either buggy because it violates the IEEE 754 spec, or
there's a documentation bug in that the actual floating point spec GCC intends
to implement is not documented. At least, all I was able to find is
https://gcc.gnu.org/wiki/FloatingPointMath, which just says "does not care
about signalling NaNs". (I hope this does not mean that any arithmetic
operation may arbitrarily produce signaling NaNs. That would be an issue for
operations which are sensitive to the difference between quiet NaN and
signaling NaN, such as `pow`.)

As a point of comparison, LLVM recently added this to their documentation to
answer these kinds of questions:
https://llvm.org/docs/LangRef.html#behavior-of-floating-point-nan-values. (That
PR was authored by me but received input from a lot of people.) LLVM goes
further than to just document signaling vs quiet NaN there, since in practice
there's some critical code that would break if arithmetic operations returned
NaNs with arbitrary bits in their payload (specifically, that would break NaN
boxing as performing by some JavaScript engines, or at least make it a lot less
efficient since engines would have to re-normalize NaNs after every single
operation -- which to my knowledge, they don't actually do in practice).

Reply via email to