ada/8606: GNAT floating point optimization bug

Jim Wilson wilson@tuliptree.org
Sun Jun 1 18:13:00 GMT 2003


kalmquist1@hotmail.com wrote:
> The issue I was raising was a different one:  The value of a variable
> changing over time even though it has not been assigned to.  The code
> I included used the value of the variable named "guess" twice, and
> got two different values.  This is prohibited by the Ada standard.

It is fairly well known that gcc emits incorrect x86 FP code.  This is 
partly a problem with the design of the x86 FPU, and partly a problem 
with the design of the gcc x86 backend.  We call this the "excess 
precision problem".

This problem has been known for over a decade, and hasn't been fixed 
yet.  It probably never will be fixed in gcc.  There are few people 
affected, and even fewer who understand what the problem is.  This is 
also a difficult problem to fix because of the x86 FP design.

-ffloat-store incidentally only papers over the problem.  It forces user 
declared variables to be allocated to memory, which avoids the excess 
precision problem for them.  However, temporaries are still allocated to 
registers, and hence you can still see a problem with some programs even 
when -ffloat-store is used.

If you must use x86 processors for FP code, then you should look into 
using SSE registers instead of the traditional x87 FP register stack. 
The SSE registers do not have the excess precision problem.  You can get 
FP to use the SSE registers by using the -mfpmath=sse option.  The AMD64 
people by the way have apparently permanently solved the problem by 
changing the ABI to require use of the SSE registers.

The underlying gcc problem here is that the x86 gcc backend lies, and 
claims that it has SFmode/DFmode instructions.  Gcc then thinks that 
there are SFmode/DFmode values in FP registers, but they are actually 
80-bit values.  This excess precision is relatively harmless for most FP 
algorithms.  The real problem here though is when the register allocator 
needs to spill a value to the stack.  It spills a SFmode/DFmode value, 
because that is what it thinks is in the register.  This means that 
80-bit values get accidentally truncated to SFmode/DFmode values at 
unpredictable places in the code.  This can cause havoc even for well 
behaved FP algorithms.

Jim



More information about the Gcc-bugs mailing list