[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #22 from joseph at codesourcery dot com --- On Mon, 2 Oct 2023, eggert at cs dot ucla.edu via Gcc-bugs wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 > > --- Comment #20 from Paul Eggert --- > (In reply to jos...@codesourcery.com from comment #14) > > This is just the same as other unspecified things like converting an > > out-of-range value from floating-point to integer. > No, because when GCC's constant folding disagrees with machine arithmetic, GCC > can generate code that violates the relevant standards. The issue you describe is orthogonal to my comment in this bug. The unspecified cases - both the one I mentioned in my comment and the one in the description of this bug - do not require any particular result (choice of quiet NaN, choice of value for out-of-range conversion to integer, etc.), and in particular do not require a result that could be generated by the hardware being used, but they do require that, for each evaluation of such an operation in the abstract machine, the implementation behaves as if some particular valid choice of result was made for that evaluation; wobbly values (some uses of the result behaving as if one choice of value were made and other uses behaving as if some other choice were made) are not permitted. (This is similar to the question of whether use of uninitialized variables (if not undefined behavior) can produce a wobbly value, as such a value naturally results from optimizing a PHI node with one uninitialized operand to the value of the other operand.)
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Alexander Monakov changed: What|Removed |Added CC||amonakov at gcc dot gnu.org --- Comment #21 from Alexander Monakov --- Bug 111655 is not a dup, I left a comment and reopened.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #20 from Paul Eggert --- (In reply to jos...@codesourcery.com from comment #14) > This is just the same as other unspecified things like converting an > out-of-range value from floating-point to integer. No, because when GCC's constant folding disagrees with machine arithmetic, GCC can generate code that violates the relevant standards. Here's an example taken from Bug 111655: int main () { double x = 0.0 / 0.0; return !__builtin_signbit (x) == !__builtin_signbit (-x); } 'main' must return 0 no matter what x's sign happens to be, because "-x" must flip x's sign bit, so __builtin_signbit(-x) must yield the opposite result from __builtin_signbit(x). However, this code returns 1 with gcc (GCC) 13.2.1 20230728 (Red Hat 13.2.1-1) on x86-64, compiled with -O2. The bug occurs because the evaluation of __builtin_signbit (x) is constant-folded to 0 (under the assumption that 0.0/0.0 yields +NaN), whereas the evaluation of __builtin_signbit (-x) iuses machine arithmetic to first calculate 0.0/0.0 (i.e., -NaN), then negate that to +NaN, and then calculate its sign bit to be 0. At least for this particular example, GCC is generating the wrong code so this bug report should be decorated with a "wrong-code" keyword.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Andrew Pinski changed: What|Removed |Added CC||eggert at cs dot ucla.edu --- Comment #19 from Andrew Pinski --- *** Bug 111655 has been marked as a duplicate of this bug. ***
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Roger Sayle changed: What|Removed |Added CC||joshua.england@worldprogram ||ming.com --- Comment #18 from Roger Sayle --- *** Bug 78249 has been marked as a duplicate of this bug. ***
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #17 from lucier at math dot purdue.edu --- (In reply to lucier from comment #16) > Created attachment 52026 [details] > CPU and Memorty usage reports for compilling all.i, _num.i, and compiler.i Sorry, added comment to wrong PR.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #16 from lucier at math dot purdue.edu --- Created attachment 52026 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52026=edit CPU and Memorty usage reports for compilling all.i, _num.i, and compiler.i
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Joel Sherrill joel at gcc dot gnu.org changed: What|Removed |Added CC||joel at gcc dot gnu.org --- Comment #15 from Joel Sherrill joel at gcc dot gnu.org 2013-01-10 01:04:50 UTC --- Confirming still broken as of: xgcc (GCC) 4.8.0 20130108 (experimental) [trunk revision 195030]
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Richard Guenther rguenth at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2011-12-08 Component|tree-optimization |middle-end Ever Confirmed|0 |1 --- Comment #4 from Richard Guenther rguenth at gcc dot gnu.org 2011-12-08 10:10:17 UTC --- (In reply to comment #3) I've looked through the code in real.c a bit (and perhaps the component of this bug report should be changed). It appears that do_divide, when given 0.0/0.0, calls get_canonical_qnan with sign=0 (line 816 in real.c), but divsd actually returns a qnan with sign bit = 1. Similarly, do_add when given Inf - Inf, calls get_canonical_qnan with sign bit = 0 (line 574 of real.c), while subsd returns a qnan with sign bit = 1. It seems that the sign bit in this situation should be target-dependent if you want the constants to match what the actual instructions will provide. Interesting. Does IEEE say anything about the sign of the qnan? Do the architecture manuals say anything about the sign of the qnan?
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #5 from lucier at math dot purdue.edu 2011-12-08 14:30:00 UTC --- Re: Do the architecture manuals say anything about the sign of the qnan? Amazingly enough, they do! I downloaded the combined x86-64 manuals from http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-manual-325462-rmver.html and found the following: Table 4-3: Floating-point number and NaN encodings: QNaN Floating-point indefinite: sign is 1 Section 4.8.3.7: Description of QNaN for floating-point indefinite Section 8.5.1.2: 0/0, 0*Inf, Inf-Inf, etc., return this QNaN floating-point indefinite. So at least for Intel x87 processors, the sign bit of the canonical QNaN for floating-point indefinite should be 1.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #6 from lucier at math dot purdue.edu 2011-12-08 14:31:23 UTC --- PS: I don't know whether IEEE says anything about the sign bit, but I doubt it. Brad
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 kargl at gcc dot gnu.org changed: What|Removed |Added CC||kargl at gcc dot gnu.org --- Comment #7 from kargl at gcc dot gnu.org 2011-12-08 15:29:17 UTC --- (In reply to comment #6) PS: I don't know whether IEEE says anything about the sign bit, but I doubt it. Brad 6.3 The Sign Bit This standard does not interpret the sign of an NaN. -- steve
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #8 from Dominique d'Humieres dominiq at lps dot ens.fr 2011-12-08 16:06:43 UTC --- Does IEEE say anything about the sign of the qnan? From Draft 1.2.5 DRAFT Standard for Floating-Point Arithmetic P754 October 4, 2006 at http://www.validlab.com/754R/drafts/archive/2006-10-04.pdf : 8.2.1 NaN encodings in binary formats ... All binary NaN bitstrings have all the bits of the biased exponent field E set to 1 (see 5.4). A quiet NaN bitstring should be encoded with the first bit (d1) of the trailing significand field T being 1. A signaling NaN bitstring should be encoded with the first bit of the trailing significand field being 0. If the first bit of the trailing significand is 0, some other bit of the trailing significand field must be non-zero to distinguish the NaN from infinity. In the preferred encoding, a signaling NaN should be quieted by setting d1 to 1, leaving the remaining bits of T unchanged. ... 8.3 The sign bit 8.3.0 When either an input or result is NaN, this standard does not interpret the sign of a NaN. Note however that operations on bitstrings – copy, negate, abs, copySign – specify the sign bit of a NaN result, sometimes based upon the sign bit of a NaN operand. The logical predicate totalOrder is also affected by the sign bit of a NaN operand. For all other operations, this standard does not specify the sign bit of a NaN result, even when there is only one input NaN, or when the NaN is produced from an invalid operation. ...
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #9 from lucier at math dot purdue.edu 2011-12-08 17:05:43 UTC --- Table 4.7 of the AMD64 Architecture Programmer’s Manual Volume 1: Application Programming has a footnote 3 that says 3. The floating-point indefinite value is a QNaN with a negative sign and a significand whose value is 1.100 ... 000. Table 4.8 gives the encodings for all the indefinite values again.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #10 from lucier at math dot purdue.edu 2011-12-08 18:32:56 UTC --- Near the end of section 5.3.2 of Book E: Enhanced PowerPC Architecture Version 1.0 May 7, 2002 it says Any instruction that generates a QNaN as the result of a disabled Invalid Operation must generate this QNaN (i.e., 0x7FF8___). The string x7ff8 does not otherwise occur in the manual. The book PowerPC User Instruction Set Architecture Book I Version 2.02 January 28, 2005 has the same text. And a small test on my 10-year-old Mac Cube with a G4 powerpc processor shows that the results have sign bit = 0, i.e., the output is 9221120237041090560 9221120237041090560 So the result is architecture dependent. Blah. Brad
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 Jakub Jelinek jakub at gcc dot gnu.org changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #11 from Jakub Jelinek jakub at gcc dot gnu.org 2011-12-08 18:59:12 UTC --- find libgcc/config -name sfp-machine.h | xargs grep NANSIGN shows we already track it for a banch of targets, just in libgcc soft-fp configuration and not in the compiler itself. Not sure how accurrate it is on all targets, but i?86/x86_64/ia64 use negative qNaNs, others positive.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #12 from joseph at codesourcery dot com joseph at codesourcery dot com 2011-12-08 20:37:11 UTC --- I think the soft-fp code tries to generate particular target-specific NaNs because it's also used in the Linux kernel emulation of floating-point instructions - which is a use case where doing the same as particular hardware is desirable. At the level of GCC compiling C code, the compiler provides the language semantics. It doesn't provide the semantics of any particular choice of instructions someone might expect to be used to implement the source code - and in particular doesn't guarantee any choice of NaN where the language (and IEEE 754 as applicable) don't determine the choice of NaN.
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #13 from lucier at math dot purdue.edu 2011-12-08 20:54:18 UTC --- On Thu, 2011-12-08 at 20:37 +, joseph at codesourcery dot com wrote: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #12 from joseph at codesourcery dot com joseph at codesourcery dot com 2011-12-08 20:37:11 UTC --- I think the soft-fp code tries to generate particular target-specific NaNs because it's also used in the Linux kernel emulation of floating-point instructions - which is a use case where doing the same as particular hardware is desirable. Indeed, I couldn't find a place in the gcc sources where this macro was used: heine:~/programs/gcc/mainline grep -R _FP_NANSIGN_Q * | grep -v svn libgcc/config/ia64/sfp-machine.h:#define _FP_NANSIGN_Q1 libgcc/config/score/sfp-machine.h:#define _FP_NANSIGN_Q0 libgcc/config/rs6000/sfp-machine.h:#define _FP_NANSIGN_Q0 libgcc/config/i386/32/sfp-machine.h:#define _FP_NANSIGN_Q1 libgcc/config/i386/64/sfp-machine.h:#define _FP_NANSIGN_Q1 libgcc/config/c6x/sfp-machine.h:#define _FP_NANSIGN_Q0 libgcc/config/moxie/sfp-machine.h:#define _FP_NANSIGN_Q0 libgcc/config/lm32/sfp-machine.h:#define _FP_NANSIGN_Q0 libgcc/config/arm/sfp-machine.h:#define _FP_NANSIGN_Q0 At the level of GCC compiling C code, the compiler provides the language semantics. It doesn't provide the semantics of any particular choice of instructions someone might expect to be used to implement the source code - and in particular doesn't guarantee any choice of NaN where the language (and IEEE 754 as applicable) don't determine the choice of NaN. I don't think the result of 0./0. in C code on a particular target should depend on telling the compiler that the runtime library is set up so that floating-point operations never trap. Brad
[Bug middle-end/51446] -fno-trapping-math generates NaN constant with different sign
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446 --- Comment #14 from joseph at codesourcery dot com joseph at codesourcery dot com 2011-12-08 22:32:24 UTC --- On Thu, 8 Dec 2011, lucier at math dot purdue.edu wrote: Indeed, I couldn't find a place in the gcc sources where this macro was used: heine:~/programs/gcc/mainline grep -R _FP_NANSIGN_Q * | grep -v svn It's used as _FP_NANSIGN_##fs. At the level of GCC compiling C code, the compiler provides the language semantics. It doesn't provide the semantics of any particular choice of instructions someone might expect to be used to implement the source code - and in particular doesn't guarantee any choice of NaN where the language (and IEEE 754 as applicable) don't determine the choice of NaN. I don't think the result of 0./0. in C code on a particular target should depend on telling the compiler that the runtime library is set up so that floating-point operations never trap. This is just the same as other unspecified things like converting an out-of-range value from floating-point to integer. There is no C language binding to the processor that defines the result of a/b as being the result of some particular divide instruction (and it's quite likely that on some processors the choice of NaN could depend e.g. on whether a scalar or vector instruction is used); it's only specified as far as the language specifies it. This also allows transformations such as converting -1.0*x to -x even if -1.0*x doesn't change the sign of an input NaN (negate *is* specified by 754-2008 to change the sign of a NaN).