https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55212
--- Comment #391 from Kazumoto Kojima <kkojima at gcc dot gnu.org> --- (In reply to John Paul Adrian Glaubitz from comment #388) > (In reply to Oleg Endo from comment #387) > > > Currently, I'm using the sh-lra-take3 branch with the patches 59216, 59219 > > > and 59286 which works best so far for all my tests, including WebKit. > > > > Please push your branch version into some git repository and share it. It > > will make it easier to reproduce for others and figure out what is going on. > > I'll look into it. But it's really just Kaz' most recent tree with the three > additional patches. > > I also just tried your latest tree and I'm still getting the subreg3 ICE > there: Sorry for the slow reply. I'm having trouble with my physical condition right now. After syncing my local tree with the latest devel/sh-lra, pr55212-c384.C failed at subreg3 pass again, although almost imported changes are simply cleanups. After bisecting, I found the change causing it. *mov<mode>_store_mem_index is moved after mov<mode>_store_mem_index on devel/sh-lra. Order matters?! I found that the recog function for those insns in insn-recog.cc is generated like as static int recog_21 (rtx x1 ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED, int *pnum_clobbers ATTRIBUTE_UNUSED) { rtx * const operands ATTRIBUTE_UNUSED = &recog_data.operand[0]; rtx x2, x3, x4, x5, x6; int res ATTRIBUTE_UNUSED; x2 = XEXP (x1, 0); ... switch (GET_MODE (x2)) { case E_QImode: if (pnum_clobbers != NULL && arith_reg_operand (operands[1], E_SImode) && arith_reg_operand (operands[2], E_QImode) && #line 5411 "/git/gcc/gcc/config/sh/sh.md" (TARGET_SH1 && ! TARGET_SH2A && sh_lra_p ())) { *pnum_clobbers = 1; return 196; /* movqi_store_mem_index */ } if (!hard_reg_r0 (operands[1], E_SImode) || !arith_reg_operand (operands[2], E_QImode) || ! #line 5426 "/git/gcc/gcc/config/sh/sh.md" (TARGET_SH1 && ! TARGET_SH2A && sh_lra_p ())) return -1; return 198; /* *movqi_store_mem_index */ for devel/sh-lra. The pattern of *movqi_store_mem_index is wrongly recognized at the 1st if clause as movqi_store_mem_index. It seems that this ends up in that ICE. The problem is that mov<mode>_store_mem_index can match even when operands[1] is r0. A quick fix would be to add !hard_reg_r0 (operands[1], SImode) to the condition of mov<mode>_store_mem_index or define&use arith_reg_operand_not_r0 predicate. I confirmed the former fixes the ICE. Similar changes are needed for movsf_ie_{load,store}_mem_index.