https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65249
--- Comment #19 from Kazumoto Kojima <kkojima at gcc dot gnu.org> ---
Although this is essentially a problem with the old reload, I'm testing
another adhoc patch which is hinted by an Oleg's patch for gbr addressing.
The problematic insn is (set (DImode R0) (DImode reg for <return value>))
originally. The subreg lowering pass splits it to two SImode move's:
(set (SImode R0) (SImode reg for the first word of <return value>))
(set (SImode R1) (SImode reg for the second word of <return value>))
The ICE happens on the latter insn because R0 is live there and the source
is replaced by memory with index addressing afterwards. The patch below
pre-splits the original DImode move in the reversed order when generating.
It also produces a bit better code for the test case even when -mlra
is specified. I intentionally limit this pre-splitting with pseudo reg
sources. If not, I've got some wired ICEs with too complex subreg rtl
in building gcc. I think that almost use of R0 destination is the above
pseudo reg for <retval> source and limiting it to that case would be
not a problem.
* config/sh/sh.md (movdi): Split simple reg move to two movsi
when the destination is R0.
--- ../../ORIG/trunk/gcc/config/sh/sh.md 2015-07-08 10:04:22.000000000
+0900
+++ config/sh/sh.md 2015-07-13 11:09:43.028613182 +0900
@@ -7892,6 +7892,24 @@ label:
""
{
prepare_move_operands (operands, DImode);
+ if (TARGET_SH1)
+ {
+ /* When the dest operand is (R0, R1) register pair, split it to
+ two movsi of which dest is R1 and R0 so as to lower R0-register
+ pressure on the first movsi. Apply only for simple source not
+ to make complex rtl here. */
+ if (REG_P (operands[0])
+ && REGNO (operands[0]) == R0_REG
+ && REG_P (operands[1])
+ && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
+ {
+ emit_insn (gen_movsi (gen_rtx_REG (SImode, R1_REG),
+ gen_rtx_SUBREG (SImode, operands[1], 4)));
+ emit_insn (gen_movsi (gen_rtx_REG (SImode, R0_REG),
+ gen_rtx_SUBREG (SImode, operands[1], 0)));
+ DONE;
+ }
+ }
})
(define_insn "movdf_media"