[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #13 from joseph at codesourcery dot com --- On Fri, 10 Nov 2023, rguenth at gcc dot gnu.org via Gcc-bugs wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 > > --- Comment #11 from Richard Biener --- > (In reply to post+gcc from comment #10) > > The standard says > > > > > This annex does not require the full support for signaling NaNs specified > > > in IEC 60559. This > > annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs. > > Where specification of > > signaling NaNs is not provided, the behavior of signaling NaNs is > > implementation-defined (either > > treated as an IEC 60559 quiet NaN or treated as an IEC 60559 signaling NaN). > > I don't see implement-c.texi saying anything about this. Joseph, can you > improve documentation here? Updating implement-c.texi for C23 is on my list for after C23 is out and so we have final subclause references (but the list of implementation-defined behavior in J.3 doesn't seem to have that point from Annex F at present).
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #12 from post+gcc at ralfj dot de --- > GCC will not create an sNaN out of nowhere. That's the part I was hoping for. :) I just don't think it obviously follows from any docs (the C standard or GCC docs).
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #11 from Richard Biener --- (In reply to post+gcc from comment #10) > The standard says > > > This annex does not require the full support for signaling NaNs specified > > in IEC 60559. This > annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs. > Where specification of > signaling NaNs is not provided, the behavior of signaling NaNs is > implementation-defined (either > treated as an IEC 60559 quiet NaN or treated as an IEC 60559 signaling NaN). I don't see implement-c.texi saying anything about this. Joseph, can you improve documentation here? > I have no idea how that allows a situation where the *output* of an > operation becomes signaling -- that can't usually happen no matter whether > the inputs are signaling or quiet. > > But that seems to be the common interpretation. > > Still, it seems important that `pow(1.0, 0.0/0.0)` returns `1.0` and not a > NaN. That's what the `pow` docs say. So for this there must be a guarantee > that `0.0/0.0` is a quiet NaN. GCC will not create an sNaN out of nowhere. But unless you enable -fsignaling-nans it is unspecified whether and when an sNaN will become a quiet NaN as GCC - as you observed - will happily elide x * 1.0 even when 'x' might be a sNaN (basically with -fno-signaling-nans GCC assumes that inputs are _never_ sNaN). The -fsignaling-nans might also need clarification to make it more obvious what omitting it means.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #10 from post+gcc at ralfj dot de --- The standard says > This annex does not require the full support for signaling NaNs specified in > IEC 60559. This annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs. Where specification of signaling NaNs is not provided, the behavior of signaling NaNs is implementation-defined (either treated as an IEC 60559 quiet NaN or treated as an IEC 60559 signaling NaN). I have no idea how that allows a situation where the *output* of an operation becomes signaling -- that can't usually happen no matter whether the inputs are signaling or quiet. But that seems to be the common interpretation. Still, it seems important that `pow(1.0, 0.0/0.0)` returns `1.0` and not a NaN. That's what the `pow` docs say. So for this there must be a guarantee that `0.0/0.0` is a quiet NaN.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #9 from joseph at codesourcery dot com --- To quote the C23 DIS, "This annex does not require the full support for signaling NaNs specified in IEC 60559. This annex uses the term NaN, unless explicitly qualified, to denote quiet NaNs.". Support for signaling NaNs is indicated by FE_SNANS_ALWAYS_SIGNAL in , which glibc makes sure to define only if __SUPPORT_SNAN__ (which is defined by GCC if -fsignaling-nans). If -fsignaling-nans is not used, you should not expect consistency in whether a signaling NaN is handled differently from a quiet NaN (including whether optimizations might be applied that result in a signaling NaN result from an operation that can't produce such a result with IEEE signaling NaN semantics).
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 Richard Biener changed: What|Removed |Added CC||jsm28 at gcc dot gnu.org, ||rguenth at gcc dot gnu.org --- Comment #8 from Richard Biener --- I think if you can reproduce the issue with -fsignaling-nans (which defaults to off) then I would consider this to be an implementation issue. The GCC middle-end shouldn't clang to contradicting wording in the C standard here. In particular we say @opindex fsignaling-nans @item -fsignaling-nans Compile code assuming that IEEE signaling NaNs may generate user-visible traps during floating-point operations. Setting this option disables optimizations that may change the number of exceptions visible with signaling NaNs. This option implies @option{-ftrapping-math}. Changing tem = x * 1.0 to tem = x would possibly change the number of observed traps if tem is used more than once. OTOH below we also say This option is experimental and does not currently guarantee to disable all GCC optimizations that affect signaling NaN behavior. so bugs in this area are expected (but they are still bugs IMHO). CCing Joseph for clarification. Note a quick check with double foo (double x) { return x * 1.0; } and -O2 -fsignaling-nans shows the multiplication is preserved (on x86_64), so is your example in godbolt where you fail to specify -fsignaling-nans. I agree the documentation is maybe not entirely clear about the effect.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #7 from post+gcc at ralfj dot de --- I guess the idea is that by passing a signaling NaN to a float operation, I am already entering unspecified behavior, so it's okay for that float operation to violate its usual contract and return a signaling NaN?
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #6 from post+gcc at ralfj dot de --- Hm, OTOH the C standard says > The expressions 1×x, x/1, and x are equivalent (on IEC 60559 machines, among others). So, it seems like when they say "The + ,- , * , and / operators provide the IEC 60559 add, subtract, multiply, and divide operations.", they don't quite mean that. This seems internally inconsistent in the C standard, since C also permits `pow(1, sNaN)` to behave different from `pow(1, qNaN)` -- and in fact they do behave different in GNU's libm. So on the one hand `pow(1, x * y)` must always be `1` but on the other hand it can return a NaN when `x` is an sNaN and `y` is `1`?
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #5 from post+gcc at ralfj dot de --- > See > https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fsignaling-nans That's unrelated. That's about whether operation on signaling NaNs can trap. I am asking when operations can output a signaling NaN. So, for code like float x = y z; return is_signaling_nan(x); when can that code return `true`? Normal IEEE semantics would say "never". And yet if "z" is the constant 1, is `*`, and "y" is a signaling NaN, then this evidently can output a signaling NaN. I would hope the answer is "this can output a signaling NaN only if one of the inputs is a signaling NaN", but is that documented anywhere? > Note mips and sh and a few other targets have the quiet bit meaning the > opposite. I know. LLVM is currently buggy on those targets. > GCC does document some of this on > https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Floating-point-implementation.html > but not the signaling nan part. This seems to list a bunch of implementation-defined aspects of C? To my knowledge, my question is not implementation defined. C (with the annex for floating-point arithmetic) requires the above operations to always return "false". GCC violates the C spec here (since it defines __STDC_IEC_559__, declaring support for the annex), and it'd be good to know how far it is going in that violation.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #4 from Andrew Pinski --- And documented other parts here: https://gcc.gnu.org/onlinedocs/gcc-13.2.0/cpp/Common-Predefined-Macros.html specifically: It does not indicate whether optimizations respect signaling NaN semantics (the macro for that is __SUPPORT_SNAN__).
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #3 from Andrew Pinski --- GCC does document some of this on https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Floating-point-implementation.html but not the signaling nan part.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #2 from Andrew Pinski --- Note mips and sh and a few other targets have the quiet bit meaning the opposite.
[Bug c/112449] Arithmetic operations can produce signaling NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112449 --- Comment #1 from Andrew Pinski --- See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fsignaling-nans