When i build the example below with -O1 or above, it goes into an infinite loop:
$ g++ -o x -O1 x.cc $ ./x ... doesn't exit At -O0, it exits as expected: $ g++ -o x -O0 x.cc $ ./x $ Here's the code that's generated (eh-related labels removed for clarity). As you can see, there's an obvious infinite loop... main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp subl $16, %esp movzbl s, %eax testb %al, %al je .L2 .L5: jmp .L5 ; <-- infinite loop! .L2: movb %al, s movl $0, %eax leave ret The problem seems to be introduced in the `lim' ssa pass, where this (from t44.loopinit): int main() () { const unsigned char * prephitmp.3; const unsigned char * pretmp.2; const unsigned char * D.1593; const unsigned char D.1594; int D.1595; int D.1590; int D.1589; const char * str; int D.1578; bool D.1575; bool retval.0; int D.1588; <bb 0>: pretmp.2_13 = (const unsigned char *) &s[0]; goto <bb 2> (<L1>); <L0>:; s[0] = 0; # prephitmp.3_14 = PHI <pretmp.2_13(0), D.1593_6(1)>; <L1>:; D.1593_6 = pretmp.2_13; D.1594_3 = *D.1593_6; D.1595_12 = (int) D.1594_3; D.1590_4 = D.1595_12; if (D.1590_4 != 0) goto <L0>; else goto <L3>; <L3>:; return 0; } gets transformed to this (from t45.lim): int main() () { char lsm_tmp.4; const unsigned char * prephitmp.3; const unsigned char * pretmp.2; const unsigned char * D.1593; const unsigned char D.1594; int D.1595; int D.1590; int D.1589; const char * str; int D.1578; bool D.1575; bool retval.0; int D.1588; <bb 0>: pretmp.2_13 = (const unsigned char *) &s[0]; D.1593_6 = pretmp.2_13; D.1594_3 = *D.1593_6; D.1595_12 = (int) D.1594_3; D.1590_4 = D.1595_12; lsm_tmp.4_15 = s[0]; goto <bb 2> (<L1>); <L0>:; lsm_tmp.4_17 = 0; # lsm_tmp.4_18 = PHI <lsm_tmp.4_15(0), lsm_tmp.4_17(1)>; # prephitmp.3_14 = PHI <pretmp.2_13(0), D.1593_6(1)>; <L1>:; if (D.1590_4 != 0) goto <L0>; else goto <L3>; # lsm_tmp.4_19 = PHI <lsm_tmp.4_18(2)>; <L3>:; s[0] = lsm_tmp.4_19; return 0; } Note that the variable being tested at L1 (D.1590_4) never changes. This feels like it may be related to bugs 17133/17425, but the patch for that doesn't fix this. Environment: System: Linux karma 2.6.8.1 #20 Mon Sep 13 23:48:47 EDT 2004 i686 i686 i386 GNU/Linux Architecture: i686 <machine, os, target, libraries (multiple lines)> host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /home/sss/gcc/gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,f95 How-To-Repeat: Compile and run with -O1 or above. ------------------------------------------- extern "C" int strcmp (const char*, const char*); char s[2048] = "a"; inline bool foo(const char *str) { return !strcmp(s,str); } int main() { while(!(foo(""))) { s[0] = '\0'; } return 0; } ------------------------------------------- ------- Additional Comments From snyder at fnal dot gov 2004-11-04 15:59 ------- Fix: <how to correct or work around the problem, if known (multiple lines)> -- Summary: 4.0: bad code from lim ssa pass with strcmp Product: gcc Version: 0.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: snyder at fnal dot gov CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18298