This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch: fix SPEC regressions


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]