This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

stmt.c bugfix



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;





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]