This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR target/34930: instantiate_virtual_regs fix
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 13 Feb 2008 22:46:44 +0100 (CET)
- Subject: Fix PR target/34930: instantiate_virtual_regs fix
Hi,
(from my bugzilla comment):
-----------------
The problem is that rs6000.c accepts all offsets in addresses when they
are based on virtual-stack-reg (as here), at least before reload. The
change from virtual-stack-reg to a different pseudo leaves an offsetted
address, but one that isn't acceptable anymore, as V4SImode only accepts
reg+reg or reg. That's why the predicate doesn't match the operand in the
check of instantiate_virtual_regs, but the fallback code simply forces it
into a register in that case. That of course only works when the
predicate accepts a register, which it doesn't in this case.
The solution is simple: if we have a MEM, whose address got changed, and
now isn't acceptable anymore, load the address into a REG instead of the
whole MEM. If that still isn't acceptable the original check will also
happen again and reload the whole operand, so it's conservatively correct.
-----------------
I wrote also that I have no altivec machines to properly test this patch,
but on reflection it's changing common code, so regstrapping on i386 and
x86_64 should do, I've started that now. I would still appreciate someone
with an altivec machine test this too.
Okay for trunk if my regstrapping passes?
Ciao,
Michael.
--
PR target/34930
* function.c (instantiate_virtual_regs_in_insn): Reload address
before falling back to reloading the whole operand.
Index: gcc/function.c
===================================================================
--- gcc/function.c (Revision 132291)
+++ gcc/function.c (Arbeitskopie)
@@ -1468,6 +1468,20 @@ instantiate_virtual_regs_in_insn (rtx in
start_sequence ();
x = replace_equiv_address (x, addr);
+ /* It may happen that the address with the virtual reg
+ was valid (e.g. based on the virtual stack reg, which might
+ be acceptable to the predicates with all offsets), whereas
+ the address now isn't anymore, for instance when the address
+ is still offsetted, but the base reg isn't virtual-stack-reg
+ anymore. Below we would do a force_reg on the whole operand,
+ but this insn might actually only accept memory. Hence,
+ before doing that last resort, try to reload the address into
+ a register, so this operand stays a MEM. */
+ if (!safe_insn_predicate (insn_code, i, x))
+ {
+ addr = force_reg (GET_MODE (addr), addr);
+ x = replace_equiv_address (x, addr);
+ }
seq = get_insns ();
end_sequence ();
if (seq)