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.

Reply via email to