This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR rtl-optimization/16028 (reload inheritance)
- From: Eric Botcazou <ebotcazou at act-europe dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 21 Jun 2004 14:37:08 +0200
- Subject: Fix PR rtl-optimization/16028 (reload inheritance)
Hi,
This is again the reload inheritance bug I ran into with the ACATS testsuite
on i586. Fariborz recently ran into it too, but with C code on PowerPC.
Description: http://gcc.gnu.org/ml/gcc-patches/2004-04/msg01779.html
Discussion (Joern): http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00061.html
How reload inheritance works appears to be a little unclear, especially its
failure mode. So I think a step in the right direction could be to make
sure that both tests use the same criterion to determine whether a (spill)
reg is suitable for inheritance.
The patch was bootstrapped/regtested on i586-redhat-linux-gnu by me and on
ppc-darwin by Fariborz. Fariborz also ran SPEC on G5 and saw no performance
degradation. OK for mainline?
2004-06-21 Eric Botcazou <ebotcazou@act-europe.fr>
PR rtl-optimization/16028
* reload1.c (choose_reload_regs): When searching for an
equivalent reload register, always check that it is free
for the value being reloaded.
2004-06-21 Fariborz Jahanian <fjahanian@apple.com>
* gcc.c-torture/execute/20040621-1.c: New test.
--
Eric BotcazouIndex: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.437
diff -c -p -r1.437 reload1.c
*** reload1.c 15 Jun 2004 18:02:34 -0000 1.437
--- reload1.c 20 Jun 2004 13:41:59 -0000
*************** choose_reload_regs (struct insn_chain *c
*** 5638,5664 ****
abort ();
}
! /* If we found a spill reg, reject it unless it is free
! and of the desired class. */
if (equiv != 0)
{
- int regs_used = 0;
int bad_for_class = 0;
int max_regno = regno + rld[r].nregs;
for (i = regno; i < max_regno; i++)
! {
! regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
! i);
! bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
! i);
! }
! if ((regs_used
! && ! free_for_value_p (regno, rld[r].mode,
! rld[r].opnum, rld[r].when_needed,
! rld[r].in, rld[r].out, r, 1))
! || bad_for_class)
equiv = 0;
}
--- 5638,5658 ----
abort ();
}
! /* If we found a spill reg, reject it unless it is of the
! desired class and free. */
if (equiv != 0)
{
int bad_for_class = 0;
int max_regno = regno + rld[r].nregs;
for (i = regno; i < max_regno; i++)
! bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
! i);
! if (bad_for_class
! || ! free_for_value_p (regno, rld[r].mode,
! rld[r].opnum, rld[r].when_needed,
! rld[r].in, rld[r].out, r, 1))
equiv = 0;
}
/* PR rtl-optimization/16028 */
/* Origin: Fariborz Jahanian <fjahanian@apple.com> */
typedef short __attribute__ ((vector_size (16))) vecint;
vecint i = { 150, 100, 150, 200, 0, 0, 0, 0 };
vecint j = { 10, 13, 20, 30, 1, 1, 1, 1 };
vecint k;
union {
vecint v;
short i[8];
} res;
void
verify (int a1, int b1)
{
if (a1 != b1)
abort ();
}
int
main ()
{
k = i + j;
res.v = k;
verify (res.i[0], 160);
k = i & j; /* bad code gen for this statement causes the abort. */
res.v = k;
verify (res.i[0], 2);
k = i * j;
res.v = k;
verify (res.i[0], 1500);
exit (0);
}