Bug 34951

Summary: gcse+O1 triggers invalid floating point stack management
Product: gcc Reporter: Timothy B. Terriberry <tterribe>
Component: rtl-optimizationAssignee: Not yet assigned to anyone <unassigned>
Severity: normal CC: 166255, 36876, adam, anoullez, benoit.sibaud, bernert, birger.b, brad_atcheson, brooks, cognot, csk, debian-gcc, denis.nagorny, deshpand, dsell, dyang, eda-qa, egon, gbburkhardt, gcc-bugs, gcc-erikd, gcczilla1, Graham.Murphy, green, gsinai, gtalbot, have, hjl.tools, ismail, jmurray, konstantin, lani, macracan, neff.kevin, npr1, olcios, P.Schaffnit, paul_blankenbaker, petr.savicky, piaget, pr2345, preciseflight, rozenman, sk2alexa, sliwa, sunjoong, themis_hv, tjf, tterribe, u.strempel, whaley, wirawan0, xiaoyi_wu
Priority: P3    
Version: 4.2.2   
Target Milestone: ---   
Host: Target:
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed:
Attachments: Pre-processed source.

Description Timothy B. Terriberry 2008-01-24 04:01:40 UTC
-fgcse (only at optimization level -O1 or higher) causes the compare at line 3639 of the pre-processed linprog.i (attached) to fire with only one of its operands on the stack. This leads to non-sensical results such as normal floating point number being declared less than itself.

If the je .L345 is change to a je .L365 in the resulting assembly, the code functions correctly.

The following input (on stdin) triggers the problem:
4 3 0 1
-2 -3   1 -204
 7  4   1  408
-5  6   1    0
 1  1   0  102
 0  0 102

This should report that 102 (0x4059800000000000) is less than itself.

The compiler output follows:

gcc -Wall -v -lm -O1 -fgcse -save-temps linprog.c -o linprog-bug
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.2.2/work/gcc-4.2.2/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.2.2 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.2.2 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.2.2/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.2.2/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-libunwind-exceptions --disable-multilib --enable-libmudflap --disable-libssp --disable-libgcj --with-arch=i686 --enable-languages=c,c++,treelang,fortran --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu
Thread model: posix
gcc version 4.2.2 (Gentoo 4.2.2 p1.0)
 /usr/libexec/gcc/i686-pc-linux-gnu/4.2.2/cc1 -E -quiet -v linprog.c -mtune=generic -march=i686 -Wall -fgcse -O1 -fpch-preprocess -o linprog.i
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
End of search list.
 /usr/libexec/gcc/i686-pc-linux-gnu/4.2.2/cc1 -fpreprocessed linprog.i -quiet -dumpbase linprog.c -mtune=generic -march=i686 -auxbase linprog -O1 -Wall -version -fgcse -o linprog.s
GNU C version 4.2.2 (Gentoo 4.2.2 p1.0) (i686-pc-linux-gnu)
        compiled by GNU C version 4.2.2 (Gentoo 4.2.2 p1.0).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: b5268e820b5e470b4c5cb18dc589783e
linprog.c: In function ‘lp_solve_phase0’:
linprog.c:77: warning: suggest parentheses around && within ||
linprog.c:78: warning: suggest parentheses around && within ||
linprog.c: In function ‘lp_solve_phase1’:
linprog.c:163: warning: suggest parentheses around && within ||
linprog.c: In function ‘lp_solve_impl’:
linprog.c:49: warning: ‘jmax’ may be used uninitialized in this function
linprog.c:49: note: ‘jmax’ was declared here
linprog.c:141: warning: ‘imin’ may be used uninitialized in this function
linprog.c:141: note: ‘imin’ was declared here
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../i686-pc-linux-gnu/bin/as -V -Qy -o linprog.o linprog.s
GNU assembler version 2.18 (i686-pc-linux-gnu) using BFD version (GNU Binutils) 2.18
 /usr/libexec/gcc/i686-pc-linux-gnu/4.2.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o linprog-bug /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.2.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.2.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../i686-pc-linux-gnu/lib -L/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../.. -lm linprog.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../crtn.o
Comment 1 Timothy B. Terriberry 2008-01-24 04:02:34 UTC
Created attachment 15013 [details]
Pre-processed source.
Comment 2 Andrew Pinski 2008-01-24 04:51:51 UTC
Actually no this is not really a "bug" in GCC, just your assumption about x87 fp math.

Anyways this is duplicate of bug 323.

Adding -ffloat-store fixes the issue.

*** This bug has been marked as a duplicate of 323 ***