Hi,

This patch (diff-reload) backports fixes for a couple of problems in
PowerPC reload handling.

Thanks,
Bill


2014-03-19  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        Apply mainline r207798
        2014-02-26  Alan Modra  <amo...@gmail.com>
        PR target/58675
        PR target/57935
        * config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Use
        find_replacement on parts of insn rtl that might be reloaded.

        Backport from mainline r208287
        2014-03-03  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        * config/rs6000/rs6000.c (rs6000_preferred_reload_class): Disallow
        reload of PLUS rtx's outside of GENERAL_REGS or BASE_REGS; relax
        constraint on constants to permit them being loaded into
        GENERAL_REGS or BASE_REGS.


Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.c
@@ -16380,7 +16380,7 @@ rs6000_secondary_reload_inner (rtx reg,
     rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
 
   rclass = REGNO_REG_CLASS (regno);
-  addr = XEXP (mem, 0);
+  addr = find_replacement (&XEXP (mem, 0));
 
   switch (rclass)
     {
@@ -16391,19 +16391,18 @@ rs6000_secondary_reload_inner (rtx reg,
       if (GET_CODE (addr) == AND)
        {
          and_op2 = XEXP (addr, 1);
-         addr = XEXP (addr, 0);
+         addr = find_replacement (&XEXP (addr, 0));
        }
 
       if (GET_CODE (addr) == PRE_MODIFY)
        {
-         scratch_or_premodify = XEXP (addr, 0);
+         scratch_or_premodify = find_replacement (&XEXP (addr, 0));
          if (!REG_P (scratch_or_premodify))
            rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
 
-         if (GET_CODE (XEXP (addr, 1)) != PLUS)
+         addr = find_replacement (&XEXP (addr, 1));
+         if (GET_CODE (addr) != PLUS)
            rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
-
-         addr = XEXP (addr, 1);
        }
 
       if (GET_CODE (addr) == PLUS
@@ -16411,6 +16410,8 @@ rs6000_secondary_reload_inner (rtx reg,
              || !rs6000_legitimate_offset_address_p (PTImode, addr,
                                                      false, true)))
        {
+         /* find_replacement already recurses into both operands of
+            PLUS so we don't need to call it here.  */
          addr_op1 = XEXP (addr, 0);
          addr_op2 = XEXP (addr, 1);
          if (!legitimate_indirect_address_p (addr_op1, false))
@@ -16486,7 +16487,7 @@ rs6000_secondary_reload_inner (rtx reg,
              || !VECTOR_MEM_ALTIVEC_P (mode)))
        {
          and_op2 = XEXP (addr, 1);
-         addr = XEXP (addr, 0);
+         addr = find_replacement (&XEXP (addr, 0));
        }
 
       /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
@@ -16498,14 +16499,13 @@ rs6000_secondary_reload_inner (rtx reg,
              || and_op2 != NULL_RTX
              || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
        {
-         scratch_or_premodify = XEXP (addr, 0);
+         scratch_or_premodify = find_replacement (&XEXP (addr, 0));
          if (!legitimate_indirect_address_p (scratch_or_premodify, false))
            rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
 
-         if (GET_CODE (XEXP (addr, 1)) != PLUS)
+         addr = find_replacement (&XEXP (addr, 1));
+         if (GET_CODE (addr) != PLUS)
            rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p);
-
-         addr = XEXP (addr, 1);
        }
 
       if (legitimate_indirect_address_p (addr, false)  /* reg */
@@ -16765,8 +16765,14 @@ rs6000_preferred_reload_class (rtx x, en
       && easy_vector_constant (x, mode))
     return ALTIVEC_REGS;
 
-  if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
-    return NO_REGS;
+  if ((CONSTANT_P (x) || GET_CODE (x) == PLUS))
+    {
+      if (reg_class_subset_p (GENERAL_REGS, rclass))
+       return GENERAL_REGS;
+      if (reg_class_subset_p (BASE_REGS, rclass))
+       return BASE_REGS;
+      return NO_REGS;
+    }
 
   if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
     return GENERAL_REGS;



Reply via email to