The simple test which I'll attach shortly, loops infinitely when compiled with -O1 -fstrength-reduce and executes fine with plain -O1. Doing a little debugging, it seems the loop index variable "i" is not incremented within the loop causing us to loop forever. I have tested this using the latest FSF 4.1, 4.2 and mainline compiler sources and it only fails using the 4.1 compiler. Using an older 3.4.6 distro compiler, it executes fine, so this _looks_ like a regression.
Created attachment 13092 [details] Reduced testcase showing the infinite looping
I cannot reproduce this. Please paste the output of gcc -v.
> it only fails using the 4.1 compiler. Well that is because loop.c has been removed in 4.2 and above.
This is using source checked out this afternoon (revision 122219): bg47:bergner% ./install/gcc-4.1/bin/gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../../gcc-4_1-20070222/configure --enable-shared --enable-threads=posix --enable-checking --enable-languages=c --prefix=/tmp/bergner/install/gcc-4.1 Thread model: posix gcc version 4.1.3 20070222 (prerelease)
Works for me. Can you tell us all options in effect? I.e. gcc -O -fstrength-reduce t.c -v output?
Here's the output you asked for using the latest 4.1 sources I built yesterday. This also fails for me using the system compilers on Ubuntu Edgy and SLES10. I'll try and track down a x86 RHEL5 system to test there too. Please note it's not the compiler that is looping forever, but the built binary when executed. bg47:bergner% ./install/gcc-4.1/bin/gcc -O1 -fstrength-reduce pr30311.c -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../../gcc-4_1-20070222/configure --enable-shared --enable-threads=posix --enable-checking --enable-languages=c --prefix=/tmp/bergner/install/gcc-4.1 Thread model: posix gcc version 4.1.3 20070222 (prerelease) /tmp/bergner/install/gcc-4.1/libexec/gcc/i686-pc-linux-gnu/4.1.3/cc1 -quiet -v pr30311.c -quiet -dumpbase pr30311.c -mtune=pentiumpro -auxbase pr30311 -O1 -version -fstrength-reduce -o /tmp/cc6Cx7Y6.s ignoring nonexistent directory "/tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /tmp/bergner/install/gcc-4.1/include /tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3/include /usr/include End of search list. GNU C version 4.1.3 20070222 (prerelease) (i686-pc-linux-gnu) compiled by GNU C version 3.4.4 20050721 (Red Hat 3.4.4-2). GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: 3c763771770d7626aeca3ba678fea9f5 as -V -Qy -o /tmp/ccmkRFA6.o /tmp/cc6Cx7Y6.s GNU assembler version 2.15.92.0.2 (i386-redhat-linux) using BFD version 2.15.92.0.2 20040927 /tmp/bergner/install/gcc-4.1/libexec/gcc/i686-pc-linux-gnu/4.1.3/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3/crtbegin.o -L/tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3 -L/tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3/../../.. /tmp/ccmkRFA6.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /tmp/bergner/install/gcc-4.1/lib/gcc/i686-pc-linux-gnu/4.1.3/crtend.o /usr/lib/crtn.o
Confirmed.
Created attachment 13097 [details] Good assembly output from the 4.1 compiler (-O1 -fno-strength-reduce)
Created attachment 13098 [details] Bad assembly output from the 4.1 compiler (-O1 -fstrength-reduce)
No, i (which is in %edx) *is* being incremented. It's the strength-reduced derived induction variable that is constructed in a wrong way. The optimized code looks like: void bug (struct s *p) { int i; struct s *pp = p; for (i=0; i < 2; i++) { goto loop_cond; loop: /* ??? I think gcc assumes that pp (%eax) is an induction variable of the inner loop... */ pp[-1].first = 0; loop_cond: if (!pp[0].first) goto break_out_of_inner_loop; if (pp[0].done) goto loop; break_out_of_inner_loop; pp++; /* actually adds sizeof (struct s) in the asm code */ i++; } }
> for (i=0; i < 2; i++) Well, that's obviously for (i=0; i < 2; ) in my code of comment #10.
Investigating.
Subject: Bug 30931 Author: ebotcazou Date: Tue Feb 27 20:21:17 2007 New Revision: 122383 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=122383 Log: PR rtl-optimization/30931 * loop.c (combine_givs_p): Return false if either GIV is not always executed. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.c-torture/execute/20070227-1.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/loop.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
Fixed on 4.1 branch.