This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch: fix SPEC regressions
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>,Dale Johannesen <dalej at apple dot com>
- Date: Tue, 17 Dec 2002 14:30:16 +0100
- Subject: Re: Patch: fix SPEC regressions
- References: <1C457790-EAAD-11D6-B8DA-000393D76DAA@apple.com> <200211211909.59272.ebotcazou@libertysurf.fr> <200212142339.21146.ebotcazou@libertysurf.fr>
> I'm asking permission to remove the backport of that patch from the 3.2
> branch because, while fixing the computation for 4 iterations, it breaks it
> for any other number of iterations :-(
And to commit this one instead, which gives the correct computation in all
cases on K6 with -O2 -funroll-loops. It passed bootstrapping/regtesting on
i586-redhat-linux-gnu and I've asked Franz Sirl to test it on powerpc too.
I think Dale's analysis
http://gcc.gnu.org/ml/gcc-patches/2002-10/msg01815.html
is correct only for non-preconditioned loops on the 3.2 branch. For
preconditioned loops, Alan's analysis is correct (quoted from doloop.c):
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.
That is, we don't have to run the unrolled loop an additional time in order to
run the few remaining loop iterations because preconditioning just handles
this case.
Alan simply forgot to add the abs_inc-1 correction factor needed for every
doloop loop.
> The original bug occurs because we start with 4 iterations, then lose the
> value through BIV elimination, then pre-condition the loop before unrolling
> it 4 times (the default setting), hence the subtil clash.
The original bug actually occurs for every multiple of 4: the loop is unrolled
4 times and the resulting loop is executed (n/4-1) times instead of n/4 times
when (n%4 == 0, n>0).
--
Eric Botcazou
2002-12-17 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/8599
* doloop.c (doloop_modify_runtime): Fix loop count computation
for preconditioned unrolled loops.
2002-12-17 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/i386-unroll-2.c: New test.
Index: doloop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doloop.c,v
retrieving revision 1.16.8.2
diff -u -r1.16.8.2 doloop.c
--- doloop.c 26 Sep 2002 23:10:38 -0000 1.16.8.2
+++ doloop.c 15 Dec 2002 18:44:55 -0000
@@ -598,9 +598,13 @@
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
+
+ n = (abs (final - initial) + t1 - 1) / t1;
However, in certain cases the unrolled loop will be preconditioned
by emitting copies of the loop body with conditional branches,
@@ -682,13 +686,15 @@
if (shift_count < 0)
abort ();
- if (!loop_info->preconditioned)
+ if (loop_info->preconditioned)
+ diff = expand_simple_binop (GET_MODE (diff), PLUS,
+ diff, GEN_INT (abs_inc - 1),
+ diff, 1, OPTAB_LIB_WIDEN);
+ else
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 = expand_simple_binop (GET_MODE (diff), LSHIFTRT,
diff, GEN_INT (shift_count),
diff, 1, OPTAB_LIB_WIDEN);
/* PR optimization/8599 */
/* { dg-do run { target i?86-*-* } } */
/* { dg-options "-mcpu=k6 -O2 -funroll-loops" } */
extern void exit (int);
void *array[5];
int main ()
{
int i;
for (i = 0; i < 5; i++)
array[i] = 0;
exit (0);
}