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.