On Wed, Feb 12, 2014 at 06:47:37PM +0100, Ulrich Weigand wrote:
> Note that find_replacement itself already recurses into both sides
> of a PLUS.

Thanks, I missed seeing that.  I'd analysed the bug and knew what
needed doing from past forays into reload, so went looking for ways to
get at the reloads, ie. "replacements" at that stage of reload.  Lo
and behold, there's a function tailor made to do just that!  So I
plugged in find_replacements() wherever it seemed necessary.

> So it might be
> easier and cheaper overall to just do a find_replacement within
> the PRE_MODIFY clause ...

That's a good idea, since PRE_MODIFY doesn't occur that often.
Here is the revised patch with your recommendations.  Bootstrapped
and regression tested powerpc64-linux.

        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.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 207649)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -16170,7 +16156,7 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r
     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)
     {
@@ -16181,19 +16167,18 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r
       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
@@ -16201,6 +16186,8 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r
              || !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))
@@ -16276,7 +16263,7 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r
              || !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
@@ -16288,14 +16275,13 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r
              || 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 */

-- 
Alan Modra
Australia Development Lab, IBM

Reply via email to