about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-20 18:13:48 +0200
committerGitHub <noreply@github.com>2024-05-20 18:13:48 +0200
commit9987e900c075b085d5ec43417ef0234d38daceca (patch)
tree1ce88e7fdbde34e79c2c47ddd6ba8de4b9654354
parente0d922842de8a3acab29e57434a1c7a387288d27 (diff)
parentd83c65e9873002f657a32051ba51a7d17883b2f8 (diff)
downloadrust-9987e900c075b085d5ec43417ef0234d38daceca.tar.gz
rust-9987e900c075b085d5ec43417ef0234d38daceca.zip
Rollup merge of #125173 - scottmcm:never-checked, r=davidtwco
Remove `Rvalue::CheckedBinaryOp`

Zulip conversation: <https://rust-lang.zulipchat.com/#narrow/stream/189540-t-compiler.2Fwg-mir-opt/topic/intrinsics.20vs.20binop.2Funop/near/438729996>
cc `@RalfJung`

While it's a draft,
r? ghost
-rw-r--r--compiler/rustc_borrowck/src/lib.rs3
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs3
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/src/codegen_i128.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs36
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs14
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/resolver.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs29
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs9
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs3
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs1
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs19
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs34
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs27
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs42
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs8
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs5
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs29
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--tests/mir-opt/building/custom/operators.f.built.after.mir2
-rw-r--r--tests/mir-opt/const_prop/checked_add.main.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/checked_add.main.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/indirect.main.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/indirect.main.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/return_place.add.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/return_place.add.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff4
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff4
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff2
-rw-r--r--tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff12
-rw-r--r--tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff12
-rw-r--r--tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir2
-rw-r--r--tests/mir-opt/lower_intrinsics.rs6
-rw-r--r--tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff6
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff2
-rw-r--r--tests/run-make/const_fn_mir/dump.mir4
61 files changed, 212 insertions, 215 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index abe57e26af4..1d5801467da 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1312,8 +1312,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
             }
 
-            Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
-            | Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
+            Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
                 self.consume_operand(location, (operand1, span), flow_state);
                 self.consume_operand(location, (operand2, span), flow_state);
             }
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index a1e59977ede..6979910a02d 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -302,8 +302,7 @@ impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
                 );
             }
 
-            Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
-            | Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
+            Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
                 self.consume_operand(location, operand1);
                 self.consume_operand(location, operand2);
             }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6cf9ac45aa3..e48130ebddf 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2417,8 +2417,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.check_operand(op, location);
             }
 
-            Rvalue::BinaryOp(_, box (left, right))
-            | Rvalue::CheckedBinaryOp(_, box (left, right)) => {
+            Rvalue::BinaryOp(_, box (left, right)) => {
                 self.check_operand(left, location);
                 self.check_operand(right, location);
             }
@@ -2445,7 +2444,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::BinaryOp(..)
-            | Rvalue::CheckedBinaryOp(..)
             | Rvalue::NullaryOp(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::UnaryOp(..)
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 5846689643f..8d778f736d6 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -609,14 +609,11 @@ fn codegen_stmt<'tcx>(
                     let lhs = codegen_operand(fx, &lhs_rhs.0);
                     let rhs = codegen_operand(fx, &lhs_rhs.1);
 
-                    let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs);
-                    lval.write_cvalue(fx, res);
-                }
-                Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => {
-                    let lhs = codegen_operand(fx, &lhs_rhs.0);
-                    let rhs = codegen_operand(fx, &lhs_rhs.1);
-
-                    let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
+                    let res = if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
+                        crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs)
+                    } else {
+                        crate::num::codegen_binop(fx, bin_op, lhs, rhs)
+                    };
                     lval.write_cvalue(fx, res);
                 }
                 Rvalue::UnaryOp(un_op, ref operand) => {
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
index 4a5ef352151..e16b77648d1 100644
--- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
+++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs
@@ -70,6 +70,7 @@ pub(crate) fn maybe_codegen<'tcx>(
         }
         BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne | BinOp::Cmp => None,
         BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => None,
+        BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(),
     }
 }
 
@@ -132,6 +133,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
             Some(out_place.to_cvalue(fx))
         }
         BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(),
+        BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(),
         BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
         BinOp::Div | BinOp::Rem => unreachable!(),
         BinOp::Cmp => unreachable!(),
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index 4d96a26ea4f..fb18f45d7dc 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -179,6 +179,9 @@ pub(crate) fn codegen_int_binop<'tcx>(
             }
         }
         BinOp::Offset => unreachable!("Offset is not an integer operation"),
+        BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => {
+            unreachable!("Overflow binops handled by `codegen_checked_int_binop`")
+        }
         // Compare binops handles by `codegen_binop`.
         BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Cmp => {
             unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index ff176a79675..00b28cbd0c6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -576,6 +576,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
+            mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs))
+                if let Some(op) = op_with_overflow.overflowing_to_wrapping() =>
+            {
+                let lhs = self.codegen_operand(bx, lhs);
+                let rhs = self.codegen_operand(bx, rhs);
+                let result = self.codegen_scalar_checked_binop(
+                    bx,
+                    op,
+                    lhs.immediate(),
+                    rhs.immediate(),
+                    lhs.layout.ty,
+                );
+                let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
+                let operand_ty = Ty::new_tup(bx.tcx(), &[val_ty, bx.tcx().types.bool]);
+                OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
+            }
             mir::Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => {
                 let lhs = self.codegen_operand(bx, lhs);
                 let rhs = self.codegen_operand(bx, rhs);
@@ -604,20 +620,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     layout: bx.cx().layout_of(op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)),
                 }
             }
-            mir::Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => {
-                let lhs = self.codegen_operand(bx, lhs);
-                let rhs = self.codegen_operand(bx, rhs);
-                let result = self.codegen_scalar_checked_binop(
-                    bx,
-                    op,
-                    lhs.immediate(),
-                    rhs.immediate(),
-                    lhs.layout.ty,
-                );
-                let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
-                let operand_ty = Ty::new_tup(bx.tcx(), &[val_ty, bx.tcx().types.bool]);
-                OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }
-            }
 
             mir::Rvalue::UnaryOp(op, ref operand) => {
                 let operand = self.codegen_operand(bx, operand);
@@ -928,6 +930,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge)
                 }
             }
+            mir::BinOp::AddWithOverflow
+            | mir::BinOp::SubWithOverflow
+            | mir::BinOp::MulWithOverflow => {
+                bug!("{op:?} needs to return a pair, so call codegen_scalar_checked_binop instead")
+            }
         }
     }
 
@@ -1040,7 +1047,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Cast(..) | // (*)
             mir::Rvalue::ShallowInitBox(..) | // (*)
             mir::Rvalue::BinaryOp(..) |
-            mir::Rvalue::CheckedBinaryOp(..) |
             mir::Rvalue::UnaryOp(..) |
             mir::Rvalue::Discriminant(..) |
             mir::Rvalue::NullaryOp(..) |
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index ee415c380de..cb72d55a9ba 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -167,15 +167,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let left = self.read_immediate(&self.eval_operand(left, layout)?)?;
                 let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout);
                 let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
-                self.binop_ignore_overflow(bin_op, &left, &right, &dest)?;
-            }
-
-            CheckedBinaryOp(bin_op, box (ref left, ref right)) => {
-                // Due to the extra boolean in the result, we can never reuse the `dest.layout`.
-                let left = self.read_immediate(&self.eval_operand(left, None)?)?;
-                let layout = util::binop_right_homogeneous(bin_op).then_some(left.layout);
-                let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
-                self.binop_with_overflow(bin_op, &left, &right, &dest)?;
+                if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
+                    self.binop_with_overflow(bin_op, &left, &right, &dest)?;
+                } else {
+                    self.binop_ignore_overflow(bin_op, &left, &right, &dest)?;
+                }
             }
 
             UnaryOp(un_op, ref operand) => {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 5edf5bb39dd..c8c54143f61 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -580,7 +580,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 }
             }
 
-            Rvalue::BinaryOp(op, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => {
+            Rvalue::BinaryOp(op, box (lhs, rhs)) => {
                 let lhs_ty = lhs.ty(self.body, self.tcx);
                 let rhs_ty = rhs.ty(self.body, self.tcx);
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index eae0e2f27db..7e8a208659b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -261,7 +261,7 @@ where
         | Rvalue::Cast(_, operand, _)
         | Rvalue::ShallowInitBox(operand, _) => in_operand::<Q, _>(cx, in_local, operand),
 
-        Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
+        Rvalue::BinaryOp(_, box (lhs, rhs)) => {
             in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
         }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
index 5ae3ffaaec2..011341472b4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
@@ -200,7 +200,6 @@ where
             | mir::Rvalue::Repeat(..)
             | mir::Rvalue::Len(..)
             | mir::Rvalue::BinaryOp(..)
-            | mir::Rvalue::CheckedBinaryOp(..)
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
             | mir::Rvalue::Discriminant(..)
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index fdc7f6a69cb..3a2b2c5f300 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -1037,8 +1037,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             )
                         }
                     }
-                    AddUnchecked | SubUnchecked | MulUnchecked | Shl | ShlUnchecked | Shr
-                    | ShrUnchecked => {
+                    AddUnchecked | AddWithOverflow | SubUnchecked | SubWithOverflow
+                    | MulUnchecked | MulWithOverflow | Shl | ShlUnchecked | Shr | ShrUnchecked => {
                         for x in [a, b] {
                             check_kinds!(
                                 x,
@@ -1067,31 +1067,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                 }
             }
-            Rvalue::CheckedBinaryOp(op, vals) => {
-                use BinOp::*;
-                let a = vals.0.ty(&self.body.local_decls, self.tcx);
-                let b = vals.1.ty(&self.body.local_decls, self.tcx);
-                match op {
-                    Add | Sub | Mul => {
-                        for x in [a, b] {
-                            check_kinds!(
-                                x,
-                                "Cannot perform checked arithmetic on type {:?}",
-                                ty::Uint(..) | ty::Int(..)
-                            )
-                        }
-                        if a != b {
-                            self.fail(
-                                location,
-                                format!(
-                                    "Cannot perform checked arithmetic on unequal types {a:?} and {b:?}"
-                                ),
-                            );
-                        }
-                    }
-                    _ => self.fail(location, format!("There is no checked version of {op:?}")),
-                }
-            }
             Rvalue::UnaryOp(op, operand) => {
                 let a = operand.ty(&self.body.local_decls, self.tcx);
                 match op {
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 0c3b59a0e78..66a1addfb52 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -19,7 +19,9 @@ pub fn binop_left_homogeneous(op: mir::BinOp) -> bool {
     match op {
         Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor
         | BitAnd | BitOr | Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => true,
-        Eq | Ne | Lt | Le | Gt | Ge | Cmp => false,
+        AddWithOverflow | SubWithOverflow | MulWithOverflow | Eq | Ne | Lt | Le | Gt | Ge | Cmp => {
+            false
+        }
     }
 }
 
@@ -29,8 +31,9 @@ pub fn binop_left_homogeneous(op: mir::BinOp) -> bool {
 pub fn binop_right_homogeneous(op: mir::BinOp) -> bool {
     use rustc_middle::mir::BinOp::*;
     match op {
-        Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor
-        | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge | Cmp => true,
+        Add | AddUnchecked | AddWithOverflow | Sub | SubUnchecked | SubWithOverflow | Mul
+        | MulUnchecked | MulWithOverflow | Div | Rem | BitXor | BitAnd | BitOr | Eq | Ne | Lt
+        | Le | Gt | Ge | Cmp => true,
         Offset | Shl | ShlUnchecked | Shr | ShrUnchecked => false,
     }
 }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 5aaa1c30cad..7e8598b49df 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -971,9 +971,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                 with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})"))
             }
             BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{op:?}({a:?}, {b:?})"),
-            CheckedBinaryOp(ref op, box (ref a, ref b)) => {
-                write!(fmt, "Checked{op:?}({a:?}, {b:?})")
-            }
             UnaryOp(ref op, ref a) => write!(fmt, "{op:?}({a:?})"),
             Discriminant(ref place) => write!(fmt, "discriminant({place:?})"),
             NullaryOp(ref op, ref t) => {
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 375f1f15a39..4d9a931d697 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -438,7 +438,6 @@ impl<'tcx> Rvalue<'tcx> {
                 _,
             )
             | Rvalue::BinaryOp(_, _)
-            | Rvalue::CheckedBinaryOp(_, _)
             | Rvalue::NullaryOp(_, _)
             | Rvalue::UnaryOp(_, _)
             | Rvalue::Discriminant(_)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index e124b478f41..2b28496faec 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1295,18 +1295,12 @@ pub enum Rvalue<'tcx> {
     ///   truncated as needed.
     /// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
     ///   types and return a value of that type.
+    /// * The `FooWithOverflow` are like the `Foo`, but returning `(T, bool)` instead of just `T`,
+    ///   where the `bool` is true if the result is not equal to the infinite-precision result.
     /// * The remaining operations accept signed integers, unsigned integers, or floats with
     ///   matching types and return a value of that type.
     BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
 
-    /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
-    ///
-    /// For addition, subtraction, and multiplication on integers the error condition is set when
-    /// the infinite precision result would not be equal to the actual result.
-    ///
-    /// Other combinations of types and operators are unsupported.
-    CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
-
     /// Computes a value as described by the operation.
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
 
@@ -1449,14 +1443,23 @@ pub enum BinOp {
     Add,
     /// Like `Add`, but with UB on overflow.  (Integers only.)
     AddUnchecked,
+    /// Like `Add`, but returns `(T, bool)` of both the wrapped result
+    /// and a bool indicating whether it overflowed.
+    AddWithOverflow,
     /// The `-` operator (subtraction)
     Sub,
     /// Like `Sub`, but with UB on overflow.  (Integers only.)
     SubUnchecked,
+    /// Like `Sub`, but returns `(T, bool)` of both the wrapped result
+    /// and a bool indicating whether it overflowed.
+    SubWithOverflow,
     /// The `*` operator (multiplication)
     Mul,
     /// Like `Mul`, but with UB on overflow.  (Integers only.)
     MulUnchecked,
+    /// Like `Mul`, but returns `(T, bool)` of both the wrapped result
+    /// and a bool indicating whether it overflowed.
+    MulWithOverflow,
     /// The `/` operator (division)
     ///
     /// For integer types, division by zero is UB, as is `MIN / -1` for signed.
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 4994679ad5d..e1ae2e08666 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -179,12 +179,6 @@ impl<'tcx> Rvalue<'tcx> {
                 let rhs_ty = rhs.ty(local_decls, tcx);
                 op.ty(tcx, lhs_ty, rhs_ty)
             }
-            Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) => {
-                let lhs_ty = lhs.ty(local_decls, tcx);
-                let rhs_ty = rhs.ty(local_decls, tcx);
-                let ty = op.ty(tcx, lhs_ty, rhs_ty);
-                Ty::new_tup(tcx, &[ty, tcx.types.bool])
-            }
             Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
             Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
@@ -263,6 +257,11 @@ impl<'tcx> BinOp {
                 assert_eq!(lhs_ty, rhs_ty);
                 lhs_ty
             }
+            &BinOp::AddWithOverflow | &BinOp::SubWithOverflow | &BinOp::MulWithOverflow => {
+                // these should be integers of the same size.
+                assert_eq!(lhs_ty, rhs_ty);
+                Ty::new_tup(tcx, &[lhs_ty, tcx.types.bool])
+            }
             &BinOp::Shl
             | &BinOp::ShlUnchecked
             | &BinOp::Shr
@@ -315,6 +314,9 @@ impl BinOp {
             BinOp::Le => hir::BinOpKind::Le,
             BinOp::Ge => hir::BinOpKind::Ge,
             BinOp::Cmp
+            | BinOp::AddWithOverflow
+            | BinOp::SubWithOverflow
+            | BinOp::MulWithOverflow
             | BinOp::AddUnchecked
             | BinOp::SubUnchecked
             | BinOp::MulUnchecked
@@ -325,4 +327,24 @@ impl BinOp {
             }
         }
     }
+
+    /// If this is a `FooWithOverflow`, return `Some(Foo)`.
+    pub fn overflowing_to_wrapping(self) -> Option<BinOp> {
+        Some(match self {
+            BinOp::AddWithOverflow => BinOp::Add,
+            BinOp::SubWithOverflow => BinOp::Sub,
+            BinOp::MulWithOverflow => BinOp::Mul,
+            _ => return None,
+        })
+    }
+
+    /// If this is a `Foo`, return `Some(FooWithOverflow)`.
+    pub fn wrapping_to_overflowing(self) -> Option<BinOp> {
+        Some(match self {
+            BinOp::Add => BinOp::AddWithOverflow,
+            BinOp::Sub => BinOp::SubWithOverflow,
+            BinOp::Mul => BinOp::MulWithOverflow,
+            _ => return None,
+        })
+    }
 }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index d97abc3f190..8901fd42d93 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -696,8 +696,7 @@ macro_rules! make_mir_visitor {
                         self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
                     }
 
-                    Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
-                    | Rvalue::CheckedBinaryOp(_bin_op, box(lhs, rhs)) => {
+                    Rvalue::BinaryOp(_bin_op, box(lhs, rhs)) => {
                         self.visit_operand(lhs, location);
                         self.visit_operand(rhs, location);
                     }
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index c669d3fd623..6f8cfc3af44 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -195,9 +195,15 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
             },
             @call(mir_checked, args) => {
                 parse_by_kind!(self, args[0], _, "binary op",
-                    ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
-                        *op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
-                    )),
+                    ExprKind::Binary { op, lhs, rhs } => {
+                        if let Some(op_with_overflow) = op.wrapping_to_overflowing() {
+                            Ok(Rvalue::BinaryOp(
+                                op_with_overflow, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
+                            ))
+                        } else {
+                            Err(self.expr_error(expr_id, "No WithOverflow form of this operator"))
+                        }
+                    },
                 )
             },
             @call(mir_offset, args) => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 0b2248d049a..60a2827a3e2 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -568,11 +568,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let result_tup = Ty::new_tup(self.tcx, &[ty, bool_ty]);
                 let result_value = self.temp(result_tup, span);
 
+                let op_with_overflow = op.wrapping_to_overflowing().unwrap();
+
                 self.cfg.push_assign(
                     block,
                     source_info,
                     result_value,
-                    Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
+                    Rvalue::BinaryOp(op_with_overflow, Box::new((lhs.to_copy(), rhs.to_copy()))),
                 );
                 let val_fld = FieldIdx::ZERO;
                 let of_fld = FieldIdx::new(1);
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index bdc70de58e8..706bb796349 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -109,7 +109,6 @@ where
             | Rvalue::Repeat(..)
             | Rvalue::Len(..)
             | Rvalue::BinaryOp(..)
-            | Rvalue::CheckedBinaryOp(..)
             | Rvalue::NullaryOp(..)
             | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..)
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 6ae7df79d30..521ecb1b9a5 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -420,8 +420,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
             | Rvalue::Cast(_, ref operand, _)
             | Rvalue::ShallowInitBox(ref operand, _)
             | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
-            Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs))
-            | Rvalue::CheckedBinaryOp(ref _binop, box (ref lhs, ref rhs)) => {
+            Rvalue::BinaryOp(ref _binop, box (ref lhs, ref rhs)) => {
                 self.gather_operand(lhs);
                 self.gather_operand(rhs);
             }
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 807bef07411..1e5322dd99b 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -184,7 +184,6 @@ pub trait ValueAnalysis<'tcx> {
             | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::BinaryOp(..)
-            | Rvalue::CheckedBinaryOp(..)
             | Rvalue::NullaryOp(..)
             | Rvalue::UnaryOp(..)
             | Rvalue::Discriminant(..)
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index a42d64f86be..3d24a56cdd7 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -165,7 +165,9 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                     }
                 }
             }
-            Rvalue::CheckedBinaryOp(op, box (left, right)) => {
+            Rvalue::BinaryOp(overflowing_op, box (left, right))
+                if let Some(op) = overflowing_op.overflowing_to_wrapping() =>
+            {
                 // Flood everything now, so we can use `insert_value_idx` directly later.
                 state.flood(target.as_ref(), self.map());
 
@@ -175,7 +177,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                 let overflow_target = self.map().apply(target, TrackElem::Field(1_u32.into()));
 
                 if value_target.is_some() || overflow_target.is_some() {
-                    let (val, overflow) = self.binary_op(state, *op, left, right);
+                    let (val, overflow) = self.binary_op(state, op, left, right);
 
                     if let Some(value_target) = value_target {
                         // We have flooded `target` earlier.
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 1bc383fccc7..b1016c0867c 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -564,7 +564,7 @@ impl WriteInfo {
                     | Rvalue::ShallowInitBox(op, _) => {
                         self.add_operand(op);
                     }
-                    Rvalue::BinaryOp(_, ops) | Rvalue::CheckedBinaryOp(_, ops) => {
+                    Rvalue::BinaryOp(_, ops) => {
                         for op in [&ops.0, &ops.1] {
                             self.add_operand(op);
                         }
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 123166a764d..1f3e407180b 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -831,23 +831,18 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 // on both operands for side effect.
                 let lhs = lhs?;
                 let rhs = rhs?;
-                if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
-                    return Some(value);
-                }
-                Value::BinaryOp(op, lhs, rhs)
-            }
-            Rvalue::CheckedBinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
-                let ty = lhs.ty(self.local_decls, self.tcx);
-                let lhs = self.simplify_operand(lhs, location);
-                let rhs = self.simplify_operand(rhs, location);
-                // Only short-circuit options after we called `simplify_operand`
-                // on both operands for side effect.
-                let lhs = lhs?;
-                let rhs = rhs?;
-                if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
-                    return Some(value);
+
+                if let Some(op) = op.overflowing_to_wrapping() {
+                    if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
+                        return Some(value);
+                    }
+                    Value::CheckedBinaryOp(op, lhs, rhs)
+                } else {
+                    if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
+                        return Some(value);
+                    }
+                    Value::BinaryOp(op, lhs, rhs)
                 }
-                Value::CheckedBinaryOp(op, lhs, rhs)
             }
             Rvalue::UnaryOp(op, ref mut arg) => {
                 let arg = self.simplify_operand(arg, location)?;
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index d0a5a6cada8..38fc37a3a31 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -399,16 +399,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             }
             Rvalue::BinaryOp(op, box (left, right)) => {
                 trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
-                self.check_binary_op(*op, left, right, location)?;
-            }
-            Rvalue::CheckedBinaryOp(op, box (left, right)) => {
-                trace!(
-                    "checking CheckedBinaryOp(op = {:?}, left = {:?}, right = {:?})",
-                    op,
-                    left,
-                    right
-                );
-                self.check_binary_op(*op, left, right, location)?;
+                let op = op.overflowing_to_wrapping().unwrap_or(*op);
+                self.check_binary_op(op, left, right, location)?;
             }
 
             // Do not try creating references (#67862)
@@ -555,24 +547,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 let right = self.eval_operand(right)?;
                 let right = self.use_ecx(|this| this.ecx.read_immediate(&right))?;
 
-                let val =
-                    self.use_ecx(|this| this.ecx.wrapping_binary_op(bin_op, &left, &right))?;
-                val.into()
-            }
-
-            CheckedBinaryOp(bin_op, box (ref left, ref right)) => {
-                let left = self.eval_operand(left)?;
-                let left = self.use_ecx(|this| this.ecx.read_immediate(&left))?;
-
-                let right = self.eval_operand(right)?;
-                let right = self.use_ecx(|this| this.ecx.read_immediate(&right))?;
-
-                let (val, overflowed) =
-                    self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
-                let overflowed = ImmTy::from_bool(overflowed, self.tcx);
-                Value::Aggregate {
-                    variant: VariantIdx::ZERO,
-                    fields: [Value::from(val), overflowed.into()].into_iter().collect(),
+                if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
+                    let (val, overflowed) =
+                        self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
+                    let overflowed = ImmTy::from_bool(overflowed, self.tcx);
+                    Value::Aggregate {
+                        variant: VariantIdx::ZERO,
+                        fields: [Value::from(val), overflowed.into()].into_iter().collect(),
+                    }
+                } else {
+                    let val =
+                        self.use_ecx(|this| this.ecx.wrapping_binary_op(bin_op, &left, &right))?;
+                    val.into()
                 }
             }
 
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 43d8c45bb2d..221301b2ceb 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -140,16 +140,16 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                                 rhs = args.next().unwrap();
                             }
                             let bin_op = match intrinsic.name {
-                                sym::add_with_overflow => BinOp::Add,
-                                sym::sub_with_overflow => BinOp::Sub,
-                                sym::mul_with_overflow => BinOp::Mul,
+                                sym::add_with_overflow => BinOp::AddWithOverflow,
+                                sym::sub_with_overflow => BinOp::SubWithOverflow,
+                                sym::mul_with_overflow => BinOp::MulWithOverflow,
                                 _ => bug!("unexpected intrinsic"),
                             };
                             block.statements.push(Statement {
                                 source_info: terminator.source_info,
                                 kind: StatementKind::Assign(Box::new((
                                     *destination,
-                                    Rvalue::CheckedBinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
+                                    Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
                                 ))),
                             });
                             terminator.kind = TerminatorKind::Goto { target };
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index b3116c002d3..34aa31baab7 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -470,7 +470,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 self.validate_operand(operand)?;
             }
 
-            Rvalue::BinaryOp(op, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(op, box (lhs, rhs)) => {
+            Rvalue::BinaryOp(op, box (lhs, rhs)) => {
                 let op = *op;
                 let lhs_ty = lhs.ty(self.body, self.tcx);
 
@@ -539,10 +539,13 @@ impl<'tcx> Validator<'_, 'tcx> {
                     | BinOp::Offset
                     | BinOp::Add
                     | BinOp::AddUnchecked
+                    | BinOp::AddWithOverflow
                     | BinOp::Sub
                     | BinOp::SubUnchecked
+                    | BinOp::SubWithOverflow
                     | BinOp::Mul
                     | BinOp::MulUnchecked
+                    | BinOp::MulWithOverflow
                     | BinOp::BitXor
                     | BinOp::BitAnd
                     | BinOp::BitOr
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 452ab04c44c..d89caabab3e 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -1,5 +1,6 @@
 //! Conversion of internal Rust compiler `mir` items to stable ones.
 
+use rustc_middle::bug;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::alloc_range;
 use rustc_middle::mir::mono::MonoItem;
@@ -183,16 +184,21 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 op.stable(tables),
                 ty.stable(tables),
             ),
-            BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
-                bin_op.stable(tables),
-                ops.0.stable(tables),
-                ops.1.stable(tables),
-            ),
-            CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
-                bin_op.stable(tables),
-                ops.0.stable(tables),
-                ops.1.stable(tables),
-            ),
+            BinaryOp(bin_op, ops) => {
+                if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
+                    stable_mir::mir::Rvalue::CheckedBinaryOp(
+                        bin_op.stable(tables),
+                        ops.0.stable(tables),
+                        ops.1.stable(tables),
+                    )
+                } else {
+                    stable_mir::mir::Rvalue::BinaryOp(
+                        bin_op.stable(tables),
+                        ops.0.stable(tables),
+                        ops.1.stable(tables),
+                    )
+                }
+            }
             NullaryOp(null_op, ty) => {
                 stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables))
             }
@@ -485,10 +491,13 @@ impl<'tcx> Stable<'tcx> for mir::BinOp {
         match self {
             BinOp::Add => stable_mir::mir::BinOp::Add,
             BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked,
+            BinOp::AddWithOverflow => bug!("AddWithOverflow should have been translated already"),
             BinOp::Sub => stable_mir::mir::BinOp::Sub,
             BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked,
+            BinOp::SubWithOverflow => bug!("AddWithOverflow should have been translated already"),
             BinOp::Mul => stable_mir::mir::BinOp::Mul,
             BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked,
+            BinOp::MulWithOverflow => bug!("AddWithOverflow should have been translated already"),
             BinOp::Div => stable_mir::mir::BinOp::Div,
             BinOp::Rem => stable_mir::mir::BinOp::Rem,
             BinOp::BitXor => stable_mir::mir::BinOp::BitXor,
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index fec02f515ca..b40a0d0a58e 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -81,9 +81,9 @@ fn destructure_const<'tcx>(
 fn check_binop(op: mir::BinOp) -> bool {
     use mir::BinOp::*;
     match op {
-        Add | AddUnchecked | Sub | SubUnchecked | Mul | MulUnchecked | Div | Rem | BitXor
-        | BitAnd | BitOr | Shl | ShlUnchecked | Shr | ShrUnchecked | Eq | Lt | Le | Ne | Ge
-        | Gt | Cmp => true,
+        Add | AddUnchecked | AddWithOverflow | Sub | SubUnchecked | SubWithOverflow | Mul
+        | MulUnchecked | MulWithOverflow | Div | Rem | BitXor | BitAnd | BitOr | Shl
+        | ShlUnchecked | Shr | ShrUnchecked | Eq | Lt | Le | Ne | Ge | Gt | Cmp => true,
         Offset => false,
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index 06229ac938f..7b4fd8a210e 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -149,7 +149,7 @@ impl TypeVisitor<TyCtxt<'_>> for ContainsRegion {
 }
 
 fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
-    use rustc_middle::mir::Rvalue::{Aggregate, BinaryOp, Cast, CheckedBinaryOp, Repeat, UnaryOp, Use};
+    use rustc_middle::mir::Rvalue::{Aggregate, BinaryOp, Cast, Repeat, UnaryOp, Use};
 
     let mut visit_op = |op: &mir::Operand<'_>| match op {
         mir::Operand::Copy(p) | mir::Operand::Move(p) => visit(p.local),
@@ -159,7 +159,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
     match rvalue {
         Use(op) | Repeat(op, _) | Cast(_, op, _) | UnaryOp(_, op) => visit_op(op),
         Aggregate(_, ops) => ops.iter().for_each(visit_op),
-        BinaryOp(_, box (lhs, rhs)) | CheckedBinaryOp(_, box (lhs, rhs)) => {
+        BinaryOp(_, box (lhs, rhs)) => {
             visit_op(lhs);
             visit_op(rhs);
         },
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 95851a2eed8..ff9f06531ea 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -161,7 +161,7 @@ fn check_rvalue<'tcx>(
             "transmute can attempt to turn pointers into integers, so is unstable in const fn".into(),
         )),
         // binops are fine on integers
-        Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => {
+        Rvalue::BinaryOp(_, box (lhs, rhs)) => {
             check_operand(tcx, lhs, span, body)?;
             check_operand(tcx, rhs, span, body)?;
             let ty = lhs.ty(body, tcx);
diff --git a/tests/mir-opt/building/custom/operators.f.built.after.mir b/tests/mir-opt/building/custom/operators.f.built.after.mir
index 33eb6b720e8..cac82f7b3ea 100644
--- a/tests/mir-opt/building/custom/operators.f.built.after.mir
+++ b/tests/mir-opt/building/custom/operators.f.built.after.mir
@@ -21,7 +21,7 @@ fn f(_1: i32, _2: bool) -> i32 {
         _2 = Le(_1, _1);
         _2 = Ge(_1, _1);
         _2 = Gt(_1, _1);
-        _3 = CheckedAdd(_1, _1);
+        _3 = AddWithOverflow(_1, _1);
         _2 = (_3.1: bool);
         _1 = (_3.0: i32);
         _0 = _1;
diff --git a/tests/mir-opt/const_prop/checked_add.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/checked_add.main.GVN.panic-abort.diff
index d5117b2f638..0e93c167ebc 100644
--- a/tests/mir-opt/const_prop/checked_add.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/checked_add.main.GVN.panic-abort.diff
@@ -11,7 +11,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 1_u32, const 1_u32);
+-         _2 = AddWithOverflow(const 1_u32, const 1_u32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind unreachable];
 +         _2 = const (2_u32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/const_prop/checked_add.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/checked_add.main.GVN.panic-unwind.diff
index 2118d37672c..589eed5776c 100644
--- a/tests/mir-opt/const_prop/checked_add.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/checked_add.main.GVN.panic-unwind.diff
@@ -11,7 +11,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 1_u32, const 1_u32);
+-         _2 = AddWithOverflow(const 1_u32, const 1_u32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
 +         _2 = const (2_u32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_u32, const 1_u32) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/const_prop/indirect.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/indirect.main.GVN.panic-abort.diff
index 8301a4c1aa8..f24b9755eae 100644
--- a/tests/mir-opt/const_prop/indirect.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/indirect.main.GVN.panic-abort.diff
@@ -14,7 +14,7 @@
           StorageLive(_1);
           StorageLive(_2);
 -         _2 = const 2_u32 as u8 (IntToInt);
--         _3 = CheckedAdd(_2, const 1_u8);
+-         _3 = AddWithOverflow(_2, const 1_u8);
 -         assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind unreachable];
 +         _2 = const 2_u8;
 +         _3 = const (3_u8, false);
diff --git a/tests/mir-opt/const_prop/indirect.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/indirect.main.GVN.panic-unwind.diff
index 8dcbfd2c2c1..44ff313b532 100644
--- a/tests/mir-opt/const_prop/indirect.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/indirect.main.GVN.panic-unwind.diff
@@ -14,7 +14,7 @@
           StorageLive(_1);
           StorageLive(_2);
 -         _2 = const 2_u32 as u8 (IntToInt);
--         _3 = CheckedAdd(_2, const 1_u8);
+-         _3 = AddWithOverflow(_2, const 1_u8);
 -         assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", move _2, const 1_u8) -> [success: bb1, unwind continue];
 +         _2 = const 2_u8;
 +         _3 = const (3_u8, false);
diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-abort.diff
index 8c5a0df94f4..de9cb7a47a2 100644
--- a/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-abort.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const 1_u8;
           StorageLive(_4);
--         _4 = CheckedAdd(_2, _3);
+-         _4 = AddWithOverflow(_2, _3);
 -         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable];
 +         _4 = const (0_u8, true);
 +         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-unwind.diff
index 7887a8a9072..1f19a13c1e8 100644
--- a/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/inherit_overflow.main.GVN.panic-unwind.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const 1_u8;
           StorageLive(_4);
--         _4 = CheckedAdd(_2, _3);
+-         _4 = AddWithOverflow(_2, _3);
 -         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
 +         _4 = const (0_u8, true);
 +         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/const_prop/return_place.add.GVN.panic-abort.diff b/tests/mir-opt/const_prop/return_place.add.GVN.panic-abort.diff
index 51f8227c36b..b2d40daa80c 100644
--- a/tests/mir-opt/const_prop/return_place.add.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/return_place.add.GVN.panic-abort.diff
@@ -6,7 +6,7 @@
       let mut _1: (u32, bool);
   
       bb0: {
--         _1 = CheckedAdd(const 2_u32, const 2_u32);
+-         _1 = AddWithOverflow(const 2_u32, const 2_u32);
 -         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind unreachable];
 +         _1 = const (4_u32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/const_prop/return_place.add.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/return_place.add.GVN.panic-unwind.diff
index 8174b4edea6..2eafc51cd3d 100644
--- a/tests/mir-opt/const_prop/return_place.add.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/return_place.add.GVN.panic-unwind.diff
@@ -6,7 +6,7 @@
       let mut _1: (u32, bool);
   
       bb0: {
--         _1 = CheckedAdd(const 2_u32, const 2_u32);
+-         _1 = AddWithOverflow(const 2_u32, const 2_u32);
 -         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
 +         _1 = const (4_u32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_u32, const 2_u32) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff
index b35538f8972..53663c6476b 100644
--- a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-abort.diff
@@ -40,7 +40,7 @@
 +         _4 = const 1_i32;
           StorageLive(_5);
 -         _5 = _2;
--         _6 = CheckedAdd(_4, _5);
+-         _6 = AddWithOverflow(_4, _5);
 -         assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind unreachable];
 +         _5 = const 2_i32;
 +         _6 = const (3_i32, false);
@@ -57,7 +57,7 @@
           StorageLive(_8);
           StorageLive(_9);
 -         _9 = _7;
--         _10 = CheckedAdd(_9, const 1_i32);
+-         _10 = AddWithOverflow(_9, const 1_i32);
 -         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> [success: bb2, unwind unreachable];
 +         _9 = const i32::MAX;
 +         _10 = const (i32::MIN, true);
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
index 05c96969233..34feb2a6406 100644
--- a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.panic-unwind.diff
@@ -40,7 +40,7 @@
 +         _4 = const 1_i32;
           StorageLive(_5);
 -         _5 = _2;
--         _6 = CheckedAdd(_4, _5);
+-         _6 = AddWithOverflow(_4, _5);
 -         assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> [success: bb1, unwind continue];
 +         _5 = const 2_i32;
 +         _6 = const (3_i32, false);
@@ -57,7 +57,7 @@
           StorageLive(_8);
           StorageLive(_9);
 -         _9 = _7;
--         _10 = CheckedAdd(_9, const 1_i32);
+-         _10 = AddWithOverflow(_9, const 1_i32);
 -         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> [success: bb2, unwind continue];
 +         _9 = const i32::MAX;
 +         _10 = const (i32::MIN, true);
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff
index ca1bd737caf..8d62de0c821 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-abort.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const 1_u8;
           StorageLive(_4);
--         _4 = CheckedAdd(_2, _3);
+-         _4 = AddWithOverflow(_2, _3);
 -         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind unreachable];
 +         _4 = const (0_u8, true);
 +         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
index 0d7fe9360c1..25624851cb3 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.panic-unwind.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const 1_u8;
           StorageLive(_4);
--         _4 = CheckedAdd(_2, _3);
+-         _4 = AddWithOverflow(_2, _3);
 -         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> [success: bb1, unwind continue];
 +         _4 = const (0_u8, true);
 +         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff
index a45d9920a68..5bf22af6ae8 100644
--- a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff
@@ -31,9 +31,9 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = _1;
--         _5 = CheckedAdd(_4, const 0_u64);
+-         _5 = AddWithOverflow(_4, const 0_u64);
 -         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, const 0_u64) -> [success: bb1, unwind unreachable];
-+         _5 = CheckedAdd(_1, const 0_u64);
++         _5 = AddWithOverflow(_1, const 0_u64);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", _1, const 0_u64) -> [success: bb1, unwind unreachable];
       }
   
@@ -52,7 +52,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = _1;
--         _9 = CheckedSub(_8, const 0_u64);
+-         _9 = SubWithOverflow(_8, const 0_u64);
 -         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", move _8, const 0_u64) -> [success: bb3, unwind unreachable];
 +         _9 = _5;
 +         assert(!const false, "attempt to compute `{} - {}`, which would overflow", _1, const 0_u64) -> [success: bb3, unwind unreachable];
@@ -76,7 +76,7 @@
           _12 = _1;
           StorageLive(_13);
           _13 = _1;
--         _14 = CheckedSub(_12, _13);
+-         _14 = SubWithOverflow(_12, _13);
 -         assert(!move (_14.1: bool), "attempt to compute `{} - {}`, which would overflow", move _12, move _13) -> [success: bb5, unwind unreachable];
 +         _14 = const (0_u64, false);
 +         assert(!const false, "attempt to compute `{} - {}`, which would overflow", _1, _1) -> [success: bb5, unwind unreachable];
@@ -99,7 +99,7 @@
           StorageLive(_16);
           StorageLive(_17);
           _17 = _1;
--         _18 = CheckedMul(_17, const 0_u64);
+-         _18 = MulWithOverflow(_17, const 0_u64);
 -         assert(!move (_18.1: bool), "attempt to compute `{} * {}`, which would overflow", move _17, const 0_u64) -> [success: bb7, unwind unreachable];
 +         _18 = const (0_u64, false);
 +         assert(!const false, "attempt to compute `{} * {}`, which would overflow", _1, const 0_u64) -> [success: bb7, unwind unreachable];
@@ -120,7 +120,7 @@
           StorageLive(_20);
           StorageLive(_21);
           _21 = _1;
--         _22 = CheckedMul(_21, const 1_u64);
+-         _22 = MulWithOverflow(_21, const 1_u64);
 -         assert(!move (_22.1: bool), "attempt to compute `{} * {}`, which would overflow", move _21, const 1_u64) -> [success: bb9, unwind unreachable];
 +         _22 = _5;
 +         assert(!const false, "attempt to compute `{} * {}`, which would overflow", _1, const 1_u64) -> [success: bb9, unwind unreachable];
diff --git a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff
index 9033b392bd4..18d2029e445 100644
--- a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff
@@ -31,9 +31,9 @@
           StorageLive(_3);
           StorageLive(_4);
           _4 = _1;
--         _5 = CheckedAdd(_4, const 0_u64);
+-         _5 = AddWithOverflow(_4, const 0_u64);
 -         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, const 0_u64) -> [success: bb1, unwind continue];
-+         _5 = CheckedAdd(_1, const 0_u64);
++         _5 = AddWithOverflow(_1, const 0_u64);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", _1, const 0_u64) -> [success: bb1, unwind continue];
       }
   
@@ -52,7 +52,7 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = _1;
--         _9 = CheckedSub(_8, const 0_u64);
+-         _9 = SubWithOverflow(_8, const 0_u64);
 -         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", move _8, const 0_u64) -> [success: bb3, unwind continue];
 +         _9 = _5;
 +         assert(!const false, "attempt to compute `{} - {}`, which would overflow", _1, const 0_u64) -> [success: bb3, unwind continue];
@@ -76,7 +76,7 @@
           _12 = _1;
           StorageLive(_13);
           _13 = _1;
--         _14 = CheckedSub(_12, _13);
+-         _14 = SubWithOverflow(_12, _13);
 -         assert(!move (_14.1: bool), "attempt to compute `{} - {}`, which would overflow", move _12, move _13) -> [success: bb5, unwind continue];
 +         _14 = const (0_u64, false);
 +         assert(!const false, "attempt to compute `{} - {}`, which would overflow", _1, _1) -> [success: bb5, unwind continue];
@@ -99,7 +99,7 @@
           StorageLive(_16);
           StorageLive(_17);
           _17 = _1;
--         _18 = CheckedMul(_17, const 0_u64);
+-         _18 = MulWithOverflow(_17, const 0_u64);
 -         assert(!move (_18.1: bool), "attempt to compute `{} * {}`, which would overflow", move _17, const 0_u64) -> [success: bb7, unwind continue];
 +         _18 = const (0_u64, false);
 +         assert(!const false, "attempt to compute `{} * {}`, which would overflow", _1, const 0_u64) -> [success: bb7, unwind continue];
@@ -120,7 +120,7 @@
           StorageLive(_20);
           StorageLive(_21);
           _21 = _1;
--         _22 = CheckedMul(_21, const 1_u64);
+-         _22 = MulWithOverflow(_21, const 1_u64);
 -         assert(!move (_22.1: bool), "attempt to compute `{} * {}`, which would overflow", move _21, const 1_u64) -> [success: bb9, unwind continue];
 +         _22 = _5;
 +         assert(!const false, "attempt to compute `{} * {}`, which would overflow", _1, const 1_u64) -> [success: bb9, unwind continue];
diff --git a/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
index 7dafeabaacc..7d2e97f8d56 100644
--- a/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
+++ b/tests/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
@@ -5,7 +5,7 @@
     let mut _1: (usize, bool);
 
     bb0: {
-        _1 = CheckedAdd(const 1_usize, const 1_usize);
+        _1 = AddWithOverflow(const 1_usize, const 1_usize);
         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2];
     }
 
diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs
index 12e526ab074..180bfd0a924 100644
--- a/tests/mir-opt/lower_intrinsics.rs
+++ b/tests/mir-opt/lower_intrinsics.rs
@@ -184,9 +184,9 @@ pub fn assume() {
 // EMIT_MIR lower_intrinsics.with_overflow.LowerIntrinsics.diff
 pub fn with_overflow(a: i32, b: i32) {
     // CHECK-LABEL: fn with_overflow(
-    // CHECK: CheckedAdd(
-    // CHECK: CheckedSub(
-    // CHECK: CheckedMul(
+    // CHECK: AddWithOverflow(
+    // CHECK: SubWithOverflow(
+    // CHECK: MulWithOverflow(
 
     let _x = core::intrinsics::add_with_overflow(a, b);
     let _y = core::intrinsics::sub_with_overflow(a, b);
diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff
index da84449aaa5..efbbeeeac73 100644
--- a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-abort.diff
@@ -31,7 +31,7 @@
           StorageLive(_5);
           _5 = _2;
 -         _3 = add_with_overflow::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable];
-+         _3 = CheckedAdd(move _4, move _5);
++         _3 = AddWithOverflow(move _4, move _5);
 +         goto -> bb1;
       }
   
@@ -44,7 +44,7 @@
           StorageLive(_8);
           _8 = _2;
 -         _6 = sub_with_overflow::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable];
-+         _6 = CheckedSub(move _7, move _8);
++         _6 = SubWithOverflow(move _7, move _8);
 +         goto -> bb2;
       }
   
@@ -57,7 +57,7 @@
           StorageLive(_11);
           _11 = _2;
 -         _9 = mul_with_overflow::<i32>(move _10, move _11) -> [return: bb3, unwind unreachable];
-+         _9 = CheckedMul(move _10, move _11);
++         _9 = MulWithOverflow(move _10, move _11);
 +         goto -> bb3;
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff
index da84449aaa5..efbbeeeac73 100644
--- a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.panic-unwind.diff
@@ -31,7 +31,7 @@
           StorageLive(_5);
           _5 = _2;
 -         _3 = add_with_overflow::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable];
-+         _3 = CheckedAdd(move _4, move _5);
++         _3 = AddWithOverflow(move _4, move _5);
 +         goto -> bb1;
       }
   
@@ -44,7 +44,7 @@
           StorageLive(_8);
           _8 = _2;
 -         _6 = sub_with_overflow::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable];
-+         _6 = CheckedSub(move _7, move _8);
++         _6 = SubWithOverflow(move _7, move _8);
 +         goto -> bb2;
       }
   
@@ -57,7 +57,7 @@
           StorageLive(_11);
           _11 = _2;
 -         _9 = mul_with_overflow::<i32>(move _10, move _11) -> [return: bb3, unwind unreachable];
-+         _9 = CheckedMul(move _10, move _11);
++         _9 = MulWithOverflow(move _10, move _11);
 +         goto -> bb3;
       }
   
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
index 0e7e1f971ec..2f34a62b3d1 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
@@ -24,7 +24,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 2_i32, const 2_i32);
+-         _2 = AddWithOverflow(const 2_i32, const 2_i32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
 +         _2 = const (4_i32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
index 9071a3339c0..da7add371a5 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
@@ -24,7 +24,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 2_i32, const 2_i32);
+-         _2 = AddWithOverflow(const 2_i32, const 2_i32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
 +         _2 = const (4_i32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
index 0e7e1f971ec..2f34a62b3d1 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
@@ -24,7 +24,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 2_i32, const 2_i32);
+-         _2 = AddWithOverflow(const 2_i32, const 2_i32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
 +         _2 = const (4_i32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
index 9071a3339c0..da7add371a5 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
@@ -24,7 +24,7 @@
   
       bb0: {
           StorageLive(_1);
--         _2 = CheckedAdd(const 2_i32, const 2_i32);
+-         _2 = AddWithOverflow(const 2_i32, const 2_i32);
 -         assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
 +         _2 = const (4_i32, false);
 +         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
index 5f2a096bb1f..802bfbbcdc5 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
@@ -26,7 +26,7 @@
   
       bb0: {
           StorageLive(_1);
-          _2 = CheckedAdd(const 2_i32, const 2_i32);
+          _2 = AddWithOverflow(const 2_i32, const 2_i32);
           assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
index a49546f158c..de94a557403 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
@@ -26,7 +26,7 @@
   
       bb0: {
           StorageLive(_1);
-          _2 = CheckedAdd(const 2_i32, const 2_i32);
+          _2 = AddWithOverflow(const 2_i32, const 2_i32);
           assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
index 5f2a096bb1f..802bfbbcdc5 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
@@ -26,7 +26,7 @@
   
       bb0: {
           StorageLive(_1);
-          _2 = CheckedAdd(const 2_i32, const 2_i32);
+          _2 = AddWithOverflow(const 2_i32, const 2_i32);
           assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
index a49546f158c..de94a557403 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
@@ -26,7 +26,7 @@
   
       bb0: {
           StorageLive(_1);
-          _2 = CheckedAdd(const 2_i32, const 2_i32);
+          _2 = AddWithOverflow(const 2_i32, const 2_i32);
           assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/run-make/const_fn_mir/dump.mir b/tests/run-make/const_fn_mir/dump.mir
index ced170bbeee..b1802c990cf 100644
--- a/tests/run-make/const_fn_mir/dump.mir
+++ b/tests/run-make/const_fn_mir/dump.mir
@@ -5,7 +5,7 @@ fn foo() -> i32 {
     let mut _1: (i32, bool);
 
     bb0: {
-        _1 = CheckedAdd(const 5_i32, const 6_i32);
+        _1 = AddWithOverflow(const 5_i32, const 6_i32);
         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> [success: bb1, unwind continue];
     }
 
@@ -21,7 +21,7 @@ fn foo() -> i32 {
     let mut _1: (i32, bool);
 
     bb0: {
-        _1 = CheckedAdd(const 5_i32, const 6_i32);
+        _1 = AddWithOverflow(const 5_i32, const 6_i32);
         assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 5_i32, const 6_i32) -> [success: bb1, unwind continue];
     }