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.

Reply via email to