On Thu, Oct 5, 2023 at 5:54 PM Jeff Law <jeffreya...@gmail.com> wrote:
>
>
>
> On 10/3/23 05:45, Manolis Tsamis wrote:
> > This is a new RTL pass that tries to optimize memory offset calculations
>
> > +
> > +/* If INSN is a root memory instruction then compute a potentially new 
> > offset
> > +   for it and test if the resulting instruction is valid.  */
> > +static void
> > +do_check_validity (rtx_insn *insn, fold_mem_info *info)
> > +{
> > +  rtx mem, reg;
> > +  HOST_WIDE_INT cur_offset;
> > +  if (!get_fold_mem_root (insn, &mem, &reg, &cur_offset))
> > +    return;
> > +
> > +  HOST_WIDE_INT new_offset = cur_offset + info->added_offset;
> > +
> > +  /* Test if it is valid to change MEM's address offset to NEW_OFFSET.  */
> > +  int icode = INSN_CODE (insn);
> > +  rtx mem_addr = XEXP (mem, 0);
> > +  machine_mode mode = GET_MODE (mem_addr);
> > +  if (new_offset != 0)
> > +    XEXP (mem, 0) = gen_rtx_PLUS (mode, reg, gen_int_mode (new_offset, 
> > mode));
> > +  else
> > +    XEXP (mem, 0) = reg;
> > +
> > +  bool illegal = insn_invalid_p (insn, false)
> > +              || !memory_address_addr_space_p (mode, XEXP (mem, 0),
> > +                                               MEM_ADDR_SPACE (mem));
> > +
> > +  /* Restore the instruction.  */
> > +  XEXP (mem, 0) = mem_addr;
> > +  INSN_CODE (insn) = icode;
> > +
> > +  if (illegal)
> > +    bitmap_ior_into (&cannot_fold_insns, info->fold_insns);
> > +  else
> > +    bitmap_ior_into (&candidate_fold_insns, info->fold_insns);
> > +}
> > +
> So overnight testing with the latest version of your patch triggered a
> fault on the sh3-linux-gnu target with this code at -O2:
>
> > enum
> > {
> >   _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)),
> > };
> > extern const unsigned short int **__ctype_b_loc (void)
> >      __attribute__ ((__nothrow__ )) __attribute__ ((__const__));
> > void
> > read_alias_file (const char *fname, int fname_len)
> > {
> >       char buf[400];
> >       char *cp;
> >       cp = buf;
> >       while (((*__ctype_b_loc ())[(int) (((unsigned char) cp[0]))] & 
> > (unsigned short int) _ISspace))
> >        ++cp;
> > }
> >
>
>
> The problem is we need to clear the INSN_CODE before we call recog.  In
> this specific case we had (mem (plus (reg) (offset)) after f-m-o does
> its job, the offset went to zero so we changed the structure of the RTL
> to (mem (reg)).  But we had the old INSN_CODE still in place which
> caused us to reference operands that no longer exist.
>
> A simple INSN_CODE (insn) = -1 before calling_insn_invalid_p is the
> right fix.
>
Thanks for catching that. I had some thoughts that the change that
doesn't emit rtx plus when offset is zero could do something like
this, but I missed that change needed.
Will fix this in the next iteration.

Manolis
> jeff

Reply via email to