]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/8599 (loop unroll bug with -march=k6-3)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Sat, 21 Dec 2002 20:25:44 +0000 (21:25 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 21 Dec 2002 20:25:44 +0000 (20:25 +0000)
PR optimization/8599
* doloop.c (doloop_modify_runtime): Revert 2002-11-22 change.
* loop.c (loop_invariant_p): Likewise.

From-SVN: r60392

gcc/ChangeLog
gcc/doloop.c
gcc/loop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/unroll-1.c [new file with mode: 0644]

index a088ccf3d212586f229218f1a4ee6e603faf8ee4..82630b7c41c987c4ea203804f594d69aab58c81e 100644 (file)
@@ -1,3 +1,9 @@
+2002-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/8599
+       * doloop.c (doloop_modify_runtime): Revert 2002-11-22 change.
+       * loop.c (loop_invariant_p): Likewise.
+
 2002-12-19  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        PR optimization/8988
index 6207763a3280d80537a6e3a411f62387101c5aa2..06d8d5734853c384304c589829bb79aa57ec713e 100644 (file)
@@ -598,19 +598,16 @@ doloop_modify_runtime (loop, iterations_max,
 
      If the loop has been unrolled, the full calculation is
 
-       t1 = abs_inc * unroll_number;                   increment per loop
-       n = (abs (final - initial) + abs_inc - 1) / t1;    full loops
-       n += (abs (final - initial) + abs_inc - 1) % t1) >= abs_inc;
-                                                          partial loop
-     which works out to be equivalent to
+       t1 = abs_inc * unroll_number;           increment per loop
+       n = abs (final - initial) / t1;         full loops
+       n += (abs (final - initial) % t1) != 0; partial loop
 
-       n = (abs (final - initial) + t1 - 1) / t1;
-
-     In the case where the loop was preconditioned, a few iterations
-     may have been executed earlier; but 'initial' was adjusted as they
-     were executed, so we don't need anything special for that case here.
-     As above, when t1 is a power of two we don't need to worry about
-     overflow.
+     However, in certain cases the unrolled loop will be preconditioned
+     by emitting copies of the loop body with conditional branches,
+     so that the unrolled loop is always a full loop and thus needs
+     no exit tests.  In this case we don't want to add the partial
+     loop count.  As above, when t1 is a power of two we don't need to
+     worry about overflow.
 
      The division and modulo operations can be avoided by requiring
      that the increment is a power of 2 (precondition_loop_p enforces
@@ -685,10 +682,10 @@ doloop_modify_runtime (loop, iterations_max,
       if (shift_count < 0)
        abort ();
 
-      /* (abs (final - initial) + abs_inc * unroll_number - 1) */
-      diff = expand_simple_binop (GET_MODE (diff), PLUS,
-                                 diff, GEN_INT (abs_loop_inc - 1),
-                                 diff, 1, OPTAB_LIB_WIDEN);
+      if (!loop_info->preconditioned)
+       diff = expand_simple_binop (GET_MODE (diff), PLUS,
+                                   diff, GEN_INT (abs_loop_inc - 1),
+                                   diff, 1, OPTAB_LIB_WIDEN);
 
       /* (abs (final - initial) + abs_inc * unroll_number - 1)
         / (abs_inc * unroll_number)  */
index 2dddc66e63ea39c7d4d026951f48856b047e0000..58e0255d8c3a724f4503a51f8dcf91d919318ef5 100644 (file)
@@ -3278,13 +3278,6 @@ loop_invariant_p (loop, x)
          && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
        return 0;
 
-      /* Out-of-range regs can occur when we are called from unrolling.
-        These have always been created by the unroller and are set in
-        the loop, hence are never invariant. */
-
-      if (REGNO (x) >= regs->num)
-       return 0;
-
       if (regs->array[REGNO (x)].set_in_loop < 0)
        return 2;
 
index 17e079d5e9b3caa7083088d5626e5a540ead9f59..e49ad5f4379f23d8d6f9c4f924976f8d412fc60f 100644 (file)
@@ -1,3 +1,7 @@
+2002-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/unroll-1.c: New test.
+
 2002-12-19  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * gcc.c-torture/execute/20021219-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/unroll-1.c b/gcc/testsuite/gcc.dg/unroll-1.c
new file mode 100644 (file)
index 0000000..c2a24cf
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR optimization/8599 */
+/* { dg-do run } */
+/* { dg-options "-O2 -funroll-loops" } */
+/* { dg-options "-mcpu=k6 -O2 -funroll-loops" { target i?86-*-* } } */
+
+extern void abort (void);
+
+int array[6] = { 1,2,3,4,5,6 };
+
+void foo()
+{
+  int i;
+
+  for (i = 0; i < 5; i++)
+    array[i] = 0;
+}
+
+int main()
+{
+  foo();
+  if (array[0] || array [1] || array[2] || array[3] || array[4])
+    abort ();
+  if (array[5] != 6)
+    abort ();
+  return 0;
+}