Bug 37811 - GCC gives different math results on sun and intel
GCC gives different math results on sun and intel
Status: CLOSED UPSTREAM
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.1
i386 Linux
high Severity high
: ---
: ---
Assigned To: Jakub Jelinek
David Lawrence
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-04-26 09:25 EDT by Wade Minter
Modified: 2005-10-31 17:00 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-10-01 18:03:38 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
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 09:26 EDT, Wade Minter
no flags Details
Sun assembly language generated from dan.c on sparc. (1.08 KB, text/plain)
2001-04-26 09:27 EDT, Wade Minter
no flags Details
Intel assembly code generated from dan.c (972 bytes, text/plain)
2001-04-26 09:28 EDT, Wade Minter
no flags Details

  None (edit)
Description Wade Minter 2001-04-26 09:25:33 EDT
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
7.1).

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
(dan.s.sun).  

Let me know if we can provide any further information.
Comment 1 Wade Minter 2001-04-26 09:26:44 EDT
Created attachment 16485 [details]
C program to generate the bug - different output on sun vs. intel
Comment 2 Wade Minter 2001-04-26 09:27:25 EDT
Created attachment 16486 [details]
Sun assembly language generated from dan.c on sparc.
Comment 3 Wade Minter 2001-04-26 09:28:10 EDT
Created attachment 16487 [details]
Intel assembly code generated from dan.c
Comment 4 Wade Minter 2001-04-26 09:32:14 EDT
Just for reference, running the compiled version of dan.c on a Sun (gcc 2.95.2)
gives:

[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 17:28:16 EDT
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 15:39:24 EDT
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 18:03:38 EDT
The gcc bugzilla tracker for this problem is
  http://gcc.gnu.org/PR323

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.