https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99830
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The particular ICE could be fixed also e.g. with: --- gcc/simplify-rtx.c.jj 2021-01-05 10:59:00.279810449 +0100 +++ gcc/simplify-rtx.c 2021-04-09 16:18:24.275668496 +0200 @@ -470,6 +470,30 @@ simplify_replace_fn_rtx (rtx x, const_rt op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data); if (op0 == SUBREG_REG (x)) return x; + scalar_int_mode outer_mode, inner_mode; + if (known_eq (subreg_lowpart_offset (GET_MODE (x), + GET_MODE (SUBREG_REG (x))), + SUBREG_BYTE (x)) + && is_int_mode (GET_MODE (x), &outer_mode) + && is_int_mode (GET_MODE (SUBREG_REG (x)), &inner_mode)) + { + if (GET_CODE (op0) == ASHIFT + && CONST_INT_P (XEXP (op0, 1)) + && UINTVAL (XEXP (op0, 1)) >= GET_MODE_BITSIZE (outer_mode)) + return const0_rtx; + if (GET_CODE (op0) == IOR + && GET_CODE (XEXP (op0, 1)) == ASHIFT + && CONST_INT_P (XEXP (XEXP (op0, 1), 1)) + && UINTVAL (XEXP (XEXP (op0, 1), 1)) + >= GET_MODE_BITSIZE (outer_mode)) + op0 = XEXP (op0, 0); + if (GET_CODE (op0) == IOR + && GET_CODE (XEXP (op0, 0)) == ASHIFT + && CONST_INT_P (XEXP (XEXP (op0, 0), 1)) + && UINTVAL (XEXP (XEXP (op0, 0), 1)) + >= GET_MODE_BITSIZE (outer_mode)) + op0 = XEXP (op0, 1); + } op0 = simplify_gen_subreg (GET_MODE (x), op0, GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); but that handles just one specific case that appears in the testcase. Perhaps it is a nice optimization for GCC 12, but can't cover anything else.