summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-02-06 20:56:48 +0000
committerbors <bors@rust-lang.org>2025-02-06 20:56:48 +0000
commit38213856a8a3a6d49a234e0d95a722a4f28a2b18 (patch)
treeee486aab46d9b430698ffcc3d2e71fe1ce83bf5b
parent0277061b9a4096437b9b35f471c915e1cbe3128f (diff)
parentbf24cade3ef2aae66a5047f762d66b70d2b4b92f (diff)
downloadrust-38213856a8a3a6d49a234e0d95a722a4f28a2b18.tar.gz
rust-38213856a8a3a6d49a234e0d95a722a4f28a2b18.zip
Auto merge of #136650 - cuviper:beta-next, r=cuviper
[beta] backports

- Ensure that we don't try to access fields on a non-struct pattern type #135222
- Do not include GCC source code in source tarballs #135658
- Temporarily bring back `Rvalue::Len` #135709
- Add a couple of missing `ensure_sufficient_stacks` #136352
- Enable kernel sanitizers for aarch64-unknown-none-softfloat #135905

r? cuviper
-rw-r--r--compiler/rustc_borrowck/src/lib.rs10
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs3
-rw-r--r--compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs9
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs29
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs28
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs21
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs3
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs1
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs1
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs10
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs1
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs8
-rw-r--r--compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs1
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_place.rs110
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs7
-rw-r--r--compiler/rustc_mir_build/src/check_tail_calls.rs13
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs12
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs51
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs13
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs15
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs4
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs16
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs1
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs4
-rw-r--r--library/core/src/intrinsics/mir.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs13
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-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/custom/arrays.arrays.built.after.mir14
-rw-r--r--tests/mir-opt/building/custom/arrays.rs22
-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.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff13
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff13
-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/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff4
-rw-r--r--tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff4
-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_76432.test.SimplifyComparisonIntegral.panic-abort.diff32
-rw-r--r--tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff32
-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/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff9
-rw-r--r--tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs30
-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/const-generics/issues/index_array_bad_type.rs15
-rw-r--r--tests/ui/const-generics/issues/index_array_bad_type.stderr8
-rw-r--r--tests/ui/consts/issue-65348.rs4
-rw-r--r--tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs10
-rw-r--r--tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr34
-rw-r--r--tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs9
-rw-r--r--tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr14
-rw-r--r--tests/ui/stable-mir-print/operands.stdout294
145 files changed, 2058 insertions, 1554 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index e7aa827e680..38b1d391be7 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -828,6 +828,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write};
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum ArtificialField {
+    ArrayLength,
     FakeBorrow,
 }
 
@@ -1345,11 +1346,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 );
             }
 
-            &Rvalue::Discriminant(place) => {
+            &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
+                let af = match *rvalue {
+                    Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+                    Rvalue::Discriminant(..) => None,
+                    _ => unreachable!(),
+                };
                 self.access_place(
                     location,
                     (place, span),
-                    (Shallow(None), Read(ReadKind::Copy)),
+                    (Shallow(af), Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
                     state,
                 );
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 560b8c0349a..679e111caa9 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -203,7 +203,8 @@ fn place_components_conflict<'tcx>(
             let base_ty = base.ty(body, tcx).ty;
 
             match (elem, base_ty.kind(), access) {
-                (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
+                (_, _, Shallow(Some(ArtificialField::ArrayLength)))
+                | (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
                     // The array length is like additional fields on the
                     // type; it does not overlap any existing data there.
                     // Furthermore, if cannot actually be a prefix of any
diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
index bb6d593d0d8..bb73bc9fcbd 100644
--- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
@@ -298,11 +298,16 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
                 self.consume_operand(location, op);
             }
 
-            &Rvalue::Discriminant(place) => {
+            &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
+                let af = match rvalue {
+                    Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+                    Rvalue::Discriminant(..) => None,
+                    _ => unreachable!(),
+                };
                 self.access_place(
                     location,
                     place,
-                    (Shallow(None), Read(ReadKind::Copy)),
+                    (Shallow(af), Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
                 );
             }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 10fb8a399a2..084f122a210 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2221,6 +2221,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
             Rvalue::RawPtr(..)
             | Rvalue::ThreadLocalRef(..)
+            | Rvalue::Len(..)
             | Rvalue::Discriminant(..)
             | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {}
         }
@@ -2236,6 +2237,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::Repeat(..)
             | Rvalue::Ref(..)
             | Rvalue::RawPtr(..)
+            | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::BinaryOp(..)
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 956a024fa4d..34066eb83fc 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -828,6 +828,12 @@ fn codegen_stmt<'tcx>(
                         fx.bcx.ins().nop();
                     }
                 }
+                Rvalue::Len(place) => {
+                    let place = codegen_place(fx, place);
+                    let usize_layout = fx.layout_of(fx.tcx.types.usize);
+                    let len = codegen_array_len(fx, place);
+                    lval.write_cvalue(fx, CValue::by_val(len, usize_layout));
+                }
                 Rvalue::ShallowInitBox(ref operand, content_ty) => {
                     let content_ty = fx.monomorphize(content_ty);
                     let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty));
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 3b62148abb7..cf537392234 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -10,9 +10,9 @@ use rustc_session::config::OptLevel;
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
-use super::FunctionCx;
 use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
+use super::{FunctionCx, LocalRef};
 use crate::common::IntPredicate;
 use crate::traits::*;
 use crate::{MemFlags, base};
@@ -593,6 +593,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_place_to_pointer(bx, place, mk_ptr)
             }
 
+            mir::Rvalue::Len(place) => {
+                let size = self.evaluate_array_len(bx, place);
+                OperandRef {
+                    val: OperandValue::Immediate(size),
+                    layout: bx.cx().layout_of(bx.tcx().types.usize),
+                }
+            }
+
             mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs))
                 if let Some(op) = op_with_overflow.overflowing_to_wrapping() =>
             {
@@ -792,6 +800,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
+    fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
+        // ZST are passed as operands and require special handling
+        // because codegen_place() panics if Local is operand.
+        if let Some(index) = place.as_local() {
+            if let LocalRef::Operand(op) = self.locals[index] {
+                if let ty::Array(_, n) = op.layout.ty.kind() {
+                    let n = n
+                        .try_to_target_usize(bx.tcx())
+                        .expect("expected monomorphic const in codegen");
+                    return bx.cx().const_usize(n);
+                }
+            }
+        }
+        // use common size calculation for non zero-sized types
+        let cg_value = self.codegen_place(bx, place.as_ref());
+        cg_value.len(bx.cx())
+    }
+
     /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
     fn codegen_place_to_pointer(
         &mut self,
@@ -1063,6 +1089,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Ref(..) |
             mir::Rvalue::CopyForDeref(..) |
             mir::Rvalue::RawPtr(..) |
+            mir::Rvalue::Len(..) |
             mir::Rvalue::Cast(..) | // (*)
             mir::Rvalue::ShallowInitBox(..) | // (*)
             mir::Rvalue::BinaryOp(..) |
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index e895c44199b..cbc0d5b0596 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -488,7 +488,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             Rvalue::Use(_)
             | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
-            | Rvalue::Discriminant(..) => {}
+            | Rvalue::Discriminant(..)
+            | Rvalue::Len(_) => {}
 
             Rvalue::Aggregate(kind, ..) => {
                 if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref()
@@ -572,27 +573,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
-            Rvalue::UnaryOp(op, operand) => {
+            Rvalue::UnaryOp(_, operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                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:?}",
-                            );
-                        }
-                    }
+                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);
                 }
             }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index b1b7fb406b1..e244b50a4b5 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -230,7 +230,9 @@ where
             Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx))
         }
 
-        Rvalue::Discriminant(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
+        Rvalue::Discriminant(place) | Rvalue::Len(place) => {
+            in_place::<Q, _>(cx, in_local, place.as_ref())
+        }
 
         Rvalue::CopyForDeref(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
 
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 5a6e7ab2bee..79df63a9e84 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -197,6 +197,7 @@ where
             | mir::Rvalue::CopyForDeref(..)
             | mir::Rvalue::ThreadLocalRef(..)
             | mir::Rvalue::Repeat(..)
+            | mir::Rvalue::Len(..)
             | mir::Rvalue::BinaryOp(..)
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 32e77fe1024..b61865be667 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,13 +9,12 @@ 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};
 
 use super::{
     FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
-    Projectable, interp_ok, throw_ub,
+    Projectable, Scalar, interp_ok, throw_ub,
 };
 use crate::util;
 
@@ -81,9 +80,7 @@ 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, stmt.source_info.span)?
-            }
+            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
 
             SetDiscriminant { place, variant_index } => {
                 let dest = self.eval_place(**place)?;
@@ -162,7 +159,6 @@ 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?
@@ -218,6 +214,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_repeat(operand, &dest)?;
             }
 
+            Len(place) => {
+                let src = self.eval_place(place)?;
+                let len = src.len(self)?;
+                self.write_scalar(Scalar::from_target_usize(len, self), &dest)?;
+            }
+
             Ref(_, borrow_kind, place) => {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
@@ -248,13 +250,8 @@ 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
-                    && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
-                {
+                if !place_base_raw {
                     // 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_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 1231ea88569..60e1ff1d049 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -467,9 +467,6 @@ impl<'tcx> Const<'tcx> {
                 let const_val = tcx.valtree_to_const_val((ty, valtree));
                 Self::Val(const_val, ty)
             }
-            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
-                Self::Unevaluated(UnevaluatedConst { def, args, promoted: None }, ty)
-            }
             _ => Self::Ty(ty, c),
         }
     }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 47522f00bb1..2d1a0e36f90 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1068,6 +1068,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                 pretty_print_const(b, fmt, false)?;
                 write!(fmt, "]")
             }
+            Len(ref a) => write!(fmt, "Len({a:?})"),
             Cast(ref kind, ref place, ref ty) => {
                 with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})"))
             }
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index da3fa9e324a..1ce735cec63 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -424,6 +424,7 @@ impl<'tcx> Rvalue<'tcx> {
             | Rvalue::Ref(_, _, _)
             | Rvalue::ThreadLocalRef(_)
             | Rvalue::RawPtr(_, _)
+            | Rvalue::Len(_)
             | Rvalue::Cast(
                 CastKind::IntToInt
                 | CastKind::FloatToInt
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index bbbaffc5a35..0c17a2e0fe5 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1351,6 +1351,16 @@ pub enum Rvalue<'tcx> {
     /// model.
     RawPtr(Mutability, Place<'tcx>),
 
+    /// Yields the length of the place, as a `usize`.
+    ///
+    /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
+    /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
+    /// ill-formed for places of other types.
+    ///
+    /// This cannot be a `UnOp(PtrMetadata, _)` because that expects a value, and we only
+    /// have a place, and `UnOp(PtrMetadata, RawPtr(place))` is not a thing.
+    Len(Place<'tcx>),
+
     /// Performs essentially all of the casts that can be performed via `as`.
     ///
     /// This allows for casts from/to a variety of types.
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index cbb26b83c79..db77017310a 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -210,6 +210,7 @@ impl<'tcx> Rvalue<'tcx> {
                 let place_ty = place.ty(local_decls, tcx).ty;
                 Ty::new_ptr(tcx, place_ty, mutability)
             }
+            Rvalue::Len(..) => tcx.types.usize,
             Rvalue::Cast(.., ty) => ty,
             Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => {
                 let lhs_ty = lhs.ty(local_decls, tcx);
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 12a024a219e..058acbd4024 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -695,6 +695,14 @@ macro_rules! make_mir_visitor {
                         self.visit_place(path, ctx, location);
                     }
 
+                    Rvalue::Len(path) => {
+                        self.visit_place(
+                            path,
+                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
+                            location
+                        );
+                    }
+
                     Rvalue::Cast(_cast_kind, operand, ty) => {
                         self.visit_operand(operand, location);
                         self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
index 3dd5de02230..59f440432eb 100644
--- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
@@ -246,6 +246,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
                 let offset = self.parse_operand(args[1])?;
                 Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
             },
+            @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
             @call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)),
             @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
             ExprKind::Borrow { borrow_kind, arg } => Ok(
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 89c7bb357ef..b1851e79d5c 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::{DesugaringKind, Span};
+use rustc_span::Span;
 use tracing::{debug, instrument, trace};
 
 use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -630,98 +630,6 @@ 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`.
-    pub(in crate::builder) 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) => {
-                let ty_const = if let Some((_, len_ty)) = len_const.try_to_valtree()
-                    && len_ty != self.tcx.types.usize
-                {
-                    // Bad const generics can give us a constant from the type that's
-                    // not actually a `usize`, so in that case give an error instead.
-                    // FIXME: It'd be nice if the type checker made sure this wasn't
-                    // possible, instead.
-                    let err = self.tcx.dcx().span_delayed_bug(
-                        span,
-                        format!(
-                            "Array length should have already been a type error, as it's {len_ty:?}"
-                        ),
-                    );
-                    ty::Const::new_error(self.tcx, err)
-                } else {
-                    // 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);
-                    *len_const
-                };
-
-                let const_ = Const::from_ty_const(ty_const, usize_ty, self.tcx);
-                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,
@@ -730,25 +638,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr_span: Span,
         source_info: SourceInfo,
     ) -> BasicBlock {
-        let slice = slice.to_place(self);
+        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);
 
         // len = len(slice)
-        let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
-
+        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
         // 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)), len.to_copy())),
+                Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
             ),
         );
-        let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
-
+        let msg = BoundsCheck { len: Operand::Move(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_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index 0d36b7bb3ee..8cca84d7fcc 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -243,8 +243,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             TestKind::Len { len, op } => {
+                let usize_ty = self.tcx.types.usize;
+                let actual = self.temp(usize_ty, test.span);
+
                 // actual = len(place)
-                let actual = self.len_of_slice_or_array(block, place, test.span, source_info);
+                self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place));
 
                 // expected = <N>
                 let expected = self.push_usize(block, source_info, len);
@@ -259,7 +262,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     fail_block,
                     source_info,
                     op,
-                    actual,
+                    Operand::Move(actual),
                     Operand::Move(expected),
                 );
             }
diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs
index 0659e3ea314..921205428db 100644
--- a/compiler/rustc_mir_build/src/check_tail_calls.rs
+++ b/compiler/rustc_mir_build/src/check_tail_calls.rs
@@ -1,4 +1,5 @@
 use rustc_abi::ExternAbi;
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem;
 use rustc_hir::def::DefKind;
@@ -344,12 +345,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'a Expr<'tcx>) {
-        if let ExprKind::Become { value } = expr.kind {
-            let call = &self.thir[value];
-            self.check_tail_call(call, expr);
-        }
+        ensure_sufficient_stack(|| {
+            if let ExprKind::Become { value } = expr.kind {
+                let call = &self.thir[value];
+                self.check_tail_call(call, expr);
+            }
 
-        visit::walk_expr(self, expr);
+            visit::walk_expr(self, expr);
+        });
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f7071eb139f..967e523a49c 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -2,6 +2,7 @@ use std::borrow::Cow;
 use std::mem;
 use std::ops::Bound;
 
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::DiagArgValue;
 use rustc_hir::def::DefKind;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
@@ -473,7 +474,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
                 let prev_id = self.hir_context;
                 self.hir_context = hir_id;
-                self.visit_expr(&self.thir[value]);
+                ensure_sufficient_stack(|| {
+                    self.visit_expr(&self.thir[value]);
+                });
                 self.hir_context = prev_id;
                 return; // don't visit the whole expression
             }
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 217594b3238..568d8a5acaf 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -91,6 +91,7 @@ where
             | Rvalue::Use(..)
             | Rvalue::ThreadLocalRef(..)
             | Rvalue::Repeat(..)
+            | Rvalue::Len(..)
             | Rvalue::BinaryOp(..)
             | Rvalue::NullaryOp(..)
             | Rvalue::UnaryOp(..)
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 80875f32e4f..d1b3a389e9e 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -413,6 +413,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             Rvalue::Ref(..)
             | Rvalue::RawPtr(..)
             | Rvalue::Discriminant(..)
+            | Rvalue::Len(..)
             | Rvalue::NullaryOp(
                 NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::UbChecks,
                 _,
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index cc44114782c..51af77778af 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -408,6 +408,18 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
         state: &mut State<FlatSet<Scalar>>,
     ) -> ValueOrPlace<FlatSet<Scalar>> {
         let val = match rvalue {
+            Rvalue::Len(place) => {
+                let place_ty = place.ty(self.local_decls, self.tcx);
+                if let ty::Array(_, len) = place_ty.ty.kind() {
+                    Const::Ty(self.tcx.types.usize, *len)
+                        .try_eval_scalar(self.tcx, self.typing_env)
+                        .map_or(FlatSet::Top, FlatSet::Elem)
+                } else if let [ProjectionElem::Deref] = place.projection[..] {
+                    state.get_len(place.local.into(), &self.map)
+                } else {
+                    FlatSet::Top
+                }
+            }
             Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => {
                 let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else {
                     return ValueOrPlace::Value(FlatSet::Top);
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index e99bee6a01f..8f977d2979e 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -574,6 +574,7 @@ impl WriteInfo {
                     | Rvalue::NullaryOp(_, _)
                     | Rvalue::Ref(_, _, _)
                     | Rvalue::RawPtr(_, _)
+                    | Rvalue::Len(_)
                     | Rvalue::Discriminant(_)
                     | Rvalue::CopyForDeref(_) => {}
                 }
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 283ed94b615..d5a813ec8ec 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -223,6 +223,8 @@ enum Value<'tcx> {
     Projection(VnIndex, ProjectionElem<VnIndex, Ty<'tcx>>),
     /// Discriminant of the given value.
     Discriminant(VnIndex),
+    /// Length of an array or slice.
+    Len(VnIndex),
 
     // Operations.
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
@@ -511,6 +513,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     self.ecx.discriminant_for_variant(base.layout.ty, variant).discard_err()?;
                 discr_value.into()
             }
+            Len(slice) => {
+                let slice = self.evaluated[slice].as_ref()?;
+                let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
+                let len = slice.len(&self.ecx).discard_err()?;
+                let imm = ImmTy::from_uint(len, usize_layout);
+                imm.into()
+            }
             NullaryOp(null_op, ty) => {
                 let layout = self.ecx.layout_of(ty).ok()?;
                 if let NullOp::SizeOf | NullOp::AlignOf = null_op
@@ -854,6 +863,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
 
             // Operations.
+            Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
             Rvalue::Cast(ref mut kind, ref mut value, to) => {
                 return self.simplify_cast(kind, value, to, location);
             }
@@ -1423,6 +1433,47 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         Some(self.insert(Value::Cast { kind: *kind, value, from, to }))
     }
 
+    fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option<VnIndex> {
+        // Trivial case: we are fetching a statically known length.
+        let place_ty = place.ty(self.local_decls, self.tcx).ty;
+        if let ty::Array(_, len) = place_ty.kind() {
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
+        }
+
+        let mut inner = self.simplify_place_value(place, location)?;
+
+        // The length information is stored in the wide pointer.
+        // Reborrowing copies length information from one pointer to the other.
+        while let Value::Address { place: borrowed, .. } = self.get(inner)
+            && let [PlaceElem::Deref] = borrowed.projection[..]
+            && let Some(borrowed) = self.locals[borrowed.local]
+        {
+            inner = borrowed;
+        }
+
+        // We have an unsizing cast, which assigns the length to wide pointer metadata.
+        if let Value::Cast { kind, from, to, .. } = self.get(inner)
+            && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind
+            && let Some(from) = from.builtin_deref(true)
+            && let ty::Array(_, len) = from.kind()
+            && let Some(to) = to.builtin_deref(true)
+            && let ty::Slice(..) = to.kind()
+        {
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
+        }
+
+        // Fallback: a symbolic `Len`.
+        Some(self.insert(Value::Len(inner)))
+    }
+
     fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool {
         let left_meta_ty = left_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
         let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 1a65affe812..f5938e7b60e 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -46,6 +46,7 @@ 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);
                     }
@@ -130,6 +131,18 @@ 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::from_ty_const(len, self.tcx.types.usize, self.tcx);
+                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/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index f1705d0c831..acf3eb2b62c 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -440,6 +440,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             | Rvalue::Use(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
+            | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
@@ -599,6 +600,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 return None;
             }
 
+            Len(place) => {
+                let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
+                {
+                    n.try_to_target_usize(self.tcx)?
+                } else {
+                    match self.get_const(place)? {
+                        Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
+                        Value::Aggregate { fields, .. } => fields.len() as u64,
+                        Value::Uninit => return None,
+                    }
+                };
+                ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
+            }
+
             Ref(..) | RawPtr(..) => return None,
 
             NullaryOp(ref null_op, ty) => {
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 7451f419304..6be95b1f0f1 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -430,7 +430,9 @@ impl<'tcx> Validator<'_, 'tcx> {
                 self.validate_operand(op)?
             }
 
-            Rvalue::Discriminant(place) => self.validate_place(place.as_ref())?,
+            Rvalue::Discriminant(place) | Rvalue::Len(place) => {
+                self.validate_place(place.as_ref())?
+            }
 
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index a670da94fcc..404fbb6b839 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1009,6 +1009,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             Rvalue::Ref(..) => {}
+            Rvalue::Len(p) => {
+                let pty = p.ty(&self.body.local_decls, self.tcx).ty;
+                check_kinds!(
+                    pty,
+                    "Cannot compute length of non-array type {:?}",
+                    ty::Array(..) | ty::Slice(..)
+                );
+            }
             Rvalue::BinaryOp(op, vals) => {
                 use BinOp::*;
                 let a = vals.0.ty(&self.body.local_decls, self.tcx);
@@ -1107,6 +1115,14 @@ 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_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 6ee02e9f47f..d15eca69270 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1130,7 +1130,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let None = following_seg else { return };
         for rib in self.ribs[ValueNS].iter().rev() {
             for (def_id, spans) in &rib.patterns_with_skipped_bindings {
-                if let Some(fields) = self.r.field_idents(*def_id) {
+                if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id)
+                    && let Some(fields) = self.r.field_idents(*def_id)
+                {
                     for field in fields {
                         if field.name == segment.ident.name {
                             if spans.iter().all(|(_, had_error)| had_error.is_err()) {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index de933952c6a..a5a17b4b573 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -181,6 +181,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
             RawPtr(mutability, place) => {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
             }
+            Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
             Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
                 cast_kind.stable(tables),
                 op.stable(tables),
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 3cdae437b7d..a5826137181 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,9 +1163,6 @@ 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 {
@@ -1182,7 +1179,6 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
-            DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
         }
     }
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4ecc4201f89..e3f55221d70 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1283,6 +1283,7 @@ symbols! {
         mir_drop,
         mir_field,
         mir_goto,
+        mir_len,
         mir_make_place,
         mir_move,
         mir_offset,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
index d6b77ffd091..3b719ebaf07 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
@@ -7,7 +7,8 @@
 // For example, `-C target-cpu=cortex-a53`.
 
 use crate::spec::{
-    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions,
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target,
+    TargetOptions,
 };
 
 pub(crate) fn target() -> Target {
@@ -19,6 +20,7 @@ pub(crate) fn target() -> Target {
         relocation_model: RelocModel::Static,
         disable_redzone: true,
         max_atomic_width: Some(128),
+        supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
         stack_probes: StackProbeType::Inline,
         panic_strategy: PanicStrategy::Abort,
         ..Default::default()
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index 834f44c7790..55dcf7cd47e 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -233,7 +233,7 @@
 //!
 //!  - Operands implicitly convert to `Use` rvalues.
 //!  - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
-//!  - [`Discriminant`] and [`CopyForDeref`] have associated functions.
+//!  - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions.
 //!  - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
 //!  - The binary operation `Offset` can be created via [`Offset`].
 //!  - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
@@ -401,6 +401,7 @@ define!("mir_storage_dead", fn StorageDead<T>(local: T));
 define!("mir_assume", fn Assume(operand: bool));
 define!("mir_deinit", fn Deinit<T>(place: T));
 define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
+define!("mir_len", fn Len<T>(place: T) -> usize);
 define!(
     "mir_ptr_metadata",
     fn PtrMetadata<P: ?Sized>(place: *const P) -> <P as ::core::ptr::Pointee>::Metadata
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index aa664998f97..34e6a1e1d35 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -995,7 +995,18 @@ impl Step for PlainSourceTarball {
         ];
         let src_dirs = ["src", "compiler", "library", "tests"];
 
-        copy_src_dirs(builder, &builder.src, &src_dirs, &[], plain_dst_src);
+        copy_src_dirs(
+            builder,
+            &builder.src,
+            &src_dirs,
+            &[
+                // We don't currently use the GCC source code for building any official components,
+                // it is very big, and has unclear licensing implications due to being GPL licensed.
+                // We thus exclude it from the source tarball from now.
+                "src/gcc",
+            ],
+            plain_dst_src,
+        );
 
         // Copy the files normally
         for item in &src_files {
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 428b40c5771..104ae154e36 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -109,7 +109,7 @@ fn check_rvalue<'tcx>(
 ) -> McfResult {
     match rvalue {
         Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
-        Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+        Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
             check_place(tcx, *place, span, body, msrv)
         },
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
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 8d9176ef301..a467987e886 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,7 +7,8 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: bool;
+    let mut _8: usize;
+    let mut _9: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _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];
+        _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];
     }
 
     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 e1df0e3e2a3..bd7365543bd 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,7 +7,8 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: bool;
+    let mut _8: usize;
+    let mut _9: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _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];
+        _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];
     }
 
     bb2: {
diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
new file mode 100644
index 00000000000..30d11e31e4d
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `arrays` after built
+
+fn arrays() -> usize {
+    let mut _0: usize;
+    let mut _1: [i32; C];
+    let mut _2: usize;
+
+    bb0: {
+        _1 = [const 5_i32; C];
+        _2 = Len(_1);
+        _0 = copy _2;
+        return;
+    }
+}
diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs
new file mode 100644
index 00000000000..4bd6f93e113
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.rs
@@ -0,0 +1,22 @@
+// skip-filecheck
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR arrays.arrays.built.after.mir
+#[custom_mir(dialect = "built")]
+fn arrays<const C: usize>() -> usize {
+    mir! {
+        {
+            let x = [5_i32; C];
+            let c = Len(x);
+            RET = c;
+            Return()
+        }
+    }
+}
+
+fn main() {
+    assert_eq!(arrays::<20>(), 20);
+}
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
deleted file mode 100644
index d28a2031013..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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
deleted file mode 100644
index e9627532c38..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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
deleted file mode 100644
index 00f2b7e07d5..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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
deleted file mode 100644
index cb0b2f600c8..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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
deleted file mode 100644
index 0911df59049..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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
deleted file mode 100644
index 16d0b983132..00000000000
--- a/tests/mir-opt/building/index_array_and_slice.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-//@ 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 3a5a8d00991..e754af95ce3 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 62d6e6007e5..e15a35c7fe9 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 3a5a8d00991..e754af95ce3 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 62d6e6007e5..e15a35c7fe9 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 be42c4d60c8..15d30140367 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
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_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];
-+         _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];
++         _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];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
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 b51d0c0845f..dd411d84f9f 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
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_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];
-+         _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];
++         _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];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
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 be42c4d60c8..15d30140367 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
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_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];
-+         _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];
++         _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];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
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 b51d0c0845f..dd411d84f9f 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
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_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];
-+         _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];
++         _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];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
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 3569998b13f..49ea51deed6 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 50b31c9ac13..103bfbcaf64 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 3569998b13f..49ea51deed6 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 50b31c9ac13..103bfbcaf64 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 a41668b6fa3..f7c1c2da01f 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 2313084b49e..436773c8556 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 a41668b6fa3..f7c1c2da01f 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 2313084b49e..436773c8556 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 0798b303929..8a8ea5b7e20 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,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _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];
++         _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];
       }
   
       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 c0b3d4d3219..f0c844884f6 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,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _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];
++         _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];
       }
   
       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 0798b303929..8a8ea5b7e20 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,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _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];
++         _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];
       }
   
       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 c0b3d4d3219..f0c844884f6 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,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _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];
++         _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];
       }
   
       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 689083dfc1d..6d967257df1 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,7 +18,8 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: bool;
+      let mut _19: usize;
+      let mut _20: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -91,10 +92,11 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
--         _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];
+          _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];
       }
   
       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 7f768a9f834..3580c87c469 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,7 +18,8 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: bool;
+      let mut _19: usize;
+      let mut _20: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -91,10 +92,11 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
--         _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];
+          _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];
       }
   
       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 0275d7e8a0d..a46daef435f 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 490ed4b55a1..1a4e15b45fa 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 0275d7e8a0d..a46daef435f 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 490ed4b55a1..1a4e15b45fa 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,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 1aa8dcd28f4..e442ef99f79 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/array_index.rs
@@ -11,10 +11,9 @@ 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 2_usize;
+    // CHECK:       {{_.*}} = const 4_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 f0d59ef5923..b7ff0b671f7 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 959c3e75214..af6e3626142 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 f0d59ef5923..b7ff0b671f7 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 959c3e75214..af6e3626142 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,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _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;
+-         _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;
 +         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 e490cfde247..e9f2fa2badf 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 2_usize;
+    // CHECK: {{_.*}} = const 5000_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 618121ea632..dfa541b1200 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 1788f58432b..9ede3c5f7ac 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 618121ea632..dfa541b1200 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 1788f58432b..9ede3c5f7ac 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,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _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;
+-         _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;
 +         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 1bc2cb82a60..2067aa3d709 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.rs
+++ b/tests/mir-opt/dataflow-const-prop/repeat.rs
@@ -9,9 +9,8 @@ fn main() {
 
     // CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
     // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = PtrMetadata(
     // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK: {{_.*}} = const 2_usize;
+    // CHECK: {{_.*}} = const 8_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
new file mode 100644
index 00000000000..e71992316dc
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..26de8595768
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..e71992316dc
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..26de8595768
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..e0e68f9fde5
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs
@@ -0,0 +1,34 @@
+// 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/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
index b4197c09ac9..60742ef0e9a 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
@@ -22,14 +22,14 @@
   
       bb1: {
           StorageDead(_3);
-          _4 = PtrMetadata(copy _2);
+          _4 = Len((*_2));
           _5 = const 4_usize;
           _6 = Ge(move _4, move _5);
           switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
           _8 = const 3_usize;
           _9 = Ge(move _7, move _8);
 -         switchInt(move _9) -> [0: bb7, otherwise: bb8];
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
index 4bcb13ca49c..7337a32f525 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
@@ -22,14 +22,14 @@
   
       bb1: {
           StorageDead(_3);
-          _4 = PtrMetadata(copy _2);
+          _4 = Len((*_2));
           _5 = const 4_usize;
           _6 = Ge(move _4, move _5);
           switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
           _8 = const 3_usize;
           _9 = Ge(move _7, move _8);
 -         switchInt(move _9) -> [0: bb7, otherwise: bb8];
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 183b4d2599f..3f052ee19fd 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 = PtrMetadata(copy _1);
+          _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: bb3, unwind unreachable];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = PtrMetadata(copy _1);
+          _12 = Len((*_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 03e8aa3bd9b..84b738c7804 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 = PtrMetadata(copy _1);
+          _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: bb3, unwind continue];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = PtrMetadata(copy _1);
+          _12 = Len((*_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
deleted file mode 100644
index 4b077f580f1..00000000000
--- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // 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
deleted file mode 100644
index 87e69d44006..00000000000
--- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // 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 7f44176b756..d4b22d05f6c 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -10,11 +10,13 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: bool;
-      let _9: ();
-      let mut _10: T;
-      let _11: usize;
-      let mut _12: bool;
+      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;
       scope 1 {
           debug a => _3;
       }
@@ -30,10 +32,12 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _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];
+-         _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];
       }
   
       bb1: {
@@ -47,27 +51,29 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          _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];
+          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];
       }
   
       bb3: {
--         _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];
+-         _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];
       }
   
       bb4: {
-          StorageDead(_10);
           StorageDead(_11);
-          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_10);
           _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 d34882d725f..708c0f92e54 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -10,11 +10,13 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: bool;
-      let _9: ();
-      let mut _10: T;
-      let _11: usize;
-      let mut _12: bool;
+      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;
       scope 1 {
           debug a => _3;
       }
@@ -30,10 +32,12 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _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];
+-         _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];
       }
   
       bb1: {
@@ -47,27 +51,29 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          _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];
+          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];
       }
   
       bb3: {
--         _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];
+-         _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];
       }
   
       bb4: {
-          StorageDead(_10);
           StorageDead(_11);
-          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_10);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 19b58a917f8..97513248e23 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -835,25 +835,6 @@ 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
@@ -1031,7 +1012,6 @@ fn identity<T>(x: T) -> T {
 // 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.cast_pointer_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 1b305e746f5..6b6152c1117 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,60 +10,62 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: 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 _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 _18: bool;
-      let mut _19: *const dyn std::marker::Send;
-      let mut _20: *const dyn std::marker::Send;
+      let _19: ();
+      let mut _20: bool;
       let mut _21: *const dyn std::marker::Send;
-      let _22: ();
-      let mut _23: bool;
-      let mut _24: *const dyn std::marker::Send;
-      let mut _25: *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 mut _26: *const dyn std::marker::Send;
-      let _27: ();
-      let mut _28: bool;
-      let mut _29: *const dyn std::marker::Send;
-      let mut _30: *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 mut _31: *const dyn std::marker::Send;
-      let _32: ();
-      let mut _33: bool;
-      let mut _34: *const dyn std::marker::Send;
-      let mut _35: *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 mut _36: *const dyn std::marker::Send;
-      let _37: ();
-      let mut _38: bool;
-      let mut _39: *const dyn std::marker::Send;
-      let mut _40: *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 mut _41: *const dyn std::marker::Send;
-      let _42: ();
-      let mut _43: bool;
-      let mut _44: *const dyn std::marker::Send;
-      let mut _45: *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 mut _46: *const dyn std::marker::Send;
-      let mut _47: &[i32; 2];
+      let mut _47: *const dyn std::marker::Send;
+      let mut _48: *const dyn std::marker::Send;
+      let mut _49: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _10: *const dyn std::marker::Send;
+              let _11: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _10;
+                  debug b => _11;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _47 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_47);
+          _49 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_49);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -72,9 +74,11 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _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;
+-         _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
@@ -91,168 +95,170 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_10);
--         StorageLive(_11);
+          StorageLive(_11);
+-         StorageLive(_12);
 +         nop;
-          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          _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;
+          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;
 +         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: {
--         _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;
+-         _15 = &(*_1)[_16];
++         _15 = &(*_1)[1 of 2];
+          _14 = &(*_15);
+          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_14);
-          StorageDead(_12);
-          StorageLive(_17);
-          StorageLive(_18);
+          _12 = &raw const (*_13);
+-         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_12);
++         _11 = copy _12;
++         nop;
+          StorageDead(_15);
+          StorageDead(_13);
           StorageLive(_19);
--         _19 = copy _3;
-+         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _10;
--         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _21 = copy _11;
-+         _20 = copy _11;
+-         _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);
           StorageDead(_21);
--         _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];
+          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
-          StorageDead(_18);
-          StorageDead(_17);
-          StorageLive(_22);
-          StorageLive(_23);
+          StorageDead(_20);
+          StorageDead(_19);
           StorageLive(_24);
--         _24 = copy _3;
-+         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _10;
--         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _26 = copy _11;
-+         _25 = copy _11;
+-         _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);
           StorageDead(_26);
--         _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];
+          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_23);
-          StorageDead(_22);
-          StorageLive(_27);
-          StorageLive(_28);
+          StorageDead(_25);
+          StorageDead(_24);
           StorageLive(_29);
--         _29 = copy _3;
-+         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _10;
--         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _31 = copy _11;
-+         _30 = copy _11;
+-         _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);
           StorageDead(_31);
--         _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];
+          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_28);
-          StorageDead(_27);
-          StorageLive(_32);
-          StorageLive(_33);
+          StorageDead(_30);
+          StorageDead(_29);
           StorageLive(_34);
--         _34 = copy _3;
-+         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _10;
--         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _36 = copy _11;
-+         _35 = copy _11;
+-         _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);
           StorageDead(_36);
--         _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];
+          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind unreachable];
       }
   
       bb6: {
-          StorageDead(_33);
-          StorageDead(_32);
-          StorageLive(_37);
-          StorageLive(_38);
+          StorageDead(_35);
+          StorageDead(_34);
           StorageLive(_39);
--         _39 = copy _3;
-+         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _10;
--         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _41 = copy _11;
-+         _40 = copy _11;
+-         _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);
           StorageDead(_41);
--         _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];
+          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
-          StorageDead(_38);
-          StorageDead(_37);
-          StorageLive(_42);
-          StorageLive(_43);
+          StorageDead(_40);
+          StorageDead(_39);
           StorageLive(_44);
--         _44 = copy _3;
-+         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _10;
--         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _46 = copy _11;
-+         _45 = copy _11;
+-         _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);
           StorageDead(_46);
--         _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];
+          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind unreachable];
       }
   
       bb8: {
-          StorageDead(_43);
-          StorageDead(_42);
+          StorageDead(_45);
+          StorageDead(_44);
           _0 = const ();
-          StorageDead(_15);
-          StorageDead(_10);
+          StorageDead(_16);
+          StorageDead(_11);
           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 e418ecf25bd..093c1ec6ce3 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,60 +10,62 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: 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 _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 _18: bool;
-      let mut _19: *const dyn std::marker::Send;
-      let mut _20: *const dyn std::marker::Send;
+      let _19: ();
+      let mut _20: bool;
       let mut _21: *const dyn std::marker::Send;
-      let _22: ();
-      let mut _23: bool;
-      let mut _24: *const dyn std::marker::Send;
-      let mut _25: *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 mut _26: *const dyn std::marker::Send;
-      let _27: ();
-      let mut _28: bool;
-      let mut _29: *const dyn std::marker::Send;
-      let mut _30: *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 mut _31: *const dyn std::marker::Send;
-      let _32: ();
-      let mut _33: bool;
-      let mut _34: *const dyn std::marker::Send;
-      let mut _35: *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 mut _36: *const dyn std::marker::Send;
-      let _37: ();
-      let mut _38: bool;
-      let mut _39: *const dyn std::marker::Send;
-      let mut _40: *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 mut _41: *const dyn std::marker::Send;
-      let _42: ();
-      let mut _43: bool;
-      let mut _44: *const dyn std::marker::Send;
-      let mut _45: *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 mut _46: *const dyn std::marker::Send;
-      let mut _47: &[i32; 2];
+      let mut _47: *const dyn std::marker::Send;
+      let mut _48: *const dyn std::marker::Send;
+      let mut _49: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _10: *const dyn std::marker::Send;
+              let _11: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _10;
+                  debug b => _11;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _47 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_47);
+          _49 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_49);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -72,9 +74,11 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _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;
+-         _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue];
       }
   
@@ -91,168 +95,170 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_10);
--         StorageLive(_11);
+          StorageLive(_11);
+-         StorageLive(_12);
 +         nop;
-          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          _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;
+          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;
 +         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: {
--         _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;
+-         _15 = &(*_1)[_16];
++         _15 = &(*_1)[1 of 2];
+          _14 = &(*_15);
+          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_14);
-          StorageDead(_12);
-          StorageLive(_17);
-          StorageLive(_18);
+          _12 = &raw const (*_13);
+-         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_12);
++         _11 = copy _12;
++         nop;
+          StorageDead(_15);
+          StorageDead(_13);
           StorageLive(_19);
--         _19 = copy _3;
-+         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _10;
--         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _21 = copy _11;
-+         _20 = copy _11;
+-         _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);
           StorageDead(_21);
--         _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];
+          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind continue];
       }
   
       bb3: {
-          StorageDead(_18);
-          StorageDead(_17);
-          StorageLive(_22);
-          StorageLive(_23);
+          StorageDead(_20);
+          StorageDead(_19);
           StorageLive(_24);
--         _24 = copy _3;
-+         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _10;
--         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _26 = copy _11;
-+         _25 = copy _11;
+-         _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);
           StorageDead(_26);
--         _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];
+          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_23);
-          StorageDead(_22);
-          StorageLive(_27);
-          StorageLive(_28);
+          StorageDead(_25);
+          StorageDead(_24);
           StorageLive(_29);
--         _29 = copy _3;
-+         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _10;
--         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _31 = copy _11;
-+         _30 = copy _11;
+-         _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);
           StorageDead(_31);
--         _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];
+          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind continue];
       }
   
       bb5: {
-          StorageDead(_28);
-          StorageDead(_27);
-          StorageLive(_32);
-          StorageLive(_33);
+          StorageDead(_30);
+          StorageDead(_29);
           StorageLive(_34);
--         _34 = copy _3;
-+         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _10;
--         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _36 = copy _11;
-+         _35 = copy _11;
+-         _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);
           StorageDead(_36);
--         _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];
+          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind continue];
       }
   
       bb6: {
-          StorageDead(_33);
-          StorageDead(_32);
-          StorageLive(_37);
-          StorageLive(_38);
+          StorageDead(_35);
+          StorageDead(_34);
           StorageLive(_39);
--         _39 = copy _3;
-+         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _10;
--         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _41 = copy _11;
-+         _40 = copy _11;
+-         _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);
           StorageDead(_41);
--         _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];
+          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind continue];
       }
   
       bb7: {
-          StorageDead(_38);
-          StorageDead(_37);
-          StorageLive(_42);
-          StorageLive(_43);
+          StorageDead(_40);
+          StorageDead(_39);
           StorageLive(_44);
--         _44 = copy _3;
-+         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _10;
--         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _46 = copy _11;
-+         _45 = copy _11;
+-         _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);
           StorageDead(_46);
--         _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];
+          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind continue];
       }
   
       bb8: {
-          StorageDead(_43);
-          StorageDead(_42);
+          StorageDead(_45);
+          StorageDead(_44);
           _0 = const ();
-          StorageDead(_15);
-          StorageDead(_10);
+          StorageDead(_16);
+          StorageDead(_11);
           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
new file mode 100644
index 00000000000..f39df7ffca0
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..0e7d5653c68
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // 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
new file mode 100644
index 00000000000..91f43f75689
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.rs
@@ -0,0 +1,15 @@
+// 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 7593b795432..314cf8b367f 100644
--- a/tests/mir-opt/issue_72181.foo.built.after.mir
+++ b/tests/mir-opt/issue_72181.foo.built.after.mir
@@ -4,14 +4,15 @@ fn foo(_1: [(Never, u32); 1]) -> u32 {
     debug xs => _1;
     let mut _0: u32;
     let _2: usize;
-    let mut _3: bool;
+    let mut _3: usize;
+    let mut _4: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = const 0_usize;
-        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];
+        _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];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index 9f3803f5407..aade84a6dd2 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -7,7 +7,8 @@ fn main() -> () {
     let mut _4: Foo;
     let mut _5: u64;
     let _6: usize;
-    let mut _7: bool;
+    let mut _7: usize;
+    let mut _8: bool;
     scope 1 {
         let _2: [Foo; 2];
         scope 2 {
@@ -37,9 +38,9 @@ fn main() -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = const 0_usize;
-        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];
+        _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];
     }
 
     bb2: {
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
index 94ba7082c66..c02bab3524b 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
@@ -7,16 +7,18 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _8: !;
+      let mut _5: usize;
+      let mut _6: bool;
+      let mut _10: !;
       scope 1 {
           debug v => _2;
-          let _5: &T;
-          let _6: &T;
           let _7: &T;
+          let _8: &T;
+          let _9: &T;
           scope 2 {
-              debug v1 => _5;
-              debug v2 => _6;
-              debug v3 => _7;
+              debug v1 => _7;
+              debug v2 => _8;
+              debug v3 => _9;
           }
       }
   
@@ -25,23 +27,25 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
+          nop;
+          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable;
+          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable;
       }
   
       bb2: {
-          StorageLive(_5);
-          _5 = &(*_2)[0 of 3];
-          StorageLive(_6);
-          _6 = &(*_2)[1 of 3];
           StorageLive(_7);
-          _7 = &(*_2)[2 of 3];
+          _7 = &(*_2)[0 of 3];
+          StorageLive(_8);
+          _8 = &(*_2)[1 of 3];
+          StorageLive(_9);
+          _9 = &(*_2)[2 of 3];
+          StorageDead(_9);
+          StorageDead(_8);
           StorageDead(_7);
-          StorageDead(_6);
-          StorageDead(_5);
           StorageDead(_4);
           return;
       }
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
index 0455b2c326e..49be042588c 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
@@ -7,16 +7,18 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _8: !;
+      let mut _5: usize;
+      let mut _6: bool;
+      let mut _10: !;
       scope 1 {
           debug v => _2;
-          let _5: &T;
-          let _6: &T;
           let _7: &T;
+          let _8: &T;
+          let _9: &T;
           scope 2 {
-              debug v1 => _5;
-              debug v2 => _6;
-              debug v3 => _7;
+              debug v1 => _7;
+              debug v2 => _8;
+              debug v3 => _9;
           }
       }
   
@@ -25,23 +27,25 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
+          nop;
+          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
+          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
       }
   
       bb2: {
-          StorageLive(_5);
-          _5 = &(*_2)[0 of 3];
-          StorageLive(_6);
-          _6 = &(*_2)[1 of 3];
           StorageLive(_7);
-          _7 = &(*_2)[2 of 3];
+          _7 = &(*_2)[0 of 3];
+          StorageLive(_8);
+          _8 = &(*_2)[1 of 3];
+          StorageLive(_9);
+          _9 = &(*_2)[2 of 3];
+          StorageDead(_9);
+          StorageDead(_8);
           StorageDead(_7);
-          StorageDead(_6);
-          StorageDead(_5);
           StorageDead(_4);
           return;
       }
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
index bf65b5b4a8c..50fdf08375a 100644
--- a/tests/mir-opt/issue_91633.foo.built.after.mir
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -6,9 +6,8 @@ fn foo(_1: Box<[T]>) -> T {
     let _2: T;
     let mut _3: &T;
     let _4: usize;
-    let mut _5: *const [T];
-    let mut _6: usize;
-    let mut _7: bool;
+    let mut _5: usize;
+    let mut _6: bool;
     scope 1 {
         debug f => _2;
     }
@@ -18,10 +17,9 @@ fn foo(_1: Box<[T]>) -> T {
         StorageLive(_3);
         StorageLive(_4);
         _4 = const 0_usize;
-        _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];
+        _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];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir
index d2fc438d3e8..5b41b376719 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 = PtrMetadata(copy _1);
+        _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: 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 98c5e868046..f052c8f63dc 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,14 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
+      let mut _9: usize;
+      let mut _10: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -38,13 +40,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _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;
+-         _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;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -56,7 +61,8 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           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 72c73137869..3299e300431 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,14 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
+      let mut _9: usize;
+      let mut _10: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -38,13 +40,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _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;
+-         _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;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -56,7 +61,8 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           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 9ffaf44c02b..329eb80b3c4 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,16 +11,19 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
-      let _10: usize;
-      let mut _11: bool;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,13 +43,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _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;
+-         _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;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -58,20 +64,23 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
-          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];
+          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];
       }
   
       bb5: {
--         (*_2)[_10] = const 42_u8;
+-         (*_2)[_11] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_10);
+          StorageDead(_11);
           _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 08008e46335..ab007e133ec 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,16 +11,19 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
-      let _10: usize;
-      let mut _11: bool;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,13 +43,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _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;
+-         _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;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -58,20 +64,23 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
-          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];
+          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];
       }
   
       bb5: {
--         (*_2)[_10] = const 42_u8;
+-         (*_2)[_11] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_10);
+          StorageDead(_11);
           _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 4b39e18d16c..20001f1248e 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 = PtrMetadata(copy _2);
+          _8 = Len((*_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 f0d4afa21ae..ca8f92df5de 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 = PtrMetadata(copy _2);
+          _8 = Len((*_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 35e44b2314a..7294302609a 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,19 +27,20 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x00000003): usize)];
     let _3: usize;
-    let mut _4: bool;
-    let mut _6: bool;
-    let _7: bool;
-    let mut _8: usize;
-    let _9: bool;
+    let mut _4: usize;
+    let mut _5: bool;
+    let mut _7: bool;
+    let _8: bool;
+    let mut _9: usize;
+    let _10: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _5: &'?4 usize;
+            let _6: &'?4 usize;
             scope 3 {
-                debug q => _5;
+                debug q => _6;
             }
         }
     }
@@ -51,50 +52,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x00000000): usize);
-        FakeRead(ForIndex, _1);
-        _4 = Lt(copy _3, const ConstValue(Scalar(0x00000003): usize));
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7];
+        _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];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
-        StorageLive(_5);
-        _5 = copy _2;
-        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _6) -> [0: bb4, otherwise: bb2];
+        _6 = copy _2;
+        FakeRead(ForLet(None), _6);
+        StorageLive(_7);
+        _7 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _7) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
-        StorageLive(_7);
         StorageLive(_8);
-        _8 = copy (*_5);
-        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
+        StorageLive(_9);
+        _9 = copy (*_6);
+        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_9);
-        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_10);
+        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_9);
+        StorageDead(_10);
         _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 6d415f42d06..85b89a013c4 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,19 +27,20 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)];
     let _3: usize;
-    let mut _4: bool;
-    let mut _6: bool;
-    let _7: bool;
-    let mut _8: usize;
-    let _9: bool;
+    let mut _4: usize;
+    let mut _5: bool;
+    let mut _7: bool;
+    let _8: bool;
+    let mut _9: usize;
+    let _10: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _5: &'?4 usize;
+            let _6: &'?4 usize;
             scope 3 {
-                debug q => _5;
+                debug q => _6;
             }
         }
     }
@@ -51,50 +52,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x0000000000000000): usize);
-        FakeRead(ForIndex, _1);
-        _4 = Lt(copy _3, const ConstValue(Scalar(0x0000000000000003): usize));
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7];
+        _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];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
-        StorageLive(_5);
-        _5 = copy _2;
-        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _6) -> [0: bb4, otherwise: bb2];
+        _6 = copy _2;
+        FakeRead(ForLet(None), _6);
+        StorageLive(_7);
+        _7 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _7) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
-        StorageLive(_7);
         StorageLive(_8);
-        _8 = copy (*_5);
-        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
+        StorageLive(_9);
+        _9 = copy (*_6);
+        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_9);
-        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_10);
+        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_9);
+        StorageDead(_10);
         _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 5b39e45806e..6575610727b 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,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _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 = 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;
+          _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           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 ea2742a6471..1a4ed5767fe 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,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _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 = 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;
+          _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           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 5b39e45806e..6575610727b 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,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _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 = 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;
+          _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           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 ea2742a6471..1a4ed5767fe 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,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _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 = 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;
+          _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;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           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 f7fe08831b9..e2420a341e0 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,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _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 = 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 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];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           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 6e36386bea6..a2fb3b979e6 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,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _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 = 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 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];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           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 f7fe08831b9..e2420a341e0 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,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _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 = 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 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];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           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 6e36386bea6..a2fb3b979e6 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,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _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 = 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 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];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           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 5dac535d195..574062d6c35 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]+]] = PtrMetadata(copy _1)
+    // CHECK: [[LEN:_[0-9]+]] = Len((*_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 81e60b8ec2c..cc1034229fc 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 = PtrMetadata(copy _1);
+        _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 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 c0fdc839608..358226fb529 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 = PtrMetadata(copy _1);
+        _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 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 151783969dd..ecac03ad0f9 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,19 +7,20 @@ 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: bool;
-    let mut _13: &impl Fn(usize, &T);
-    let mut _14: (usize, &T);
-    let _15: ();
+    let mut _11: usize;
+    let mut _12: bool;
+    let mut _14: &impl Fn(usize, &T);
+    let mut _15: (usize, &T);
+    let _16: ();
     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 _12: &T;
+            let _13: &T;
             scope 3 {
-                debug x => _12;
+                debug x => _13;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _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];
+        _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];
     }
 
     bb6: {
-        _12 = &(*_1)[_10];
-        StorageLive(_13);
-        _13 = &_2;
+        _13 = &(*_1)[_10];
         StorageLive(_14);
-        _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
+        _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];
     }
 
     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 006329dc20d..1032473b9b2 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,19 +7,20 @@ 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: bool;
-    let mut _13: &impl Fn(usize, &T);
-    let mut _14: (usize, &T);
-    let _15: ();
+    let mut _11: usize;
+    let mut _12: bool;
+    let mut _14: &impl Fn(usize, &T);
+    let mut _15: (usize, &T);
+    let _16: ();
     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 _12: &T;
+            let _13: &T;
             scope 3 {
-                debug x => _12;
+                debug x => _13;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _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];
+        _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];
     }
 
     bb6: {
-        _12 = &(*_1)[_10];
-        StorageLive(_13);
-        _13 = &_2;
+        _13 = &(*_1)[_10];
         StorageLive(_14);
-        _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
+        _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];
     }
 
     bb7: {
+        StorageDead(_15);
         StorageDead(_14);
-        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
index e9eea69377f..05ad9dbf3cc 100644
--- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -92,7 +92,7 @@
           StorageDead(_7);
 -         StorageDead(_6);
 -         StorageLive(_10);
-          StorageLive(_11);
+-         StorageLive(_11);
 -         StorageLive(_12);
           StorageLive(_13);
           _26 = const debuginfo::promoted[0];
@@ -105,8 +105,9 @@
       bb5: {
           StorageDead(_15);
           StorageDead(_13);
-          _11 = &(*_12);
-          _16 = PtrMetadata(copy _11);
+-         _11 = &(*_12);
+-         _16 = Len((*_11));
++         _16 = Len((*_12));
           _17 = const 3_usize;
           _18 = Ge(move _16, move _17);
           switchInt(move _18) -> [0: bb7, otherwise: bb6];
@@ -136,7 +137,7 @@
   
       bb8: {
 -         StorageDead(_12);
-          StorageDead(_11);
+-         StorageDead(_11);
 -         StorageDead(_10);
           StorageLive(_22);
           StorageLive(_23);
diff --git a/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs
new file mode 100644
index 00000000000..74b5cfcfb04
--- /dev/null
+++ b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs
@@ -0,0 +1,30 @@
+// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths
+// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no
+// tests. This is a collection of a few code samples from that issue.
+
+//@ check-pass
+
+struct Test {
+    a: i32,
+    b: i32,
+}
+
+fn one() {
+    let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }];
+    let a = &mut inputs[0].a;
+    let b = &mut inputs[0].b;
+
+    *a = 0;
+    *b = 1;
+}
+
+fn two() {
+    let slice = &mut [(0, 0)][..];
+    std::mem::swap(&mut slice[0].0, &mut slice[0].1);
+}
+
+fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) {
+    (&mut a[i].0, &mut a[j].1)
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.rs b/tests/ui/borrowck/borrowck-describe-lvalue.rs
index f3a4b382fa8..cdcff69d6e5 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.rs
@@ -231,6 +231,7 @@ 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 666a21808d8..11f2e42d42b 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:253:13
+  --> $DIR/borrowck-describe-lvalue.rs:254: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:263:20
+  --> $DIR/borrowck-describe-lvalue.rs:264: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:261:16
+  --> $DIR/borrowck-describe-lvalue.rs:262:16
    |
 LL |           let mut x = 0;
    |               ----- variable defined here
@@ -300,6 +300,17 @@ 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
    |
@@ -307,12 +318,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:242:24
+  --> $DIR/borrowck-describe-lvalue.rs:243:24
    |
 LL |         let x = &mut v;
    |                 ------ mutable borrow occurs here
@@ -346,7 +357,7 @@ LL |             drop(x);
    |                  - mutable borrow later used here
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/borrowck-describe-lvalue.rs:273:22
+  --> $DIR/borrowck-describe-lvalue.rs:274:22
    |
 LL |                 drop(x);
    |                      - value moved here
@@ -355,7 +366,7 @@ LL |                 drop(x);
    |
    = note: move occurs because `x` has type `Vec<i32>`, which does not implement the `Copy` trait
 
-error: aborting due to 31 previous errors
+error: aborting due to 32 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 2d22c9a856f..3abc81e191e 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -12,7 +12,8 @@ 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();
 }
 
@@ -54,7 +55,8 @@ fn arrays_4() {
     // c will capture `arr` completely, therefore we cannot borrow another index
     // into the array.
     println!("{}", arr[3]);
-    //~^ ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
+    //~^ ERROR: cannot use `arr` because it was mutably borrowed
+    //~| 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 97ecdfab820..9e5200ef34b 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -1,3 +1,17 @@
+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
    |
@@ -8,12 +22,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:28:5
+  --> $DIR/arrays.rs:29:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -27,7 +41,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:42:5
+  --> $DIR/arrays.rs:43:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -40,8 +54,22 @@ 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:56:20
+  --> $DIR/arrays.rs:57:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -57,7 +85,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:71:24
+  --> $DIR/arrays.rs:73:24
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -70,7 +98,7 @@ LL |     println!("{:#?}", &arr[3..2]);
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 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/const-generics/issues/index_array_bad_type.rs b/tests/ui/const-generics/issues/index_array_bad_type.rs
deleted file mode 100644
index 41e4dba026c..00000000000
--- a/tests/ui/const-generics/issues/index_array_bad_type.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ check-fail
-//@ compile-flags: -C opt-level=0
-
-#![crate_type = "lib"]
-
-// This used to fail in the known-panics lint, as the MIR was ill-typed due to
-// the length constant not actually having type usize.
-// https://github.com/rust-lang/rust/issues/134352
-
-pub struct BadStruct<const N: i64>(pub [u8; N]);
-//~^ ERROR: the constant `N` is not of type `usize`
-
-pub fn bad_array_length_type(value: BadStruct<3>) -> u8 {
-    value.0[0]
-}
diff --git a/tests/ui/const-generics/issues/index_array_bad_type.stderr b/tests/ui/const-generics/issues/index_array_bad_type.stderr
deleted file mode 100644
index e4417192150..00000000000
--- a/tests/ui/const-generics/issues/index_array_bad_type.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: the constant `N` is not of type `usize`
-  --> $DIR/index_array_bad_type.rs:10:40
-   |
-LL | pub struct BadStruct<const N: i64>(pub [u8; N]);
-   |                                        ^^^^^^^ expected `usize`, found `i64`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/consts/issue-65348.rs b/tests/ui/consts/issue-65348.rs
index 0d12da3926c..1443fcbe1c1 100644
--- a/tests/ui/consts/issue-65348.rs
+++ b/tests/ui/consts/issue-65348.rs
@@ -9,17 +9,15 @@ impl<T> Generic<T> {
 }
 
 pub const fn array<T>() -> &'static T {
-    #[expect(unconditional_panic)]
+    #[allow(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/pattern/struct-pattern-on-non-struct-resolve-error.rs b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
new file mode 100644
index 00000000000..17a5bad0e6c
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
@@ -0,0 +1,10 @@
+// Regression test for #135209.
+// We ensure that we don't try to access fields on a non-struct pattern type.
+fn main() {
+    if let <Vec<()> as Iterator>::Item { .. } = 1 {
+        //~^ ERROR E0658
+        //~| ERROR E0071
+        //~| ERROR E0277
+        x //~ ERROR E0425
+    }
+}
diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
new file mode 100644
index 00000000000..793c2d1e97f
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
@@ -0,0 +1,34 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:8:9
+   |
+LL |         x
+   |         ^ not found in this scope
+
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0071]: expected struct, variant or union type, found inferred type
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a struct
+
+error[E0277]: `Vec<()>` is not an iterator
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Vec<()>` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `Vec<()>`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0071, E0277, E0425, E0658.
+For more information about an error, try `rustc --explain E0071`.
diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
index 225891e390f..39f9f5a2c02 100644
--- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
+++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
@@ -3,6 +3,10 @@ struct Website {
     title: Option<String>,
 }
 
+enum Foo {
+    Bar { a: i32 },
+}
+
 fn main() {
     let website = Website {
         url: "http://www.example.com".into(),
@@ -18,4 +22,9 @@ fn main() {
         println!("[{}]({})", title, url); //~ ERROR cannot find value `title` in this scope
         //~^ NOTE not found in this scope
     }
+
+    let x = Foo::Bar { a: 1 };
+    if let Foo::Bar { .. } = x { //~ NOTE this pattern
+        println!("{a}"); //~ ERROR cannot find value `a` in this scope
+    }
 }
diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
index 80fcd714400..b985b771754 100644
--- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
+++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
@@ -1,5 +1,5 @@
 error: expected `,`
-  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:12:31
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:16:31
    |
 LL |     if let Website { url, Some(title) } = website {
    |            -------            ^
@@ -7,13 +7,21 @@ LL |     if let Website { url, Some(title) } = website {
    |            while parsing the fields for this pattern
 
 error[E0425]: cannot find value `title` in this scope
-  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:22:30
    |
 LL |     if let Website { url, .. } = website {
    |            ------------------- this pattern doesn't include `title`, which is available in `Website`
 LL |         println!("[{}]({})", title, url);
    |                              ^^^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error[E0425]: cannot find value `a` in this scope
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20
+   |
+LL |     if let Foo::Bar { .. } = x {
+   |            --------------- this pattern doesn't include `a`, which is available in `Bar`
+LL |         println!("{a}");
+   |                    ^ help: a local variable with a similar name exists: `x`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/stable-mir-print/operands.stdout b/tests/ui/stable-mir-print/operands.stdout
index c3b1151ae24..3c27878b3cf 100644
--- a/tests/ui/stable-mir-print/operands.stdout
+++ b/tests/ui/stable-mir-print/operands.stdout
@@ -5,183 +5,187 @@ fn operands(_1: u8) -> () {
     let  _2: [u8; 10];
     let  _3: u8;
     let  _4: usize;
-    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<'_>>;
+    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<'_>>;
     debug val => _1;
     debug array => _2;
     debug first => _3;
-    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;
+    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;
     bb0: {
         _2 = [_1; 10];
         _4 = 0_usize;
-        _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];
+        _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];
     }
     bb1: {
         _3 = _2[_4];
-        _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];
+        _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];
     }
     bb2: {
-        _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];
+        _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];
     }
     bb3: {
-        _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];
+        _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];
     }
     bb4: {
-        _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];
+        _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];
     }
     bb5: {
-        _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;
+        _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;
     }
     bb6: {
-        _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];
+        _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];
     }
     bb7: {
-        _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;
+        _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;
     }
     bb8: {
-        _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];
+        _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];
     }
     bb9: {
-        _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;
+        _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;
     }
     bb10: {
-        _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];
+        _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];
     }
     bb11: {
         return;
     }
     bb12: {
-        _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;
+        _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;
     }
 }
 fn operands::{constant#0}() -> usize {