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

--- Comment #20 from Michael Matz <matz at gcc dot gnu.org> ---
The below patch fixes at least the gcc.c-torture/execute/20030408-1.c
testcase.  Checking others as well, perhaps I manage to bootstrap later.
But if Dominik is faster... :)

diff --git a/gcc/combine.c b/gcc/combine.c
index 0210685..d1b8557 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8108,9 +8108,16 @@ make_compound_operation (rtx x, enum rtx_code in_code)
            && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
            && subreg_lowpart_p (x))
          {
+           int len = mode_width;
            new_rtx = make_compound_operation (XEXP (inner, 0), next_code);
+           /* Don't extract bits outside the underlying mode.  */
+           if (CONST_INT_P (XEXP (inner, 1))
+               && (INTVAL (XEXP (inner, 1)) + len
+                   > GET_MODE_PRECISION (GET_MODE (inner))))
+             len = GET_MODE_PRECISION (GET_MODE (inner))
+                   - INTVAL (XEXP (inner, 1));
            new_rtx = make_extraction (mode, new_rtx, 0, XEXP (inner, 1),
-                                      mode_width, 1, 0, in_code == COMPARE);
+                                      len, 1, 0, in_code == COMPARE);
            break;
          }

Reply via email to