Serious bug

Tim Hollebeek
Thu Sep 24 19:20:00 GMT 1998

Ryszard Kabatek writes ...
> On 24 Sep 1998, Alexandre Oliva wrote:
> > Complain to Intel.  They have put more precision in FP registers than
> > in doubles stored in memory, that's why you see the difference.
> > Alexandre Oliva 
> I testet the sample with VisualAge C++ 3.0 for OS/2.
> It work correct...

This is a valid complaint against gcc.  In this mail, I include a
smaller simpler C testcase, and more details.

Consider the following program:

#include <stdio.h>

int main()
    double a = 100.1;
    double b = 0.01;
    double s = a + b;
    double y = s;
    double y2 = y - (a + b);

    printf("%g\n", y2);

Using gcc version 2.7.2 on a Linux system, this prints 5.11396e-15.
Obviously, the problem is that (a + b) in y - (a + b) is being computed
with too much precision, due to the braindeadness of the Intel FPU.

*However* (and this is IMO the biggest problem) -ffloat-store, which
is supposed to prevent problems like this, does not fix the problem.
>From the gcc man page:

"but a few programs rely on the precise definition of IEEE floating
point.  Use `-ffloat-store' for such programs."

So -ffloat-store does not work as documented, since some constructs
still manage to disobey IEEE behavior even with it on.

A quick look at the disassembly shows this analysis is correct; the
key fragment is:

	fldl -8(%ebp)
	faddl -16(%ebp)
	fldl -32(%ebp)
	fsubp %st,%st(1)
	fstpl -40(%ebp)

Note that the intermediate result is held in an FPU register, even with
-ffloat-store on.  -mieee-fp doesn't fix this either.

Tim Hollebeek                           | "Everything above is a true
email:       |  statement, for sufficiently
URL: |  false values of true."

More information about the Gcc mailing list