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]

[4.1] Fix PR optimization/28970


It's a regression present on 4.1 branch for x86 and PowerPC at -O2.
Wrong code is generated for the simple loop

  while (j != -1)
    {
      outgo++;
      if (outgo > q-1)
        outgo = q-1;
      j = tar (outgo*bcount);
    }

because the old loop optimizer is again fooled by the new dialect of RTL 
generated after tree-opt

<bb 0>:
  pretmp.51 = q - 1;
  outgo = 0;

<L0>:;
  outgo.52 = outgo + 1;
  outgo = MIN_EXPR <pretmp.51, outgo.52>;
  j = tar (outgo * bcount);
  if (j != -1) goto <L0>; else goto <L4>;


It detects a BIV with 2 increments:

Loop from 45 to 46: 12 real insns.
Biv 60: insn 19 const (reg 59 [ pretmp.26 ])
Biv 60: insn 22 const (1)
Biv 60: verified
Biv 60: initialized at insn 13: initial value (0)

and then reduces the GIV associated with outgo*bcount.  Of course the BIV is 
not a simple one so the direct reduction is incorrect.


It turns out the 3.x compiler detects exactly the same BIV:

Biv 61: insn 22 const (1)
Biv 61: insn 28 const (reg 65)
Biv 61: verified
Biv 61: initialized at insn 12: initial value (0)

but the non-constant increment comes after the constant one, which is enough
to prevent the GIV from being reduced...


The attached patch simply ensures that the reduction doesn't depend on the 
order in which the increments are recorded.  It's clearly a kludge, but it's 
about all what we can do for the old loop optimizer at this point.


Bootstrapped/regtested with --enable-checking=release,rtl,rtlflag on 
x86_64-linux-gnu, applied to 4.1 branch.  No change on the 200+ GCC files.


2006-11-01  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR rtl-optimization/28970
	* loop.c (loop_giv_reduce_benefit): Take the max of the addition
	cost on all the increments of the BIV.


2006-11-01  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.c-torture/execute/20061101-1.c: New test.


-- 
Eric Botcazou
Index: loop.c
===================================================================
--- loop.c	(revision 117884)
+++ loop.c	(working copy)
@@ -5602,13 +5603,19 @@ loop_giv_reduce_benefit (struct loop *lo
 			 struct iv_class *bl, struct induction *v,
 			 rtx test_reg)
 {
-  int add_cost;
+  struct induction *biv;
+  int add_cost = 0;
   int benefit;
 
   benefit = v->benefit;
   PUT_MODE (test_reg, v->mode);
-  add_cost = iv_add_mult_cost (bl->biv->add_val, v->mult_val,
-			       test_reg, test_reg);
+  for (biv = bl->biv; biv; biv = biv->next_iv)
+    {
+      int cost = iv_add_mult_cost (biv->add_val, v->mult_val,
+				   test_reg, test_reg);
+      if (cost > add_cost)
+	add_cost = cost;
+    }
 
   /* Reduce benefit if not replaceable, since we will insert a
      move-insn to replace the insn that calculates this giv.  Don't do
/* PR rtl-optimization/28970 */
/* Origin: Peter Bergner <bergner@vnet.ibm.com> */

extern void abort (void);

int tar (int i)
{
  if (i != 36863)
    abort ();

  return -1;
}

void bug(int q, int bcount)
{
  int j = 0;
  int outgo = 0;

  while(j != -1)
    {
      outgo++;
      if (outgo > q-1)
        outgo = q-1;
      j = tar (outgo*bcount);
    }
}

int main(void)
{
  bug(5, 36863);
  return 0;
}

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