==operator gives unexpected result using -O0

James E Wilson wilson@specifix.com
Thu Jul 28 22:31:00 GMT 2005


Jakob Andreas Bærentzen wrote:
> It seems to me that if a,b, and c are float or double values and if a has been 
> assigned b*c then a == (b*c)
> should return true since a should contain the same bitpattern as the temporary 
> being assigned the value of b*c. Is it not so? 

This is the infamous x86 "excess precision" problem, which has been 
discussed in PR 323 and elsewhere.
     http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323

The problem is that the x87 FP register stack has 80 bit registers. 
Doubles are 64-bits.  If you aren't careful (or if the compiler isn't), 
then you can end up comparing a full unrounded 80-bit value against a 
rounded 64-bit value, which will not be equal.  Thus the result that you 
are seeing.

There are various ways to work around this, but unfortunately, there is 
no good solution to the problem that makes everyone happy.  The hardware 
design and the linux ABI design makes it difficult for the compiler to 
both get the right answer and give good performance.  This problem has 
gone unsolved for well over a decade, and may never be solved.

This problem can be avoided by using SSE registers instead of the x87 FP 
register stack.  If you are running 64-bit linux on an AMD64/EM64T 
system, you won't have this problem, because they use the SSE registers 
by default.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com



More information about the Gcc-bugs mailing list