aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKaz Kojima <kkojima@gcc.gnu.org>2015-06-19 22:58:58 +0000
committerKaz Kojima <kkojima@gcc.gnu.org>2015-06-19 22:58:58 +0000
commit3cad5f64a81355feef936483251875ab9a7900a6 (patch)
tree8a08b95aa317387d58a2280b13aa16585fbfd887 /gcc
parentc1a569ef313db23d0563be35eefa05d4d7bde772 (diff)
downloadgcc-3cad5f64a81355feef936483251875ab9a7900a6.zip
gcc-3cad5f64a81355feef936483251875ab9a7900a6.tar.gz
gcc-3cad5f64a81355feef936483251875ab9a7900a6.tar.bz2
re PR target/66591 ([SH] ICE: in get_reload_reg, at lra-constraints.c:633 with -mlra)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh.c22
2 files changed, 25 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d33ca13..3147eeb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index e5fcd768..6f03206 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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;
+ }
}
}