]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR rtl-optimization/122782] Fix out of range shift causing bootstrap failure with...
authorJeff Law <jlaw@ventanamicro.com>
Mon, 24 Nov 2025 13:05:27 +0000 (06:05 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 24 Nov 2025 13:05:27 +0000 (06:05 -0700)
As noted in the PR, we're doing a bogus shift in the new code triggering a
ubsan failure.  This code works up through DImode and needs to reject attempts
at handling wider modes.  Yes, it could be extended to those wider modes and I
expect we will as int128 becomes more common, but it doesn't seem worth the
effort right now.

This patch adds the same kind of test we're using elsewhere to guard against
the bogus shift.  While I haven't been able to reproduce the ubsan bootstrap
failure, I can see the bogus shift under the debugger and I can see they no
longer occur after this patch.

This has been bootstrapped and regression tested on x86 and riscv.  It's also
been through all the crosses.  Pushing to the trunk momentarily.

jeff

PR rtl-optimization/122782
gcc/
* ext-dce.cc (ext_dct_process_uses): Guard against undefined shifts
by properly checking modes on the input object.

gcc/ext-dce.cc

index e6189f973bfc22aa2c70c20d3671536a8f5d4b46..911daef9f4b0872b316cd4fdab6726c5ded90307 100644 (file)
@@ -804,11 +804,14 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj,
 
                 Key on the right shift and use (for now) simplistic tests
                 to find the corresponding left shift.  */
+             scalar_mode outer_mode;
              if ((code == LSHIFTRT || code == ASHIFTRT)
                  && CONST_INT_P (XEXP (src, 1))
                  && (INTVAL (XEXP (src, 1)) == BITS_PER_WORD - 8
                      || INTVAL (XEXP (src, 1)) == BITS_PER_WORD - 16
-                     || INTVAL (XEXP (src, 1)) == BITS_PER_WORD - 32))
+                     || INTVAL (XEXP (src, 1)) == BITS_PER_WORD - 32)
+                 && is_a <scalar_mode> (GET_MODE (src), &outer_mode)
+                 && GET_MODE_BITSIZE (outer_mode) <= HOST_BITS_PER_WIDE_INT)
                {
                  /* So we have a right shift that could correspond to
                     the second in a pair impementing QI, HI or SI -> DI