https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109092
JuzheZhong <juzhe.zhong at rivai dot ai> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |juzhe.zhong at rivai dot ai
--- Comment #6 from JuzheZhong <juzhe.zhong at rivai dot ai> ---
(In reply to Uroš Bizjak from comment #5)
> (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.
VL_REGNUM will never be used as (subreg:(reg:VL_REGNUM))
It's always used as (reg:VL_REGNUM).
So I think the !(REG_P (operands[1]) && REGNO (operands[1]) == VL_REGNUM)
is enough. I will send a patch to fix it.