Bug 37811 - GCC gives different math results on sun and intel
Summary: GCC gives different math results on sun and intel
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
(Show other bugs)
Version: 7.1
Hardware: i386 Linux
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: David Lawrence
Depends On:
TreeView+ depends on / blocked
Reported: 2001-04-26 13:25 UTC by Wade Minter
Modified: 2005-10-31 22:00 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2004-10-01 22:03:38 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
C program to generate the bug - different output on sun vs. intel (384 bytes, text/plain)
2001-04-26 13:26 UTC, Wade Minter
no flags Details
Sun assembly language generated from dan.c on sparc. (1.08 KB, text/plain)
2001-04-26 13:27 UTC, Wade Minter
no flags Details
Intel assembly code generated from dan.c (972 bytes, text/plain)
2001-04-26 13:28 UTC, Wade Minter
no flags Details

Description Wade Minter 2001-04-26 13:25:33 UTC
We're running across a bug with gcc on Intel when multiplying   (integer =
integer * double; )   The difference between the ( SUN or HP )   and (
Intel )  is that the SUN and HP gcc move the integer to a double "fitod",
then do a double precision  multiply "fmuld".     But the Intel "gcc" 
produces a special instruction to multiply a integer * double  " fmull". 
Which is different than the answer from Intel double precision multiply 
"fmulp" .   This is causing havoc porting from SUN to DELL (Red Hat Linux

Is this a bug in the intel gcc, or is it expected behavior?  It's putting a
big kink in Avant!'s plans to port our software over to Linux.  

Attached are a .c program (dan.c), the assembly language it generates on
intel (dan.s.intel) and the assembly language it generates on a sun

Let me know if we can provide any further information.

Comment 1 Wade Minter 2001-04-26 13:26:44 UTC
Created attachment 16485 [details]
C program to generate the bug - different output on sun vs. intel

Comment 2 Wade Minter 2001-04-26 13:27:25 UTC
Created attachment 16486 [details]
Sun assembly language generated from dan.c on sparc.

Comment 3 Wade Minter 2001-04-26 13:28:10 UTC
Created attachment 16487 [details]
Intel assembly code generated from dan.c

Comment 4 Wade Minter 2001-04-26 13:32:14 UTC
Just for reference, running the compiled version of dan.c on a Sun (gcc 2.95.2)

[minter@therock ]$ ./dan
width = uWidth * uuToDb  = 360
width2 = (double) (uWidth * uuToDb)  = 360.00000000000000000000

Running it on an intel (Red Hat Linux 7.1, gcc 2.96) gives:

[wminter@stonecold wminter]$ ./dan
width = uWidth * uuToDb  = 359
width2 = (double) (uWidth * uuToDb)  = 360.00000000000000000000

Comment 5 Trond Eivind Glomsrxd 2001-04-27 21:28:16 UTC
This isn't a bug - it's a demonstration of the fact that floating point numbers
in binary aren't (usually) exact (you can't map an infinite amount of numbers
onto a finite set of combinations of 0 and 1, so there is a lot of accuracy).

And if the result is 359.99999999999999999999999999999999999999999999999999,
making an int of it will make it 359 as the operation truncates.

That you get different results on different CPUs is to be expected - you could
also get different results on different compilers, if the instructions were
ordered slightly different (but still correct).

Comment 6 Wade Minter 2001-04-30 19:39:24 UTC
Just a clarification before closing.

Our engineer asks:

The problem is that on Linux the statement

i1 = r1 = i*r;

gives different answers to

r1 = i*r;

i1 = r1;

where on the Sun it gives the same answer.


Looking at the assembly code for Linux we get

fmull -16(%ebp)
fstl -32(%ebp)

for the first, and

fmulp %st,%st(1)
fstpl -32(%ebp)
fldl -32(%ebp)

for the second.


If we change the assembly code for the second to

fmulp %st,%st(1)
fstl -32(%ebp)

we get the same answer.


What we want to know is why the value in the first (from fstl) is different from
the second (from fldl), and can the compiler be changed to get over this
(Pentium?) problem.


So, it appears that the compiler may be generating an incorrect assembly
instruction, or possibly a suboptimal one.  

I can attach the code samples if you need them.

Comment 7 Richard Henderson 2004-10-01 22:03:38 UTC
The gcc bugzilla tracker for this problem is

This is a known problem with gcc spill code generation.
You can work around the problem with -ffloat-store or
with -mfpmath=sse -msse2.  The later should also get you
the same numerical results as the Sun, but does require
quite modern hardware (p4 or athlon).

Note You need to log in before you can comment on or make changes to this bug.