On Thu, Aug 08, 2024 at 07:57:43AM -0600, Jeff Law wrote:
> 
> 
> On 8/8/24 6:26 AM, Stefan Schulze Frielinghaus wrote:
> > On Thu, Aug 08, 2024 at 06:03:13AM -0600, Jeff Law wrote:
> > > 
> > > 
> > > On 8/8/24 5:15 AM, Stefan Schulze Frielinghaus via Gcc wrote:
> > > 
> > > > 
> > > > However `(reg:DI 61 [ MEM[(const union T *)p_2(D)] ])` referencing the
> > > > same pseudo in a different mode is not substituted in insn 6 which
> > > > leads in the following to an error.  The insn is emitted in
> > > > s390_expand_insv() during
> > > There can only be a single instance of a given pseudo, if you have 
> > > multiple
> > > instances, that's the bug.
> > 
> > Yeah I was fearing this might be the culprit.
> It doesn't come up much, but I've stumbled across it a few times through the
> years.  It comes up less often than sharing nodes that aren't supposed to be
> shared though.
> 
> You know we probably could build a checker for this.  Walk the IL (prior to
> register allocation) and for every pseudo referenced, see if it compares
> equal to regno_reg_rtx[regnum], if not ICE.  Probably could be embedded in
> one of the existing RTL checking phases with minimal cost.

Since you installed this idea into my brain, I gave it a try.  Maybe something
along the lines:

void
verify_references_to_pseudos ()
{
  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      FOR_BB_INSNS (bb, insn)
        {
          subrtx_iterator::array_type array;
          FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
            {
              const_rtx reg = *iter;
              if (!reg || !REG_P (reg))
                continue;
              int regno = REGNO (reg);
              /* Hard registers may be referenced in different modes.  */
              if (HARD_REGISTER_NUM_P (regno))
                continue;
              rtx orig_reg = regno_reg_rtx[regno];
              machine_mode m1 = GET_MODE (orig_reg);
              machine_mode m2 = GET_MODE (reg);
              if (m1 != m2)
                internal_error (
                    "pseudo %i defined for mode %s but referenced in "
                    "mode %s in insn %i", regno, GET_MODE_NAME (m1),
                    GET_MODE_NAME (m2), INSN_UID (insn));
            }
        }
    }
}

I haven't tested it extensively but it triggers at least for the current case.
I would have loved to also print the insn but couldn't figure out how to ICE
and stringify an insn.  I will have a look at this tomorrow.  Did you have any
place in mind where to put/call something like this?

Cheers,
Stefan

Reply via email to