Here is one more patch concerning

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61325

The following patch prevents complex address transformation just by checking a change in address validity of subreg memory substitution.

The patch was bootstrapped and tested on x86-64.

Committed as rev. 211716 to gcc-4.9-branch and as rev. 211715 to the trunk.

2014-06-16  Vladimir Makarov  <vmaka...@redhat.com>

        PR rtl-optimization/61325
        * lra-constraints.c (valid_address_p): Add forward declaration.
        (simplify_operand_subreg): Check address validity before and after
        alter_reg of memory subreg.


Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 211654)
+++ lra-constraints.c   (working copy)
@@ -1231,6 +1231,8 @@
     }
 }
 
+static int valid_address_p (enum machine_mode mode, rtx addr, addr_space_t as);
+
 /* Make reloads for subreg in operand NOP with internal subreg mode
    REG_MODE, add new reloads for further processing.  Return true if
    any reload was generated.  */
@@ -1261,12 +1263,28 @@
      equivalences in function lra_constraints) and because for spilled
      pseudos we allocate stack memory enough for the biggest
      corresponding paradoxical subreg.  */
-  if ((MEM_P (reg)
-       && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg))
-          || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode)))
-      || (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER))
+  if (MEM_P (reg)
+      && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg))
+         || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode)))
     {
+      rtx subst, old = *curr_id->operand_loc[nop];
+
       alter_subreg (curr_id->operand_loc[nop], false);
+      subst = *curr_id->operand_loc[nop];
+      lra_assert (MEM_P (subst));
+      if (! valid_address_p (GET_MODE (reg), XEXP (reg, 0),
+                            MEM_ADDR_SPACE (reg))
+         || valid_address_p (GET_MODE (subst), XEXP (subst, 0),
+                             MEM_ADDR_SPACE (subst)))
+       return true;
+      /* If the address was valid and became invalid, prefer to reload
+        the memory.  Typical case is when the index scale should
+        correspond the memory.  */
+      *curr_id->operand_loc[nop] = old;
+    }
+  else if (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER)
+    {
+      alter_subreg (curr_id->operand_loc[nop], false);
       return true;
     }
   /* Put constant into memory when we have mixed modes.  It generates

Reply via email to