]> 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>
Fri, 22 Nov 2002 21:20:04 +0000 (21:20 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 22 Nov 2002 21:20:04 +0000 (21:20 +0000)
PR optimization/8599

Merge from mainline:
2002-11-04 �Dale Johannesen �<dalej@apple.com>

* doloop.c (doloop_modify_runtime): �Fix loop count computation
for unrolled loops.
* loop.c (loop_invariant_p): �Support calling from unroller.

From-SVN: r59387

gcc/ChangeLog
gcc/doloop.c
gcc/loop.c

index aec310883ef76c39cecee60d96ece4773e55722e..8ba30d3e2631a4e7f18cd2575f47140937bd16c9 100644 (file)
@@ -1,3 +1,14 @@
+2002-11-22  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/8599
+
+       Merge from mainline:
+       2002-11-04  Dale Johannesen  <dalej@apple.com>
+
+       * doloop.c (doloop_modify_runtime):  Fix loop count computation
+       for unrolled loops.
+       * loop.c (loop_invariant_p):  Support calling from unroller.
+
 2002-11-22  Daniel Jacobowitz  <drow@mvista.com>
 
        * config/sh/sh.md (ashrdi3+1, ashrdi3+2): Predicate on
index 06d8d5734853c384304c589829bb79aa57ec713e..6207763a3280d80537a6e3a411f62387101c5aa2 100644 (file)
@@ -598,16 +598,19 @@ 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) / t1;         full loops
-       n += (abs (final - initial) % t1) != 0; partial loop
+       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
 
-     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.
+       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.
 
      The division and modulo operations can be avoided by requiring
      that the increment is a power of 2 (precondition_loop_p enforces
@@ -682,10 +685,10 @@ doloop_modify_runtime (loop, iterations_max,
       if (shift_count < 0)
        abort ();
 
-      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) */
+      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 149e7d1b97b43f8384db0bc6bfc0403cdffc5f1d..ff598d323c49e627962f88fce2911acfccba105b 100644 (file)
@@ -3278,6 +3278,13 @@ 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;