https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114801
--- Comment #24 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Another short term (14.1 only) possibility would be to force_reg a CONST_INT operand into a register if it didn't have all bits the same (and hope combine or whatever else won't simplify it again), i.e. else if (VALID_MVE_PRED_MODE (mode)) { if (CONST_INT_P (x) && (mode == V8BImode || mode == V4BImode)) { /* In V8BI or V4BI each element has 2 or 4 bits, if those bits aren't all the same, gen_lowpart might ICE. */ unsigned HOST_WIDE_INT xi = UINTVAL (xi); if ((xi & 0x5555) != ((xi >> 1) & 0x5555) || (mode == V4BImode && (xi & 0x3333) != ((xi >> 2) & 0x3333))) x = force_reg (HImode, x); } else if (SUBREG_P (x)) /* gen_lowpart on a SUBREG can ICE. */ x = force_reg (GET_MODE (x), x); x = gen_lowpart (mode, x); } If that fixes just the ICE during expansion but ICEs during fwprop, combine etc., then you might try (temporarily) harder and hide the constant from the optimizers, e.g. instead of using force_reg emit some (set (reg:HI) (unspec:HI (const_int ...) UNSPEC_MVE_PRED)) insn that expands like (set (reg:HI) (const_int ...)) but the optimizers don't know that.