Bug 224280 - gcc optimzer (-O) bug produces wrong program results
gcc optimzer (-O) bug produces wrong program results
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: gcc (Show other bugs)
i386 Linux
medium Severity high
: ---
: ---
Assigned To: Jakub Jelinek
Depends On:
  Show dependency treegraph
Reported: 2007-01-24 19:22 EST by Jonathan Dagresta
Modified: 2007-11-16 20:14 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2007-01-25 04:17:18 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Test program (578 bytes, text/plain)
2007-01-24 19:28 EST, Jonathan Dagresta
no flags Details

  None (edit)
Description Jonathan Dagresta 2007-01-24 19:22:37 EST
Test program attached produces wrong results when compiled optimzied (-O): 
> uname -a
Linux redhat1 2.6.9-34.EL #1 Fri Feb 24 16:44:51 EST 2006 /gcc/i686 i686 i386
> cc -v -DNOTOPT=1 -g linuxtest.c -o dbglinuxtest -lm
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.6/specs
Configured with: ../configure --previx=/usr --mandir = /usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix --disable
-checking --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-jsava-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)
 /usr/libexec/gcc/i386-redhat-linux/3.4.6/cc1 -quiet -v -DNOTOPT=1 linuxtest.c
-quiet -dumpbase linuxtest.c -auxbase linuxtest -g -version -o /tmp/ccpqmcjF.s
ignoring nonexistent directory
#include "..." search starts here:
#include <...> search starts here:
End of search list.
GNU C version 3.4.6 20060404 (Red Hat 3.4.6-3) (i386-redhat-linux)
        compiled by GNU C version 3.4.6 20060404 (Red Hat
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
 as -V -Qy -o /tmp/ccG9Ghze.o /tmp/ccpqmcjF.s
GNU assembler version (i386-redhat-linux) using BFD version 20040927
 /usr/libexec/gcc/i386-redhat-linux/3.4.6/collect2 --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linus.so.2 -o dbglinuxtest
/usr/lib/i386-redhat-linux/3.4.6/crtbegin.o -L/usr/lib/i386-redhat-linux/3.4.6
-L/usr/lib/i386-redhat-linux/3.4.6/../../.. /tmp/ccG9Ghze.o -lm -lgcc
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
> cc -v -O -g linuxtest.c -o optlinuxtest -lm
 /usr/libexec/gcc/i386-redhat-linux/3.4.6/cc1 -quiet -v linuxtest.c -quiet
-dumpbase linuxtest.c -auxbase linuxtest -g -O -version -o /tmp/ccbbYSTU.s
> dbglinuxtest
dvalue = 24215.000000
(int)trunc(dvalue) = 24215
value = (int)dvalue = *** 24215 ***
With only -g (not optimized) casted double to int value is OK
> optlinuxtest
dvalue = 24215.000000
(int)trunc(dvalue) = 24215
value = (int)dvalue = *** 24214 ***
With -O -g (optimized) casted double to int value is BAD
You can see from comparing the two test outputs that the optimized code is not
giving the correct results for the double value that has been cast to an integer
Comment 1 Jonathan Dagresta 2007-01-24 19:28:51 EST
Created attachment 146483 [details]
Test program
Comment 2 Jakub Jelinek 2007-01-25 04:17:18 EST
That's not a bug, but a buggy testcase relying on something you should never
rely on in IEEE 754 arithmetics.  Please google around and read some papers on
IEEE 754 floating point accuracy.  Especially on i386 where (when optimizing)
some results are computed in extended precision rather than double precision.
As cast to int is truncating and 154976.0 / 96.0 is not exactly expressible
in IEEE 754 formats, both 24215 and 24214 are acceptable results here.
Comment 3 Jonathan Dagresta 2007-01-29 16:43:26 EST
Through further investigation I discovered that the default behavior of gcc is 
not true IEEE 754 behavior for floating point arithmetic. The IEEE 754 standard 
requires that compilers, including optimizing, avoid changes which affect such 
things as floating point accuracy, and that the reason for this is to improve 
the portability of software, and this is not the default behavior of gcc! 
It would have been more useful if this had been pointed out to me instead of 
just rejecting my report by saying that my test case was "invalid". 
The solution is to use the -ffloat-store switch to gcc, which tells it to give 
true IEEE 754 standard behavior. 

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