From: Eric Botcazou Date: Sat, 21 Dec 2002 20:25:44 +0000 (+0100) Subject: re PR rtl-optimization/8599 (loop unroll bug with -march=k6-3) X-Git-Tag: releases/gcc-3.2.2~162 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64b2e87f839b18deda1db607933396a4f732f67a;p=thirdparty%2Fgcc.git re PR rtl-optimization/8599 (loop unroll bug with -march=k6-3) PR optimization/8599 * doloop.c (doloop_modify_runtime): Revert 2002-11-22 change. * loop.c (loop_invariant_p): Likewise. From-SVN: r60392 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a088ccf3d212..82630b7c41c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-12-21 Eric Botcazou + + PR optimization/8599 + * doloop.c (doloop_modify_runtime): Revert 2002-11-22 change. + * loop.c (loop_invariant_p): Likewise. + 2002-12-19 Eric Botcazou PR optimization/8988 diff --git a/gcc/doloop.c b/gcc/doloop.c index 6207763a3280..06d8d5734853 100644 --- a/gcc/doloop.c +++ b/gcc/doloop.c @@ -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) */ diff --git a/gcc/loop.c b/gcc/loop.c index 2dddc66e63ea..58e0255d8c3a 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 17e079d5e9b3..e49ad5f4379f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-12-21 Eric Botcazou + + * gcc.dg/unroll-1.c: New test. + 2002-12-19 Eric Botcazou * 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 index 000000000000..c2a24cfcea0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/unroll-1.c @@ -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; +}