diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 99eecb567f277..42ad7cc9f806e 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -17,9 +17,7 @@ use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
 use rustc_middle::ty::GenericArgs;
-use rustc_middle::ty::{
-    self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
-};
+use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::Span;
 use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout};
 
@@ -312,43 +310,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         right: &Operand<'tcx>,
         location: Location,
     ) -> Option<()> {
+        if matches!(op, BinOp::Shr | BinOp::Shl) {
+            // Shifts are linted in check_assertion() not here
+            return None;
+        }
+
         let r = self.use_ecx(location, |this| {
             this.ecx.read_immediate(&this.ecx.eval_operand(right, None)?)
         });
         let l = self
             .use_ecx(location, |this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?));
-        // Check for exceeding shifts *even if* we cannot evaluate the LHS.
-        if matches!(op, BinOp::Shr | BinOp::Shl) {
-            let r = r.clone()?;
-            // We need the type of the LHS. We cannot use `place_layout` as that is the type
-            // of the result, which for checked binops is not the same!
-            let left_ty = left.ty(self.local_decls(), self.tcx);
-            let left_size = self.ecx.layout_of(left_ty).ok()?.size;
-            let right_size = r.layout.size;
-            let r_bits = r.to_scalar().to_bits(right_size).ok();
-            if r_bits.is_some_and(|b| b >= left_size.bits() as u128) {
-                debug!("check_binary_op: reporting assert for {:?}", location);
-                let source_info = self.body().source_info(location);
-                let panic = AssertKind::Overflow(
-                    op,
-                    match l {
-                        Some(l) => l.to_const_int(),
-                        // Invent a dummy value, the diagnostic ignores it anyway
-                        None => ConstInt::new(
-                            ScalarInt::try_from_uint(1_u8, left_size).unwrap(),
-                            left_ty.is_signed(),
-                            left_ty.is_ptr_sized_integral(),
-                        ),
-                    },
-                    r.to_const_int(),
-                );
-                self.report_assert_as_lint(
-                    source_info,
-                    AssertLint::ArithmeticOverflow(source_info.span, panic),
-                );
-                return None;
-            }
-        }
 
         if let (Some(l), Some(r)) = (l, r) {
             // The remaining operators are handled through `overflowing_binary_op`.
@@ -485,18 +456,30 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     .and_then(|op| self.ecx.read_immediate(&op).ok())
                     .map_or(DbgVal::Underscore, |op| DbgVal::Val(op.to_const_int()))
             };
-            let msg = match msg {
-                AssertKind::DivisionByZero(op) => AssertKind::DivisionByZero(eval_to_int(op)),
-                AssertKind::RemainderByZero(op) => AssertKind::RemainderByZero(eval_to_int(op)),
+            let (msg, emit_overflow_lint) = match msg {
+                AssertKind::DivisionByZero(op) => {
+                    (AssertKind::DivisionByZero(eval_to_int(op)), false)
+                }
+                AssertKind::RemainderByZero(op) => {
+                    (AssertKind::RemainderByZero(eval_to_int(op)), false)
+                }
                 AssertKind::Overflow(bin_op @ (BinOp::Div | BinOp::Rem), op1, op2) => {
                     // Division overflow is *UB* in the MIR, and different than the
                     // other overflow checks.
-                    AssertKind::Overflow(*bin_op, eval_to_int(op1), eval_to_int(op2))
+                    (AssertKind::Overflow(*bin_op, eval_to_int(op1), eval_to_int(op2)), false)
+                }
+                AssertKind::Overflow(bin_op @ (BinOp::Shl | BinOp::Shr), op1, op2) => {
+                    // A hack that fixes #117949
+                    // Ideally check_binary_op() should check these shift ops,
+                    // but it can't because they are getting removed from the MIR
+                    // during const promotion. So we check the associated asserts
+                    // here instead as they are not removed by promotion.
+                    (AssertKind::Overflow(*bin_op, eval_to_int(op1), eval_to_int(op2)), true)
                 }
                 AssertKind::BoundsCheck { ref len, ref index } => {
                     let len = eval_to_int(len);
                     let index = eval_to_int(index);
-                    AssertKind::BoundsCheck { len, index }
+                    (AssertKind::BoundsCheck { len, index }, false)
                 }
                 // Remaining overflow errors are already covered by checks on the binary operators.
                 AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => return None,
@@ -506,7 +489,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             let source_info = self.body().source_info(location);
             self.report_assert_as_lint(
                 source_info,
-                AssertLint::UnconditionalPanic(source_info.span, msg),
+                if emit_overflow_lint {
+                    AssertLint::ArithmeticOverflow(source_info.span, msg)
+                } else {
+                    AssertLint::UnconditionalPanic(source_info.span, msg)
+                },
             );
         }
 
diff --git a/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr b/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
index 3a84c6c1fb1f9..77cea4b495235 100644
--- a/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
+++ b/tests/ui/lint/lint-exceeding-bitshifts.opt.stderr
@@ -10,143 +10,5 @@ note: the lint level is defined here
 LL | #![warn(arithmetic_overflow)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:22:13
-   |
-LL |     let _ = x << 42;
-   |             ^^^^^^^ attempt to shift left by `42_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:27:15
-   |
-LL |       let n = 1u8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:29:15
-   |
-LL |       let n = 1u16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:31:15
-   |
-LL |       let n = 1u32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:33:15
-   |
-LL |       let n = 1u64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:35:15
-   |
-LL |       let n = 1i8 << 8;
-   |               ^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:37:15
-   |
-LL |       let n = 1i16 << 16;
-   |               ^^^^^^^^^^ attempt to shift left by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:39:15
-   |
-LL |       let n = 1i32 << 32;
-   |               ^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:41:15
-   |
-LL |       let n = 1i64 << 64;
-   |               ^^^^^^^^^^ attempt to shift left by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:44:15
-   |
-LL |       let n = 1u8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:46:15
-   |
-LL |       let n = 1u16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:48:15
-   |
-LL |       let n = 1u32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:50:15
-   |
-LL |       let n = 1u64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:52:15
-   |
-LL |       let n = 1i8 >> 8;
-   |               ^^^^^^^^ attempt to shift right by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:54:15
-   |
-LL |       let n = 1i16 >> 16;
-   |               ^^^^^^^^^^ attempt to shift right by `16_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:56:15
-   |
-LL |       let n = 1i32 >> 32;
-   |               ^^^^^^^^^^ attempt to shift right by `32_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:58:15
-   |
-LL |       let n = 1i64 >> 64;
-   |               ^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:62:15
-   |
-LL |       let n = n << 8;
-   |               ^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:64:15
-   |
-LL |       let n = 1u8 << -8;
-   |               ^^^^^^^^^ attempt to shift left by `-8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:69:15
-   |
-LL |       let n = 1u8 << (4+4);
-   |               ^^^^^^^^^^^^ attempt to shift left by `8_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:71:15
-   |
-LL |       let n = 1i64 >> [64][0];
-   |               ^^^^^^^^^^^^^^^ attempt to shift right by `64_i32`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:77:15
-   |
-LL |       let n = 1_isize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: this arithmetic operation will overflow
-  --> $DIR/lint-exceeding-bitshifts.rs:78:15
-   |
-LL |       let n = 1_usize << BITS;
-   |               ^^^^^^^^^^^^^^^ attempt to shift left by `%BITS%`, which would overflow
-
-warning: 24 warnings emitted
+warning: 1 warning emitted