https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109092

--- Comment #5 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Uroš Bizjak from comment #2)
> (In reply to Andrew Pinski from comment #1)
> 
> > The issue is register_operand accepts subreg but then REGNO is checked on 
> > it.
> > That is obviously wrong. It should be "REG_P (operands[1]) && REGNO
> > (operands[1]) == VL_REGNUM" instead ...
> 
> reg_or_subregno is better.

However, please note that reg_or_subregno asserts that we always have SUBREG of
REG:

unsigned int
reg_or_subregno (const_rtx reg)
{
  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);
  gcc_assert (REG_P (reg));
  return REGNO (reg);
}

but before reload register_operand allows SUBREG of MEM:

bool
register_operand (rtx op, machine_mode mode)
{
  if (GET_CODE (op) == SUBREG)
    {
      rtx sub = SUBREG_REG (op);

      /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
         because it is guaranteed to be reloaded into one.
         Just make sure the MEM is valid in itself.
         (Ideally, (SUBREG (MEM)...) should not exist after reload,
         but currently it does result from (SUBREG (REG)...) where the
         reg went on the stack.)  */
      if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
        return false;
    }
  else if (!REG_P (op))
    return false;
  return general_operand (op, mode);
}

OTOH, we do have:

rtlanal.h:const unsigned int MEM_REGNO = ~0U;

which implies that it is possible to get a REGNO of a MEM, so perhaps the
assert in reg_or_subregno is too strict.

Reply via email to