about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-01-19 22:13:00 +0000
committerMichael Goulet <michael@errs.io>2025-01-27 23:42:47 +0000
commit057313b7a607513d6c1aa82e454e2370025f3b9a (patch)
treec8ebc7bdfe431a98b9c6e7dddef2f0e5644edd78
parent1cbb062e54e376abe8b6f146f64c0d849e30c476 (diff)
downloadrust-057313b7a607513d6c1aa82e454e2370025f3b9a.tar.gz
rust-057313b7a607513d6c1aa82e454e2370025f3b9a.zip
Reapply "Auto merge of #133734 - scottmcm:lower-indexing-to-ptrmetadata, r=davidtwco,RalfJung"
This reverts commit 122a55bb442bd1995df9cf9b36e6f65ed3ef4a1d.
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs25
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs13
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs92
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs13
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs8
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir8
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir8
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir31
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir31
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir34
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir34
-rw-r--r--tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir32
-rw-r--r--tests/mir-opt/building/index_array_and_slice.rs71
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff7
-rw-r--r--tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff7
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff12
-rw-r--r--tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff12
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/array_index.rs3
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/large_array_index.rs2
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff11
-rw-r--r--tests/mir-opt/dataflow-const-prop/repeat.rs3
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.rs34
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff4
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff4
-rw-r--r--tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff72
-rw-r--r--tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff72
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff48
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff48
-rw-r--r--tests/mir-opt/gvn.rs20
-rw-r--r--tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff302
-rw-r--r--tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff302
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff77
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff77
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.rs15
-rw-r--r--tests/mir-opt/issue_72181.foo.built.after.mir9
-rw-r--r--tests/mir-opt/issue_72181.main.built.after.mir9
-rw-r--r--tests/mir-opt/issue_91633.foo.built.after.mir12
-rw-r--r--tests/mir-opt/issue_91633.fun.built.after.mir2
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff20
-rw-r--r--tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff20
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff43
-rw-r--r--tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff43
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff2
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir47
-rw-r--r--tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir47
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff26
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.rs2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir30
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir30
-rw-r--r--tests/ui/borrowck/borrowck-describe-lvalue.rs1
-rw-r--r--tests/ui/borrowck/borrowck-describe-lvalue.stderr25
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs6
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr40
-rw-r--r--tests/ui/consts/issue-65348.rs4
-rw-r--r--tests/ui/stable-mir-print/operands.stdout294
99 files changed, 1432 insertions, 1655 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index ed34996a7a7..c3b609b642d 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -586,12 +586,27 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
-            Rvalue::UnaryOp(_, operand) => {
+            Rvalue::UnaryOp(op, operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                if is_int_bool_float_or_char(ty) {
-                    // Int, bool, float, and char operations are fine.
-                } else {
-                    span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
+                match op {
+                    UnOp::Not | UnOp::Neg => {
+                        if is_int_bool_float_or_char(ty) {
+                            // Int, bool, float, and char operations are fine.
+                        } else {
+                            span_bug!(
+                                self.span,
+                                "non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
+                            );
+                        }
+                    }
+                    UnOp::PtrMetadata => {
+                        if !ty.is_ref() && !ty.is_unsafe_ptr() {
+                            span_bug!(
+                                self.span,
+                                "non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}",
+                            );
+                        }
+                    }
                 }
             }
 
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index b61865be667..a26c2eca107 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,6 +9,7 @@ use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
+use rustc_span::{DesugaringKind, Span};
 use rustc_target::callconv::FnAbi;
 use tracing::{info, instrument, trace};
 
@@ -80,7 +81,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         use rustc_middle::mir::StatementKind::*;
 
         match &stmt.kind {
-            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
+            Assign(box (place, rvalue)) => {
+                self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
+            }
 
             SetDiscriminant { place, variant_index } => {
                 let dest = self.eval_place(**place)?;
@@ -159,6 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
         place: mir::Place<'tcx>,
+        span: Span,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
         // FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -250,8 +254,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
                 let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
-                if !place_base_raw {
+                if !place_base_raw
+                    && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
+                {
                     // If this was not already raw, it needs retagging.
+                    // As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
+                    // from indexing. (Really we should not do any retag on `&raw` but that does not
+                    // currently work with Stacked Borrows.)
                     val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
                 }
                 self.write_immediate(*val, &dest)?;
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index b1851e79d5c..7634bc74fcb 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
 use rustc_middle::{bug, span_bug};
-use rustc_span::Span;
+use rustc_span::{DesugaringKind, Span};
 use tracing::{debug, instrument, trace};
 
 use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -630,6 +630,80 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block.and(base_place.index(idx))
     }
 
+    /// Given a place that's either an array or a slice, returns an operand
+    /// with the length of the array/slice.
+    ///
+    /// For arrays it'll be `Operand::Constant` with the actual length;
+    /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
+    fn len_of_slice_or_array(
+        &mut self,
+        block: BasicBlock,
+        place: Place<'tcx>,
+        span: Span,
+        source_info: SourceInfo,
+    ) -> Operand<'tcx> {
+        let place_ty = place.ty(&self.local_decls, self.tcx).ty;
+        let usize_ty = self.tcx.types.usize;
+
+        match place_ty.kind() {
+            ty::Array(_elem_ty, len_const) => {
+                // We know how long an array is, so just use that as a constant
+                // directly -- no locals needed. We do need one statement so
+                // that borrow- and initialization-checking consider it used,
+                // though. FIXME: Do we really *need* to count this as a use?
+                // Could partial array tracking work off something else instead?
+                self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
+                let const_ = Const::Ty(self.tcx.types.usize, *len_const);
+                Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
+            }
+            ty::Slice(_elem_ty) => {
+                let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..]
+                    && let local_ty = self.local_decls[place.local].ty
+                    && local_ty.is_trivially_pure_clone_copy()
+                {
+                    // It's extremely common that we have something that can be
+                    // directly passed to `PtrMetadata`, so avoid an unnecessary
+                    // temporary and statement in those cases. Note that we can
+                    // only do that for `Copy` types -- not `&mut [_]` -- because
+                    // the MIR we're building here needs to pass NLL later.
+                    Operand::Copy(Place::from(place.local))
+                } else {
+                    let len_span = self.tcx.with_stable_hashing_context(|hcx| {
+                        let span = source_info.span;
+                        span.mark_with_reason(
+                            None,
+                            DesugaringKind::IndexBoundsCheckReborrow,
+                            span.edition(),
+                            hcx,
+                        )
+                    });
+                    let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
+                    let slice_ptr = self.temp(ptr_ty, span);
+                    self.cfg.push_assign(
+                        block,
+                        SourceInfo { span: len_span, ..source_info },
+                        slice_ptr,
+                        Rvalue::RawPtr(Mutability::Not, place),
+                    );
+                    Operand::Move(slice_ptr)
+                };
+
+                let len = self.temp(usize_ty, span);
+                self.cfg.push_assign(
+                    block,
+                    source_info,
+                    len,
+                    Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref),
+                );
+
+                Operand::Move(len)
+            }
+            _ => {
+                span_bug!(span, "len called on place of type {place_ty:?}")
+            }
+        }
+    }
+
     fn bounds_check(
         &mut self,
         block: BasicBlock,
@@ -638,25 +712,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr_span: Span,
         source_info: SourceInfo,
     ) -> BasicBlock {
-        let usize_ty = self.tcx.types.usize;
-        let bool_ty = self.tcx.types.bool;
-        // bounds check:
-        let len = self.temp(usize_ty, expr_span);
-        let lt = self.temp(bool_ty, expr_span);
+        let slice = slice.to_place(self);
 
         // len = len(slice)
-        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
+        let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
+
         // lt = idx < len
+        let bool_ty = self.tcx.types.bool;
+        let lt = self.temp(bool_ty, expr_span);
         self.cfg.push_assign(
             block,
             source_info,
             lt,
             Rvalue::BinaryOp(
                 BinOp::Lt,
-                Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
+                Box::new((Operand::Copy(Place::from(index)), len.to_copy())),
             ),
         );
-        let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
+        let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
+
         // assert!(lt, "...")
         self.assert(block, Operand::Move(lt), true, msg, expr_span)
     }
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 4b9ebd40b85..3dc4edaaa5a 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -46,7 +46,6 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
                         }
                         ctx.simplify_bool_cmp(rvalue);
                         ctx.simplify_ref_deref(rvalue);
-                        ctx.simplify_len(rvalue);
                         ctx.simplify_ptr_aggregate(rvalue);
                         ctx.simplify_cast(rvalue);
                         ctx.simplify_repeated_aggregate(rvalue);
@@ -166,18 +165,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
         }
     }
 
-    /// Transform `Len([_; N])` ==> `N`.
-    fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
-        if let Rvalue::Len(ref place) = *rvalue {
-            let place_ty = place.ty(self.local_decls, self.tcx).ty;
-            if let ty::Array(_, len) = *place_ty.kind() {
-                let const_ = Const::Ty(self.tcx.types.usize, len);
-                let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
-                *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
-            }
-        }
-    }
-
     /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
     fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 026923ad786..5881264cba5 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1128,14 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         );
                     }
                     UnOp::PtrMetadata => {
-                        if !matches!(self.body.phase, MirPhase::Runtime(_)) {
-                            // It would probably be fine to support this in earlier phases, but at
-                            // the time of writing it's only ever introduced from intrinsic
-                            // lowering or other runtime-phase optimization passes, so earlier
-                            // things can just `bug!` on it.
-                            self.fail(location, "PtrMetadata should be in runtime MIR only");
-                        }
-
                         check_kinds!(
                             a,
                             "Cannot PtrMetadata non-pointer non-reference type {:?}",
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index a5826137181..3cdae437b7d 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,6 +1163,9 @@ pub enum DesugaringKind {
     WhileLoop,
     /// `async Fn()` bound modifier
     BoundModifier,
+    /// Marks a `&raw const *_1` needed as part of getting the length of a mutable
+    /// slice for the bounds check, so that MIRI's retag handling can recognize it.
+    IndexBoundsCheckReborrow,
 }
 
 impl DesugaringKind {
@@ -1179,6 +1182,7 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
+            DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
         }
     }
 }
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index a467987e886..8d9176ef301 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: usize;
-    let mut _9: bool;
+    let mut _8: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -41,9 +40,8 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Len(_1);
-        _9 = Lt(copy _7, copy _8);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
+        _8 = Lt(copy _7, const 3_usize);
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable];
     }
 
     bb2: {
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index bd7365543bd..e1df0e3e2a3 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: usize;
-    let mut _9: bool;
+    let mut _8: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -41,9 +40,8 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Len(_1);
-        _9 = Lt(copy _7, copy _8);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
+        _8 = Lt(copy _7, const 3_usize);
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue];
     }
 
     bb2: {
diff --git a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
new file mode 100644
index 00000000000..d28a2031013
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
@@ -0,0 +1,31 @@
+// MIR for `index_array` after built
+
+fn index_array(_1: &[i32; 7], _2: usize) -> &i32 {
+    debug array => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        FakeRead(ForIndex, (*_1));
+        _5 = Lt(copy _4, const 7_usize);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
new file mode 100644
index 00000000000..e9627532c38
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
@@ -0,0 +1,31 @@
+// MIR for `index_const_generic_array` after built
+
+fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 {
+    debug array => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        FakeRead(ForIndex, (*_1));
+        _5 = Lt(copy _4, const N);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
new file mode 100644
index 00000000000..00f2b7e07d5
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
@@ -0,0 +1,34 @@
+// MIR for `index_custom` after built
+
+fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 {
+    debug custom => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: *const [i32];
+    let mut _6: usize;
+    let mut _7: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = &raw const ((*_1).1: [i32]);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &((*_1).1: [i32])[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
new file mode 100644
index 00000000000..cb0b2f600c8
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
@@ -0,0 +1,34 @@
+// MIR for `index_mut_slice` after built
+
+fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: *const [i32];
+    let mut _6: usize;
+    let mut _7: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = &raw const (*_1);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
new file mode 100644
index 00000000000..0911df59049
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
@@ -0,0 +1,32 @@
+// MIR for `index_slice` after built
+
+fn index_slice(_1: &[i32], _2: usize) -> &i32 {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: &i32;
+    let _3: &i32;
+    let _4: usize;
+    let mut _5: usize;
+    let mut _6: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = copy _2;
+        _5 = PtrMetadata(copy _1);
+        _6 = Lt(copy _4, copy _5);
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2];
+    }
+
+    bb1: {
+        _3 = &(*_1)[_4];
+        _0 = &(*_3);
+        StorageDead(_4);
+        StorageDead(_3);
+        return;
+    }
+
+    bb2 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.rs b/tests/mir-opt/building/index_array_and_slice.rs
new file mode 100644
index 00000000000..16d0b983132
--- /dev/null
+++ b/tests/mir-opt/building/index_array_and_slice.rs
@@ -0,0 +1,71 @@
+//@ compile-flags: -C opt-level=0
+
+// EMIT_MIR index_array_and_slice.index_array.built.after.mir
+fn index_array(array: &[i32; 7], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LT:_.+]] = Lt(copy _2, const 7_usize);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _2) -> [success: bb1, unwind
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &array[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_const_generic_array.built.after.mir
+fn index_const_generic_array<const N: usize>(array: &[i32; N], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LT:_.+]] = Lt(copy _2, const N);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _2) -> [success: bb1, unwind
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &array[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_slice.built.after.mir
+fn index_slice(slice: &[i32], index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &slice[index]
+}
+
+// EMIT_MIR index_array_and_slice.index_mut_slice.built.after.mir
+fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 {
+    // While the filecheck here is identical to the above test, the emitted MIR is different.
+    // This cannot `copy _1` in the *built* MIR, only in the *runtime* MIR.
+
+    // CHECK: bb0:
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &(*_1)[_2];
+    &slice[index]
+}
+
+struct WithSliceTail(f64, [i32]);
+
+// EMIT_MIR index_array_and_slice.index_custom.built.after.mir
+fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
+    // CHECK: bb0:
+    // CHECK: [[PTR:_.+]] = &raw const ((*_1).1: [i32]);
+    // CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
+    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
+    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
+
+    // CHECK: bb1:
+    // CHECK: _0 = &((*_1).1: [i32])[_2];
+    &custom.1[index]
+}
+
+fn main() {
+    index_array(&[1, 2, 3, 4, 5, 6, 7], 3);
+    index_slice(&[1, 2, 3, 4, 5, 6, 7][..], 3);
+    _ = index_custom;
+}
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
index e754af95ce3..3a5a8d00991 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
index e15a35c7fe9..62d6e6007e5 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
index e754af95ce3..3a5a8d00991 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
index e15a35c7fe9..62d6e6007e5 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
index 15d30140367..b7cb37a335f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
@@ -32,11 +32,12 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
index dd411d84f9f..50388cbac36 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
@@ -32,11 +32,12 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
index 15d30140367..b7cb37a335f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
@@ -32,11 +32,12 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
index dd411d84f9f..50388cbac36 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
@@ -32,11 +32,12 @@
           StorageLive(_5);
           StorageLive(_6);
           _6 = const 3_usize;
-          _7 = Len((*_1));
+-         _7 = PtrMetadata(copy _1);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 3_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const false;
++         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
index 49ea51deed6..3569998b13f 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
index 103bfbcaf64..50b31c9ac13 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
index 49ea51deed6..3569998b13f 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
index 103bfbcaf64..50b31c9ac13 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
index f7c1c2da01f..a41668b6fa3 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
index 436773c8556..2313084b49e 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
index f7c1c2da01f..a41668b6fa3 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
index 436773c8556..2313084b49e 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
index 8a8ea5b7e20..0798b303929 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
index f0c844884f6..c0b3d4d3219 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
index 8a8ea5b7e20..0798b303929 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
index f0c844884f6..c0b3d4d3219 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
@@ -30,11 +30,12 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
-          _7 = Len((*_2));
+-         _7 = PtrMetadata(copy _2);
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 1_usize, copy _7);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
index 6d967257df1..689083dfc1d 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
@@ -18,8 +18,7 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: usize;
-      let mut _20: bool;
+      let mut _19: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -92,11 +91,10 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
-          _19 = Len(_2);
--         _20 = Lt(copy _18, copy _19);
--         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind unreachable];
-+         _20 = Lt(copy _16, copy _19);
-+         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind unreachable];
+-         _19 = Lt(copy _18, const 4_usize);
+-         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind unreachable];
++         _19 = Lt(copy _16, const 4_usize);
++         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind unreachable];
       }
   
       bb7: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
index 3580c87c469..7f768a9f834 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
@@ -18,8 +18,7 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: usize;
-      let mut _20: bool;
+      let mut _19: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -92,11 +91,10 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
-          _19 = Len(_2);
--         _20 = Lt(copy _18, copy _19);
--         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind continue];
-+         _20 = Lt(copy _16, copy _19);
-+         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind continue];
+-         _19 = Lt(copy _18, const 4_usize);
+-         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind continue];
++         _19 = Lt(copy _16, const 4_usize);
++         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind continue];
       }
   
       bb7: {
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
index a46daef435f..0275d7e8a0d 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index 1a4e15b45fa..490ed4b55a1 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
index a46daef435f..0275d7e8a0d 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index 1a4e15b45fa..490ed4b55a1 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 4_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 4_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs
index e442ef99f79..1aa8dcd28f4 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/array_index.rs
@@ -11,9 +11,10 @@ fn main() {
 
     // CHECK:       [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
     // CHECK-NOT:   {{_.*}} = Len(
+    // CHECK-NOT:   {{_.*}} = PtrMetadata(
     // CHECK-NOT:   {{_.*}} = Lt(
     // CHECK-NOT:   assert(move _
-    // CHECK:       {{_.*}} = const 4_usize;
+    // CHECK:       {{_.*}} = const 2_usize;
     // CHECK:       {{_.*}} = const true;
     // CHECK:       assert(const true
     // CHECK:       [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
index b7ff0b671f7..f0d59ef5923 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index af6e3626142..959c3e75214 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
index b7ff0b671f7..f0d59ef5923 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index af6e3626142..959c3e75214 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,8 +6,7 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
+      let mut _4: bool;
       scope 1 {
           debug x => _1;
       }
@@ -18,11 +17,9 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Len(_2);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const 5000_usize;
-+         _5 = const true;
+-         _4 = Lt(copy _3, const 5000_usize);
+-         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
++         _4 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
index e9f2fa2badf..e490cfde247 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
@@ -10,7 +10,7 @@ fn main() {
 
     // CHECK: debug x => [[x:_.*]];
     // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
-    // CHECK: {{_.*}} = const 5000_usize;
+    // CHECK: {{_.*}} = const 2_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
     // CHECK: [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
index dfa541b1200..618121ea632 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
index 9ede3c5f7ac..1788f58432b 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
index dfa541b1200..618121ea632 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
index 9ede3c5f7ac..1788f58432b 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -7,8 +7,7 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: usize;
-      let mut _6: bool;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -20,11 +19,9 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Len(_3);
--         _6 = Lt(copy _4, copy _5);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const 8_usize;
-+         _6 = const true;
+-         _5 = Lt(copy _4, const 8_usize);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs
index 2067aa3d709..1bc2cb82a60 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.rs
+++ b/tests/mir-opt/dataflow-const-prop/repeat.rs
@@ -9,8 +9,9 @@ fn main() {
 
     // CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
     // CHECK-NOT: {{_.*}} = Len(
+    // CHECK-NOT: {{_.*}} = PtrMetadata(
     // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK: {{_.*}} = const 8_usize;
+    // CHECK: {{_.*}} = const 2_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
 
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
deleted file mode 100644
index e71992316dc..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
deleted file mode 100644
index 26de8595768..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
deleted file mode 100644
index e71992316dc..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
deleted file mode 100644
index 26de8595768..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `main` before DataflowConstProp
-+ // MIR for `main` after DataflowConstProp
-  
-  fn main() -> () {
-      let mut _0: ();
-      let _1: u32;
-      let mut _2: &[u32];
-      let mut _3: &[u32; 3];
-      let _4: &[u32; 3];
-      let _5: [u32; 3];
-      let _6: usize;
-      let mut _7: usize;
-      let mut _8: bool;
-      let mut _10: &[u32];
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-      let mut _14: &[u32; 3];
-      scope 1 {
-          debug local => _1;
-          let _9: u32;
-          scope 2 {
-              debug constant => _9;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _14 = const main::promoted[0];
-          _4 = copy _14;
-          _3 = copy _4;
-          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
-          StorageDead(_3);
-          StorageLive(_6);
-          _6 = const 1_usize;
--         _7 = Len((*_2));
--         _8 = Lt(copy _6, copy _7);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
--         _1 = copy (*_2)[_6];
-+         _1 = copy (*_2)[1 of 2];
-          StorageDead(_6);
-          StorageDead(_4);
-          StorageDead(_2);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = const main::SLICE;
-          StorageLive(_11);
-          _11 = const 1_usize;
--         _12 = Len((*_10));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
-+         _12 = const 3_usize;
-+         _13 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
--         _9 = copy (*_10)[_11];
-+         _9 = copy (*_10)[1 of 2];
-          StorageDead(_11);
-          StorageDead(_10);
-          _0 = const ();
-          StorageDead(_9);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs
deleted file mode 100644
index e0e68f9fde5..00000000000
--- a/tests/mir-opt/dataflow-const-prop/slice_len.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
-//@ test-mir-pass: DataflowConstProp
-//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg
-// EMIT_MIR_FOR_EACH_BIT_WIDTH
-
-// EMIT_MIR slice_len.main.DataflowConstProp.diff
-
-// CHECK-LABEL: fn main(
-fn main() {
-    // CHECK: debug local => [[local:_.*]];
-    // CHECK: debug constant => [[constant:_.*]];
-
-    // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK-NOT: assert(move _
-    // CHECK: {{_.*}} = const 3_usize;
-    // CHECK: {{_.*}} = const true;
-    // CHECK: assert(const true,
-
-    // CHECK: [[local]] = copy (*{{_.*}})[1 of 2];
-    let local = (&[1u32, 2, 3] as &[u32])[1];
-
-    // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK-NOT: assert(move _
-    const SLICE: &[u32] = &[1, 2, 3];
-    // CHECK: {{_.*}} = const 3_usize;
-    // CHECK: {{_.*}} = const true;
-    // CHECK: assert(const true,
-
-    // CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_
-    // CHECK: [[constant]] = copy (*{{_.*}})[1 of 2];
-    let constant = SLICE[1];
-}
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
index 3f052ee19fd..183b4d2599f 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = Len((*_1));
+          _9 = PtrMetadata(copy _1);
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = Len((*_1));
+          _12 = PtrMetadata(copy _1);
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
index 84b738c7804..03e8aa3bd9b 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = Len((*_1));
+          _9 = PtrMetadata(copy _1);
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = Len((*_1));
+          _12 = PtrMetadata(copy _1);
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
new file mode 100644
index 00000000000..4b077f580f1
--- /dev/null
+++ b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
@@ -0,0 +1,72 @@
+- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
++ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
+  
+  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
+      debug x => _1;
+      let mut _0: [i32; 3];
+      let mut _2: i32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let mut _6: i32;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: i32;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 42_usize;
+          _4 = PtrMetadata(copy _1);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _5 = Lt(const 42_usize, copy _4);
++         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         _2 = copy (*_1)[_3];
++         _2 = copy (*_1)[42 of 43];
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 13_usize;
+-         _8 = PtrMetadata(copy _1);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
++         _8 = copy _4;
++         _9 = Lt(const 13_usize, copy _4);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         _6 = copy (*_1)[_7];
++         _6 = copy (*_1)[13 of 14];
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = const 7_usize;
+-         _12 = PtrMetadata(copy _1);
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind unreachable];
++         _12 = copy _4;
++         _13 = Lt(const 7_usize, copy _4);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+-         _10 = copy (*_1)[_11];
++         _10 = copy (*_1)[7 of 8];
+          _0 = [move _2, move _6, move _10];
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_11);
+          StorageDead(_7);
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..87e69d44006
--- /dev/null
+++ b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
@@ -0,0 +1,72 @@
+- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
++ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
+  
+  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
+      debug x => _1;
+      let mut _0: [i32; 3];
+      let mut _2: i32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let mut _6: i32;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: i32;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 42_usize;
+          _4 = PtrMetadata(copy _1);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _5 = Lt(const 42_usize, copy _4);
++         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         _2 = copy (*_1)[_3];
++         _2 = copy (*_1)[42 of 43];
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 13_usize;
+-         _8 = PtrMetadata(copy _1);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
++         _8 = copy _4;
++         _9 = Lt(const 13_usize, copy _4);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         _6 = copy (*_1)[_7];
++         _6 = copy (*_1)[13 of 14];
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = const 7_usize;
+-         _12 = PtrMetadata(copy _1);
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind continue];
++         _12 = copy _4;
++         _13 = Lt(const 7_usize, copy _4);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind continue];
+      }
+  
+      bb3: {
+-         _10 = copy (*_1)[_11];
++         _10 = copy (*_1)[7 of 8];
+          _0 = [move _2, move _6, move _10];
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          StorageDead(_11);
+          StorageDead(_7);
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
index d4b22d05f6c..7f44176b756 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -10,13 +10,11 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let _10: ();
-      let mut _11: T;
-      let _12: usize;
-      let mut _13: usize;
-      let mut _14: bool;
+      let mut _8: bool;
+      let _9: ();
+      let mut _10: T;
+      let _11: usize;
+      let mut _12: bool;
       scope 1 {
           debug a => _3;
       }
@@ -32,12 +30,10 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Len(_3);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind unreachable];
-+         _8 = const N;
-+         _9 = Lt(const 0_usize, const N);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
+-         _8 = Lt(copy _7, const N);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 0_usize, const N);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
@@ -51,29 +47,27 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
+          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          StorageLive(_12);
-          _12 = copy _2;
--         _13 = Len(_3);
--         _14 = Lt(copy _12, copy _13);
--         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind unreachable];
-+         _13 = const N;
-+         _14 = Lt(copy _2, const N);
-+         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
+          _11 = copy _2;
+-         _12 = Lt(copy _11, const N);
+-         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind unreachable];
++         _12 = Lt(copy _2, const N);
++         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
       }
   
       bb3: {
--         _11 = copy _3[_12];
--         _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
-+         _11 = copy _1;
-+         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
+-         _10 = copy _3[_11];
+-         _9 = opaque::<T>(move _10) -> [return: bb4, unwind unreachable];
++         _10 = copy _1;
++         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_11);
-          StorageDead(_12);
           StorageDead(_10);
+          StorageDead(_11);
+          StorageDead(_9);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
index 708c0f92e54..d34882d725f 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -10,13 +10,11 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let _10: ();
-      let mut _11: T;
-      let _12: usize;
-      let mut _13: usize;
-      let mut _14: bool;
+      let mut _8: bool;
+      let _9: ();
+      let mut _10: T;
+      let _11: usize;
+      let mut _12: bool;
       scope 1 {
           debug a => _3;
       }
@@ -32,12 +30,10 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Len(_3);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind continue];
-+         _8 = const N;
-+         _9 = Lt(const 0_usize, const N);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
+-         _8 = Lt(copy _7, const N);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind continue];
++         _8 = Lt(const 0_usize, const N);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -51,29 +47,27 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
+          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          StorageLive(_12);
-          _12 = copy _2;
--         _13 = Len(_3);
--         _14 = Lt(copy _12, copy _13);
--         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind continue];
-+         _13 = const N;
-+         _14 = Lt(copy _2, const N);
-+         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
+          _11 = copy _2;
+-         _12 = Lt(copy _11, const N);
+-         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind continue];
++         _12 = Lt(copy _2, const N);
++         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
       }
   
       bb3: {
--         _11 = copy _3[_12];
--         _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
-+         _11 = copy _1;
-+         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
+-         _10 = copy _3[_11];
+-         _9 = opaque::<T>(move _10) -> [return: bb4, unwind continue];
++         _10 = copy _1;
++         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_11);
-          StorageDead(_12);
           StorageDead(_10);
+          StorageDead(_11);
+          StorageDead(_9);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 10d1ccfdece..c895a579259 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -835,6 +835,25 @@ fn array_len(x: &mut [i32; 42]) -> usize {
     std::intrinsics::ptr_metadata(x)
 }
 
+// Check that we only load the length once, rather than all 3 times.
+fn dedup_multiple_bounds_checks_lengths(x: &[i32]) -> [i32; 3] {
+    // CHECK-LABEL: fn dedup_multiple_bounds_checks_lengths
+    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
+    // CHECK: Lt(const 42_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[A:_.+]] = copy (*_1)[42 of 43];
+    // CHECK-NOT: PtrMetadata
+    // CHECK: Lt(const 13_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[B:_.+]] = copy (*_1)[13 of 14];
+    // CHECK-NOT: PtrMetadata
+    // CHECK: Lt(const 7_usize, copy [[LEN]]);
+    // CHECK: assert{{.+}}copy [[LEN]]
+    // CHECK: [[C:_.+]] = copy (*_1)[7 of 8];
+    // CHECK: _0 = [move [[A]], move [[B]], move [[C]]]
+    [x[42], x[13], x[7]]
+}
+
 #[custom_mir(dialect = "runtime")]
 fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
     // CHECK-LABEL: fn generic_cast_metadata
@@ -1109,6 +1128,7 @@ enum Never {}
 // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
 // EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
 // EMIT_MIR gvn.array_len.GVN.diff
+// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
 // EMIT_MIR gvn.generic_cast_metadata.GVN.diff
 // EMIT_MIR gvn.cast_pointer_eq.GVN.diff
 // EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
index 6b6152c1117..1b305e746f5 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
@@ -10,62 +10,60 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let mut _12: *const dyn std::marker::Send;
-      let _13: &dyn std::marker::Send;
-      let mut _14: &i32;
-      let _15: &i32;
-      let _16: usize;
-      let mut _17: usize;
+      let mut _9: bool;
+      let mut _11: *const dyn std::marker::Send;
+      let _12: &dyn std::marker::Send;
+      let mut _13: &i32;
+      let _14: &i32;
+      let _15: usize;
+      let mut _16: bool;
+      let _17: ();
       let mut _18: bool;
-      let _19: ();
-      let mut _20: bool;
+      let mut _19: *const dyn std::marker::Send;
+      let mut _20: *const dyn std::marker::Send;
       let mut _21: *const dyn std::marker::Send;
-      let mut _22: *const dyn std::marker::Send;
-      let mut _23: *const dyn std::marker::Send;
-      let _24: ();
-      let mut _25: bool;
+      let _22: ();
+      let mut _23: bool;
+      let mut _24: *const dyn std::marker::Send;
+      let mut _25: *const dyn std::marker::Send;
       let mut _26: *const dyn std::marker::Send;
-      let mut _27: *const dyn std::marker::Send;
-      let mut _28: *const dyn std::marker::Send;
-      let _29: ();
-      let mut _30: bool;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: *const dyn std::marker::Send;
+      let mut _30: *const dyn std::marker::Send;
       let mut _31: *const dyn std::marker::Send;
-      let mut _32: *const dyn std::marker::Send;
-      let mut _33: *const dyn std::marker::Send;
-      let _34: ();
-      let mut _35: bool;
+      let _32: ();
+      let mut _33: bool;
+      let mut _34: *const dyn std::marker::Send;
+      let mut _35: *const dyn std::marker::Send;
       let mut _36: *const dyn std::marker::Send;
-      let mut _37: *const dyn std::marker::Send;
-      let mut _38: *const dyn std::marker::Send;
-      let _39: ();
-      let mut _40: bool;
+      let _37: ();
+      let mut _38: bool;
+      let mut _39: *const dyn std::marker::Send;
+      let mut _40: *const dyn std::marker::Send;
       let mut _41: *const dyn std::marker::Send;
-      let mut _42: *const dyn std::marker::Send;
-      let mut _43: *const dyn std::marker::Send;
-      let _44: ();
-      let mut _45: bool;
+      let _42: ();
+      let mut _43: bool;
+      let mut _44: *const dyn std::marker::Send;
+      let mut _45: *const dyn std::marker::Send;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: *const dyn std::marker::Send;
-      let mut _48: *const dyn std::marker::Send;
-      let mut _49: &[i32; 2];
+      let mut _47: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _11: *const dyn std::marker::Send;
+              let _10: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _11;
+                  debug b => _10;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _49 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_49);
+          _47 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_47);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -74,11 +72,9 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Len((*_1));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind unreachable];
-+         _9 = const 2_usize;
-+         _10 = const true;
+-         _9 = Lt(copy _8, const 2_usize);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable];
++         _9 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
@@ -95,170 +91,168 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_11);
--         StorageLive(_12);
+          StorageLive(_10);
+-         StorageLive(_11);
 +         nop;
+          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          StorageLive(_16);
-          _16 = const 1_usize;
--         _17 = Len((*_1));
--         _18 = Lt(copy _16, copy _17);
--         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind unreachable];
-+         _17 = const 2_usize;
-+         _18 = const true;
+          _15 = const 1_usize;
+-         _16 = Lt(copy _15, const 2_usize);
+-         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable];
++         _16 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
--         _15 = &(*_1)[_16];
-+         _15 = &(*_1)[1 of 2];
-          _14 = &(*_15);
-          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_14);
-          _12 = &raw const (*_13);
--         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_12);
-+         _11 = copy _12;
-+         nop;
-          StorageDead(_15);
+-         _14 = &(*_1)[_15];
++         _14 = &(*_1)[1 of 2];
+          _13 = &(*_14);
+          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_13);
+          _11 = &raw const (*_12);
+-         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_11);
++         _10 = copy _11;
++         nop;
+          StorageDead(_14);
+          StorageDead(_12);
+          StorageLive(_17);
+          StorageLive(_18);
           StorageLive(_19);
+-         _19 = copy _3;
++         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _3;
-+         _21 = copy _4;
-          StorageLive(_22);
-          StorageLive(_23);
--         _23 = copy _11;
--         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _23 = copy _12;
-+         _22 = copy _12;
-          StorageDead(_23);
--         _20 = Eq(move _21, move _22);
-+         _20 = Eq(copy _4, copy _12);
-          StorageDead(_22);
+-         _21 = copy _10;
+-         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _21 = copy _11;
++         _20 = copy _11;
           StorageDead(_21);
-          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind unreachable];
+-         _18 = Eq(move _19, move _20);
++         _18 = Eq(copy _4, copy _11);
+          StorageDead(_20);
+          StorageDead(_19);
+          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
-          StorageDead(_20);
-          StorageDead(_19);
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_22);
+          StorageLive(_23);
           StorageLive(_24);
+-         _24 = copy _3;
++         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _3;
-+         _26 = copy _4;
-          StorageLive(_27);
-          StorageLive(_28);
--         _28 = copy _11;
--         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _28 = copy _12;
-+         _27 = copy _12;
-          StorageDead(_28);
--         _25 = Ne(move _26, move _27);
-+         _25 = Ne(copy _4, copy _12);
-          StorageDead(_27);
+-         _26 = copy _10;
+-         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _26 = copy _11;
++         _25 = copy _11;
           StorageDead(_26);
-          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind unreachable];
+-         _23 = Ne(move _24, move _25);
++         _23 = Ne(copy _4, copy _11);
+          StorageDead(_25);
+          StorageDead(_24);
+          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_25);
-          StorageDead(_24);
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_27);
+          StorageLive(_28);
           StorageLive(_29);
+-         _29 = copy _3;
++         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _3;
-+         _31 = copy _4;
-          StorageLive(_32);
-          StorageLive(_33);
--         _33 = copy _11;
--         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _33 = copy _12;
-+         _32 = copy _12;
-          StorageDead(_33);
--         _30 = Lt(move _31, move _32);
-+         _30 = Lt(copy _4, copy _12);
-          StorageDead(_32);
+-         _31 = copy _10;
+-         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _31 = copy _11;
++         _30 = copy _11;
           StorageDead(_31);
-          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind unreachable];
+-         _28 = Lt(move _29, move _30);
++         _28 = Lt(copy _4, copy _11);
+          StorageDead(_30);
+          StorageDead(_29);
+          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_30);
-          StorageDead(_29);
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_32);
+          StorageLive(_33);
           StorageLive(_34);
+-         _34 = copy _3;
++         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _3;
-+         _36 = copy _4;
-          StorageLive(_37);
-          StorageLive(_38);
--         _38 = copy _11;
--         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _38 = copy _12;
-+         _37 = copy _12;
-          StorageDead(_38);
--         _35 = Le(move _36, move _37);
-+         _35 = Le(copy _4, copy _12);
-          StorageDead(_37);
+-         _36 = copy _10;
+-         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _36 = copy _11;
++         _35 = copy _11;
           StorageDead(_36);
-          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind unreachable];
+-         _33 = Le(move _34, move _35);
++         _33 = Le(copy _4, copy _11);
+          StorageDead(_35);
+          StorageDead(_34);
+          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind unreachable];
       }
   
       bb6: {
-          StorageDead(_35);
-          StorageDead(_34);
+          StorageDead(_33);
+          StorageDead(_32);
+          StorageLive(_37);
+          StorageLive(_38);
           StorageLive(_39);
+-         _39 = copy _3;
++         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _3;
-+         _41 = copy _4;
-          StorageLive(_42);
-          StorageLive(_43);
--         _43 = copy _11;
--         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _43 = copy _12;
-+         _42 = copy _12;
-          StorageDead(_43);
--         _40 = Gt(move _41, move _42);
-+         _40 = Gt(copy _4, copy _12);
-          StorageDead(_42);
+-         _41 = copy _10;
+-         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _41 = copy _11;
++         _40 = copy _11;
           StorageDead(_41);
-          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind unreachable];
+-         _38 = Gt(move _39, move _40);
++         _38 = Gt(copy _4, copy _11);
+          StorageDead(_40);
+          StorageDead(_39);
+          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
-          StorageDead(_40);
-          StorageDead(_39);
+          StorageDead(_38);
+          StorageDead(_37);
+          StorageLive(_42);
+          StorageLive(_43);
           StorageLive(_44);
+-         _44 = copy _3;
++         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _3;
-+         _46 = copy _4;
-          StorageLive(_47);
-          StorageLive(_48);
--         _48 = copy _11;
--         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _48 = copy _12;
-+         _47 = copy _12;
-          StorageDead(_48);
--         _45 = Ge(move _46, move _47);
-+         _45 = Ge(copy _4, copy _12);
-          StorageDead(_47);
+-         _46 = copy _10;
+-         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _46 = copy _11;
++         _45 = copy _11;
           StorageDead(_46);
-          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind unreachable];
+-         _43 = Ge(move _44, move _45);
++         _43 = Ge(copy _4, copy _11);
+          StorageDead(_45);
+          StorageDead(_44);
+          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind unreachable];
       }
   
       bb8: {
-          StorageDead(_45);
-          StorageDead(_44);
+          StorageDead(_43);
+          StorageDead(_42);
           _0 = const ();
-          StorageDead(_16);
-          StorageDead(_11);
+          StorageDead(_15);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
index 093c1ec6ce3..e418ecf25bd 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
@@ -10,62 +10,60 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let mut _12: *const dyn std::marker::Send;
-      let _13: &dyn std::marker::Send;
-      let mut _14: &i32;
-      let _15: &i32;
-      let _16: usize;
-      let mut _17: usize;
+      let mut _9: bool;
+      let mut _11: *const dyn std::marker::Send;
+      let _12: &dyn std::marker::Send;
+      let mut _13: &i32;
+      let _14: &i32;
+      let _15: usize;
+      let mut _16: bool;
+      let _17: ();
       let mut _18: bool;
-      let _19: ();
-      let mut _20: bool;
+      let mut _19: *const dyn std::marker::Send;
+      let mut _20: *const dyn std::marker::Send;
       let mut _21: *const dyn std::marker::Send;
-      let mut _22: *const dyn std::marker::Send;
-      let mut _23: *const dyn std::marker::Send;
-      let _24: ();
-      let mut _25: bool;
+      let _22: ();
+      let mut _23: bool;
+      let mut _24: *const dyn std::marker::Send;
+      let mut _25: *const dyn std::marker::Send;
       let mut _26: *const dyn std::marker::Send;
-      let mut _27: *const dyn std::marker::Send;
-      let mut _28: *const dyn std::marker::Send;
-      let _29: ();
-      let mut _30: bool;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: *const dyn std::marker::Send;
+      let mut _30: *const dyn std::marker::Send;
       let mut _31: *const dyn std::marker::Send;
-      let mut _32: *const dyn std::marker::Send;
-      let mut _33: *const dyn std::marker::Send;
-      let _34: ();
-      let mut _35: bool;
+      let _32: ();
+      let mut _33: bool;
+      let mut _34: *const dyn std::marker::Send;
+      let mut _35: *const dyn std::marker::Send;
       let mut _36: *const dyn std::marker::Send;
-      let mut _37: *const dyn std::marker::Send;
-      let mut _38: *const dyn std::marker::Send;
-      let _39: ();
-      let mut _40: bool;
+      let _37: ();
+      let mut _38: bool;
+      let mut _39: *const dyn std::marker::Send;
+      let mut _40: *const dyn std::marker::Send;
       let mut _41: *const dyn std::marker::Send;
-      let mut _42: *const dyn std::marker::Send;
-      let mut _43: *const dyn std::marker::Send;
-      let _44: ();
-      let mut _45: bool;
+      let _42: ();
+      let mut _43: bool;
+      let mut _44: *const dyn std::marker::Send;
+      let mut _45: *const dyn std::marker::Send;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: *const dyn std::marker::Send;
-      let mut _48: *const dyn std::marker::Send;
-      let mut _49: &[i32; 2];
+      let mut _47: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _11: *const dyn std::marker::Send;
+              let _10: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _11;
+                  debug b => _10;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _49 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_49);
+          _47 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_47);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -74,11 +72,9 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Len((*_1));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind continue];
-+         _9 = const 2_usize;
-+         _10 = const true;
+-         _9 = Lt(copy _8, const 2_usize);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue];
++         _9 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue];
       }
   
@@ -95,170 +91,168 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_11);
--         StorageLive(_12);
+          StorageLive(_10);
+-         StorageLive(_11);
 +         nop;
+          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          StorageLive(_16);
-          _16 = const 1_usize;
--         _17 = Len((*_1));
--         _18 = Lt(copy _16, copy _17);
--         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind continue];
-+         _17 = const 2_usize;
-+         _18 = const true;
+          _15 = const 1_usize;
+-         _16 = Lt(copy _15, const 2_usize);
+-         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue];
++         _16 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue];
       }
   
       bb2: {
--         _15 = &(*_1)[_16];
-+         _15 = &(*_1)[1 of 2];
-          _14 = &(*_15);
-          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_14);
-          _12 = &raw const (*_13);
--         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_12);
-+         _11 = copy _12;
-+         nop;
-          StorageDead(_15);
+-         _14 = &(*_1)[_15];
++         _14 = &(*_1)[1 of 2];
+          _13 = &(*_14);
+          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_13);
+          _11 = &raw const (*_12);
+-         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_11);
++         _10 = copy _11;
++         nop;
+          StorageDead(_14);
+          StorageDead(_12);
+          StorageLive(_17);
+          StorageLive(_18);
           StorageLive(_19);
+-         _19 = copy _3;
++         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _3;
-+         _21 = copy _4;
-          StorageLive(_22);
-          StorageLive(_23);
--         _23 = copy _11;
--         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _23 = copy _12;
-+         _22 = copy _12;
-          StorageDead(_23);
--         _20 = Eq(move _21, move _22);
-+         _20 = Eq(copy _4, copy _12);
-          StorageDead(_22);
+-         _21 = copy _10;
+-         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _21 = copy _11;
++         _20 = copy _11;
           StorageDead(_21);
-          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind continue];
+-         _18 = Eq(move _19, move _20);
++         _18 = Eq(copy _4, copy _11);
+          StorageDead(_20);
+          StorageDead(_19);
+          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind continue];
       }
   
       bb3: {
-          StorageDead(_20);
-          StorageDead(_19);
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_22);
+          StorageLive(_23);
           StorageLive(_24);
+-         _24 = copy _3;
++         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _3;
-+         _26 = copy _4;
-          StorageLive(_27);
-          StorageLive(_28);
--         _28 = copy _11;
--         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _28 = copy _12;
-+         _27 = copy _12;
-          StorageDead(_28);
--         _25 = Ne(move _26, move _27);
-+         _25 = Ne(copy _4, copy _12);
-          StorageDead(_27);
+-         _26 = copy _10;
+-         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _26 = copy _11;
++         _25 = copy _11;
           StorageDead(_26);
-          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind continue];
+-         _23 = Ne(move _24, move _25);
++         _23 = Ne(copy _4, copy _11);
+          StorageDead(_25);
+          StorageDead(_24);
+          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_25);
-          StorageDead(_24);
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_27);
+          StorageLive(_28);
           StorageLive(_29);
+-         _29 = copy _3;
++         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _3;
-+         _31 = copy _4;
-          StorageLive(_32);
-          StorageLive(_33);
--         _33 = copy _11;
--         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _33 = copy _12;
-+         _32 = copy _12;
-          StorageDead(_33);
--         _30 = Lt(move _31, move _32);
-+         _30 = Lt(copy _4, copy _12);
-          StorageDead(_32);
+-         _31 = copy _10;
+-         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _31 = copy _11;
++         _30 = copy _11;
           StorageDead(_31);
-          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind continue];
+-         _28 = Lt(move _29, move _30);
++         _28 = Lt(copy _4, copy _11);
+          StorageDead(_30);
+          StorageDead(_29);
+          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind continue];
       }
   
       bb5: {
-          StorageDead(_30);
-          StorageDead(_29);
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_32);
+          StorageLive(_33);
           StorageLive(_34);
+-         _34 = copy _3;
++         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _3;
-+         _36 = copy _4;
-          StorageLive(_37);
-          StorageLive(_38);
--         _38 = copy _11;
--         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _38 = copy _12;
-+         _37 = copy _12;
-          StorageDead(_38);
--         _35 = Le(move _36, move _37);
-+         _35 = Le(copy _4, copy _12);
-          StorageDead(_37);
+-         _36 = copy _10;
+-         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _36 = copy _11;
++         _35 = copy _11;
           StorageDead(_36);
-          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind continue];
+-         _33 = Le(move _34, move _35);
++         _33 = Le(copy _4, copy _11);
+          StorageDead(_35);
+          StorageDead(_34);
+          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind continue];
       }
   
       bb6: {
-          StorageDead(_35);
-          StorageDead(_34);
+          StorageDead(_33);
+          StorageDead(_32);
+          StorageLive(_37);
+          StorageLive(_38);
           StorageLive(_39);
+-         _39 = copy _3;
++         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _3;
-+         _41 = copy _4;
-          StorageLive(_42);
-          StorageLive(_43);
--         _43 = copy _11;
--         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _43 = copy _12;
-+         _42 = copy _12;
-          StorageDead(_43);
--         _40 = Gt(move _41, move _42);
-+         _40 = Gt(copy _4, copy _12);
-          StorageDead(_42);
+-         _41 = copy _10;
+-         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _41 = copy _11;
++         _40 = copy _11;
           StorageDead(_41);
-          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind continue];
+-         _38 = Gt(move _39, move _40);
++         _38 = Gt(copy _4, copy _11);
+          StorageDead(_40);
+          StorageDead(_39);
+          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind continue];
       }
   
       bb7: {
-          StorageDead(_40);
-          StorageDead(_39);
+          StorageDead(_38);
+          StorageDead(_37);
+          StorageLive(_42);
+          StorageLive(_43);
           StorageLive(_44);
+-         _44 = copy _3;
++         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _3;
-+         _46 = copy _4;
-          StorageLive(_47);
-          StorageLive(_48);
--         _48 = copy _11;
--         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _48 = copy _12;
-+         _47 = copy _12;
-          StorageDead(_48);
--         _45 = Ge(move _46, move _47);
-+         _45 = Ge(copy _4, copy _12);
-          StorageDead(_47);
+-         _46 = copy _10;
+-         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _46 = copy _11;
++         _45 = copy _11;
           StorageDead(_46);
-          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind continue];
+-         _43 = Ge(move _44, move _45);
++         _43 = Ge(copy _4, copy _11);
+          StorageDead(_45);
+          StorageDead(_44);
+          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind continue];
       }
   
       bb8: {
-          StorageDead(_45);
-          StorageDead(_44);
+          StorageDead(_43);
+          StorageDead(_42);
           _0 = const ();
-          StorageDead(_16);
-          StorageDead(_11);
+          StorageDead(_15);
+          StorageDead(_10);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
deleted file mode 100644
index f39df7ffca0..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `norm2` before InstSimplify-after-simplifycfg
-+ // MIR for `norm2` after InstSimplify-after-simplifycfg
-  
-  fn norm2(_1: [f32; 2]) -> f32 {
-      debug x => _1;
-      let mut _0: f32;
-      let _2: f32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: f32;
-      let mut _11: f32;
-      let mut _12: f32;
-      let mut _13: f32;
-      let mut _14: f32;
-      let mut _15: f32;
-      scope 1 {
-          debug a => _2;
-          let _6: f32;
-          scope 2 {
-              debug b => _6;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 0_usize;
--         _4 = Len(_1);
-+         _4 = const 2_usize;
-          _5 = Lt(copy _3, copy _4);
-          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
-          _2 = copy _1[_3];
-          StorageDead(_3);
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 1_usize;
--         _8 = Len(_1);
-+         _8 = const 2_usize;
-          _9 = Lt(copy _7, copy _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          _6 = copy _1[_7];
-          StorageDead(_7);
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = copy _2;
-          StorageLive(_12);
-          _12 = copy _2;
-          _10 = Mul(move _11, move _12);
-          StorageDead(_12);
-          StorageDead(_11);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = copy _6;
-          StorageLive(_15);
-          _15 = copy _6;
-          _13 = Mul(move _14, move _15);
-          StorageDead(_15);
-          StorageDead(_14);
-          _0 = Add(move _10, move _13);
-          StorageDead(_13);
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
deleted file mode 100644
index 0e7d5653c68..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
+++ /dev/null
@@ -1,77 +0,0 @@
-- // MIR for `norm2` before InstSimplify-after-simplifycfg
-+ // MIR for `norm2` after InstSimplify-after-simplifycfg
-  
-  fn norm2(_1: [f32; 2]) -> f32 {
-      debug x => _1;
-      let mut _0: f32;
-      let _2: f32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: f32;
-      let mut _11: f32;
-      let mut _12: f32;
-      let mut _13: f32;
-      let mut _14: f32;
-      let mut _15: f32;
-      scope 1 {
-          debug a => _2;
-          let _6: f32;
-          scope 2 {
-              debug b => _6;
-          }
-      }
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 0_usize;
--         _4 = Len(_1);
-+         _4 = const 2_usize;
-          _5 = Lt(copy _3, copy _4);
-          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
-          _2 = copy _1[_3];
-          StorageDead(_3);
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 1_usize;
--         _8 = Len(_1);
-+         _8 = const 2_usize;
-          _9 = Lt(copy _7, copy _8);
-          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
-          _6 = copy _1[_7];
-          StorageDead(_7);
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = copy _2;
-          StorageLive(_12);
-          _12 = copy _2;
-          _10 = Mul(move _11, move _12);
-          StorageDead(_12);
-          StorageDead(_11);
-          StorageLive(_13);
-          StorageLive(_14);
-          _14 = copy _6;
-          StorageLive(_15);
-          _15 = copy _6;
-          _13 = Mul(move _14, move _15);
-          StorageDead(_15);
-          StorageDead(_14);
-          _0 = Add(move _10, move _13);
-          StorageDead(_13);
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs
deleted file mode 100644
index 91f43f75689..00000000000
--- a/tests/mir-opt/instsimplify/combine_array_len.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
-//@ test-mir-pass: InstSimplify-after-simplifycfg
-
-// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff
-fn norm2(x: [f32; 2]) -> f32 {
-    // CHECK-LABEL: fn norm2(
-    // CHECK-NOT: Len(
-    let a = x[0];
-    let b = x[1];
-    a * a + b * b
-}
-
-fn main() {
-    assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0);
-}
diff --git a/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir
index 314cf8b367f..7593b795432 100644
--- a/tests/mir-opt/issue_72181.foo.built.after.mir
+++ b/tests/mir-opt/issue_72181.foo.built.after.mir
@@ -4,15 +4,14 @@ fn foo(_1: [(Never, u32); 1]) -> u32 {
     debug xs => _1;
     let mut _0: u32;
     let _2: usize;
-    let mut _3: usize;
-    let mut _4: bool;
+    let mut _3: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = const 0_usize;
-        _3 = Len(_1);
-        _4 = Lt(copy _2, copy _3);
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind: bb2];
+        FakeRead(ForIndex, _1);
+        _3 = Lt(copy _2, const 1_usize);
+        assert(move _3, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _2) -> [success: bb1, unwind: bb2];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index aade84a6dd2..9f3803f5407 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -7,8 +7,7 @@ fn main() -> () {
     let mut _4: Foo;
     let mut _5: u64;
     let _6: usize;
-    let mut _7: usize;
-    let mut _8: bool;
+    let mut _7: bool;
     scope 1 {
         let _2: [Foo; 2];
         scope 2 {
@@ -38,9 +37,9 @@ fn main() -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = const 0_usize;
-        _7 = Len(_2);
-        _8 = Lt(copy _6, copy _7);
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb3, unwind: bb5];
+        FakeRead(ForIndex, _2);
+        _7 = Lt(copy _6, const 2_usize);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb3, unwind: bb5];
     }
 
     bb2: {
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
index 50fdf08375a..bf65b5b4a8c 100644
--- a/tests/mir-opt/issue_91633.foo.built.after.mir
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -6,8 +6,9 @@ fn foo(_1: Box<[T]>) -> T {
     let _2: T;
     let mut _3: &T;
     let _4: usize;
-    let mut _5: usize;
-    let mut _6: bool;
+    let mut _5: *const [T];
+    let mut _6: usize;
+    let mut _7: bool;
     scope 1 {
         debug f => _2;
     }
@@ -17,9 +18,10 @@ fn foo(_1: Box<[T]>) -> T {
         StorageLive(_3);
         StorageLive(_4);
         _4 = const 0_usize;
-        _5 = Len((*_1));
-        _6 = Lt(copy _4, copy _5);
-        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb5];
+        _5 = &raw const (*_1);
+        _6 = PtrMetadata(move _5);
+        _7 = Lt(copy _4, copy _6);
+        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir
index 5b41b376719..d2fc438d3e8 100644
--- a/tests/mir-opt/issue_91633.fun.built.after.mir
+++ b/tests/mir-opt/issue_91633.fun.built.after.mir
@@ -15,7 +15,7 @@ fn fun(_1: &[T]) -> &T {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const 0_usize;
-        _4 = Len((*_1));
+        _4 = PtrMetadata(copy _1);
         _5 = Lt(copy _3, copy _4);
         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2];
     }
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
index f052c8f63dc..98c5e868046 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
@@ -11,16 +11,14 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
+      let mut _9: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,16 +38,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -61,8 +56,7 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
index 3299e300431..72c73137869 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
@@ -11,16 +11,14 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
+      let mut _9: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,16 +38,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -61,8 +56,7 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
index 329eb80b3c4..9ffaf44c02b 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
@@ -11,19 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
+      let mut _9: bool;
+      let _10: usize;
+      let mut _11: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -43,16 +40,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -64,23 +58,20 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_11);
-          _11 = const 0_usize;
--         _12 = Len((*_2));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
-+         _12 = const N;
-+         _13 = Lt(const 0_usize, const N);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
+          StorageLive(_10);
+          _10 = const 0_usize;
+-         _11 = Lt(copy _10, const N);
+-         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind unreachable];
++         _11 = Lt(const 0_usize, const N);
++         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
       }
   
       bb5: {
--         (*_2)[_11] = const 42_u8;
+-         (*_2)[_10] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_11);
+          StorageDead(_10);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
index ab007e133ec..08008e46335 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
@@ -11,19 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: usize;
-      let mut _10: bool;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
+      let mut _9: bool;
+      let _10: usize;
+      let mut _11: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
--         StorageLive(_5);
-+         nop;
+          StorageLive(_5);
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -43,16 +40,13 @@
       }
   
       bb2: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Len((*_2));
--         _10 = Lt(copy _8, copy _9);
--         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
-+         _9 = const N;
-+         _10 = copy _3;
+-         _9 = Lt(copy _8, const N);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
++         _9 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -64,23 +58,20 @@
       }
   
       bb4: {
--         StorageDead(_5);
-+         nop;
+          StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_11);
-          _11 = const 0_usize;
--         _12 = Len((*_2));
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
-+         _12 = const N;
-+         _13 = Lt(const 0_usize, const N);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
+          StorageLive(_10);
+          _10 = const 0_usize;
+-         _11 = Lt(copy _10, const N);
+-         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind continue];
++         _11 = Lt(const 0_usize, const N);
++         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
       }
   
       bb5: {
--         (*_2)[_11] = const 42_u8;
+-         (*_2)[_10] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_11);
+          StorageDead(_10);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
index 20001f1248e..4b39e18d16c 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = Len((*_2));
+          _8 = PtrMetadata(copy _2);
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind unreachable];
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
index ca8f92df5de..f0d4afa21ae 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = Len((*_2));
+          _8 = PtrMetadata(copy _2);
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind continue];
       }
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 7294302609a..42b38803336 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -27,20 +27,19 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x00000003): usize)];
     let _3: usize;
-    let mut _4: usize;
-    let mut _5: bool;
-    let mut _7: bool;
-    let _8: bool;
-    let mut _9: usize;
-    let _10: bool;
+    let mut _4: bool;
+    let mut _6: bool;
+    let _7: bool;
+    let mut _8: usize;
+    let _9: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _6: &'?4 usize;
+            let _5: &'?4 usize;
             scope 3 {
-                debug q => _6;
+                debug q => _5;
             }
         }
     }
@@ -52,50 +51,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x00000000): usize);
-        _4 = Len(_1);
-        _5 = Lt(copy _3, copy _4);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
+        FakeRead(ForIndex, _1);
+        _4 = Lt(copy _3, const ValTree(Leaf(0x00000003): usize));
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
+        StorageLive(_5);
+        _5 = copy _2;
+        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = copy _2;
-        FakeRead(ForLet(None), _6);
-        StorageLive(_7);
-        _7 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _7) -> [0: bb4, otherwise: bb2];
+        _6 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _6) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
+        StorageLive(_7);
         StorageLive(_8);
-        StorageLive(_9);
-        _9 = copy (*_6);
-        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
+        _8 = copy (*_5);
+        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
-        StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_10);
-        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_9);
+        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_10);
+        StorageDead(_9);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
-        StorageDead(_7);
         StorageDead(_6);
+        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 85b89a013c4..15395fd470e 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -27,20 +27,19 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)];
     let _3: usize;
-    let mut _4: usize;
-    let mut _5: bool;
-    let mut _7: bool;
-    let _8: bool;
-    let mut _9: usize;
-    let _10: bool;
+    let mut _4: bool;
+    let mut _6: bool;
+    let _7: bool;
+    let mut _8: usize;
+    let _9: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _6: &'?4 usize;
+            let _5: &'?4 usize;
             scope 3 {
-                debug q => _6;
+                debug q => _5;
             }
         }
     }
@@ -52,50 +51,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x0000000000000000): usize);
-        _4 = Len(_1);
-        _5 = Lt(copy _3, copy _4);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
+        FakeRead(ForIndex, _1);
+        _4 = Lt(copy _3, const ValTree(Leaf(0x0000000000000003): usize));
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ValTree(Leaf(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
+        StorageLive(_5);
+        _5 = copy _2;
+        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = copy _2;
-        FakeRead(ForLet(None), _6);
-        StorageLive(_7);
-        _7 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _7) -> [0: bb4, otherwise: bb2];
+        _6 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _6) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
+        StorageLive(_7);
         StorageLive(_8);
-        StorageLive(_9);
-        _9 = copy (*_6);
-        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
+        _8 = copy (*_5);
+        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
-        StorageDead(_9);
         StorageDead(_8);
+        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_10);
-        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_9);
+        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_10);
+        StorageDead(_9);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
-        StorageDead(_7);
         StorageDead(_6);
+        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
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 6575610727b..5b39e45806e 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
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 1a4ed5767fe..ea2742a6471 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
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 6575610727b..5b39e45806e 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
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 1a4ed5767fe..ea2742a6471 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
@@ -7,17 +7,16 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: u32;
+      let mut _6: bool;
+      let mut _8: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -38,10 +37,9 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
--         _7 = Lt(copy _5, copy _6);
--         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
-+         _7 = const true;
+-         _6 = Lt(copy _5, const 6_usize);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -50,13 +48,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
+          StorageLive(_7);
           StorageLive(_8);
-          StorageLive(_9);
-          _9 = const 42_u32;
--         _8 = copy _9;
-+         _8 = const 42_u32;
-          StorageDead(_9);
+          _8 = const 42_u32;
+-         _7 = copy _8;
++         _7 = const 42_u32;
           StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 e2420a341e0..f7fe08831b9 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
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 a2fb3b979e6..6e36386bea6 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
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 e2420a341e0..f7fe08831b9 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
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
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 a2fb3b979e6..6e36386bea6 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
@@ -7,19 +7,18 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: usize;
-      let mut _7: bool;
-      let mut _9: Point;
+      let mut _6: bool;
+      let mut _8: Point;
++     let mut _9: u32;
 +     let mut _10: u32;
-+     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _8: u32;
+              let _7: u32;
               scope 3 {
-                  debug z => _8;
+                  debug z => _7;
               }
           }
       }
@@ -37,31 +36,30 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = const 6_usize;
-          _7 = Lt(copy _5, copy _6);
-          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
+          _6 = Lt(copy _5, const 6_usize);
+          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_8);
--         StorageLive(_9);
--         _9 = Point { x: const 12_u32, y: const 42_u32 };
--         _8 = copy (_9.1: u32);
--         StorageDead(_9);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = Point { x: const 12_u32, y: const 42_u32 };
+-         _7 = copy (_8.1: u32);
+-         StorageDead(_8);
++         StorageLive(_9);
 +         StorageLive(_10);
-+         StorageLive(_11);
 +         nop;
-+         _10 = const 12_u32;
-+         _11 = const 42_u32;
++         _9 = const 12_u32;
++         _10 = const 42_u32;
 +         nop;
-+         _8 = copy _11;
++         _7 = copy _10;
++         StorageDead(_9);
 +         StorageDead(_10);
-+         StorageDead(_11);
 +         nop;
-          StorageDead(_8);
+          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs
index 574062d6c35..5dac535d195 100644
--- a/tests/mir-opt/pre-codegen/slice_index.rs
+++ b/tests/mir-opt/pre-codegen/slice_index.rs
@@ -9,7 +9,7 @@ use std::ops::Range;
 // EMIT_MIR slice_index.slice_index_usize.PreCodegen.after.mir
 pub fn slice_index_usize(slice: &[u32], index: usize) -> u32 {
     // CHECK-LABEL: slice_index_usize
-    // CHECK: [[LEN:_[0-9]+]] = Len((*_1))
+    // CHECK: [[LEN:_[0-9]+]] = PtrMetadata(copy _1)
     // CHECK: Lt(copy _2, copy [[LEN]])
     // CHECK-NOT: precondition_check
     // CHECK: _0 = copy (*_1)[_2];
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
index cc1034229fc..81e60b8ec2c 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = Len((*_1));
+        _3 = PtrMetadata(copy _1);
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind unreachable];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
index 358226fb529..c0fdc839608 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = Len((*_1));
+        _3 = PtrMetadata(copy _1);
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind continue];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index ecac03ad0f9..151783969dd 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -7,20 +7,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: usize;
-    let mut _12: bool;
-    let mut _14: &impl Fn(usize, &T);
-    let mut _15: (usize, &T);
-    let _16: ();
+    let mut _11: bool;
+    let mut _13: &impl Fn(usize, &T);
+    let mut _14: (usize, &T);
+    let _15: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _13: &T;
+            let _12: &T;
             scope 3 {
-                debug x => _13;
+                debug x => _12;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -82,23 +81,22 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Len((*_1));
-        _12 = Lt(copy _10, copy _11);
-        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind unreachable];
+        _11 = Lt(copy _10, copy _3);
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable];
     }
 
     bb6: {
-        _13 = &(*_1)[_10];
+        _12 = &(*_1)[_10];
+        StorageLive(_13);
+        _13 = &_2;
         StorageLive(_14);
-        _14 = &_2;
-        StorageLive(_15);
-        _15 = (copy _10, copy _13);
-        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind unreachable];
+        _14 = (copy _10, copy _12);
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
     }
 
     bb7: {
-        StorageDead(_15);
         StorageDead(_14);
+        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 1032473b9b2..006329dc20d 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -7,20 +7,19 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: usize;
-    let mut _12: bool;
-    let mut _14: &impl Fn(usize, &T);
-    let mut _15: (usize, &T);
-    let _16: ();
+    let mut _11: bool;
+    let mut _13: &impl Fn(usize, &T);
+    let mut _14: (usize, &T);
+    let _15: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _13: &T;
+            let _12: &T;
             scope 3 {
-                debug x => _13;
+                debug x => _12;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -82,23 +81,22 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Len((*_1));
-        _12 = Lt(copy _10, copy _11);
-        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind: bb8];
+        _11 = Lt(copy _10, copy _3);
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8];
     }
 
     bb6: {
-        _13 = &(*_1)[_10];
+        _12 = &(*_1)[_10];
+        StorageLive(_13);
+        _13 = &_2;
         StorageLive(_14);
-        _14 = &_2;
-        StorageLive(_15);
-        _15 = (copy _10, copy _13);
-        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind: bb8];
+        _14 = (copy _10, copy _12);
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
     }
 
     bb7: {
-        StorageDead(_15);
         StorageDead(_14);
+        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.rs b/tests/ui/borrowck/borrowck-describe-lvalue.rs
index cdcff69d6e5..f3a4b382fa8 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.rs
@@ -231,7 +231,6 @@ fn main() {
         let x = &mut v;
         v[0].y;
         //~^ ERROR cannot use `v[_].y` because it was mutably borrowed
-        //~| ERROR cannot use `*v` because it was mutably borrowed
         drop(x);
     }
     // Field of constant index
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
index 11f2e42d42b..666a21808d8 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:254:13
+  --> $DIR/borrowck-describe-lvalue.rs:253:13
    |
 LL |             let y = &mut x;
    |                     ------ first mutable borrow occurs here
@@ -9,7 +9,7 @@ LL |             *y = 1;
    |             ------ first borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:264:20
+  --> $DIR/borrowck-describe-lvalue.rs:263:20
    |
 LL |                    let y = &mut x;
    |                            ------ first mutable borrow occurs here
@@ -19,7 +19,7 @@ LL |                    *y = 1;
    |                    ------ first borrow later used here
 
 error: captured variable cannot escape `FnMut` closure body
-  --> $DIR/borrowck-describe-lvalue.rs:262:16
+  --> $DIR/borrowck-describe-lvalue.rs:261:16
    |
 LL |           let mut x = 0;
    |               ----- variable defined here
@@ -300,17 +300,6 @@ LL |             S  { x: F { y: ref x0, .. }, .. } =>
 LL |         drop(x);
    |              - mutable borrow later used here
 
-error[E0503]: cannot use `*v` because it was mutably borrowed
-  --> $DIR/borrowck-describe-lvalue.rs:232:9
-   |
-LL |         let x = &mut v;
-   |                 ------ `v` is borrowed here
-LL |         v[0].y;
-   |         ^^^^ use of borrowed `v`
-...
-LL |         drop(x);
-   |              - borrow later used here
-
 error[E0503]: cannot use `v[_].y` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:232:9
    |
@@ -318,12 +307,12 @@ LL |         let x = &mut v;
    |                 ------ `v` is borrowed here
 LL |         v[0].y;
    |         ^^^^^^ use of borrowed `v`
-...
+LL |
 LL |         drop(x);
    |              - borrow later used here
 
 error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-describe-lvalue.rs:243:24
+  --> $DIR/borrowck-describe-lvalue.rs:242:24
    |
 LL |         let x = &mut v;
    |                 ------ mutable borrow occurs here
@@ -357,7 +346,7 @@ LL |             drop(x);
    |                  - mutable borrow later used here
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/borrowck-describe-lvalue.rs:274:22
+  --> $DIR/borrowck-describe-lvalue.rs:273:22
    |
 LL |                 drop(x);
    |                      - value moved here
@@ -366,7 +355,7 @@ LL |                 drop(x);
    |
    = note: move occurs because `x` has type `Vec<i32>`, which does not implement the `Copy` trait
 
-error: aborting due to 32 previous errors
+error: aborting due to 31 previous errors
 
 Some errors have detailed explanations: E0382, E0499, E0502, E0503.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
index 3abc81e191e..2d22c9a856f 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -12,8 +12,7 @@ fn arrays_1() {
     // c will capture `arr` completely, therefore another index into the
     // array can't be modified here
     arr[1] += 10;
-    //~^ ERROR: cannot use `arr` because it was mutably borrowed
-    //~| ERROR: cannot use `arr[_]` because it was mutably borrowed
+    //~^ ERROR: cannot use `arr[_]` because it was mutably borrowed
     c();
 }
 
@@ -55,8 +54,7 @@ fn arrays_4() {
     // c will capture `arr` completely, therefore we cannot borrow another index
     // into the array.
     println!("{}", arr[3]);
-    //~^ ERROR: cannot use `arr` because it was mutably borrowed
-    //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
+    //~^ ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
 
     c();
 }
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index 9e5200ef34b..97ecdfab820 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -1,17 +1,3 @@
-error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:14:5
-   |
-LL |     let mut c = || {
-   |                 -- `arr` is borrowed here
-LL |         arr[0] += 10;
-   |         --- borrow occurs due to use of `arr` in closure
-...
-LL |     arr[1] += 10;
-   |     ^^^^^^ use of borrowed `arr`
-...
-LL |     c();
-   |     - borrow later used here
-
 error[E0503]: cannot use `arr[_]` because it was mutably borrowed
   --> $DIR/arrays.rs:14:5
    |
@@ -22,12 +8,12 @@ LL |         arr[0] += 10;
 ...
 LL |     arr[1] += 10;
    |     ^^^^^^^^^^^^ use of borrowed `arr`
-...
+LL |
 LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:29:5
+  --> $DIR/arrays.rs:28:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -41,7 +27,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:43:5
+  --> $DIR/arrays.rs:42:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -54,22 +40,8 @@ LL |
 LL |     c();
    |     - borrow later used here
 
-error[E0503]: cannot use `arr` because it was mutably borrowed
-  --> $DIR/arrays.rs:57:20
-   |
-LL |     let mut c = || {
-   |                 -- `arr` is borrowed here
-LL |         arr[1] += 10;
-   |         --- borrow occurs due to use of `arr` in closure
-...
-LL |     println!("{}", arr[3]);
-   |                    ^^^^^^ use of borrowed `arr`
-...
-LL |     c();
-   |     - borrow later used here
-
 error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:57:20
+  --> $DIR/arrays.rs:56:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -85,7 +57,7 @@ LL |     c();
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:73:24
+  --> $DIR/arrays.rs:71:24
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -98,7 +70,7 @@ LL |     println!("{:#?}", &arr[3..2]);
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0502, E0503, E0506.
 For more information about an error, try `rustc --explain E0502`.
diff --git a/tests/ui/consts/issue-65348.rs b/tests/ui/consts/issue-65348.rs
index 1443fcbe1c1..0d12da3926c 100644
--- a/tests/ui/consts/issue-65348.rs
+++ b/tests/ui/consts/issue-65348.rs
@@ -9,15 +9,17 @@ impl<T> Generic<T> {
 }
 
 pub const fn array<T>() -> &'static T {
-    #[allow(unconditional_panic)]
+    #[expect(unconditional_panic)]
     &Generic::<T>::ARRAY[0]
 }
 
 pub const fn newtype_array<T>() -> &'static T {
+    #[expect(unconditional_panic)]
     &Generic::<T>::NEWTYPE_ARRAY.0[0]
 }
 
 pub const fn array_field<T>() -> &'static T {
+    #[expect(unconditional_panic)]
     &(Generic::<T>::ARRAY_FIELD.0).1[0]
 }
 
diff --git a/tests/ui/stable-mir-print/operands.stdout b/tests/ui/stable-mir-print/operands.stdout
index 3c27878b3cf..c3b1151ae24 100644
--- a/tests/ui/stable-mir-print/operands.stdout
+++ b/tests/ui/stable-mir-print/operands.stdout
@@ -5,187 +5,183 @@ fn operands(_1: u8) -> () {
     let  _2: [u8; 10];
     let  _3: u8;
     let  _4: usize;
-    let mut _5: usize;
-    let mut _6: bool;
-    let  _7: u8;
-    let  _8: usize;
-    let mut _9: (usize, bool);
-    let mut _10: usize;
-    let mut _11: bool;
-    let mut _12: (&u8, &u8);
-    let mut _13: &u8;
-    let mut _14: &u8;
-    let  _15: &u8;
-    let  _16: &u8;
-    let mut _17: bool;
-    let mut _18: u8;
-    let mut _19: u8;
-    let  _20: core::panicking::AssertKind;
-    let  _21: !;
-    let mut _22: Option<Arguments<'_>>;
-    let  _23: &u8;
-    let  _24: u8;
-    let mut _25: (&u8, &u8);
-    let mut _26: &u8;
-    let mut _27: &u8;
-    let  _28: &u8;
-    let  _29: &u8;
-    let mut _30: bool;
-    let mut _31: u8;
-    let mut _32: u8;
-    let  _33: core::panicking::AssertKind;
-    let  _34: !;
-    let mut _35: Option<Arguments<'_>>;
-    let  _36: (u8, u8);
-    let  _37: u8;
-    let  _38: u8;
-    let mut _39: (&u8, &u8);
-    let mut _40: &u8;
-    let mut _41: &u8;
-    let  _42: &u8;
-    let  _43: &u8;
-    let mut _44: bool;
-    let mut _45: u8;
-    let mut _46: u8;
-    let  _47: core::panicking::AssertKind;
-    let  _48: !;
-    let mut _49: Option<Arguments<'_>>;
-    let  _50: usize;
-    let mut _51: &[u8];
-    let mut _52: &[u8; 10];
-    let  _53: usize;
-    let  _54: &usize;
-    let mut _55: (&usize, &usize);
-    let mut _56: &usize;
-    let mut _57: &usize;
-    let  _58: &usize;
-    let  _59: &usize;
-    let mut _60: bool;
-    let mut _61: usize;
-    let mut _62: usize;
-    let  _63: core::panicking::AssertKind;
-    let  _64: !;
-    let mut _65: Option<Arguments<'_>>;
+    let mut _5: bool;
+    let  _6: u8;
+    let  _7: usize;
+    let mut _8: (usize, bool);
+    let mut _9: bool;
+    let mut _10: (&u8, &u8);
+    let mut _11: &u8;
+    let mut _12: &u8;
+    let  _13: &u8;
+    let  _14: &u8;
+    let mut _15: bool;
+    let mut _16: u8;
+    let mut _17: u8;
+    let  _18: core::panicking::AssertKind;
+    let  _19: !;
+    let mut _20: Option<Arguments<'_>>;
+    let  _21: &u8;
+    let  _22: u8;
+    let mut _23: (&u8, &u8);
+    let mut _24: &u8;
+    let mut _25: &u8;
+    let  _26: &u8;
+    let  _27: &u8;
+    let mut _28: bool;
+    let mut _29: u8;
+    let mut _30: u8;
+    let  _31: core::panicking::AssertKind;
+    let  _32: !;
+    let mut _33: Option<Arguments<'_>>;
+    let  _34: (u8, u8);
+    let  _35: u8;
+    let  _36: u8;
+    let mut _37: (&u8, &u8);
+    let mut _38: &u8;
+    let mut _39: &u8;
+    let  _40: &u8;
+    let  _41: &u8;
+    let mut _42: bool;
+    let mut _43: u8;
+    let mut _44: u8;
+    let  _45: core::panicking::AssertKind;
+    let  _46: !;
+    let mut _47: Option<Arguments<'_>>;
+    let  _48: usize;
+    let mut _49: &[u8];
+    let mut _50: &[u8; 10];
+    let  _51: usize;
+    let  _52: &usize;
+    let mut _53: (&usize, &usize);
+    let mut _54: &usize;
+    let mut _55: &usize;
+    let  _56: &usize;
+    let  _57: &usize;
+    let mut _58: bool;
+    let mut _59: usize;
+    let mut _60: usize;
+    let  _61: core::panicking::AssertKind;
+    let  _62: !;
+    let mut _63: Option<Arguments<'_>>;
     debug val => _1;
     debug array => _2;
     debug first => _3;
-    debug last => _7;
-    debug left_val => _15;
-    debug right_val => _16;
-    debug kind => _20;
-    debug reference => _23;
-    debug dereferenced => _24;
-    debug left_val => _28;
-    debug right_val => _29;
-    debug kind => _33;
-    debug tuple => _36;
-    debug first_again => _37;
-    debug first_again_again => _38;
-    debug left_val => _42;
-    debug right_val => _43;
-    debug kind => _47;
-    debug length => _50;
-    debug size_of => _53;
-    debug left_val => _58;
-    debug right_val => _59;
-    debug kind => _63;
+    debug last => _6;
+    debug left_val => _13;
+    debug right_val => _14;
+    debug kind => _18;
+    debug reference => _21;
+    debug dereferenced => _22;
+    debug left_val => _26;
+    debug right_val => _27;
+    debug kind => _31;
+    debug tuple => _34;
+    debug first_again => _35;
+    debug first_again_again => _36;
+    debug left_val => _40;
+    debug right_val => _41;
+    debug kind => _45;
+    debug length => _48;
+    debug size_of => _51;
+    debug left_val => _56;
+    debug right_val => _57;
+    debug kind => _61;
     bb0: {
         _2 = [_1; 10];
         _4 = 0_usize;
-        _5 = 10_usize;
-        _6 = Lt(_4, _5);
-        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
+        _5 = Lt(_4, 10_usize);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", 10_usize, _4) -> [success: bb1, unwind unreachable];
     }
     bb1: {
         _3 = _2[_4];
-        _9 = CheckedSub(10_usize, 1_usize);
-        assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
+        _8 = CheckedSub(10_usize, 1_usize);
+        assert(!move (_8.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
     }
     bb2: {
-        _8 = move (_9.0: usize);
-        _10 = 10_usize;
-        _11 = Lt(_8, _10);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _8) -> [success: bb3, unwind unreachable];
+        _7 = move (_8.0: usize);
+        _9 = Lt(_7, 10_usize);
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", 10_usize, _7) -> [success: bb3, unwind unreachable];
     }
     bb3: {
-        _7 = _2[_8];
-        _13 = &_3;
-        _14 = &_7;
-        _12 = (move _13, move _14);
-        _15 = (_12.0: &u8);
-        _16 = (_12.1: &u8);
-        _18 = (*_15);
-        _19 = (*_16);
-        _17 = Eq(move _18, move _19);
-        switchInt(move _17) -> [0: bb5, otherwise: bb4];
+        _6 = _2[_7];
+        _11 = &_3;
+        _12 = &_6;
+        _10 = (move _11, move _12);
+        _13 = (_10.0: &u8);
+        _14 = (_10.1: &u8);
+        _16 = (*_13);
+        _17 = (*_14);
+        _15 = Eq(move _16, move _17);
+        switchInt(move _15) -> [0: bb5, otherwise: bb4];
     }
     bb4: {
-        _23 = &_3;
-        _24 = (*_23);
-        _26 = &_24;
-        _27 = &_3;
-        _25 = (move _26, move _27);
-        _28 = (_25.0: &u8);
-        _29 = (_25.1: &u8);
-        _31 = (*_28);
-        _32 = (*_29);
-        _30 = Eq(move _31, move _32);
-        switchInt(move _30) -> [0: bb7, otherwise: bb6];
+        _21 = &_3;
+        _22 = (*_21);
+        _24 = &_22;
+        _25 = &_3;
+        _23 = (move _24, move _25);
+        _26 = (_23.0: &u8);
+        _27 = (_23.1: &u8);
+        _29 = (*_26);
+        _30 = (*_27);
+        _28 = Eq(move _29, move _30);
+        switchInt(move _28) -> [0: bb7, otherwise: bb6];
     }
     bb5: {
-        _20 = core::panicking::AssertKind::Eq;
-        _22 = std::option::Option::None;
-        _21 = core::panicking::assert_failed::<u8, u8>(move _20, _15, _16, move _22) -> unwind unreachable;
+        _18 = core::panicking::AssertKind::Eq;
+        _20 = std::option::Option::None;
+        _19 = core::panicking::assert_failed::<u8, u8>(move _18, _13, _14, move _20) -> unwind unreachable;
     }
     bb6: {
-        _36 = (_3, _7);
-        _37 = (_36.0: u8);
-        _38 = (_36.0: u8);
-        _40 = &_37;
-        _41 = &_38;
-        _39 = (move _40, move _41);
-        _42 = (_39.0: &u8);
-        _43 = (_39.1: &u8);
-        _45 = (*_42);
-        _46 = (*_43);
-        _44 = Eq(move _45, move _46);
-        switchInt(move _44) -> [0: bb9, otherwise: bb8];
+        _34 = (_3, _6);
+        _35 = (_34.0: u8);
+        _36 = (_34.0: u8);
+        _38 = &_35;
+        _39 = &_36;
+        _37 = (move _38, move _39);
+        _40 = (_37.0: &u8);
+        _41 = (_37.1: &u8);
+        _43 = (*_40);
+        _44 = (*_41);
+        _42 = Eq(move _43, move _44);
+        switchInt(move _42) -> [0: bb9, otherwise: bb8];
     }
     bb7: {
-        _33 = core::panicking::AssertKind::Eq;
-        _35 = std::option::Option::None;
-        _34 = core::panicking::assert_failed::<u8, u8>(move _33, _28, _29, move _35) -> unwind unreachable;
+        _31 = core::panicking::AssertKind::Eq;
+        _33 = std::option::Option::None;
+        _32 = core::panicking::assert_failed::<u8, u8>(move _31, _26, _27, move _33) -> unwind unreachable;
     }
     bb8: {
-        _52 = &_2;
-        _51 = move _52 as &[u8];
-        _50 = PtrMetadata(move _51);
-        _54 = &_50;
-        _53 = std::mem::size_of_val::<usize>(_54) -> [return: bb10, unwind unreachable];
+        _50 = &_2;
+        _49 = move _50 as &[u8];
+        _48 = PtrMetadata(move _49);
+        _52 = &_48;
+        _51 = std::mem::size_of_val::<usize>(_52) -> [return: bb10, unwind unreachable];
     }
     bb9: {
-        _47 = core::panicking::AssertKind::Eq;
-        _49 = std::option::Option::None;
-        _48 = core::panicking::assert_failed::<u8, u8>(move _47, _42, _43, move _49) -> unwind unreachable;
+        _45 = core::panicking::AssertKind::Eq;
+        _47 = std::option::Option::None;
+        _46 = core::panicking::assert_failed::<u8, u8>(move _45, _40, _41, move _47) -> unwind unreachable;
     }
     bb10: {
-        _56 = &_50;
-        _57 = &_53;
-        _55 = (move _56, move _57);
-        _58 = (_55.0: &usize);
-        _59 = (_55.1: &usize);
-        _61 = (*_58);
-        _62 = (*_59);
-        _60 = Eq(move _61, move _62);
-        switchInt(move _60) -> [0: bb12, otherwise: bb11];
+        _54 = &_48;
+        _55 = &_51;
+        _53 = (move _54, move _55);
+        _56 = (_53.0: &usize);
+        _57 = (_53.1: &usize);
+        _59 = (*_56);
+        _60 = (*_57);
+        _58 = Eq(move _59, move _60);
+        switchInt(move _58) -> [0: bb12, otherwise: bb11];
     }
     bb11: {
         return;
     }
     bb12: {
-        _63 = core::panicking::AssertKind::Eq;
-        _65 = std::option::Option::None;
-        _64 = core::panicking::assert_failed::<usize, usize>(move _63, _58, _59, move _65) -> unwind unreachable;
+        _61 = core::panicking::AssertKind::Eq;
+        _63 = std::option::Option::None;
+        _62 = core::panicking::assert_failed::<usize, usize>(move _61, _56, _57, move _63) -> unwind unreachable;
     }
 }
 fn operands::{constant#0}() -> usize {