From 3cad5f64a81355feef936483251875ab9a7900a6 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Fri, 19 Jun 2015 22:58:58 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/config/sh/sh.c | 22 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d33ca138c60..3147eeb91e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-06-19 Kaz Kojima + + 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 * config/aarch64/aarch64.md (mov:GPF): Don't call force_reg if diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index e5fcd7683ef..6f03206ccb9 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; + } } } -- 2.30.2