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