This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.1] Fix PR optimization/28970
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Nov 2006 13:13:52 +0100
- Subject: [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;
}