From: Eric Botcazou Date: Fri, 22 Nov 2002 21:20:04 +0000 (+0000) Subject: re PR rtl-optimization/8599 (loop unroll bug with -march=k6-3) X-Git-Tag: releases/gcc-3.2.2~267 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e6ec8432ac6b1a882a7bc73d2808b33f6ae4254b;p=thirdparty%2Fgcc.git re PR rtl-optimization/8599 (loop unroll bug with -march=k6-3) PR optimization/8599 Merge from mainline: 2002-11-04 �Dale Johannesen � * doloop.c (doloop_modify_runtime): �Fix loop count computation for unrolled loops. * loop.c (loop_invariant_p): �Support calling from unroller. From-SVN: r59387 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aec310883ef7..8ba30d3e2631 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2002-11-22  Eric Botcazou   + + PR optimization/8599 + + Merge from mainline: + 2002-11-04  Dale Johannesen   + + * 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 * config/sh/sh.md (ashrdi3+1, ashrdi3+2): Predicate on diff --git a/gcc/doloop.c b/gcc/doloop.c index 06d8d5734853..6207763a3280 100644 --- a/gcc/doloop.c +++ b/gcc/doloop.c @@ -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) */ diff --git a/gcc/loop.c b/gcc/loop.c index 149e7d1b97b4..ff598d323c49 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -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;