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.