re PR target/66591 ([SH] ICE: in get_reload_reg, at lra-constraints.c:633 with -mlra)
authorKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Jun 2015 22:58:58 +0000 (22:58 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Fri, 19 Jun 2015 22:58:58 +0000 (22:58 +0000)
PR target/66591
* config/sh/sh.c (prepare_move_operands): Pre-allocate R0 for subreg
  index term for base and index addressing when LRA is used.

From-SVN: r224701

gcc/ChangeLog
gcc/config/sh/sh.c

index d33ca138c60a54fbd68b2125a2b3dcf0fe92c05f..3147eeb91e1b80c7540a2a13ce57e7f16e9797a7 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-19  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       PR target/66591
+       * config/sh/sh.c (prepare_move_operands): Replace subreg
+       index term with R0 for base and index addressing.
+
 2015-06-19  Jim Wilson  <jim.wilson@linaro.org>
 
        * config/aarch64/aarch64.md (mov<mode>:GPF): Don't call force_reg if
index e5fcd7683ef7e06d56a10427d792ba018d1af884..6f03206ccb907ff232c5594cce7fc5b18d81320f 100644 (file)
@@ -1775,10 +1775,14 @@ prepare_move_operands (rtx operands[], machine_mode mode)
         target/55212.
         We split possible load/store to two move insns via r0 so as to
         shorten R0 live range.  It will make some codes worse but will
-        win on avarage for LRA.  */
+        win on average for LRA.
+        Also when base+index addressing is used and the index term is
+        a subreg, LRA assumes that more hard registers can be available
+        in some situation.  It isn't the case for SH in the problematic
+        case.  We can pre-allocate R0 for that index term to avoid
+        the issue.  See PR target/66591.  */
       else if (sh_lra_p ()
               && TARGET_SH1 && ! TARGET_SH2A
-              && (mode == QImode || mode == HImode)
               && ((REG_P (operands[0]) && MEM_P (operands[1]))
                   || (REG_P (operands[1]) && MEM_P (operands[0]))))
        {
@@ -1786,7 +1790,8 @@ prepare_move_operands (rtx operands[], machine_mode mode)
          rtx reg = operands[load_p ? 0 : 1];
          rtx adr = XEXP (operands[load_p ? 1 : 0], 0);
 
-         if (REGNO (reg) >= FIRST_PSEUDO_REGISTER
+         if ((mode == QImode || mode == HImode)
+             && REGNO (reg) >= FIRST_PSEUDO_REGISTER
              && GET_CODE (adr) == PLUS
              && REG_P (XEXP (adr, 0))
              && (REGNO (XEXP (adr, 0)) >= FIRST_PSEUDO_REGISTER)
@@ -1798,6 +1803,17 @@ prepare_move_operands (rtx operands[], machine_mode mode)
              emit_move_insn (r0_rtx, operands[1]);
              operands[1] = r0_rtx;
            }
+         if (REGNO (reg) >= FIRST_PSEUDO_REGISTER
+             && GET_CODE (adr) == PLUS
+             && REG_P (XEXP (adr, 0))
+             && (REGNO (XEXP (adr, 0)) >= FIRST_PSEUDO_REGISTER)
+             && SUBREG_P (XEXP (adr, 1))
+             && REG_P (SUBREG_REG (XEXP (adr, 1))))
+           {
+             rtx r0_rtx = gen_rtx_REG (GET_MODE (XEXP (adr, 1)), R0_REG);
+             emit_move_insn (r0_rtx, XEXP (adr, 1));
+             XEXP (adr, 1) = r0_rtx;
+           }
        }
     }