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
This commit is contained in:
Eric Botcazou 2002-12-21 21:25:44 +01:00 committed by Eric Botcazou
parent 5d2f795c35
commit 64b2e87f83
5 changed files with 49 additions and 23 deletions

View 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

View 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) */

View 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;

View 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.

View File

@ -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;
}