public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/16607] New: Incorrect FP code generated in member data initialization
@ 2004-07-17 17:20 npr1 at suomi24 dot fi
  2004-07-17 17:40 ` [Bug c++/16607] " pinskia at gcc dot gnu dot org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-17 17:20 UTC (permalink / raw)
  To: gcc-bugs

In some conditions a member initializer of double data is handled in single 
precision.

Attached is a quite fragile minimized test program. In it, the bug only surfaces 
in inlined code, i.e. compiled with -O.

At least GCC 3.3, 3.3.3 and 3.4.1 are affected. A test on GCC 2.95.4 on i686-pc-
linux-gnu didn't show the bug. It might be x86 only, as the test program doesn't 
show it with GCC 3.3 on sparc-sun-solaris2.8.

For example, "gcc -v" of the 3.3.3:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/
usr/share/info --enable-shared --enable-threads=posix --disable-checking --
disable-libunwind-exceptions --with-system-zlib --enable-__cxa_atexit --
host=i386-redhat-linux
Thread model: posix
gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7)

/* $ g++ -Wall -O gccbug.cpp && ./a.out
 *  -1.19209e-07 0
 *  0 1.19209e-07
 * $ g++ -Wall -O0 gccbug.cpp && ./a.out
 *  0 1.19209e-07
 *  0 1.19209e-07
 */

int printf(const char*, ...);

struct C {
	double x;
	C(double x_) : x(x_) {
		printf(" ");
		printf("%g %g\n", x - x_, x - float(x_));
	}
};

void f(float x) {
	const double y = x * .9f;
	if (x) {
		new C(y);
		new C(y);
	}
}

int main() {
	f(3);
	return 0;
}

-- 
           Summary: Incorrect FP code generated in member data
                    initialization
           Product: gcc
           Version: 3.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: npr1 at suomi24 dot fi
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
@ 2004-07-17 17:40 ` pinskia at gcc dot gnu dot org
  2004-07-17 20:41 ` npr1 at suomi24 dot fi
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-07-17 17:40 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-07-17 17:40 -------
This is a dup of bug 323.

*** This bug has been marked as a duplicate of 323 ***

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
  2004-07-17 17:40 ` [Bug c++/16607] " pinskia at gcc dot gnu dot org
@ 2004-07-17 20:41 ` npr1 at suomi24 dot fi
  2004-07-17 22:29 ` pinskia at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-17 20:41 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From npr1 at suomi24 dot fi  2004-07-17 20:41 -------
(In reply to comment #1)
> This is a dup of bug 323.

No it's not. Please read the code and the example output.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|DUPLICATE                   |


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
  2004-07-17 17:40 ` [Bug c++/16607] " pinskia at gcc dot gnu dot org
  2004-07-17 20:41 ` npr1 at suomi24 dot fi
@ 2004-07-17 22:29 ` pinskia at gcc dot gnu dot org
  2004-07-18  0:38 ` npr1 at suomi24 dot fi
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-07-17 22:29 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-07-17 22:29 -------
Yes it is, read the whole bug next time.

*** This bug has been marked as a duplicate of 323 ***

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
                   ` (2 preceding siblings ...)
  2004-07-17 22:29 ` pinskia at gcc dot gnu dot org
@ 2004-07-18  0:38 ` npr1 at suomi24 dot fi
  2004-07-19  2:01 ` npr1 at suomi24 dot fi
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-18  0:38 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From npr1 at suomi24 dot fi  2004-07-18 00:38 -------
(In reply to comment #3)
> Yes it is, read the whole bug next time.
> *** This bug has been marked as a duplicate of 323 ***

I'm sorry but I must insist on the opposite. I hope you'll spare me yet some 
more of your time and explain what I am thinking wrong, if this still doesn't 
make sense.

I've read all of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 a few times 
already, and agree that "bug" 323 (about x != y in floating point) is clearly a 
case of rounding. This bug has nothing to do with that.

You can see that my program prints two lines, each from an identical call to new 
C(y); In the flawed case (compiled with -O), the first printout is completely 
different from the second one which is correct. Between calls (and also in 
relation to x_ in the wrong case), the value of x changes by the printed value 
of ~1e-7 which is very much more than the precision of double x_ which has a 
value of ~2.7. The effect of rounding would be of the same magnitude as the 
double epsilon, less than 1e-15.

You should notice that there are no floats used after the initialization of 
const double y. There's no way the value in y or x_ could fluctuate more than 
the precision of a double.

I understand that your time is limited and seeing identical bug reports for non-
bugs is frustrating. I should have initially documented better why I think the 
result is invalid and not from rounding.

If all this is wrong, I wholeheartedly apologize and will stop reopening the 
bug. :)

-- 


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
                   ` (3 preceding siblings ...)
  2004-07-18  0:38 ` npr1 at suomi24 dot fi
@ 2004-07-19  2:01 ` npr1 at suomi24 dot fi
  2004-07-19  2:58 ` npr1 at suomi24 dot fi
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-19  2:01 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From npr1 at suomi24 dot fi  2004-07-19 02:01 -------
To bring up the error in compilation clearly, here's a part of the original 
program's assembly, for essentially this part of code:

struct C {
	double x;
	C(double x_) : x(x_) { }
};

void f(float x) {
	const double y = x * .9f;
	new C(y);
}

The above code alone doesn't compile that way, though. This is just to 
illustrate what I left to show in the assembly.

_Z1ff:
        ; snip stack frame setup
        flds    8(%ebp)
        fld     %st(0)
        fmuls   .LC0	; .LC0 is ".9f", obviously
        fsts    -28(%ebp)	; float version saved for some reason (*bug*)
        fstpl   -24(%ebp)	; this is later used in other uses of y
        ; snip code for the "if" which is in the original program
        pushl   $8
        call    _Znwj
        movl    %eax, %ebx
        flds    -28(%ebp)	; the float version loaded (*bug*)
        fstpl   (%eax)	; and saved as double x

I forgot to reopen the bug last time, doing it now.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|DUPLICATE                   |


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
                   ` (4 preceding siblings ...)
  2004-07-19  2:01 ` npr1 at suomi24 dot fi
@ 2004-07-19  2:58 ` npr1 at suomi24 dot fi
  2004-07-19  3:22 ` zack at gcc dot gnu dot org
  2004-07-19 14:40 ` npr1 at suomi24 dot fi
  7 siblings, 0 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-19  2:58 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From npr1 at suomi24 dot fi  2004-07-19 02:58 -------
I'm taking it back now. (skip to --- if you're in a hurry)

It took so long to understand, now I feel ashamed. I'm not a floating point 
guru, which you might have guessed. I have read about the extra precision within 
FPU, but didn't understand the same might apply between float and double /and/ 
that grammatically, in double = float * float the right side is actually of the 
type float, and so the result /may or may not/ contain extra precision relative 
to that float. To add to the matter, it obviously also can both have the extra 
precision and not have it in the same run.

It's quite weird how the compiler only in this case goes through extra hoops 
(with a minor performance loss, too) to lose the extra precision. If the program 
is modified in any great way, and in all other uses of y even this way, it uses 
the value with extra precision.

This came up in such a complicated program spun across function calls that I 
just couldn't imagine the cause being so simple. Sorry for overlooking the 
possibility so long.

---

I'm still wondering if the standards allow this extra precision to happen across 
function calls, albait inlined by the compiler. If it does, feel free to once 
again mark this as a duplicate of report 323, forget this issue, and I'll go 
repent and not bother you any more.

I'm sorry I didn't find an authoritative source and must still speculate. I 
don't have the standard or know where else to look.

I've learned from this in any case. The lesson, sadly, is that even within the 
insides of one function, I can't rely on a double argument to hold it's value to 
more precision than that of a float. I'm still hoping this is not the case, so a 
confirmation either way would be greatly appreciated.

-- 


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
                   ` (5 preceding siblings ...)
  2004-07-19  2:58 ` npr1 at suomi24 dot fi
@ 2004-07-19  3:22 ` zack at gcc dot gnu dot org
  2004-07-19 14:40 ` npr1 at suomi24 dot fi
  7 siblings, 0 replies; 9+ messages in thread
From: zack at gcc dot gnu dot org @ 2004-07-19  3:22 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From zack at gcc dot gnu dot org  2004-07-19 03:22 -------
The C standard is actually quite clear that *none* of the problems covered by
bug 323 are allowed.  We are agreed with you that this is a bug.  The thing is,
it's a *hardware* bug.  The 80387 floating point unit is broken as designed,
such that it is impossible to get standard-compliant floating point semantics
and good performance at the same time.  Thus, we have -ffloat-store, which lets
you choose which you want, and that's the best we can do on the x86.

It's usually possible to structure floating-point code such that it's robust
against the sorts of errors that the bug introduces.  You can also get a
computer without the hardware bug - neither the AMD64 nor the PowerPC has this
problem.

*** This bug has been marked as a duplicate of 323 ***

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/16607] Incorrect FP code generated in member data initialization
  2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
                   ` (6 preceding siblings ...)
  2004-07-19  3:22 ` zack at gcc dot gnu dot org
@ 2004-07-19 14:40 ` npr1 at suomi24 dot fi
  7 siblings, 0 replies; 9+ messages in thread
From: npr1 at suomi24 dot fi @ 2004-07-19 14:40 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From npr1 at suomi24 dot fi  2004-07-19 14:39 -------
Personally, I don't mind floats being imprecise in the last few bits, or doubles 
being imprecise in their last few bits. What I do mind is that after assigning 
float * float to double, that double value can have "simultaneously" two values 
that differ in almost half of their last bits. If this is allowed, one can never 
count on double having any more practical precision than float, especially with 
the duality being carried over [inlined] function calls. I'm sure many programs 
rely on this but, since it's broken so rarely it's not noticed until with a new 
compiler or a small non-related change in code structure. (Ouch!)

The "double = float * float" case could be fixed without performance issues, 
too. The compiler could well generate code that always uses the value with extra 
precision (that of double, or more). As I noted, the compiler already does this 
in all cases but the one. At least in my example, using two forms (single and 
double precision) of the result generates an unnecessary instruction, so 
actually there would be a performance increase.

I suppose a compiler patch could be too laborious compared to the gains, 
especially as it mustn't affect non-x86 compilations. My personal fix will be 
converting all uses of float to double, but obviously this is not good for all 
programs.

-- 


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


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-07-19 14:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-17 17:20 [Bug c++/16607] New: Incorrect FP code generated in member data initialization npr1 at suomi24 dot fi
2004-07-17 17:40 ` [Bug c++/16607] " pinskia at gcc dot gnu dot org
2004-07-17 20:41 ` npr1 at suomi24 dot fi
2004-07-17 22:29 ` pinskia at gcc dot gnu dot org
2004-07-18  0:38 ` npr1 at suomi24 dot fi
2004-07-19  2:01 ` npr1 at suomi24 dot fi
2004-07-19  2:58 ` npr1 at suomi24 dot fi
2004-07-19  3:22 ` zack at gcc dot gnu dot org
2004-07-19 14:40 ` npr1 at suomi24 dot fi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).