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

--- Comment #7 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
It looks like the late-combine ICE might just exposing invalid RTL created by
an earlier pass, namely cse_local.  cse_local propagates the T register from
insn 8 to insn 10 in:

(insn 8 7 10 2 (set (reg:SI 173)
        (reg:SI 147 t)) "/tmp/pr.c":4:24 … {movt}
     (expr_list:REG_DEAD (reg:SI 147 t)
        (nil)))

(insn 10 8 12 2 (set (reg:SI 170 [ _16+-3 ])
        (zero_extend:SI (subreg:QI (reg:SI 173) 3))) …
{*zero_extendqisi2_compact}
     (nil))

giving:

(insn 10 7 12 2 (set (reg:SI 170 [ _16+-3 ])
        (zero_extend:SI (subreg:QI (reg:SI 147 t) 3))) … {movt}
     (expr_list:REG_DEAD (reg:SI 173)
        (nil)))

even though this subreg is invalid according to validate_subreg.

Note how the insn is now "movt".  And indeed, t_reg_operand has:

      case ZERO_EXTEND:
      case SIGN_EXTEND:
        if (REG_P (XEXP (op, 0)) && REGNO (XEXP (op, 0)) == T_REG)
          return true;
        return GET_CODE (XEXP (op, 0)) == SUBREG
               && REG_P (SUBREG_REG (XEXP (op, 0)))
               && REGNO (SUBREG_REG (XEXP (op, 0))) == T_REG;

I don't understand what the port is trying to do.  Why is zero-extension
equivalent to a move?  Why does sh_hard_regno_mode_ok specifically reject
anything other than SImode for the T register, then go to such lengths to allow
QImode references via extension?  If the T register is just a single bit,
wouldn't QImode and HImode be valid too?

Rejecting QImode for the T register is what makes validate_subreg reject the
subreg.

Reply via email to