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]

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)


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