https://gcc.gnu.org/g:d3c11a21eea2fd1ebb90cdb55684c0182407105c

commit r16-5547-gd3c11a21eea2fd1ebb90cdb55684c0182407105c
Author: Jeff Law <[email protected]>
Date:   Mon Nov 24 06:05:27 2025 -0700

    [PR rtl-optimization/122782] Fix out of range shift causing bootstrap 
failure with ubsan
    
    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.

Diff:
---
 gcc/ext-dce.cc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc
index e6189f973bfc..911daef9f4b0 100644
--- a/gcc/ext-dce.cc
+++ b/gcc/ext-dce.cc
@@ -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

Reply via email to