Article View: gnu.gcc.help
Article #41578Re: gcc fails Paranoia (numeric) test under Linux
From: Harald Anlauf
Date: Wed, 13 Mar 1996 00:00
Date: Wed, 13 Mar 1996 00:00
144 lines
6323 bytes
6323 bytes
>>>>> "Dean" == Dean Schulze <schulze@lpl.arizona.edu> writes:
In article <4hn916$ejs@news.ccit.arizona.edu> schulze@lpl.arizona.edu (Dean Schulze) writes:
Dean> I compiled the paranoia test program (netlib.att.com, netlib/paranoia)
Dean> both with and without optimization using gcc 2.7.2 on Linux 1.2.13.
Dean> With optimization off paranoia detected a flaw in the arithmetic
Dean> rounding mode (perhaps controlled by a compiler switch). This is not
Dean> considered a serious flaw, and paranoia pronounced the arithmetic to
Dean> be OK. However, when I compiled with -O2 paranoia found some serious
Dean> flaws and hung before completing the test.
To my experience, there are several reasons for your observations.
First, under Linux (on x86 hardware) the default floating point format
is the so-called extended precision (80 bits), while double precision
floats hold only 64 bits. Therefore results depend on whether
arithmetic is done with variables kept in registers or in memory.
(There is informational output on extra precision early in the
paranoia test). Also look at the gcc option "-ffloat-store" for more
info. If you want strict IEEE conformance, you should try with no
optimization (-O0), and set the FPU control word via
main()
{
__setfpucw (0x127f);
...
}
at the beginning of the paranoia test. This choice enforces strict
rounding to 64 bits. See /usr/include/i386/fpu_control.h (Linux's
default is 0x137[2f])
Second, there is a real bug present at least in gcc versions 2.6.3 and
2.7.0, reported by Geoff Kuenning, that I'll append below. I cannot
check newer releases right now, so please someone follow-up.
Dean> This doesn't prove that my hardware works correctly in all cases, but
Dean> it does show that gcc's optimization is seriously flawed.
As far as I understand, the paranoia test does not take optimization
into account. Under Linux, the precision used during optimization of
FP stuff while compiling with gcc is unknown unless you fix the
startup code of any program using the FPU with the above code snippet,
or modify your crt?.o to set the FPU flags accordingly and recompile
your whole system.
Cheers,
Harald
P.S.: There is a new "stress test" for FPU's from UCB. I found it on
netlib, subdirectory fp. Very interesting...
-------------8<---------------> cut here <--------------8<--------------
From: geoff@ficus.cs.ucla.edu (Geoff Kuenning)
Subject: 80 vs. 64-bit comparisons on x86 architectures, gcc 2.6.3
Newsgroups: gnu.gcc.bug
Date: 8 Nov 1995 15:28:37 -0500
Organization: GNUs Not Usenet
Lines: 69
Sender: daemon@cis.ohio-state.edu
Approved: bug-gcc@prep.ai.mit.edu
Distribution: gnu
SYSTEM:
I am running gcc 2.6.3 on under Slackware Linux 1.2.13, on a 486-based
laptop.
DESCRIPTION:
It appears that on x86 architectures, the result from a "double"
function is returned in one of the 80-bit floating-point registers.
This is usually an advantage if further computation is to be done, and
no disadvantage if it is to be stored in a double. However, if the
result of the function is used in a comparison with a saved double,
the comparison is done incorrectly because the double is widened to 80
bits, rather than narrowing the function return to 64. The program
below shows this.
My first reaction was that this is no different than the widening of
char to int in expressions. Certainly, if "save" had been declared as
a float, the error would be in the program, not the compiler.
However, the difference here is that the function in question,
divby3(), was not declared to return 80 bits. Instead, the compiler
has taken it upon itself to "helpfully" expand my function
declaration. As such, I argue that it is a bug. At least when the
function result is used in a comparison, and probably in any context,
a function result should be treated as the 64-bit value that it was
declared as returning. If the user wants a "long double", he should
have to declare it as such.
REPEAT-BY:
Run the following program without arguments on an x86 architecture and
note that the equality comparison fails. Run it with the argument 42,
or any other multiple of 3, and note that it succeeds. Run it on most
other architectures (e.g., Sparc) and note that it succeeds for all
arguments.
Geoff Kuenning g.kuenning@ieee.org geoff@ITcorp.com
http://www.cs.ucla.edu/ficus-members/geoff/
#include <stdio.h>
/*
* Demonstrate that gcc's double-precision results are actually
* returned as 80 bits on x86 architectures, and that this can cause
* incorrect comparisons.
*/
double divby3(double value);
extern int atoi(const char *);
int main(int argc, char *argv[])
{
double save;
double dividend = 43.0;
if (argc == 2)
dividend = atoi(argv[1]);
save = divby3(dividend);
if (save == divby3(dividend))
fprintf(stderr, "Comparison OK\n");
else
fprintf(stderr, "Comparison failed!\n");
return 0;
}
double divby3(double value)
{
return value / 3.0;
}
-------------8<---------------> cut here <--------------8<--------------
N.B.: even truncating each intermediate result by casting to double
does _not_ help/work, therefore this is a _bug_ in gcc.
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Harald Anlauf, Theoretical High Energy Physics, TH Darmstadt, D-64289 Darmstadt
Email: <anlauf@crunch.ikp.physik.th-darmstadt.de>
It takes all your running you can do to keep in the same place.
If you want to get somewhere else, you must run at least twice as fast as that.
=Lewis Carrol, Through the Looking Glass
Technical Details
Message-ID:
<ub20mx45l5.fsf@crunch.ikp.physik.th-darmstadt.de>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<4hn916$ejs@news.ccit.arizona.edu>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 11318c,fbe8ee8d82a9766b X-Google-Attributes: gid11318c,public X-Google-Thread: 1103af,fbe8ee8d82a9766b X-Google-Attributes: gid1103af,public From: anlauf@crunch.ikp.physik.th-darmstadt.de (Harald Anlauf) Subject: Re: gcc fails Paranoia (numeric) test under Linux Date: 1996/03/13 Message-ID: <ub20mx45l5.fsf@crunch.ikp.physik.th-darmstadt.de> X-Deja-AN: 142379851 sender: anlauf@crunch.ikp.physik.th-darmstadt.de references: <4hn916$ejs@news.ccit.arizona.edu> organization: TH Darmstadt newsgroups: gnu.gcc.help,comp.os.linux.misc