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.