Bug 323 - optimized code gives strange floating point results
Summary: optimized code gives strange floating point results
Status: SUSPENDED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 2.95.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: https://gcc.gnu.org/bugzilla/show_bug...
Keywords: wrong-code
: 629 1098 2582 4251 6824 6900 7719 7935 8606 10417 10644 11394 11518 11655 11892 11914 11934 12129 12331 13265 13890 14367 14384 14652 14989 15134 15386 15437 15852 16223 16607 16686 16825 17802 18567 18756 18784 19011 19469 19675 19837 20026 20674 21809 22394 23298 23318 23407 24014 24387 25303 26000 28191 29597 30255 30752 30813 31008 32391 32976 33611 34261 34616 34951 34992 35389 35489 37390 38777 39128 40186 41195 41867 44198 45175 45691 45899 47282 47600 47834 48236 53095 55267 55544 55700 55787 55939 57080 57669 59168 61626 62623 64808 66282 85661 87128 93620 103030 106165 110564 110622 113679 (view as bug list)
Depends on:
Blocks: 92875
  Show dependency treegraph
 
Reported: 2000-06-14 14:16 UTC by mirtich
Modified: 2024-02-22 10:04 UTC (History)
93 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
bug.ii.gz (2.88 KB, application/x-gzip )
2003-05-21 15:17 UTC, mirtich
Details

Note You need to log in before you can comment on or make changes to this bug.
Description mirtich 2000-06-14 14:16:01 UTC
A simple program gives incorrect floating point results
when compiled with the -O flag.  The complete source code
is in the How-To-Repeat section below.

This program prints "error" when compiled with -O; clearly 
wrong.  The unoptimized code correctly prints no output.
Also, if I try to print out the value of y2 before the
comparison with y, then the correct value is output, 
and there is no "error" message, even when the code is
optimized.  In other words, interposing a print statement
between the declaration (and initialization) of y2 and the
comparison changes the program behavior.  The error
disappears for certain different values of the numerical
constants.  The error also goes away when an "l" suffix is 
appended to the two 1.0 constants.  However, it is also
possible to create the same type of error using only
variables and no numerical constants in the assignments to
y and y2; in this situation there is no "l" suffix 
workaround.

The gzipped .ii file is attached. 
Here is the output of gcc:

> /usr/local/bin/gcc -v --save-temps -O bug.C
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cpp -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__EXCEPTIONS -D__OPTIMIZE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__ bug.C bug.ii
GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../include/g++-3
 /usr/local/include
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../i686-pc-linux-gnu/include
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cc1plus bug.ii -quiet -dumpbase bug.cc -O -version -o bug.s
GNU C++ version 2.95.2 19991024 (release) (i686-pc-linux-gnu) compiled by GNU C version 2.95.2 19991024 (release).
 as -V -Qy -o bug.o bug.s
GNU assembler version 2.9.1 (i386-redhat-linux), using BFD version 2.9.1.0.24
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtbegin.o -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2 -L/usr/local/lib bug.o -lgcc -lc -lgcc /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/crtend.o /usr/lib/crtn.o

Release:
gcc version 2.95.2 19991024 (release)

Environment:
(Red Hat) Linux 2.2.12-20, i686 pc

How-To-Repeat:
#include <stdio.h>

void test(double x, double y)
{
  const double y2 = x + 1.0;
  if (y != y2) printf("error\n");
}

void main()
{
  const double x = .012;
  const double y = x + 1.0;

  test(x, y);
}
Comment 1 mirtich 2000-06-14 14:16:01 UTC
Fix:
This bug is elusive and only occurs for certain floating
point values.  It goes away by tweaking the program in
various ways (e.g. printing out the value of y2 before
comparing it) or by compiling unoptimized.
Comment 2 Richard Henderson 2001-01-16 06:30:04 UTC
State-Changed-From-To: open->closed
State-Changed-Why: See any faq on numerical analysis that mentions the x86.
    You are seeing the results of excess precision in the FPU.
    Either change the rounding precision in the FPCR, or work
    around the problem with -ffloat-store.
Comment 3 Richard Henderson 2001-01-16 14:30:04 UTC
From: rth@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, mirtich@merl.com, nobody@gcc.gnu.org
Cc:  
Subject: Re: optimization/323
Date: 16 Jan 2001 14:30:04 -0000

 Synopsis: optimized code gives strange floating point results
 
 State-Changed-From-To: open->closed
 State-Changed-By: rth
 State-Changed-When: Tue Jan 16 06:30:04 2001
 State-Changed-Why:
     See any faq on numerical analysis that mentions the x86.
     You are seeing the results of excess precision in the FPU.
     Either change the rounding precision in the FPCR, or work
     around the problem with -ffloat-store.
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=323&database=gcc
Comment 4 Andrew Pinski 2003-07-01 18:36:16 UTC
*** Bug 11394 has been marked as a duplicate of this bug. ***
Comment 5 Andrew Pinski 2003-07-01 18:39:14 UTC
*** Bug 629 has been marked as a duplicate of this bug. ***
Comment 6 Andrew Pinski 2003-07-01 18:45:24 UTC
*** Bug 4251 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2003-07-01 18:46:05 UTC
*** Bug 6900 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2003-07-01 18:46:52 UTC
*** Bug 10417 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2003-07-05 00:06:59 UTC
Reopening so I can mark it as ...
Comment 10 Andrew Pinski 2003-07-05 00:07:34 UTC
Invalid and so that bugzilla can pick up it for the dup count.
Comment 11 Andrew Pinski 2003-07-06 19:11:53 UTC
*** Bug 10644 has been marked as a duplicate of this bug. ***
Comment 12 Andrew Pinski 2003-07-06 19:16:24 UTC
*** Bug 2582 has been marked as a duplicate of this bug. ***
Comment 13 Andrew Pinski 2003-07-06 19:20:26 UTC
*** Bug 8606 has been marked as a duplicate of this bug. ***
Comment 14 Andrew Pinski 2003-07-10 11:35:13 UTC
*** Bug 6824 has been marked as a duplicate of this bug. ***
Comment 15 Andrew Pinski 2003-07-14 12:45:17 UTC
*** Bug 11518 has been marked as a duplicate of this bug. ***
Comment 16 Andrew Pinski 2003-07-21 17:28:50 UTC
*** Bug 11618 has been marked as a duplicate of this bug. ***
Comment 17 Andrew Pinski 2003-07-24 02:40:46 UTC
*** Bug 11655 has been marked as a duplicate of this bug. ***
Comment 18 Andrew Pinski 2003-08-03 14:14:29 UTC
*** Bug 11767 has been marked as a duplicate of this bug. ***
Comment 19 Andrew Pinski 2003-08-04 18:18:36 UTC
*** Bug 11767 has been marked as a duplicate of this bug. ***
Comment 20 Andrew Pinski 2003-08-12 12:51:35 UTC
*** Bug 11892 has been marked as a duplicate of this bug. ***
Comment 21 Christian Ehrhardt 2003-08-14 07:28:44 UTC
*** Bug 11914 has been marked as a duplicate of this bug. ***
Comment 22 Andrew Pinski 2003-08-15 20:24:06 UTC
*** Bug 11934 has been marked as a duplicate of this bug. ***
Comment 23 Andrew Pinski 2003-09-02 13:34:19 UTC
*** Bug 12129 has been marked as a duplicate of this bug. ***
Comment 24 Andrew Pinski 2003-09-18 18:36:53 UTC
*** Bug 12331 has been marked as a duplicate of this bug. ***
Comment 25 Andrew Pinski 2003-12-01 22:47:02 UTC
*** Bug 13265 has been marked as a duplicate of this bug. ***
Comment 26 Wolfgang Bangerth 2004-01-27 22:51:16 UTC
*** Bug 13890 has been marked as a duplicate of this bug. ***
Comment 27 Andrew Pinski 2004-03-01 17:28:51 UTC
*** Bug 14367 has been marked as a duplicate of this bug. ***
Comment 28 Andrew Pinski 2004-03-03 19:18:36 UTC
*** Bug 14384 has been marked as a duplicate of this bug. ***
Comment 29 Andrew Pinski 2004-03-11 05:48:35 UTC
*** Bug 14384 has been marked as a duplicate of this bug. ***
Comment 30 Andrew Pinski 2004-03-19 15:41:34 UTC
*** Bug 14652 has been marked as a duplicate of this bug. ***
Comment 31 Andrew Pinski 2004-04-17 05:29:25 UTC
*** Bug 14989 has been marked as a duplicate of this bug. ***
Comment 32 Andrew Pinski 2004-04-25 16:55:39 UTC
*** Bug 15134 has been marked as a duplicate of this bug. ***
Comment 33 Andrew Pinski 2004-05-14 16:54:38 UTC
*** Bug 15437 has been marked as a duplicate of this bug. ***
Comment 34 Andrew Pinski 2004-06-06 18:13:28 UTC
*** Bug 15852 has been marked as a duplicate of this bug. ***
Comment 35 Andrew Pinski 2004-06-27 19:46:20 UTC
*** Bug 16223 has been marked as a duplicate of this bug. ***
Comment 36 Andrew Pinski 2004-07-17 17:40:24 UTC
*** Bug 16607 has been marked as a duplicate of this bug. ***
Comment 37 Andrew Pinski 2004-07-17 22:29:13 UTC
*** Bug 16607 has been marked as a duplicate of this bug. ***
Comment 38 Andrew Pinski 2004-07-19 01:19:19 UTC
*** Bug 15386 has been marked as a duplicate of this bug. ***
Comment 39 Zack Weinberg 2004-07-19 03:22:04 UTC
*** Bug 16607 has been marked as a duplicate of this bug. ***
Comment 40 Andrew Pinski 2004-07-23 09:21:00 UTC
*** Bug 16686 has been marked as a duplicate of this bug. ***
Comment 41 Andrew Pinski 2004-10-03 14:54:07 UTC
*** Bug 17802 has been marked as a duplicate of this bug. ***
Comment 42 sliwa@cft.edu.pl 2004-10-03 15:52:19 UTC
Excessive precision should be discarded before performing any comparison. It is
done e.g. by the Intel fortran compiler. -ffloat-store rounds only the values
stored in a variable, and in some situations may trigger instead of suppressing
the bug. Existing numerical software packages (e.g. LAPACK and SLATEC fortran
libraries) fail their tests with gcc just due to this issue.
So it is a bug, even if almost all other compilers reproduce it.
If you refer me to a FAQ on numerical analysis, please note that the FAQ states
things as they are, and not as they should be.
Comment 43 Jonathan Knispel 2004-10-04 10:57:28 UTC
Some musings based on my encounter with this bug...

Comparison of doubles is not just restricted to numerical analysis.  Bug report
17802 (aka #323) arose out of a binary search of a timer queue.  Is it wrong to
assume that if "int secs = 2" and "int usecs = 100000" then "secs + 1e-6 *
usecs" will return the same result every time it is evaluated as an inline function?

Calling a trivial function twice with an identical parameter may return a value
less than, equal to or greater than itself (depending on register allocation in
the context of the calls).  This is a really nasty piece of nondeterministic
behaviour.  Weren't compilers and "high level" languages invented to get around
exactly this kind of hardware dependency?

Compiling with -ffloat-store did not help in my case.  Compiling without -O
isn't always possible either.  Since the function that causes the problem is the
trivial calculation above, inlined for performance, I can't guarrantee that
every user of the header file it appears in will know to compile without -O (or
be willing to).  The outcome will be users reporting a bug in my code.

This bug is being reported regularly, and probably affecting a lot more people
that don't report it.
Comment 44 Andrew Pinski 2004-11-19 15:32:42 UTC
*** Bug 18567 has been marked as a duplicate of this bug. ***
Comment 45 Andrew Pinski 2004-11-19 15:33:11 UTC
*** Bug 18567 has been marked as a duplicate of this bug. ***
Comment 46 Andrew Pinski 2004-12-01 15:12:37 UTC
*** Bug 18756 has been marked as a duplicate of this bug. ***
Comment 47 eda-qa 2004-12-01 16:24:06 UTC
To summarize, this defect effectively states that:

assert( (x/y) == (x/y) )

may cause an assertion if compiled with optimization.

While I understand why it happens, that doesn't mean it isn't a defect.  This
makes it impossible to turn on the optimizer with any code using floating point
and still expect to get a correct result.  Perhaps in some situations this is
okay, but in general this is not.

This would also mean the following are also invalid code -- which I'm fairly
certain the C/C++ standards would state otherwise:

a = (x/y);
assert( a == x/y ) //may Abort

if( a == x/y )
  assert( a == x/y )  //may Abort
Comment 48 Andrew Pinski 2004-12-02 14:22:04 UTC
*** Bug 18784 has been marked as a duplicate of this bug. ***
Comment 49 Andrew Pinski 2004-12-15 14:05:11 UTC
*** Bug 19011 has been marked as a duplicate of this bug. ***
Comment 50 Andrew Pinski 2004-12-15 15:10:33 UTC
*** Bug 19011 has been marked as a duplicate of this bug. ***
Comment 51 Andrew Pinski 2005-01-17 15:40:03 UTC
*** Bug 19469 has been marked as a duplicate of this bug. ***
Comment 52 Andrew Pinski 2005-01-28 18:47:16 UTC
*** Bug 19675 has been marked as a duplicate of this bug. ***
Comment 53 Andrew Pinski 2005-01-28 19:07:38 UTC
*** Bug 19675 has been marked as a duplicate of this bug. ***
Comment 54 Andrew Pinski 2005-02-09 06:35:00 UTC
*** Bug 19837 has been marked as a duplicate of this bug. ***
Comment 55 Andrew Pinski 2005-02-17 13:37:31 UTC
*** Bug 20026 has been marked as a duplicate of this bug. ***
Comment 56 Andrew Pinski 2005-03-28 21:53:54 UTC
*** Bug 20674 has been marked as a duplicate of this bug. ***
Comment 57 Andrew Pinski 2005-03-29 14:17:03 UTC
*** Bug 20674 has been marked as a duplicate of this bug. ***
Comment 58 Andrew Pinski 2005-04-20 03:00:45 UTC
*** Bug 7719 has been marked as a duplicate of this bug. ***
Comment 59 Mario Tragni 2005-05-20 08:40:01 UTC
(In reply to comment #2)
> State-Changed-From-To: open->closed
> State-Changed-Why: See any faq on numerical analysis that mentions the x86.
>     You are seeing the results of excess precision in the FPU.
>     Either change the rounding precision in the FPCR, or work
>     around the problem with -ffloat-store.
> 

I had this bug on x86 architecture, with no optimization of the code (no -OX)
and with float-store on. My workaround was to store the return of the double
function in a auxliar double variable before comparison.
Have you an other suggestion ?
Comment 60 Richard Cognot 2005-05-20 10:03:26 UTC
(In reply to comment #59)
> 
> I had this bug on x86 architecture, with no optimization of the code (no -OX)
> and with float-store on. My workaround was to store the return of the double
> function in a auxliar double variable before comparison.
> Have you an other suggestion ?
> 

The way I've "fixed" (more like avoided) this problem is to have:

#include <fpu_control.h>

void set_math_double_precision() {
  fpu_control_t fpu_control = 0x027f ;
  _FPU_SETCW(fpu_control);
}

and make sure this function is called before doing any FP operations. It only
needs to be called once.

Richard.
Comment 61 Andrew Pinski 2005-05-29 16:24:48 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 62 Andrew Pinski 2005-05-29 18:27:38 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 63 Andrew Pinski 2005-05-29 19:06:30 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 64 Andrew Pinski 2005-05-29 19:24:44 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 65 Andrew Pinski 2005-05-29 19:35:02 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 66 Andrew Pinski 2005-05-29 19:43:57 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 67 Andrew Pinski 2005-05-29 19:47:57 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 68 Andrew Pinski 2005-05-29 19:56:04 UTC
*** Bug 21809 has been marked as a duplicate of this bug. ***
Comment 69 Steven Bosscher 2005-06-19 11:05:37 UTC
Reopening...
Comment 70 Steven Bosscher 2005-06-19 11:09:11 UTC
...to end this pointless discussion.

Some people call this a bug in the x87 series.  Other call it a bug in
gcc.  See these mails at least for the reason why this could be considered
a bug in gcc: 
http://gcc.gnu.org/ml/gcc/2003-08/msg01195.html
http://gcc.gnu.org/ml/gcc/2003-08/msg01234.html
http://gcc.gnu.org/ml/gcc/2003-08/msg01257.html

Regardless of where one wishes to put the blame, this problem will _not_ be
fixed.  Period.

Comment 71 Andrew Pinski 2005-06-19 12:18:54 UTC
*** Bug 1098 has been marked as a duplicate of this bug. ***
Comment 72 Andrew Pinski 2005-07-10 18:09:24 UTC
*** Bug 22394 has been marked as a duplicate of this bug. ***
Comment 73 Andrew Pinski 2005-08-09 15:59:29 UTC
*** Bug 23298 has been marked as a duplicate of this bug. ***
Comment 74 Andrew Pinski 2005-08-15 21:23:50 UTC
*** Bug 23407 has been marked as a duplicate of this bug. ***
Comment 75 Andrew Pinski 2005-08-16 13:22:11 UTC
*** Bug 23318 has been marked as a duplicate of this bug. ***
Comment 76 Andrew Pinski 2005-09-22 15:48:17 UTC
*** Bug 24014 has been marked as a duplicate of this bug. ***
Comment 77 Andrew Pinski 2005-10-15 18:34:49 UTC
*** Bug 24387 has been marked as a duplicate of this bug. ***
Comment 78 Andrew Pinski 2005-10-21 20:24:31 UTC
*** Bug 24479 has been marked as a duplicate of this bug. ***
Comment 79 Andrew Pinski 2005-11-10 03:41:15 UTC
*** Bug 7935 has been marked as a duplicate of this bug. ***
Comment 80 Andrew Pinski 2005-12-08 01:47:33 UTC
*** Bug 25303 has been marked as a duplicate of this bug. ***
Comment 81 Andrew Pinski 2006-01-28 03:56:02 UTC
*** Bug 26000 has been marked as a duplicate of this bug. ***
Comment 82 Andrew Pinski 2006-06-28 18:49:57 UTC
*** Bug 28191 has been marked as a duplicate of this bug. ***
Comment 83 Andrew Haley 2006-08-02 10:56:07 UTC
*** Bug 16825 has been marked as a duplicate of this bug. ***
Comment 84 Andrew Pinski 2006-10-25 22:05:04 UTC
*** Bug 29597 has been marked as a duplicate of this bug. ***
Comment 85 Andrew Pinski 2006-12-18 20:16:28 UTC
*** Bug 30255 has been marked as a duplicate of this bug. ***
Comment 86 Andrew Pinski 2006-12-18 22:04:05 UTC
*** Bug 30255 has been marked as a duplicate of this bug. ***
Comment 87 Bruno Haible 2006-12-21 15:08:57 UTC
The option -ffloat-store, recommended by Richard Henderson, has the effect of
decreasing the performance of floating-point operations for the entire
compilation unit. If you want a minimal fix that does not affect other
functions in the same compilation unit, you can use 'volatile double'
instead of 'double'. It's like a one-shot -ffloat-store. Example:

#include <stdio.h>

void test(double x, double y)
{
  const volatile double y2 = x + 1.0;
  if (y != y2) printf("error\n");
}

void main()
{
  const double x = .012;
  const double y = x + 1.0;

  test(x, y);
}

Comment 88 egon 2007-01-18 16:29:12 UTC
>   const volatile double y2 = x + 1.0;

I'd also favor this "selective" approach, because the instability is harmless in most cases.  But it is dangerous sometimes, as mentioned in the binary search or when sorting, where the faulty cmpfn() could turn the sort function to infinite loop.

So, could you please advise a body of hypothetical

double discard_extended_precision(double a);

function (possibly some 387 FP insn?) that reliably truncates the argument to 64bit?  Would

inline double discard_extended_precision(volatile double a) { return a; }

do the trick?
Comment 89 Brooks Moses 2007-02-10 00:55:13 UTC
*** Bug 30752 has been marked as a duplicate of this bug. ***
Comment 90 Richard Biener 2007-03-01 16:43:33 UTC
*** Bug 31008 has been marked as a duplicate of this bug. ***
Comment 91 Andrew Pinski 2007-03-09 20:11:28 UTC
*** Bug 31114 has been marked as a duplicate of this bug. ***
Comment 92 R. Clint Whaley 2007-03-09 20:22:32 UTC
I'd like to welcome the newest members of the bug 323 community, where all x87
floating point errors in gcc come to die!  All floating point errors that use
the x87 are welcome, despite the fact that many of them are easily fixable, and
many are not!  We're all one happy family, making the egregious mistake of wanting
accuracy out of the most accurate general purpose FPU on the market!

Cheers,
Clint
Comment 93 Andrew Pinski 2007-03-09 22:45:19 UTC
*** Bug 31114 has been marked as a duplicate of this bug. ***
Comment 94 Paolo Bonzini 2007-04-02 16:20:04 UTC
I think that Uros' patch to add a -mpc switch for precision control would "fix" this.

The real fix would be to automatically insert fldcw instructions before float/double operations, in order to limit the precision of the operations.  But I think that it would kill speed even more than -ffloat-store.
Comment 95 Guillaume Melquiond 2007-04-03 17:51:11 UTC
> I think that Uros' patch to add a -mpc switch for precision control would
> "fix" this.
> The real fix would be to automatically insert fldcw instructions before
> float/double operations, in order to limit the precision of the operations.
> But I think that it would kill speed even more than -ffloat-store.

Unfortunately, it is not that simple. The -mpc switch and the fldcw instructions control the size of the significant, but they don't control the range of the exponent. So it will solve the issue with the first testcase of this bug-report, but you could still build examples where two execution paths that perform the same floating-point computations produce completely different results.
Comment 96 David Monniaux 2007-04-20 21:19:59 UTC
The following paper explains how this kind of behaviour occurs, why it is "correct", why it is difficult to fix but how it can be partly fixed, and how this breaks many testing and proving techniques:

http://hal.archives-ouvertes.fr/hal-00128124
Comment 97 Andrew Pinski 2007-06-19 08:11:21 UTC
*** Bug 32391 has been marked as a duplicate of this bug. ***
Comment 98 sliwa@cft.edu.pl 2007-08-03 12:09:51 UTC
*** Bug 32976 has been marked as a duplicate of this bug. ***
Comment 99 Adrian Grajdeanu 2007-10-01 17:43:33 UTC
*** Bug 33611 has been marked as a duplicate of this bug. ***
Comment 100 Andrew Pinski 2007-12-29 19:46:50 UTC
*** Bug 34616 has been marked as a duplicate of this bug. ***
Comment 101 Andrew Pinski 2008-01-24 04:51:51 UTC
*** Bug 34951 has been marked as a duplicate of this bug. ***
Comment 102 Andrew Pinski 2008-01-27 23:17:32 UTC
*** Bug 34992 has been marked as a duplicate of this bug. ***
Comment 103 Andrew Pinski 2008-02-27 20:38:53 UTC
*** Bug 35389 has been marked as a duplicate of this bug. ***
Comment 104 Y. Wei 2008-02-27 21:41:17 UTC
Subject: RE:  optimized code gives strange floating point results

Not sure this is the same issues as 323. All three numbers, 8, 1 and 65,
should be able to represented in IEEE 754 floating-point format exactly
without any rounding or approximation. That is
 8 = 1* 2^3
  1 = 1* 2^0
  65  = (1 + 1/64) * 2^6


-----Original Message-----
From: pinskia at gcc dot gnu dot org [mailto:gcc-bugzilla@gcc.gnu.org] 
Sent: Wednesday, February 27, 2008 12:39 PM
To: Wei, Yongbin
Subject: [Bug rtl-optimization/323] optimized code gives strange
floating point results



------- Comment #103 from pinskia at gcc dot gnu dot org  2008-02-27
20:38 -------
*** Bug 35389 has been marked as a duplicate of this bug. ***


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
------------------------------------------------------------------------
----
                 CC|                            |ywei at qualcomm dot
com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
Comment 105 Andrew Pinski 2008-03-06 22:44:47 UTC
*** Bug 35488 has been marked as a duplicate of this bug. ***
Comment 106 Richard Biener 2008-03-06 23:14:57 UTC
*** Bug 35488 has been marked as a duplicate of this bug. ***
Comment 107 Andrew Pinski 2008-03-06 23:58:07 UTC
*** Bug 35489 has been marked as a duplicate of this bug. ***
Comment 108 Richard Biener 2008-03-14 17:30:25 UTC
*** Bug 35585 has been marked as a duplicate of this bug. ***
Comment 109 Jan Lachnitt 2008-05-20 16:59:31 UTC
I also encountered such problems and was going to report it as a bug in GCC...
But in the GCC bug (not) reporting guide, there is fortunately a link to this page and here (comment #96) is a link to David Monniaux's paper about floating-point computations. This explains it closely but it is maybe too long. I have almost read it and hope I have understood it properly. So I'll give a brief explanation (for those who don't know it yet) of the reasons of such a strange behaviour. Then I'll assess where the bug actually is (in GCC or CPU). Then I'll write the solution (!) and finally a few recommendations to the GCC team.

EXPLANATION
The x87 FPU was originally designed in (or before) 1980. I think that's why it is quite simple: it has only one unit for all FP data types. Of course, the precision must be of the widest type, which is the 80-bit long double.
Consider you have a program, where all the FP variables are of the type double. You perform some FP operations and one of them is e.g. 1e-300/1e300, which results in 1e-600. Despite this value cannot be held by a "double", it is stored in an 80-bit FPU register as the result. Consider you use the variable "x" to hold that result. If the program has been compiled with optimization, the value need not be stored in RAM. So, say, it is still in the register.
Consider you need x to be nonzero, so you perform the test x != 0. Since 1e-600 is not zero, the test yields true. While you perform some other computations, the value is moved to RAM and converted to 0 because x is of type "double". Now you want to use your certainly nonzero x... Hard luck :-(
Note that if the result doesn't have its corresponding variable and you perform the test directly on an expression, the problem can come to light even without optimization.
It could seem that performing all FP operations in extended precision can bring benefits only. But it introduces a serious pitfall: moving a value may change the value!!!

WHERE'S THE BUG
This is really not a GCC bug. The bug is actually in the x87 FPU because it doesn't obey the IEEE standard.

SOLUTION
The x87 FPU is still present in contemporary processors (including AMD) due to compatibility. I think most of PC software still uses it. But new processors have also another FPU, called SSE, and this do obey the IEEE. GCC in 32-bit mode compiles for x87 by default but it is able to compile for the SSE, too. So the solution is to add these options to the compilation command:
-march=* -msse -mfpmath=sse
Yes, this definitely resolves the problem - but not for all processors. The * can be one of the following: pentium3, pentium3m, pentium-m, pentium4, pentium4m, prescott, nocona, athlon-4, athlon-xp, athlon-mp, k8, opteron, athlon64, athlon-fx and c3-2 (I'm unsure about athlon and athlon-tbird). Beside -msse, you can also add some of -mmmx, -msse2, -msse3 and -m3dnow, if the CPU supports them (see GCC doc or CPU doc).
If you wish to compile for processors which don't have SSE, you have a few possibilities:
(1) A very simple solution: Use long double everywhere. (But be careful when transfering binary data in long double format between computers because this format is not standardized and so the concrete bit representations vary between different CPU architectures.)
(2) A partial but simple solution: Do comparisons on volatile variables only.
(3) A similar solution: Try to implement a "discard_extended_precision" function suggested by Egon in comment #88.
(4) A complex solution: Before doing any mathematical operation or comparison, put the operands into variables and put also the result to a variable (i.e. don't use complex expressions). For example, instead of { c = 2*(a+b); } , write { double s = a+b; c = 2*s; } . I'm unsure about arrays but I think they should be OK. When you have modified your code in this manner, then compile it either without optimization or, when using optimization, use -ffloat-store. In order to avoid double rounding (i.e. rounding twice), it is also good to decrease the FPU precision by changing its control word in the beginning of your program (see comment #60). Then you should also apply -frounding-math.
(5) A radical solution: Find a job/hobby where computers are not used at all.

RECOMMENDATIONS
I think this problem is really serious and general. Therefore, programmers should be warned soon enough.
This recommendation should be addressed especially to authors of programming coursebooks. But I think there could also be a paragraph about it in the GCC documentation (I haven't read it wholly but it doesn't seem there's any warning against x87). And, of course, there should be a warning in the bug reporting guide (http://gcc.gnu.org/bugs.html). It's fine there's a link to this page (Bug 323) but the example with (int)(a/b) is insufficient. It only demonstrates that real numbers are often not represented exactly in the computer. It doesn't demonstrate the x87 pitfall. Hence there should be an example such as the initial code of this "GCC bug 323 report". Because when one sees the example with (int)(a/b), he can say "It's trivial" and not click the link (as I did the first time).

EPILOGUE
I hope my effort of writing this "comment #109" will be helpful for many people.
If you want more info, read the David Monniaux's work or something else about FPUs.
Thanks to David Monniaux.
Comment 110 Jan Lachnitt 2008-06-12 14:14:50 UTC
I used an old version of GCC documentation so I omitted some new processors with SSE: core2, k8-sse3, opteron-sse3, athlon64-sse3, amdfam10 and barcelona.
I think you can use -march=pentium3 for all Intel's CPUs (of course, starting with P3). I'm unsure about AMD. (Maybe you know it better.)
Comment 111 Vincent Lefèvre 2008-06-20 16:09:13 UTC
(In reply to comment #109)
> WHERE'S THE BUG
> This is really not a GCC bug. The bug is actually in the x87 FPU because it
> doesn't obey the IEEE standard.

Concerning the standards: The x87 FPU does obey the IEEE754-1985 standard, which *allows* extended precision, and double precision is *available*. In fact, one could say that GCC even obeys the IEEE standard (which doesn't define bindings: the definition of "destination" page 4 of the IEEE754-1985 standard is rather vague and lets the language to define it exactly), but it doesn't obey the ISO C99 standard on some point.

Concerning the x87 FPU: One can say however that the x87 is a badly designed because it is not possible to statically specify the precision. Nevertheless the OS/language implementations should take care of this problem.

Note: the solution chosen by some OS'es (*BSD, MS-Windows...) is to configure the processor to the IEEE double precision by default (thus "long double" is also in double precision, but this is OK as far as the C language is concerned, there's still a problem with "float", but in practice, nobody cares AFAIK).

> If you wish to compile for processors which don't have SSE, you have a few
> possibilities:
> (1) A very simple solution: Use long double everywhere.

This avoids the bug, but this is not possible for software that requires double precision exactly, e.g. XML tools that use XPath. See other examples here:

  http://www.vinc17.org/research/extended.en.html

Also this makes maintenance of software more difficult because long double can be much slower on some platforms, which support this type in software to provide more precision (e.g. PowerPC Linux and Mac OS X implement a double-double arithmetic, Solaris and HPUX implement quadruple precision).

> (But be careful when transfering binary data in long double format between
> computers because this format is not standardized and so the concrete bit
> representations vary between different CPU architectures.)

Well, this is not specific to long double anyway: there exist 3 possible endianess for the double format (x86, PowerPC, ARM).

> (2) A partial but simple solution: Do comparisons on volatile variables only.

Yes (but this is also a problem concerning the maintenance of portable programs).

> (4) A complex solution: [...]

Yes, this is the workaround I use in practice.

> RECOMMENDATIONS
> I think this problem is really serious and general. Therefore, programmers
> should be warned soon enough.

Yes, but note that this is not the only problem with compilers. See e.g.

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36578

for a bug related to casts to long double on x86_64 and ia64. This one is now tested by: http://www.vinc17.org/software/tst-ieee754.c (which has also tested bug 323 for a long time).
Comment 112 Jan Lachnitt 2008-06-21 22:38:17 UTC
(In reply to comment #111)
> Concerning the standards: The x87 FPU does obey the IEEE754-1985 standard,
> which *allows* extended precision, and double precision is *available*.

It's true that double *precision* is available on x87. But not the *IEEE-754 "double precision" type*. Beside the precision of mantissa, this includes also the range of exponent. On the x87, it is possible to set the precision of mantissa but not the range of exponent. That's why I believe it doesn't obey the IEEE. (I haven't ever seen the IEEE-754 standard but I base on the work of David Monniaux.)

> Note: the solution chosen by some OS'es (*BSD, MS-Windows...) is to configure
> the processor to the IEEE double precision by default (thus "long double" is
> also in double precision, but this is OK as far as the C language is concerned,
> there's still a problem with "float", but in practice, nobody cares AFAIK).

Do you mean that on Windows, long double has (by default) no more precision than double? I don't think so (it's confirmed by my experience). According to the paper of David Monniaux, only FreeBSD 4 sets double precision by default (but I know almost nothing about BSD).

> > (1) A very simple solution: Use long double everywhere.
> This avoids the bug, but this is not possible for software that requires double
> precision exactly, e.g. XML tools that use XPath.

Yes, of course. I don't say this can be used everywhere.

> > (But be careful when transfering binary data in long double format between
> > computers because this format is not standardized and so the concrete bit
> > representations vary between different CPU architectures.)
> Well, this is not specific to long double anyway: there exist 3 possible
> endianess for the double format (x86, PowerPC, ARM).

OK but David Monniaux mentions portability issues just in the case of long double, so the differences are probably more frequent in this case (maybe even within the x86 architecture).

> Yes, but note that this is not the only problem with compilers. See e.g.
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36578

Thanks for info.
Comment 113 Vincent Lefèvre 2008-06-22 00:52:49 UTC
(In reply to comment #112)
> It's true that double *precision* is available on x87. But not the *IEEE-754
> "double precision" type*.

It is available when storing a result to memory.

> Beside the precision of mantissa, this includes also the range of exponent.
> On the x87, it is possible to set the precision of mantissa but not the range
> of exponent.

The IEEE754-1985 allows this. Section 4.3: "Normally, a result is rounded to the precision of its destination. However, some systems deliver results only to double or extended destinations. On such a system the user, which may be a high-level language compiler, shall be able to specify that a result be rounded instead to single precision, though it may be stored in the double or extended format with its wider exponent range. [...]"

> That's why I believe it doesn't obey the IEEE. (I haven't ever seen the
> IEEE-754 standard but I base on the work of David Monniaux.)

See above. Also beware of subtilities in the wording used by David Monniaux. FYI, the IEEE754-1985 standard (with minor corrections) is available from the following page:
  http://www.validlab.com/754R/
(look at the end). AFAIK, the IEEE754-1985 standard was designed from the x87 implementation, so it would have been very surprising that x87 didn't conform to IEEE754-1985.

> Do you mean that on Windows, long double has (by default) no more precision
> than double? I don't think so (it's confirmed by my experience).

I don't remember my original reference, but here's a new one:
  http://msdn.microsoft.com/en-us/library/aa289157(vs.71).aspx
In fact, this depends on the architecture. I quote: "x86. Intermediate expressions are computed at the default 53-bit precision with an extended range provided by a 16-bit exponent. When these 53:16 values are "spilled" to memory (as can happen during a function call), the extended exponent range will be narrowed to 11-bits. That is, spilled values are cast to the standard double precision format with only an 11-bit exponent.
A user may switch to extended 64-bit precision for intermediate rounding by altering the floating-point control word using _controlfp and by enabling FPU environment access (see The fpenv_access Pragma). However, when extended precision register-values are spilled to memory, the intermediate results will still be rounded to double precision.
This particular semantic is subject to change."

Note that the behavior has changed in some version of Windows (it was using the extended precision, then it switched to double precision for x86). Now, this may also depend on the compiler.

> According to the paper of David Monniaux, only FreeBSD 4 sets double
> precision by default (but I know almost nothing about BSD).

I've noted that amongst the BSD's, NetBSD does this too (I don't remember if I've tried or got it from some document, and this might also depend on the NetBSD version and/or the processor).
Comment 114 Jan Lachnitt 2008-06-22 16:59:58 UTC
(In reply to comment #113)
> It is available when storing a result to memory.

Yes, but this requires quite a complicated workaround (solution (4) in my comment #109). So you could say that the IEEE754 double precision type is available even on a processor without any FPU because this can be emulated using integers.
Moreover, if we assess things pedantically, the workaround (4) still doesn't fully obey the IEEE single/double precision type(s), because there remains the problem of double rounding of denormals.

> The IEEE754-1985 allows this. Section 4.3: "Normally, a result is rounded to
> the precision of its destination. However, some systems deliver results only to
> double or extended destinations. On such a system the user, which may be a
> high-level language compiler, shall be able to specify that a result be rounded
> instead to single precision, though it may be stored in the double or extended
> format with its wider exponent range. [...]"
> [...]
> AFAIK, the IEEE754-1985 standard was designed from the x87
> implementation, so it would have been very surprising that x87 didn't conform
> to IEEE754-1985.

So it seems I was wrong but the IEEE754-1985 standard is also quite "wrong".

> > Do you mean that on Windows, long double has (by default) no more precision
> > than double? I don't think so (it's confirmed by my experience).
> I don't remember my original reference, but here's a new one:
>   http://msdn.microsoft.com/en-us/library/aa289157(vs.71).aspx
> In fact, this depends on the architecture. I quote: "x86. Intermediate
> expressions are computed at the default 53-bit precision with an extended range
> [...]"

I quote, too:
"Applies To
   Microsoft&#174; Visual C++&#174;"
Comment 115 Jan Lachnitt 2008-06-22 17:28:46 UTC
That &#174; should be (R).
Comment 116 Vincent Lefèvre 2008-06-22 21:14:15 UTC
(In reply to comment #114)
> Yes, but this requires quite a complicated workaround (solution (4) in my
> comment #109).

The problem is on the compiler side, which could store every result of a cast or an assignment to memory (this is inefficient, but that's what you get with the x87, and the ISO C language could be blamed too for *requiring* something like that instead of being more flexible).

> So you could say that the IEEE754 double precision type is available even on
> a processor without any FPU because this can be emulated using integers.

Yes, but a conforming implementation would be the processor + a library, not just the processor with its instruction set.

> Moreover, if we assess things pedantically, the workaround (4) still doesn't
> fully obey the IEEE single/double precision type(s), because there remains the
> problem of double rounding of denormals.

As I said, in this particular case (underflow/overflow), double rounding is allowed by the IEEE standard. It may not be allowed by some languages (e.g. XPath, and Java in some mode) for good or bad reasons, but this is another problem.

> I quote, too:
> "Applies To
>    Microsoft&#174; Visual C++&#174;"

Now I assume that it follows the MS-Windows API (though nothing is certain with Microsoft). And the other compilers under MS-Windows could (or should) do the same thing.
Comment 117 Jan Lachnitt 2008-06-24 20:12:14 UTC
(In reply to comment #116)
> > Yes, but this requires quite a complicated workaround (solution (4) in my
> > comment #109).
> 
> The problem is on the compiler side, which could store every result of a cast
> or an assignment to memory (this is inefficient, but that's what you get with
> the x87, and the ISO C language could be blamed too for *requiring* something
> like that instead of being more flexible).
> 
> > So you could say that the IEEE754 double precision type is available even on
> > a processor without any FPU because this can be emulated using integers.
> 
> Yes, but a conforming implementation would be the processor + a library, not
> just the processor with its instruction set.
> 
> > Moreover, if we assess things pedantically, the workaround (4) still doesn't
> > fully obey the IEEE single/double precision type(s), because there remains the
> > problem of double rounding of denormals.
> 
> As I said, in this particular case (underflow/overflow), double rounding is
> allowed by the IEEE standard. It may not be allowed by some languages (e.g.
> XPath, and Java in some mode) for good or bad reasons, but this is another
> problem.

OK, thanks for explanation. I think now it's clear.

> > I quote, too:
> > "Applies To
> >    Microsoft&#174; Visual C++&#174;"
> 
> Now I assume that it follows the MS-Windows API (though nothing is certain with
> Microsoft). And the other compilers under MS-Windows could (or should) do the
> same thing.

By a lucky hit, I have found this in the GCC documentation:
"
-mpc32
-mpc64
-mpc80
Set 80387 floating-point precision to 32, 64 or 80 bits. When '-mpc32' is specified,
the significands of results of floating-point operations are rounded to 24
bits (single precision); '-mpc64' rounds the the significands of results of floatingpoint
operations to 53 bits (double precision) and '-mpc80' rounds the significands
of results of floating-point operations to 64 bits (extended double precision),
which is the default. When this option is used, floating-point operations
in higher precisions are not available to the programmer without setting the
FPU control word explicitly.
[...]"

So GCC sets extended precision by default. And it's easy to change it.
Comment 118 Vincent Lefèvre 2008-06-24 20:45:31 UTC
(In reply to comment #117)
> By a lucky hit, I have found this in the GCC documentation:
> "
> -mpc32
> -mpc64
> -mpc80

OK, this is new in gcc 4.3. I haven't tried, but if gcc just changes the precision without changing the values of <float.h> macros to make them correct, this is just a workaround (better than nothing, though). Also, this is a problem for library code if it requires to have double precision instead of extended precision, as these options won't probably be taken into account at that point. (Unfortunately it's probably too late to have a clean ABI.)
Comment 119 Marek Brudka 2008-07-17 10:45:03 UTC
Another example related with fp on x87?

EXPECTED RESULT:
0 (with EPS accuracy)
0 (with EPS accuracy)
0 (with EPS accuracy)
0 (with EPS accuracy)

REAL RESULT:
5.313991e+33
5.313991e+33
0.000000e+00
0.000000e+00

CODE
#include <stdio.h>
int main( void )
{
  /* register */ double d1 = 1e50;
  /* register */ double d2 = -2.7438011834107752e+51;
  /* register */ double s = 0.036445789368634796;
  /* register */ double d3 = -d1/s;
  /* register */ double d4 = s*d2;
  /* register */ double d5 = s*d3;
  printf( "%e\n", d1 + s*d2);
  printf( "%e\n", d1 + s*d3);
  printf( "%e\n", d1 + d4);
  printf( "%e\n", d1 + d5);
  return 0;
}
Comment 120 Vincent Lefèvre 2008-07-17 12:41:50 UTC
(In reply to comment #119)
> REAL RESULT:
> 5.313991e+33
> 5.313991e+33
> 0.000000e+00
> 0.000000e+00

Only without optimizations. But since the ISO C standard allows expressions to be evaluated in a higher precision, there's no bug here (unless you show a contradiction with the value of FLT_EVAL_METHOD, but the FP_CONTRACT pragma should also be set to OFF -- though this currently has no effect on gcc).
Comment 121 Marek Brudka 2008-07-17 12:51:14 UTC
Thank you Vincent. I fact after commenting I realized that this is a plain numerical error on the last digit of double in multiplication. I think that my comment was rather irrelevant and I am the more ashamed the more I cannot remove it from bugzilla :)
Comment 122 Andrew Pinski 2008-09-06 18:01:22 UTC
*** Bug 37390 has been marked as a duplicate of this bug. ***
Comment 123 Joseph S. Myers 2008-11-04 13:25:42 UTC
Subject: Bug 323

Author: jsm28
Date: Tue Nov  4 13:24:30 2008
New Revision: 141578

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141578
Log:
	PR rtl-optimization/323
	* c-common.c (convert_and_check, c_common_truthvalue_conversion):
	Handle EXCESS_PRECISION_EXPR.
	* c-common.def (EXCESS_PRECISION_EXPR): New.
	* c-cppbuiltin.c (builtin_define_float_constants): Define
	constants with enough digits for long double.
	* c-lex.c (interpret_float): Interpret constant with excess
	precision where appropriate.
	* c-opts.c (c_common_post_options): Set
	flag_excess_precision_cmdline.
	* c-parser.c (c_parser_conditional_expression): Handle excess
	precision in condition.
	* c-typeck.c (c_fully_fold): Handle EXCESS_PRECISION_EXPR.
	(c_fully_fold_internal): Disallow EXCESS_PRECISION_EXPR.
	(convert_arguments): Handle arguments with excess precision.
	(build_unary_op): Move excess precision outside operation.
	(build_conditional_expr): Likewise.
	(build_compound_expr): Likewise.
	(build_c_cast): Do cast on operand of EXCESS_PRECISION_EXPR.
	(build_modify_expr): Handle excess precision in RHS.
	(convert_for_assignment): Handle excess precision in converted
	value.
	(digest_init, output_init_element, process_init_element): Handle
	excess precision in initializer.
	(c_finish_return): Handle excess precision in return value.
	(build_binary_op): Handle excess precision in operands and add
	excess precision as needed for operation.
	* common.opt (-fexcess-precision=): New option.
	* config/i386/i386.h (X87_ENABLE_ARITH, X87_ENABLE_FLOAT): New.
	* config/i386/i386.md (float<SSEMODEI24:mode><X87MODEF:mode>2):
	For standard excess precision, output explicit conversion to and
	truncation from XFmode.
	(*float<SSEMODEI24:mode><X87MODEF:mode>2_1,
	*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp,
	*float<SSEMODEI24:mode><X87MODEF:mode>2_i387, two unnamed
	define_splits, floatdi<X87MODEF:mode>2_i387_with_xmm, two unnamed
	define_splits, *floatunssi<mode>2_1, two unnamed define_splits,
	floatunssi<mode>2, add<mode>3, sub<mode>3, mul<mode>3, divdf3,
	divsf3, *fop_<mode>_comm_i387, *fop_<mode>_1_i387,
	*fop_<MODEF:mode>_2_i387, *fop_<MODEF:mode>_3_i387,
	*fop_df_4_i387, *fop_df_5_i387, *fop_df_6_i387, two unnamed
	define_splits, sqrt<mode>2): Disable where appropriate for
	standard excess precision.
	* convert.c (convert_to_real): Do not shorten arithmetic to type
	for which excess precision would be used.
	* doc/invoke.texi (-fexcess-precision=): Document option.
	(-mfpmath=): Correct index entry.
	* flags.h (enum excess_precision, flag_excess_precision_cmdline,
	flag_excess_precision): New.
	* langhooks.c (lhd_post_options): Set
	flag_excess_precision_cmdline.
	* opts.c (common_handle_option): Handle -fexcess-precision=.
	* toplev.c (flag_excess_precision_cmdline, flag_excess_precision,
	init_excess_precision): New.
	(lang_dependent_init_target): Call init_excess_precision.
	* tree.c (excess_precision_type): New.
	* tree.h (excess_precision_type): Declare.

ada:
	* gcc-interface/misc.c (gnat_post_options): Set
	flag_excess_precision_cmdline.

fortran:
	* options.c (gfc_post_options): Set flag_excess_precision_cmdline.

java:
	* lang.c (java_post_options): Set flag_excess_precision_cmdline.

testsuite:
	* gcc.target/i386/excess-precision-1.c,
	gcc.target/i386/excess-precision-2.c,
	gcc.target/i386/excess-precision-3.c,
	gcc.target/i386/excess-precision-4.c,
	gcc.target/i386/excess-precision-5.c,
	gcc.target/i386/excess-precision-6.c: New tests.

Added:
    branches/c-4_5-branch/gcc/ada/ChangeLog.c45
    branches/c-4_5-branch/gcc/fortran/ChangeLog.c45
    branches/c-4_5-branch/gcc/java/ChangeLog.c45
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-1.c
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-2.c
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-3.c
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-4.c
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-5.c
    branches/c-4_5-branch/gcc/testsuite/gcc.target/i386/excess-precision-6.c
Modified:
    branches/c-4_5-branch/gcc/ChangeLog.c45
    branches/c-4_5-branch/gcc/ada/gcc-interface/misc.c
    branches/c-4_5-branch/gcc/c-common.c
    branches/c-4_5-branch/gcc/c-common.def
    branches/c-4_5-branch/gcc/c-cppbuiltin.c
    branches/c-4_5-branch/gcc/c-lex.c
    branches/c-4_5-branch/gcc/c-opts.c
    branches/c-4_5-branch/gcc/c-parser.c
    branches/c-4_5-branch/gcc/c-typeck.c
    branches/c-4_5-branch/gcc/common.opt
    branches/c-4_5-branch/gcc/config/i386/i386.h
    branches/c-4_5-branch/gcc/config/i386/i386.md
    branches/c-4_5-branch/gcc/convert.c
    branches/c-4_5-branch/gcc/doc/invoke.texi
    branches/c-4_5-branch/gcc/flags.h
    branches/c-4_5-branch/gcc/fortran/options.c
    branches/c-4_5-branch/gcc/java/lang.c
    branches/c-4_5-branch/gcc/langhooks.c
    branches/c-4_5-branch/gcc/opts.c
    branches/c-4_5-branch/gcc/testsuite/ChangeLog.c45
    branches/c-4_5-branch/gcc/toplev.c
    branches/c-4_5-branch/gcc/tree.c
    branches/c-4_5-branch/gcc/tree.h

Comment 124 David Monniaux 2008-11-11 07:46:07 UTC
Vincent Lefèvre is right: the issue is quite subtle. (I should mention that Vincent is an expert in computer arithmetics, which I'm not.)

As he rightly points, conformance to IEEE-754 should be evaluated for a whole software/hardware system - it is possible to have a IEEE-754 system entirely implemented in software.

It seems like the C99 standard prohibits double rounding, and prohibits having values depend on the vagaries of register spilling. Except that this prohibition is explicit only in non-normative sections. "Language lawyers" have sent me justifications that this prohibition is implied by various normative prescriptions of the standard.

I think that in any case we should not spend too much energy trying to assign blame (who conforms to the standard) but rather try to find solutions.

The short answer is that no compiler, be it gcc, will be modified so that complex sequences of operations are used for floating-point operations in lieu of directly using x87 instructions! At least for two reasons:
* x87 is now fading away (its use is deprecated on x86-64, it's not used by default on Intel Macintosh...)
* Most people don't want to pay the performance hit.

In addition, I think there are more urgent things to fix in gcc's floating-point system, such as support for #pragma STDC FENV ACCESS

Now for some additional facts:
* It is possible to force the x87 to use reduced precision for the mantissa (with inline asm or even now with gcc options).
* This setting does not affect the range of exponents. so you can still have surprises if a very tiny nonzero value is kept in a register then is rounded to zero when spilled to memory.
* In some rare cases, you can have "double rounding on underflow": you get a different result by computing on SSE in double precision mode on the one hand, and by computing on x87 in "double precision" then writing to a double variable in memory.
Comment 125 Vincent Lefèvre 2008-11-11 10:13:33 UTC
(In reply to comment #124)
> It seems like the C99 standard prohibits double rounding,

only if Annex F is claimed to be supported (note: Annex F is not just IEEE 754, it also contains specific bindings). IEEE 754 doesn't prohibit double rounding either (this depends on the bindings), but with C99 + Annex F, double rounding is prohibited.

Now, bug 323 is not about double rounding specifically. There are two potential problems:

1. A "double" variable (or result of a cast) contains a "long double" value (not exactly representable in a "double"). This is prohibited by C99 (5.1.2.3#12, 6.3.1.5#2 and 6.3.1.8#2[52]). This problem seems to be fixed by Joseph Myers' patch mentioned in comment #123 (but I haven't tried).

2. Computations on "double" expressions are carried out in extended precision. This is allowed by C99 (except for casts and assignments), e.g. when FLT_EVAL_METHOD=2. But if the implementation (i.e. here compiler + library + ...) claims to support Annex F, then this is prohibited. This point is rather tricky because the compiler (GCC) and library (e.g. GNU libc) settings must be consistent, so their developers need to talk with each other. FYI, I reported the following bug concerning glibc:

  http://sourceware.org/bugzilla/show_bug.cgi?id=6981

because it sets __STDC_IEC_559__ to 1 unconditionally.

> The short answer is that no compiler, be it gcc, will be modified so that
> complex sequences of operations are used for floating-point operations in lieu
> of directly using x87 instructions! At least for two reasons:
> * x87 is now fading away (its use is deprecated on x86-64, it's not used by
> default on Intel Macintosh...)
> * Most people don't want to pay the performance hit.

That's why in Joseph's patch, it's just an option (disabled by default, but enabled by -std=c99 because one should assume that if a user wants C99, then he really wants it, and if he is able to add an option, then he is also able to add another one if he wants to disable this fix in case he knows it is useless for his application -- this is also true for -ffast-math).

GCC already supports SSE, but this patch is for processors that don't.

Also the performance hit depends very much on the application. Performance hit is reduced in applications that do not use intensive FP or mostly interactive applications.

> In addition, I think there are more urgent things to fix in gcc's
> floating-point system, such as support for #pragma STDC FENV ACCESS

FYI, this is bug 34678. And I submitted bug 37845 concerning the FP_CONTRACT pragma.

> * It is possible to force the x87 to use reduced precision for the mantissa
> (with inline asm or even now with gcc options).

Unfortunately, this means that "long double" wouldn't behave as expected, and the behavior is not controllable enough (e.g. due to libraries, plugins...). Such a change should have been system-wide. Now, this is needed in software where double rounding is prohibited (e.g. XSLT processor).
Comment 126 Joseph S. Myers 2009-03-30 01:51:03 UTC
Subject: Bug 323

Author: jsm28
Date: Mon Mar 30 01:50:44 2009
New Revision: 145272

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145272
Log:
	PR rtl-optimization/323
	* c-common.c (c_fully_fold, convert_and_check,
	c_common_truthvalue_conversion): Handle EXCESS_PRECISION_EXPR.
	(c_fully_fold_internal): Disallow EXCESS_PRECISION_EXPR.
	* c-common.def (EXCESS_PRECISION_EXPR): New.
	* c-cppbuiltin.c (builtin_define_float_constants): Define
	constants with enough digits for long double.
	* c-lex.c (interpret_float): Interpret constant with excess
	precision where appropriate.
	* c-opts.c (c_common_post_options): Set
	flag_excess_precision_cmdline.  Give an error for
	-fexcess-precision=standard for C++ for processors where the
	option is significant.
	* c-parser.c (c_parser_conditional_expression): Handle excess
	precision in condition.
	* c-typeck.c (convert_arguments): Handle arguments with excess
	precision.
	(build_unary_op): Move excess precision outside operation.
	(build_conditional_expr): Likewise.
	(build_compound_expr): Likewise.
	(build_c_cast): Do cast on operand of EXCESS_PRECISION_EXPR.
	(build_modify_expr): Handle excess precision in RHS.
	(convert_for_assignment): Handle excess precision in converted
	value.
	(digest_init, output_init_element, process_init_element): Handle
	excess precision in initializer.
	(c_finish_return): Handle excess precision in return value.
	(build_binary_op): Handle excess precision in operands and add
	excess precision as needed for operation.
	* common.opt (-fexcess-precision=): New option.
	* config/i386/i386.h (X87_ENABLE_ARITH, X87_ENABLE_FLOAT): New.
	* config/i386/i386.md (float<SSEMODEI24:mode><X87MODEF:mode>2):
	For standard excess precision, output explicit conversion to and
	truncation from XFmode.
	(*float<SSEMODEI24:mode><X87MODEF:mode>2_1,
	*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp,
	*float<SSEMODEI24:mode><X87MODEF:mode>2_i387, two unnamed
	define_splits, floatdi<X87MODEF:mode>2_i387_with_xmm, two unnamed
	define_splits, *floatunssi<mode>2_1, two unnamed define_splits,
	floatunssi<mode>2, add<mode>3, sub<mode>3, mul<mode>3, divdf3,
	divsf3, *fop_<mode>_comm_i387, *fop_<mode>_1_i387,
	*fop_<MODEF:mode>_2_i387, *fop_<MODEF:mode>_3_i387,
	*fop_df_4_i387, *fop_df_5_i387, *fop_df_6_i387, two unnamed
	define_splits, sqrt<mode>2): Disable where appropriate for
	standard excess precision.
	* convert.c (convert_to_real): Do not shorten arithmetic to type
	for which excess precision would be used.
	* defaults.h (TARGET_FLT_EVAL_METHOD_NON_DEFAULT): Define.
	* doc/invoke.texi (-fexcess-precision=): Document option.
	(-mfpmath=): Correct index entry.
	* flags.h (enum excess_precision, flag_excess_precision_cmdline,
	flag_excess_precision): New.
	* langhooks.c (lhd_post_options): Set
	flag_excess_precision_cmdline.
	* opts.c (common_handle_option): Handle -fexcess-precision=.
	* toplev.c (flag_excess_precision_cmdline, flag_excess_precision,
	init_excess_precision): New.
	(lang_dependent_init_target): Call init_excess_precision.
	* tree.c (excess_precision_type): New.
	* tree.h (excess_precision_type): Declare.

ada:
	* gcc-interface/misc.c (gnat_post_options): Set
	flag_excess_precision_cmdline.  Give an error for
	-fexcess-precision=standard for processors where the option is
	significant.

fortran:
	* options.c (gfc_post_options): Set
	flag_excess_precision_cmdline.  Give an error for
	-fexcess-precision=standard for processors where the option is
	significant.

java:
	* lang.c (java_post_options): Set flag_excess_precision_cmdline.
	Give an error for -fexcess-precision=standard for processors where
	the option is significant.

testsuite:
	* gcc.target/i386/excess-precision-1.c,
	gcc.target/i386/excess-precision-2.c,
	gcc.target/i386/excess-precision-3.c,
	gcc.target/i386/excess-precision-4.c,
	gcc.target/i386/excess-precision-5.c,
	gcc.target/i386/excess-precision-6.c: New tests.

Added:
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-1.c
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-2.c
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-3.c
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-4.c
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-5.c
    trunk/gcc/testsuite/gcc.target/i386/excess-precision-6.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/ada/ChangeLog
    trunk/gcc/ada/gcc-interface/misc.c
    trunk/gcc/c-common.c
    trunk/gcc/c-common.def
    trunk/gcc/c-cppbuiltin.c
    trunk/gcc/c-lex.c
    trunk/gcc/c-opts.c
    trunk/gcc/c-parser.c
    trunk/gcc/c-typeck.c
    trunk/gcc/common.opt
    trunk/gcc/config/i386/i386.h
    trunk/gcc/config/i386/i386.md
    trunk/gcc/convert.c
    trunk/gcc/defaults.h
    trunk/gcc/doc/invoke.texi
    trunk/gcc/flags.h
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/options.c
    trunk/gcc/java/ChangeLog
    trunk/gcc/java/lang.c
    trunk/gcc/langhooks.c
    trunk/gcc/opts.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/toplev.c
    trunk/gcc/tree.c
    trunk/gcc/tree.h

Comment 127 Joseph S. Myers 2009-03-30 01:57:39 UTC
Fixed for C (and ObjC) for 4.5 with the new -fexcess-precision=standard
support.

The issue remains for other languages (and maybe for some m68k processors);
I quote from my original message
<http://gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html>:

  It would be possible to implement the option for non-C languages, to
  provide whatever predictable semantics are appropriate for those
  languages (whether or not described in their standards).  Note that
  bug 323 was originally reported with a C++ testcase.  If implemented
  for all languages, the option might supersede -ffloat-store.  Right
  now, -ffloat-store checks are scattered about the optimizers and it
  seems unlikely that -ffloat-store really implements any form of
  predictable semantics now; such semantic effect as it was intended to
  have could be better represented as an alias for a
  -fexcess-precision=standard option supported for all languages.  It
  would probably be most appropriate not to close bug 323 without having
  some form of predictable semantics available for each language.

and:

  I have not changed the m68k back end in this patch.  Thus the option
  may not be fully effective for the affected m68k processors (classic
  m68k with 68881, before 68040, only, not ColdFire, not 68040 or
  later).  If anyone wishes to make it fully effective for such
  processors they should copy the testcases to gcc.target/m68k/ and go
  through m68k insn patterns appropriately adjusting them.
Comment 128 Andrew Pinski 2009-05-18 14:11:44 UTC
*** Bug 40186 has been marked as a duplicate of this bug. ***
Comment 129 Albert Zeyer 2009-05-18 14:24:36 UTC
I am a bit wondering if this bug is also for the case (a < b) && (b < a) == true. Is it?

Because if so, this becomes way more serious, as for example std::set<double> is broken then (and depending on the STL implementation, it will throw assertions then).

If not, I guess my bug #40186 is not a duplicate of this bug.
Comment 130 Szabolcs Nagy 2009-07-22 12:10:49 UTC
(In reply to comment #129)
> I am a bit wondering if this bug is also for the case (a < b) && (b < a) ==
> true. Is it?

i guess so, see:

#include <stdlib.h> 
#include <stdio.h> 

#define axiom_order(a,b)  !(a < b && b < a) 
#define axiom_eq(a)       a == a 
#define third             ((double)atoi("1")/atoi("3"))

int main(void) {
        if (axiom_order(third, third))
                puts("ok");
        else
                puts("error");

        if (axiom_eq(third))
                puts("ok");
        else
                puts("error");

        return 0;
}


here this prints
error
error
with gcc 4.2 and -S shows that this is long double vs double precision problem


> Because if so, this becomes way more serious, as for example std::set<double>
> is broken then (and depending on the STL implementation, it will throw
> assertions then).

in C99 (+TC1,TC2,TC3) different precision is not allowed

5.1.2.3 p12:
  ... In particular, casts and assignments are required to perform their specified conversion

5.2.4.2.2 p8:
  Except for assignment and cast (which remove all extra range and precision), the values 8 of operations with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.

i'm not sure about c++ though
Comment 131 Vincent Lefèvre 2009-07-22 17:33:51 UTC
(In reply to comment #130)
> #define axiom_order(a,b)  !(a < b && b < a) 
> #define axiom_eq(a)       a == a 
> #define third             ((double)atoi("1")/atoi("3"))
[...]

> in C99 (+TC1,TC2,TC3) different precision is not allowed

It is allowed, except for...

> 5.1.2.3 p12:
>   ... In particular, casts and assignments are required to perform their
> specified conversion

But a division is not a cast, nor an assignment.

> 5.2.4.2.2 p8:
>   Except for assignment and cast (which remove all extra range and precision),
> the values 8 of operations with floating operands and values subject to the
> usual arithmetic conversions and of floating constants are evaluated to a
> format whose range and precision may be greater than required by the type.

A greater precision is OK for division, in particular.
Comment 132 Albert Zeyer 2009-07-22 20:54:58 UTC
So that means that this C++ example could crash under certain circumstances (depending on how far the compiler is optimising here)?

#include <set>
#define third             ((double)atoi("1")/atoi("3"))
int main() {
  std::set<double> m;
  m.insert(third);
  m.insert(third);
  return (m.find(third) != m.end()) ? 0 : 1;
}


Because this example only works if it is guaranteed that !(third < third && third > third), otherwise it would abort. 
Comment 133 Andrew Pinski 2009-09-20 21:28:33 UTC
*** Bug 41195 has been marked as a duplicate of this bug. ***
Comment 134 Joseph S. Myers 2009-10-29 20:26:34 UTC
*** Bug 41867 has been marked as a duplicate of this bug. ***
Comment 135 Joseph S. Myers 2009-10-31 18:37:04 UTC
*** Bug 41867 has been marked as a duplicate of this bug. ***
Comment 136 Andrew Pinski 2010-05-19 18:05:09 UTC
*** Bug 44198 has been marked as a duplicate of this bug. ***
Comment 137 Jerry DeLisle 2010-08-04 02:42:02 UTC
*** Bug 45175 has been marked as a duplicate of this bug. ***
Comment 138 Andrew Pinski 2010-09-16 17:08:40 UTC
*** Bug 45691 has been marked as a duplicate of this bug. ***
Comment 139 postmaster 2010-10-05 18:44:05 UTC Comment hidden (spam)
Comment 140 Andrew Pinski 2010-10-05 18:45:34 UTC
*** Bug 45899 has been marked as a duplicate of this bug. ***
Comment 141 postmaster 2010-10-05 18:48:08 UTC Comment hidden (spam)
Comment 142 postmaster 2010-10-05 18:51:39 UTC Comment hidden (spam)
Comment 143 postmaster 2010-10-05 18:52:43 UTC Comment hidden (spam)
Comment 144 postmaster 2010-10-05 18:54:06 UTC Comment hidden (spam)
Comment 145 postmaster 2010-10-05 18:58:19 UTC Comment hidden (spam)
Comment 146 postmaster 2010-10-05 19:02:20 UTC Comment hidden (spam)
Comment 147 postmaster 2010-10-05 19:03:55 UTC Comment hidden (spam)
Comment 148 postmaster 2010-10-05 19:07:48 UTC Comment hidden (spam)
Comment 149 postmaster 2010-10-05 19:15:54 UTC Comment hidden (spam)
Comment 150 postmaster 2010-10-05 19:27:02 UTC Comment hidden (spam)
Comment 151 postmaster 2010-10-05 19:29:02 UTC Comment hidden (spam)
Comment 152 postmaster 2010-10-05 19:30:12 UTC Comment hidden (spam)
Comment 153 postmaster 2010-10-05 19:36:18 UTC Comment hidden (spam)
Comment 154 postmaster 2010-10-05 19:38:35 UTC Comment hidden (spam)
Comment 155 postmaster 2010-10-05 19:40:16 UTC Comment hidden (spam)
Comment 156 postmaster 2010-10-05 19:42:02 UTC Comment hidden (spam)
Comment 157 postmaster 2010-10-05 19:51:06 UTC Comment hidden (spam)
Comment 158 postmaster 2010-10-05 20:01:22 UTC Comment hidden (spam)
Comment 159 postmaster 2010-10-05 20:23:20 UTC Comment hidden (spam)
Comment 160 Ian Macky 2010-10-05 20:34:12 UTC
Whoever is testing mail: couldn't you have made a phoney bug report to test
with, and not used a live one which had me on the CC list?

I've gotten about two dozen random mailer-daemon bounces so far because of
this and they keep coming.

Don't test with real data: test with test data!!

On Tue, 5 Oct 2010, postmaster at jpmchase dot com wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
>
> --- Comment #155 from postmaster at jpmchase dot com 2010-10-05 19:40:16 UTC ---
> Delivery has failed to these recipients or distribution lists:
>
> rohit.x.tripathi@jpmchasex.jpmchase.net<mailto:rohit.x.tripathi@jpmchasex.jpmchase.net>
> The recipient's e-mail address was not found in the recipient's e-mail system.
> Microsoft Exchange will not try to redeliver this message for you. Please check
> the e-mail address and try resending this message, or provide the following
> diagnostic text to your system administrator.
>
> ________________________________
> Sent by Microsoft Exchange Server 2007
>
>
>
>
>
>
> Diagnostic information for administrators:
>
> Generating server: exchad.jpmchase.net
>
> rohit.x.tripathi@jpmchasex.jpmchase.net
> #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
>
> Original message headers:
>
> Received: from sg3.svr.us.jpmchase.net (155.180.248.7) by
> HUBR002.exchad.jpmchase.net (169.69.182.48) with Microsoft SMTP Server (TLS)
> id 8.2.247.2; Tue, 5 Oct 2010 15:39:30 -0400
> Received: from jpmchase.com (ime6.dmz.bankone.net [155.180.110.185])    by
> sg3.svr.us.jpmchase.net (Switch-3.4.3/Switch-3.3.3mp) with ESMTP id
> o95JdTZR023284 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256
> verify=OK)     for <rohit.x.tripathi@jpmchase.com>; Tue, 5 Oct 2010 15:39:30
> -0400
> Message-ID: <201010051939.o95JdTZR023284@sg3.svr.us.jpmchase.net>
> Received: from ([209.132.180.131])      by ime6.jpmchase.com with SMTP  id
> G6DC7G1.476932631;     Tue, 05 Oct 2010 15:39:22 -0400
> Received: (qmail 27172 invoked by uid 22791); 5 Oct 2010 19:39:22 -0000
> X-SWARE-Spam-Status: No, hits=-2.4 required=5.0
>        tests=ALL_TRUSTED,AWL,BAYES_00,MISSING_MID
> X-Spam-Status: No, hits=-2.4 required=5.0
>        tests=ALL_TRUSTED,AWL,BAYES_00,MISSING_MID
> X-Spam-Check-By: sourceware.org
> Received: from localhost (HELO gcc.gnu.org) (127.0.0.1)    by sourceware.org
> (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Oct 2010 19:39:20 +0000
> From: pinskia at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org>
> To: <rohit.x.tripathi@jpmchase.com>
> Subject: [Bug middle-end/323] optimized code gives strange floating point
> results
> X-Bugzilla-Reason: CC
> X-Bugzilla-Type: changed
> X-Bugzilla-Watch-Reason: None
> X-Bugzilla-Product: gcc
> X-Bugzilla-Component: middle-end
> X-Bugzilla-Keywords: wrong-code
> X-Bugzilla-Severity: normal
> X-Bugzilla-Who: pinskia at gcc dot gnu.org
> X-Bugzilla-Status: SUSPENDED
> X-Bugzilla-Priority: P3
> X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
> X-Bugzilla-Target-Milestone: ---
> X-Bugzilla-Changed-Fields: CC
> In-Reply-To: <bug-323-16346@http.gcc.gnu.org/bugzilla/>
> References: <bug-323-16346@http.gcc.gnu.org/bugzilla/>
> X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
> Auto-Submitted: auto-generated
> Content-Type: text/plain; charset="UTF-8"
> MIME-Version: 1.0
> Date: Tue, 5 Oct 2010 19:39:18 +0000
> X-esp: ESP<41>=
>        SHA:<0>
>        SHA_FLAGS:<0>
>        UHA:<12>
>        ISC:<0>
>        BAYES:<0>
>        SenderID:<0>
>        DKIM:<0>
>        TS:<-11>
>        SIG:<dWI3WNz1AAjh29Sc0DGR4k_GzL0bILBmaAAAAAAAAAAAAAAAAAAAAAAAAAAA
>        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>        AAAAAAAAAAAAAAAAAAAACneFFhQJDUlanas0NLpZdKWZRF868melvCcN2rP9
>        l7hRc8kJV2hwQPv2gyHiLcJNrA-LboAsb2SPkTZmJUYz6-iAA>
>        DSC:<40> (obscure_url:<40>)
>        TRU_adult_spam: <0>
>        TRU_watch_spam: <0>
>        TRU_stock_spam: <0>
>        TRU_lotto_spam: <0>
>        TRU_html_image_spam: <0>
>        TRU_freehosting: <0>
>        URL Real-Time Signatures: <0>
>        TRU_scam_spam: <0>
>        TRU_misc_spam: <0>
>        TRU_urllinks: <0>
>        TRU_embedded_image_spam: <0>
>        TRU_spam2: <0>
>        TRU_marketing_spam: <0>
>        TRU_profanity_spam: <0>
>        TRU_playsites: <0>
>        TRU_phish_spam: <0>
>        TRU_medical_spam: <0>
>        TRU_money_spam: <0>
>        TRU_spam1: <0>
>        TRU_legal_spam: <0>
>        TRU_ru_spamsubj: <0>
> Return-Path: gcc-bugzilla@gcc.gnu.org
>
> -- 
> Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug.
>
Comment 161 postmaster 2010-10-05 20:37:06 UTC Comment hidden (spam)
Comment 162 postmaster 2010-10-05 20:43:15 UTC Comment hidden (spam)
Comment 163 postmaster 2010-10-05 20:50:50 UTC Comment hidden (spam)
Comment 164 postmaster 2010-10-05 20:57:05 UTC Comment hidden (spam)
Comment 165 postmaster 2010-10-05 21:07:17 UTC Comment hidden (spam)
Comment 166 postmaster 2010-10-05 21:18:36 UTC Comment hidden (spam)
Comment 167 postmaster 2010-10-05 21:25:07 UTC Comment hidden (spam)
Comment 168 postmaster 2010-10-05 21:26:45 UTC Comment hidden (spam)
Comment 169 postmaster 2010-10-05 21:29:53 UTC Comment hidden (spam)
Comment 170 postmaster 2010-10-05 21:36:20 UTC Comment hidden (spam)
Comment 171 postmaster 2010-10-05 21:43:00 UTC Comment hidden (spam)
Comment 172 postmaster 2010-10-05 21:48:47 UTC Comment hidden (spam)
Comment 173 postmaster 2010-10-05 21:52:14 UTC Comment hidden (spam)
Comment 174 postmaster 2010-10-05 22:02:31 UTC Comment hidden (spam)
Comment 175 postmaster 2010-10-05 22:07:50 UTC Comment hidden (spam)
Comment 176 postmaster 2010-10-05 22:09:28 UTC Comment hidden (spam)
Comment 177 postmaster 2010-10-05 22:14:51 UTC Comment hidden (spam)
Comment 178 postmaster 2010-10-05 22:19:02 UTC Comment hidden (spam)
Comment 179 Andrew Pinski 2011-01-13 22:06:14 UTC
*** Bug 47282 has been marked as a duplicate of this bug. ***
Comment 180 Richard Biener 2011-02-21 12:35:53 UTC
*** Bug 47834 has been marked as a duplicate of this bug. ***
Comment 181 Alexander Bürger 2011-03-08 19:08:38 UTC
*** Bug 47600 has been marked as a duplicate of this bug. ***
Comment 182 Richard Biener 2011-03-22 15:15:24 UTC
*** Bug 48236 has been marked as a duplicate of this bug. ***
Comment 183 Andrew Pinski 2012-01-13 06:28:44 UTC
*** Bug 38777 has been marked as a duplicate of this bug. ***
Comment 184 Richard Biener 2012-04-24 08:08:06 UTC
*** Bug 53095 has been marked as a duplicate of this bug. ***
Comment 185 Paolo Carlini 2012-11-12 14:53:28 UTC
*** Bug 55267 has been marked as a duplicate of this bug. ***
Comment 186 Andrew Pinski 2012-11-30 18:06:40 UTC
*** Bug 55544 has been marked as a duplicate of this bug. ***
Comment 187 Søren Sandmann Pedersen 2012-12-15 02:09:20 UTC
*** Bug 55700 has been marked as a duplicate of this bug. ***
Comment 188 Richard Biener 2012-12-31 16:12:05 UTC
*** Bug 55787 has been marked as a duplicate of this bug. ***
Comment 189 Jakub Jelinek 2013-01-30 08:57:24 UTC
*** Bug 55939 has been marked as a duplicate of this bug. ***
Comment 190 Ondřej Surý 2013-04-26 16:07:17 UTC
*** Bug 57080 has been marked as a duplicate of this bug. ***
Comment 191 Richard Biener 2013-06-24 10:53:10 UTC
*** Bug 57669 has been marked as a duplicate of this bug. ***
Comment 192 Dominique d'Humieres 2013-11-18 18:46:20 UTC
*** Bug 59168 has been marked as a duplicate of this bug. ***
Comment 193 Martin von Gagern 2014-01-02 08:34:53 UTC
(In reply to Joseph S. Myers from comment #127)
>   It would be possible to implement the option for non-C languages, to
>   provide whatever predictable semantics are appropriate for those
>   languages (whether or not described in their standards).  Note that
>   bug 323 was originally reported with a C++ testcase.  […]  It
>   would probably be most appropriate not to close bug 323 without having
>   some form of predictable semantics available for each language.

Would it make sense to file one bug report per language, marking all of them as blocking this one here, so we can keep track of progress per language? I'm particularly interested in C++, but I guess others might care for other front-ends.
Comment 194 Andrew Pinski 2014-06-27 00:06:54 UTC
*** Bug 61626 has been marked as a duplicate of this bug. ***
Comment 195 Manuel López-Ibáñez 2014-12-30 18:45:21 UTC
(In reply to Martin von Gagern from comment #193)
> Would it make sense to file one bug report per language, marking all of them
> as blocking this one here, so we can keep track of progress per language?
> I'm particularly interested in C++, but I guess others might care for other
> front-ends.

Feel free to do just that, specially if you are planning to work on it. This PR has become too long and full of outdated info (and useless comments) to be really useful.
Comment 196 Manuel López-Ibáñez 2014-12-30 19:15:12 UTC
I believe the latest status of this PR is explained by comment 127. I added this as the URL of the bug for people to find.

Also, the official FAQ for this (https://gcc.gnu.org/bugs/#nonbugs_general) is seriously lacking info and outdated. From now on, I'll point people to: https://gcc.gnu.org/wiki/FAQ#PR323
Comment 197 Vincent Lefèvre 2014-12-30 23:59:32 UTC
(In reply to Manuel López-Ibáñez from comment #196)
> Also, the official FAQ for this (https://gcc.gnu.org/bugs/#nonbugs_general)
> is seriously lacking info and outdated. From now on, I'll point people to:
> https://gcc.gnu.org/wiki/FAQ#PR323

Note that this bug was mainly about the excess precision of x87 FPU, though its summary just says "optimized code gives strange floating point results". But the users should be aware that the floating-point results can still depend on the optimization level because this is allowed by the ISO C standard. For instance, if one has code like x*y+z, a FMA can be used or not depending on the target architecture and the optimization level (see also bug 37845 about this), and this can change the results.
Comment 198 Manuel López-Ibáñez 2014-12-31 00:45:11 UTC
(In reply to Vincent Lefèvre from comment #197)
> (In reply to Manuel López-Ibáñez from comment #196)
> > Also, the official FAQ for this (https://gcc.gnu.org/bugs/#nonbugs_general)
> > is seriously lacking info and outdated. From now on, I'll point people to:
> > https://gcc.gnu.org/wiki/FAQ#PR323
> 
> Note that this bug was mainly about the excess precision of x87 FPU, though

I added your comment to the FAQ but feel welcome to extend it:
https://gcc.gnu.org/wiki/FAQ#PR323

What it is also missing is a criteria to distinguish normal behavior from actual GCC bugs (and there are GCC bugs like bug 37845 and others for optimizations that should only be done with ffast-math). Currently, any floating-point issue is likely to end up here.
Comment 199 Andreas Schwab 2015-01-26 19:04:15 UTC
*** Bug 64808 has been marked as a duplicate of this bug. ***
Comment 200 Joseph S. Myers 2015-05-29 16:49:49 UTC
*** Bug 66282 has been marked as a duplicate of this bug. ***
Comment 201 Andrew Pinski 2016-07-25 02:06:41 UTC
*** Bug 62623 has been marked as a duplicate of this bug. ***
Comment 202 bfjsdow 2016-08-12 17:04:33 UTC Comment hidden (spam)
Comment 203 Eric Gallager 2017-07-19 18:43:52 UTC
*** Bug 34261 has been marked as a duplicate of this bug. ***
Comment 204 Andrew Pinski 2018-05-05 15:36:33 UTC
*** Bug 85661 has been marked as a duplicate of this bug. ***
Comment 205 Andrew Pinski 2018-05-28 19:12:42 UTC
*** Bug 85957 has been marked as a duplicate of this bug. ***
Comment 206 Andrew Pinski 2018-05-28 21:17:38 UTC
*** Bug 85957 has been marked as a duplicate of this bug. ***
Comment 207 Jakub Jelinek 2018-08-28 13:54:26 UTC
*** Bug 87128 has been marked as a duplicate of this bug. ***
Comment 208 Carlo B. 2019-06-18 11:22:47 UTC Comment hidden (spam)
Comment 209 Andrew Pinski 2020-02-07 02:38:34 UTC
*** Bug 93620 has been marked as a duplicate of this bug. ***
Comment 210 Rich Felker 2020-02-07 02:45:36 UTC
If new reports are going to be marked as duplicates of this, then can it please be moved from SUSPENDED status to REOPENED? The situation is far worse than what seems to have been realized last this was worked on, as evidenced by pr 85957. These issues just came up again breaking real-world software in https://github.com/OSGeo/PROJ/issues/1906
Comment 211 Rich Felker 2020-02-07 02:49:16 UTC
If new reports are going to be marked as duplicates of this, then can it please be moved from SUSPENDED status to REOPENED? The situation is far worse than what seems to have been realized last this was worked on, as evidenced by pr 85957. These issues just came up again breaking real-world software in https://github.com/OSGeo/PROJ/issues/1906
Comment 212 Eric Gallager 2020-02-07 04:04:21 UTC
(In reply to Rich Felker from comment #211)
> If new reports are going to be marked as duplicates of this, then can it
> please be moved from SUSPENDED status to REOPENED? The situation is far
> worse than what seems to have been realized last this was worked on, as
> evidenced by pr 85957. These issues just came up again breaking real-world
> software in https://github.com/OSGeo/PROJ/issues/1906

Uh... I'm not seeing "REOPENED" on the menu for possible statuses? Maybe a bug can only have the REOPENED status if it's actually been closed in the past, and this might not have actually been closed before? I thought this had been closed at one point, but it looks like I was wrong... Hold on, let me check the (very long) history for this bug...
Comment 213 Eric Gallager 2020-02-07 05:06:10 UTC
(In reply to Eric Gallager from comment #212)
> (In reply to Rich Felker from comment #211)
> > If new reports are going to be marked as duplicates of this, then can it
> > please be moved from SUSPENDED status to REOPENED? The situation is far
> > worse than what seems to have been realized last this was worked on, as
> > evidenced by pr 85957. These issues just came up again breaking real-world
> > software in https://github.com/OSGeo/PROJ/issues/1906
> 
> Uh... I'm not seeing "REOPENED" on the menu for possible statuses? Maybe a
> bug can only have the REOPENED status if it's actually been closed in the
> past, and this might not have actually been closed before? I thought this
> had been closed at one point, but it looks like I was wrong... Hold on, let
> me check the (very long) history for this bug...

OK, never mind, it looks like this bug has actually been closed before like I thought originally; whether or not a bug can have its status changed to REOPENED or not must depend on its current status, rather than any past status it might have had... So, I guess I can either close it temporarily and then immediately reopen it, or give it some other status. Which would you prefer?
Comment 214 Rich Felker 2020-02-07 15:32:29 UTC
I'm not particular in terms of the path it takes as long as this gets back to a status where it's on the radar for fixing.
Comment 215 Vincent Lefèvre 2020-02-07 16:10:27 UTC
According to https://gcc.gnu.org/bugzilla/page.cgi?id=fields.html#bug_status the possible status are UNCONFIRMED, CONFIRMED and IN_PROGRESS. I think that the correct one is CONFIRMED.
Comment 216 Manuel López-Ibáñez 2020-02-07 18:08:35 UTC
(In reply to Vincent Lefèvre from comment #215)
> According to https://gcc.gnu.org/bugzilla/page.cgi?id=fields.html#bug_status
> the possible status are UNCONFIRMED, CONFIRMED and IN_PROGRESS. I think that
> the correct one is CONFIRMED.

Those are not the main policies. They are here:
https://gcc.gnu.org/bugs/management.html

fields.html needs to be updated some day to match the actual fields used by GCC (there is no CONFIRMED status, there is NEW) and the above policies.

This is one of those bugs that it is so broad, controversial and noisy that almost no active developer is going to look at it. Bugs don't get fixed because they are NEW. There are 6979 NEW bug reports right now and many of them will never get fixed (1300 of them are more than 10 years old).

My humble suggestion for those interested in floating-point issues in GCC would be to create self-contained specific bugs with minimised reproducible testcases, a clear analysis of what GCC is doing wrong, what GCC should be doing instead, and suggestions on how it could be fixed. If the bug just says some variation of "optimized code gives strange floating point results", it will end up here and probably nobody will ever look at it.

For Rich's specific bug report, the relevant discussion is in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c127 and the expected fix is known: Implement -fexcess-precision=standard for C++ as it was done for C. Perhaps it would be useful to create a new PR that blocks this one that analyses what needs to be done towards that specific goal, collects testcases, etc. The main issue is not that this PR is not in the developers' radar. All GCC developers working on the C/C++ FEs and optimizers are aware of the infamous PR323 and of the solution suggested in comment 127.

The issue is simply that no one working on the C++ FE has the time or motivation to implement -fexcess-precision=standard. If you are interested in that, just study this email: https://gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html and do for C++ the same steps that Joseph did C.
Comment 217 jsm-csl@polyomino.org.uk 2020-02-07 18:22:49 UTC
On Fri, 7 Feb 2020, vincent-gcc at vinc17 dot net wrote:

> According to https://gcc.gnu.org/bugzilla/page.cgi?id=fields.html#bug_status
> the possible status are UNCONFIRMED, CONFIRMED and IN_PROGRESS. I think that
> the correct one is CONFIRMED.

That's generic Bugzilla documentation that's not relevant to the custom 
GCC configuration of bug states, which is documented at 
<https://gcc.gnu.org/bugs/management.html> (we also have NEW and ASSIGNED 
not CONFIRMED and IN_PROGRESS).  SUSPENDED is accurate for a bug that is 
explicitly known to be hard and not being worked on, for reasons other 
than waiting for further information from the submitter.  It's completely 
correct for this bug, which should be left as SUSPENDED unless someone 
decides to work on it and so changes it to ASSIGNED with themselves as 
assignee.
Comment 218 Andrew Pinski 2020-04-29 18:01:51 UTC
*** Bug 94852 has been marked as a duplicate of this bug. ***
Comment 219 Andrew Pinski 2021-05-31 03:46:05 UTC
*** Bug 39128 has been marked as a duplicate of this bug. ***
Comment 220 Andrew Pinski 2021-09-02 07:41:53 UTC
*** Bug 30813 has been marked as a duplicate of this bug. ***
Comment 221 Jessica King 2021-10-27 07:55:42 UTC Comment hidden (spam)
Comment 222 Andrew Pinski 2021-11-02 07:17:31 UTC
*** Bug 103030 has been marked as a duplicate of this bug. ***
Comment 223 Tim Turner 2021-11-05 23:18:14 UTC Comment hidden (spam)
Comment 224 Andrew Pinski 2022-07-02 02:09:25 UTC
*** Bug 106165 has been marked as a duplicate of this bug. ***
Comment 225 GCC Commits 2022-10-14 07:32:02 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:98e341130f87984af07c884fea773c0bb3cc8821

commit r13-3290-g98e341130f87984af07c884fea773c0bb3cc8821
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Oct 14 09:28:57 2022 +0200

    c++: Implement excess precision support for C++ [PR107097, PR323]
    
    The following patch implements excess precision support for C++.
    Like for C, it uses EXCESS_PRECISION_EXPR tree to say that its operand
    is evaluated in excess precision and what the semantic type of the
    expression is.
    In most places I've followed what the C FE does in similar spots, so
    e.g. for binary ops if one or both operands are already
    EXCESS_PRECISION_EXPR, strip those away or for operations that might need
    excess precision (+, -, *, /) check if the operands should use excess
    precision and convert to that type and at the end wrap into
    EXCESS_PRECISION_EXPR with the common semantic type.
    This patch follows the C99 handling where it differs from C11 handling.
    
    There are some cases which needed to be handled differently, the C FE can
    just strip EXCESS_PRECISION_EXPR (replace it with its operand) when handling
    explicit cast, but that IMHO isn't right for C++ - the discovery what exact
    conversion should be used (e.g. if user conversion or standard or their
    sequence) should be decided based on the semantic type (i.e. type of
    EXCESS_PRECISION_EXPR), and that decision continues in convert_like* where
    we pick the right user conversion, again, if say some class has ctor
    from double and long double and we are on ia32 with standard excess
    precision promoting float/double to long double, then we should pick the
    ctor from double.  Or when some other class has ctor from just double,
    and EXCESS_PRECISION_EXPR semantic type is float, we should choose the
    user ctor from double, but actually just convert the long double excess
    precision to double and not to float first.  We need to make sure
    even identity conversion converts from excess precision to the semantic one
    though, but if identity is chained with other conversions, we don't want
    the identity next_conversion to drop to semantic precision only to widen
    afterwards.
    
    The existing testcases tweaks were for cases on i686-linux where excess
    precision breaks those tests, e.g. if we have
      double d = 4.2;
      if (d == 4.2)
    then it does the expected thing only with -fexcess-precision=fast,
    because with -fexcess-precision=standard it is actually
      double d = 4.2;
      if ((long double) d == 4.2L)
    where 4.2L is different from 4.2.  I've added -fexcess-precision=fast
    to some tests and changed other tests to use constants that are exactly
    representable and don't suffer from these excess precision issues.
    
    There is one exception, pr68180.C looks like a bug in the patch which is
    also present in the C FE (so I'd like to get it resolved incrementally
    in both).  Reduced testcase:
    typedef float __attribute__((vector_size (16))) float32x4_t;
    float32x4_t foo(float32x4_t x, float y) { return x + y; }
    with -m32 -std=c11 -Wno-psabi or -m32 -std=c++17 -Wno-psabi
    it is rejected with:
    pr68180.c:2:52: error: conversion of scalar âlong doubleâ to vector âfloat32x4_tâ {aka â__vector(4) floatâ} involves truncation
    but without excess precision (say just -std=c11 -Wno-psabi or -std=c++17 -Wno-psabi)
    it is accepted.  Perhaps we should pass down the semantic type to
    scalar_to_vector and use the semantic type rather than excess precision type
    in the diagnostics.
    
    2022-10-14  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/323
            PR c++/107097
    gcc/
            * doc/invoke.texi (-fexcess-precision=standard): Mention that the
            option now also works in C++.
    gcc/c-family/
            * c-common.def (EXCESS_PRECISION_EXPR): Remove comment part about
            the tree being specific to C/ObjC.
            * c-opts.cc (c_common_post_options): Handle flag_excess_precision
            in C++ the same as in C.
            * c-lex.cc (interpret_float): Set const_type to excess_precision ()
            even for C++.
    gcc/cp/
            * parser.cc (cp_parser_primary_expression): Handle
            EXCESS_PRECISION_EXPR with REAL_CST operand the same as REAL_CST.
            * cvt.cc (cp_ep_convert_and_check): New function.
            * call.cc (build_conditional_expr): Add excess precision support.
            When type_after_usual_arithmetic_conversions returns error_mark_node,
            use gcc_checking_assert that it is because of uncomparable floating
            point ranks instead of checking all those conditions and make it
            work also with complex types.
            (convert_like_internal): Likewise.  Add NESTED_P argument, pass true
            to recursive calls to convert_like.
            (convert_like): Add NESTED_P argument, pass it through to
            convert_like_internal.  For other overload pass false to it.
            (convert_like_with_context): Pass false to NESTED_P.
            (convert_arg_to_ellipsis): Add excess precision support.
            (magic_varargs_p): For __builtin_is{finite,inf,inf_sign,nan,normal}
            and __builtin_fpclassify return 2 instead of 1, document what it
            means.
            (build_over_call): Don't handle former magic 2 which is no longer
            used, instead for magic 1 remove EXCESS_PRECISION_EXPR.
            (perform_direct_initialization_if_possible): Pass false to NESTED_P
            convert_like argument.
            * constexpr.cc (cxx_eval_constant_expression): Handle
            EXCESS_PRECISION_EXPR.
            (potential_constant_expression_1): Likewise.
            * pt.cc (tsubst_copy, tsubst_copy_and_build): Likewise.
            * cp-tree.h (cp_ep_convert_and_check): Declare.
            * cp-gimplify.cc (cp_fold): Handle EXCESS_PRECISION_EXPR.
            * typeck.cc (cp_common_type): For COMPLEX_TYPEs, return error_mark_node
            if recursive call returned it.
            (convert_arguments): For magic 1 remove EXCESS_PRECISION_EXPR.
            (cp_build_binary_op): Add excess precision support.  When
            cp_common_type returns error_mark_node, use gcc_checking_assert that
            it is because of uncomparable floating point ranks instead of checking
            all those conditions and make it work also with complex types.
            (cp_build_unary_op): Likewise.
            (cp_build_compound_expr): Likewise.
            (build_static_cast_1): Remove EXCESS_PRECISION_EXPR.
    gcc/testsuite/
            * gcc.target/i386/excess-precision-1.c: For C++ wrap abort and
            exit declarations into extern "C" block.
            * gcc.target/i386/excess-precision-2.c: Likewise.
            * gcc.target/i386/excess-precision-3.c: Likewise.  Remove
            check_float_nonproto and check_double_nonproto tests for C++.
            * gcc.target/i386/excess-precision-7.c: For C++ wrap abort and
            exit declarations into extern "C" block.
            * gcc.target/i386/excess-precision-9.c: Likewise.
            * g++.target/i386/excess-precision-1.C: New test.
            * g++.target/i386/excess-precision-2.C: New test.
            * g++.target/i386/excess-precision-3.C: New test.
            * g++.target/i386/excess-precision-4.C: New test.
            * g++.target/i386/excess-precision-5.C: New test.
            * g++.target/i386/excess-precision-6.C: New test.
            * g++.target/i386/excess-precision-7.C: New test.
            * g++.target/i386/excess-precision-9.C: New test.
            * g++.target/i386/excess-precision-11.C: New test.
            * c-c++-common/dfp/convert-bfp-10.c: Add -fexcess-precision=fast
            as dg-additional-options.
            * c-c++-common/dfp/compare-eq-const.c: Likewise.
            * g++.dg/cpp1z/constexpr-96862.C: Likewise.
            * g++.dg/cpp1z/decomp12.C (main): Use 2.25 instead of 2.3 to
            avoid excess precision differences.
            * g++.dg/other/thunk1.C: Add -fexcess-precision=fast
            as dg-additional-options.
            * g++.dg/vect/pr64410.cc: Likewise.
            * g++.dg/cpp1y/pr68180.C: Likewise.
            * g++.dg/vect/pr89653.cc: Likewise.
            * g++.dg/cpp0x/variadic-tuple.C: Likewise.
            * g++.dg/cpp0x/nsdmi-union1.C: Use 4.25 instead of 4.2 to
            avoid excess precision differences.
            * g++.old-deja/g++.brendan/copy9.C: Add -fexcess-precision=fast
            as dg-additional-options.
            * g++.old-deja/g++.brendan/overload7.C: Likewise.
Comment 226 Andrew Pinski 2023-07-05 19:22:47 UTC
*** Bug 110564 has been marked as a duplicate of this bug. ***
Comment 227 Vincent Lefèvre 2023-07-05 20:15:18 UTC
In "See Also", there are several bugs that are related only to vectorization optimizations. What is the relation with this bug?

For instance, PR89653 is "GCC (trunk and all earlier versions) fails to vectorize (SSE/AVX2/AVX-512) the following loop [...]". If this is SSE/AVX2/AVX-512, where does x86 extended precision occur?
Comment 228 Vincent Lefèvre 2023-07-05 21:00:02 UTC
PR64410 and PR68180 should also be removed from "See Also".
Comment 229 Mathieu Malaterre 2023-07-11 08:25:24 UTC
*** Bug 110622 has been marked as a duplicate of this bug. ***
Comment 230 Andrew Pinski 2023-09-21 13:34:00 UTC
*** Bug 110622 has been marked as a duplicate of this bug. ***
Comment 231 Andrew Pinski 2024-01-31 08:52:15 UTC
*** Bug 113679 has been marked as a duplicate of this bug. ***