This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
stmt.c bugfix
- To: egcs-patches at egcs dot cygnus dot com
- Subject: stmt.c bugfix
- From: Jeffrey A Law <law at upchuck dot cygnus dot com>
- Date: Sun, 04 Apr 1999 03:59:26 -0600
- Reply-To: law at cygnus dot com
Given this testcase:
int x[10] = { 0,1,2,3,4,5,6,7,8,9};
int
main()
{
int niterations = 0, i;
for (;;) {
int i, mi, max;
max = 0;
for (i = 0; i < 10 ; i++) {
if (x[i] > max) {
max = x[i];
mi = i;
}
}
if (max == 0)
break;
x[mi] = 0;
niterations++;
if (niterations > 10)
abort ();
}
exit (0);
}
Compile on an x86 with -O2. The program will abort instead of exiting
with zero status.
In the original testcase the outer loop would hang because entries in
the array were never zero'd and thus we always found a maximum value in
the array that was > 0. Instead of hanging I've changed the test to abort
if it iterates too many times.
The problem is when we try to duplicate the exit test for the outer for
loop we walk into the inner for loop and end up copying the wrong insns
and making a total mess of the instruction stream.
* stmt.c (expand_loop_end): When copying the loop exit test,
do not walk into a nested loop.
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 stmt.c
*** stmt.c 1999/03/06 05:34:15 1.68
--- stmt.c 1999/04/04 10:04:07
*************** expand_end_loop ()
*** 2219,2224 ****
--- 2219,2228 ----
abort ();
}
+ /* We must not walk into a nested loop. */
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ break;
+
/* We already know this INSN is a NOTE, so there's no
point in looking at it to see if it's a JUMP. */
continue;