about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-17 14:56:48 +1000
committerGitHub <noreply@github.com>2025-09-17 14:56:48 +1000
commit6473a0f02d6549dc25d8f98b3d06f80fa453fe49 (patch)
treeebddd166d5e5281032378486af5dfcd609f09665 /tests
parent577f18ffe23c2c01d98f557c1a12830eadcb7abe (diff)
parentde73af9ec47552dcade86e4ebc4edb8a68fddd2e (diff)
downloadrust-6473a0f02d6549dc25d8f98b3d06f80fa453fe49.tar.gz
rust-6473a0f02d6549dc25d8f98b3d06f80fa453fe49.zip
Rollup merge of #146564 - cjgillot:mir-nolen, r=scottmcm
Remove Rvalue::Len again.

Now that we have `RawPtrKind::FakeForPtrMetadata`, we can reimplement `Rvalue::Len` using `PtrMetadata(&raw const (fake) place)`.

r? ``@scottmcm``
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/building/custom/arrays.arrays.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/arrays.rs4
-rw-r--r--tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir155
-rw-r--r--tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir155
-rw-r--r--tests/mir-opt/building/match/array_len.rs31
-rw-r--r--tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir115
-rw-r--r--tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir115
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff77
-rw-r--r--tests/mir-opt/dataflow-const-prop/slice_len.rs34
-rw-r--r--tests/mir-opt/gvn.array_len.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff71
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff71
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff71
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff71
-rw-r--r--tests/mir-opt/instsimplify/combine_array_len.rs25
-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/lower_array_len.array_len_raw.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff85
26 files changed, 1315 insertions, 106 deletions
diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
index 30d11e31e4d..f9f24c8eabe 100644
--- a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
+++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
@@ -3,12 +3,16 @@
 fn arrays() -> usize {
     let mut _0: usize;
     let mut _1: [i32; C];
-    let mut _2: usize;
+    let mut _2: *const [i32; C];
+    let mut _3: *const [i32];
+    let mut _4: usize;
 
     bb0: {
         _1 = [const 5_i32; C];
-        _2 = Len(_1);
-        _0 = copy _2;
+        _2 = &raw const _1;
+        _3 = copy _2 as *const [i32] (PointerCoercion(Unsize, AsCast));
+        _4 = PtrMetadata(copy _3);
+        _0 = copy _4;
         return;
     }
 }
diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs
index 4bd6f93e113..e9cdded4a0e 100644
--- a/tests/mir-opt/building/custom/arrays.rs
+++ b/tests/mir-opt/building/custom/arrays.rs
@@ -10,7 +10,9 @@ fn arrays<const C: usize>() -> usize {
     mir! {
         {
             let x = [5_i32; C];
-            let c = Len(x);
+            let y = &raw const x;
+            let z = CastUnsize::<_, *const [i32]>(y);
+            let c = PtrMetadata(z);
             RET = c;
             Return()
         }
diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir
new file mode 100644
index 00000000000..8d16f074b1e
--- /dev/null
+++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir
@@ -0,0 +1,155 @@
+// MIR for `const_array_len` after built
+
+fn const_array_len(_1: [T; 5]) -> () {
+    debug x => _1;
+    let mut _0: ();
+    let _6: ();
+    let mut _7: T;
+    let _8: ();
+    let mut _9: T;
+    let _10: ();
+    let mut _11: [T; 2];
+    let _12: ();
+    let mut _13: T;
+    scope 1 {
+        debug a => _2;
+        debug b => _3;
+        debug rest => _4;
+        debug e => _5;
+        let _2: T;
+        let _3: T;
+        let _4: [T; 2];
+        let _5: T;
+    }
+
+    bb0: {
+        PlaceMention(_1);
+        falseEdge -> [real: bb2, imaginary: bb1];
+    }
+
+    bb1: {
+        goto -> bb7;
+    }
+
+    bb2: {
+        StorageLive(_2);
+        _2 = move _1[0 of 5];
+        StorageLive(_3);
+        _3 = move _1[1 of 5];
+        StorageLive(_4);
+        _4 = move _1[2..4];
+        StorageLive(_5);
+        _5 = move _1[4 of 5];
+        StorageLive(_6);
+        StorageLive(_7);
+        _7 = move _2;
+        _6 = opaque::<T>(move _7) -> [return: bb3, unwind: bb17];
+    }
+
+    bb3: {
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageLive(_8);
+        StorageLive(_9);
+        _9 = move _3;
+        _8 = opaque::<T>(move _9) -> [return: bb4, unwind: bb16];
+    }
+
+    bb4: {
+        StorageDead(_9);
+        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_11);
+        _11 = move _4;
+        _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15];
+    }
+
+    bb5: {
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageLive(_12);
+        StorageLive(_13);
+        _13 = move _5;
+        _12 = opaque::<T>(move _13) -> [return: bb6, unwind: bb14];
+    }
+
+    bb6: {
+        StorageDead(_13);
+        StorageDead(_12);
+        _0 = const ();
+        drop(_5) -> [return: bb8, unwind: bb19];
+    }
+
+    bb7: {
+        _0 = const ();
+        goto -> bb12;
+    }
+
+    bb8: {
+        StorageDead(_5);
+        drop(_4) -> [return: bb9, unwind: bb20];
+    }
+
+    bb9: {
+        StorageDead(_4);
+        drop(_3) -> [return: bb10, unwind: bb21];
+    }
+
+    bb10: {
+        StorageDead(_3);
+        drop(_2) -> [return: bb11, unwind: bb22];
+    }
+
+    bb11: {
+        StorageDead(_2);
+        goto -> bb12;
+    }
+
+    bb12: {
+        drop(_1) -> [return: bb13, unwind: bb23];
+    }
+
+    bb13: {
+        return;
+    }
+
+    bb14 (cleanup): {
+        drop(_13) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb15 (cleanup): {
+        drop(_11) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb16 (cleanup): {
+        drop(_9) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb17 (cleanup): {
+        drop(_7) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb18 (cleanup): {
+        drop(_5) -> [return: bb19, unwind terminate(cleanup)];
+    }
+
+    bb19 (cleanup): {
+        drop(_4) -> [return: bb20, unwind terminate(cleanup)];
+    }
+
+    bb20 (cleanup): {
+        drop(_3) -> [return: bb21, unwind terminate(cleanup)];
+    }
+
+    bb21 (cleanup): {
+        drop(_2) -> [return: bb22, unwind terminate(cleanup)];
+    }
+
+    bb22 (cleanup): {
+        drop(_1) -> [return: bb23, unwind terminate(cleanup)];
+    }
+
+    bb23 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir
new file mode 100644
index 00000000000..8d16f074b1e
--- /dev/null
+++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir
@@ -0,0 +1,155 @@
+// MIR for `const_array_len` after built
+
+fn const_array_len(_1: [T; 5]) -> () {
+    debug x => _1;
+    let mut _0: ();
+    let _6: ();
+    let mut _7: T;
+    let _8: ();
+    let mut _9: T;
+    let _10: ();
+    let mut _11: [T; 2];
+    let _12: ();
+    let mut _13: T;
+    scope 1 {
+        debug a => _2;
+        debug b => _3;
+        debug rest => _4;
+        debug e => _5;
+        let _2: T;
+        let _3: T;
+        let _4: [T; 2];
+        let _5: T;
+    }
+
+    bb0: {
+        PlaceMention(_1);
+        falseEdge -> [real: bb2, imaginary: bb1];
+    }
+
+    bb1: {
+        goto -> bb7;
+    }
+
+    bb2: {
+        StorageLive(_2);
+        _2 = move _1[0 of 5];
+        StorageLive(_3);
+        _3 = move _1[1 of 5];
+        StorageLive(_4);
+        _4 = move _1[2..4];
+        StorageLive(_5);
+        _5 = move _1[4 of 5];
+        StorageLive(_6);
+        StorageLive(_7);
+        _7 = move _2;
+        _6 = opaque::<T>(move _7) -> [return: bb3, unwind: bb17];
+    }
+
+    bb3: {
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageLive(_8);
+        StorageLive(_9);
+        _9 = move _3;
+        _8 = opaque::<T>(move _9) -> [return: bb4, unwind: bb16];
+    }
+
+    bb4: {
+        StorageDead(_9);
+        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_11);
+        _11 = move _4;
+        _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15];
+    }
+
+    bb5: {
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageLive(_12);
+        StorageLive(_13);
+        _13 = move _5;
+        _12 = opaque::<T>(move _13) -> [return: bb6, unwind: bb14];
+    }
+
+    bb6: {
+        StorageDead(_13);
+        StorageDead(_12);
+        _0 = const ();
+        drop(_5) -> [return: bb8, unwind: bb19];
+    }
+
+    bb7: {
+        _0 = const ();
+        goto -> bb12;
+    }
+
+    bb8: {
+        StorageDead(_5);
+        drop(_4) -> [return: bb9, unwind: bb20];
+    }
+
+    bb9: {
+        StorageDead(_4);
+        drop(_3) -> [return: bb10, unwind: bb21];
+    }
+
+    bb10: {
+        StorageDead(_3);
+        drop(_2) -> [return: bb11, unwind: bb22];
+    }
+
+    bb11: {
+        StorageDead(_2);
+        goto -> bb12;
+    }
+
+    bb12: {
+        drop(_1) -> [return: bb13, unwind: bb23];
+    }
+
+    bb13: {
+        return;
+    }
+
+    bb14 (cleanup): {
+        drop(_13) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb15 (cleanup): {
+        drop(_11) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb16 (cleanup): {
+        drop(_9) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb17 (cleanup): {
+        drop(_7) -> [return: bb18, unwind terminate(cleanup)];
+    }
+
+    bb18 (cleanup): {
+        drop(_5) -> [return: bb19, unwind terminate(cleanup)];
+    }
+
+    bb19 (cleanup): {
+        drop(_4) -> [return: bb20, unwind terminate(cleanup)];
+    }
+
+    bb20 (cleanup): {
+        drop(_3) -> [return: bb21, unwind terminate(cleanup)];
+    }
+
+    bb21 (cleanup): {
+        drop(_2) -> [return: bb22, unwind terminate(cleanup)];
+    }
+
+    bb22 (cleanup): {
+        drop(_1) -> [return: bb23, unwind terminate(cleanup)];
+    }
+
+    bb23 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/match/array_len.rs b/tests/mir-opt/building/match/array_len.rs
new file mode 100644
index 00000000000..0d889ada9b6
--- /dev/null
+++ b/tests/mir-opt/building/match/array_len.rs
@@ -0,0 +1,31 @@
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+//@ compile-flags: -Zmir-opt-level=0
+
+fn opaque<T>(x: T) {}
+
+// EMIT_MIR array_len.const_array_len.built.after.mir
+fn const_array_len<T>(x: [T; 5]) {
+    // CHECK-LABEL: fn const_array_len(
+    // CHECK-NOT: Len
+    // CHECK-NOT: PtrMetadata
+    // CHECK: = const 5_usize;
+    if let [a, b, rest @ .., e] = x {
+        opaque(a);
+        opaque(b);
+        opaque(rest);
+        opaque(e);
+    }
+}
+
+// EMIT_MIR array_len.slice_len.built.after.mir
+fn slice_len<T>(x: &[T]) {
+    // CHECK-LABEL: fn slice_len(
+    // CHECK-NOT: Len
+    // CHECK: = PtrMetadata(copy _1);
+    if let [a, b, rest @ .., e] = x {
+        opaque(a);
+        opaque(b);
+        opaque(rest);
+        opaque(e);
+    }
+}
diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir
new file mode 100644
index 00000000000..d73f5a1b6f7
--- /dev/null
+++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir
@@ -0,0 +1,115 @@
+// MIR for `slice_len` after built
+
+fn slice_len(_1: &[T]) -> () {
+    debug x => _1;
+    let mut _0: ();
+    let mut _2: usize;
+    let mut _3: usize;
+    let mut _4: usize;
+    let mut _5: bool;
+    let _10: ();
+    let mut _11: &T;
+    let _12: ();
+    let mut _13: &T;
+    let _14: ();
+    let mut _15: &[T];
+    let _16: ();
+    let mut _17: &T;
+    scope 1 {
+        debug a => _6;
+        debug b => _7;
+        debug rest => _8;
+        debug e => _9;
+        let _6: &T;
+        let _7: &T;
+        let _8: &[T];
+        let _9: &T;
+    }
+
+    bb0: {
+        PlaceMention(_1);
+        _3 = PtrMetadata(copy _1);
+        _2 = move _3;
+        _4 = const 3_usize;
+        _5 = Ge(move _2, move _4);
+        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+    }
+
+    bb1: {
+        goto -> bb9;
+    }
+
+    bb2: {
+        falseEdge -> [real: bb4, imaginary: bb1];
+    }
+
+    bb3: {
+        goto -> bb1;
+    }
+
+    bb4: {
+        StorageLive(_6);
+        _6 = &(*_1)[0 of 3];
+        StorageLive(_7);
+        _7 = &(*_1)[1 of 3];
+        StorageLive(_8);
+        _8 = &(*_1)[2:-1];
+        StorageLive(_9);
+        _9 = &(*_1)[-1 of 3];
+        StorageLive(_10);
+        StorageLive(_11);
+        _11 = copy _6;
+        _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11];
+    }
+
+    bb5: {
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageLive(_12);
+        StorageLive(_13);
+        _13 = copy _7;
+        _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11];
+    }
+
+    bb6: {
+        StorageDead(_13);
+        StorageDead(_12);
+        StorageLive(_14);
+        StorageLive(_15);
+        _15 = copy _8;
+        _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11];
+    }
+
+    bb7: {
+        StorageDead(_15);
+        StorageDead(_14);
+        StorageLive(_16);
+        StorageLive(_17);
+        _17 = copy _9;
+        _16 = opaque::<&T>(move _17) -> [return: bb8, unwind: bb11];
+    }
+
+    bb8: {
+        StorageDead(_17);
+        StorageDead(_16);
+        _0 = const ();
+        StorageDead(_9);
+        StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb10;
+    }
+
+    bb9: {
+        _0 = const ();
+        goto -> bb10;
+    }
+
+    bb10: {
+        return;
+    }
+
+    bb11 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir
new file mode 100644
index 00000000000..d73f5a1b6f7
--- /dev/null
+++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir
@@ -0,0 +1,115 @@
+// MIR for `slice_len` after built
+
+fn slice_len(_1: &[T]) -> () {
+    debug x => _1;
+    let mut _0: ();
+    let mut _2: usize;
+    let mut _3: usize;
+    let mut _4: usize;
+    let mut _5: bool;
+    let _10: ();
+    let mut _11: &T;
+    let _12: ();
+    let mut _13: &T;
+    let _14: ();
+    let mut _15: &[T];
+    let _16: ();
+    let mut _17: &T;
+    scope 1 {
+        debug a => _6;
+        debug b => _7;
+        debug rest => _8;
+        debug e => _9;
+        let _6: &T;
+        let _7: &T;
+        let _8: &[T];
+        let _9: &T;
+    }
+
+    bb0: {
+        PlaceMention(_1);
+        _3 = PtrMetadata(copy _1);
+        _2 = move _3;
+        _4 = const 3_usize;
+        _5 = Ge(move _2, move _4);
+        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+    }
+
+    bb1: {
+        goto -> bb9;
+    }
+
+    bb2: {
+        falseEdge -> [real: bb4, imaginary: bb1];
+    }
+
+    bb3: {
+        goto -> bb1;
+    }
+
+    bb4: {
+        StorageLive(_6);
+        _6 = &(*_1)[0 of 3];
+        StorageLive(_7);
+        _7 = &(*_1)[1 of 3];
+        StorageLive(_8);
+        _8 = &(*_1)[2:-1];
+        StorageLive(_9);
+        _9 = &(*_1)[-1 of 3];
+        StorageLive(_10);
+        StorageLive(_11);
+        _11 = copy _6;
+        _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11];
+    }
+
+    bb5: {
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageLive(_12);
+        StorageLive(_13);
+        _13 = copy _7;
+        _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11];
+    }
+
+    bb6: {
+        StorageDead(_13);
+        StorageDead(_12);
+        StorageLive(_14);
+        StorageLive(_15);
+        _15 = copy _8;
+        _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11];
+    }
+
+    bb7: {
+        StorageDead(_15);
+        StorageDead(_14);
+        StorageLive(_16);
+        StorageLive(_17);
+        _17 = copy _9;
+        _16 = opaque::<&T>(move _17) -> [return: bb8, unwind: bb11];
+    }
+
+    bb8: {
+        StorageDead(_17);
+        StorageDead(_16);
+        _0 = const ();
+        StorageDead(_9);
+        StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_6);
+        goto -> bb10;
+    }
+
+    bb9: {
+        _0 = const ();
+        goto -> bb10;
+    }
+
+    bb10: {
+        return;
+    }
+
+    bb11 (cleanup): {
+        resume;
+    }
+}
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..fd9ef54fe77
--- /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 = PtrMetadata(copy _2);
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
++         _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 = PtrMetadata(copy _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..1fec08c2562
--- /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 = PtrMetadata(copy _2);
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
++         _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 = PtrMetadata(copy _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..fd9ef54fe77
--- /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 = PtrMetadata(copy _2);
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
++         _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 = PtrMetadata(copy _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..1fec08c2562
--- /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 = PtrMetadata(copy _2);
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
++         _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 = PtrMetadata(copy _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/gvn.array_len.GVN.panic-abort.diff b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff
index 0d0477fe772..59b65a52f4e 100644
--- a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff
@@ -12,8 +12,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
           _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit));
@@ -23,8 +22,7 @@
 -         _0 = PtrMetadata(move _4);
 +         _0 = const 42_usize;
           StorageDead(_4);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           return;
       }
   }
diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff
index 0d0477fe772..59b65a52f4e 100644
--- a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff
@@ -12,8 +12,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           _3 = &(*_1);
           _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit));
@@ -23,8 +22,7 @@
 -         _0 = PtrMetadata(move _4);
 +         _0 = const 42_usize;
           StorageDead(_4);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           return;
       }
   }
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..feba0fe7c4a
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
@@ -0,0 +1,71 @@
+- // 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: bool;
+      let _6: usize;
+      let mut _7: bool;
+      let mut _8: f32;
+      let mut _9: f32;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      scope 1 {
+          debug a => _2;
+          let _5: f32;
+          scope 2 {
+              debug b => _5;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+          _4 = Lt(copy _3, const 2_usize);
+          assert(move _4, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _3) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_5);
+          StorageLive(_6);
+          _6 = const 1_usize;
+          _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: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          _5 = copy _1[_6];
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = copy _2;
+          StorageLive(_10);
+          _10 = copy _2;
+          _8 = Mul(move _9, move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = copy _5;
+          StorageLive(_13);
+          _13 = copy _5;
+          _11 = Mul(move _12, move _13);
+          StorageDead(_13);
+          StorageDead(_12);
+          _0 = Add(move _8, move _11);
+          StorageDead(_11);
+          StorageDead(_8);
+          StorageDead(_5);
+          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..0ccf6a825c4
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
@@ -0,0 +1,71 @@
+- // 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: bool;
+      let _6: usize;
+      let mut _7: bool;
+      let mut _8: f32;
+      let mut _9: f32;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      scope 1 {
+          debug a => _2;
+          let _5: f32;
+          scope 2 {
+              debug b => _5;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+          _4 = Lt(copy _3, const 2_usize);
+          assert(move _4, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _3) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_5);
+          StorageLive(_6);
+          _6 = const 1_usize;
+          _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: bb2, unwind continue];
+      }
+  
+      bb2: {
+          _5 = copy _1[_6];
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = copy _2;
+          StorageLive(_10);
+          _10 = copy _2;
+          _8 = Mul(move _9, move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = copy _5;
+          StorageLive(_13);
+          _13 = copy _5;
+          _11 = Mul(move _12, move _13);
+          StorageDead(_13);
+          StorageDead(_12);
+          _0 = Add(move _8, move _11);
+          StorageDead(_11);
+          StorageDead(_8);
+          StorageDead(_5);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff
new file mode 100644
index 00000000000..e9cb2c58177
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff
@@ -0,0 +1,71 @@
+- // MIR for `normN` before InstSimplify-after-simplifycfg
++ // MIR for `normN` after InstSimplify-after-simplifycfg
+  
+  fn normN(_1: [f32; N]) -> f32 {
+      debug x => _1;
+      let mut _0: f32;
+      let _2: f32;
+      let _3: usize;
+      let mut _4: bool;
+      let _6: usize;
+      let mut _7: bool;
+      let mut _8: f32;
+      let mut _9: f32;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      scope 1 {
+          debug a => _2;
+          let _5: f32;
+          scope 2 {
+              debug b => _5;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+          _4 = Lt(copy _3, const N);
+          assert(move _4, "index out of bounds: the length is {} but the index is {}", const N, copy _3) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_5);
+          StorageLive(_6);
+          _6 = const 1_usize;
+          _7 = Lt(copy _6, const N);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", const N, copy _6) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          _5 = copy _1[_6];
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = copy _2;
+          StorageLive(_10);
+          _10 = copy _2;
+          _8 = Mul(move _9, move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = copy _5;
+          StorageLive(_13);
+          _13 = copy _5;
+          _11 = Mul(move _12, move _13);
+          StorageDead(_13);
+          StorageDead(_12);
+          _0 = Add(move _8, move _11);
+          StorageDead(_11);
+          StorageDead(_8);
+          StorageDead(_5);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff
new file mode 100644
index 00000000000..0ddc70f2003
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff
@@ -0,0 +1,71 @@
+- // MIR for `normN` before InstSimplify-after-simplifycfg
++ // MIR for `normN` after InstSimplify-after-simplifycfg
+  
+  fn normN(_1: [f32; N]) -> f32 {
+      debug x => _1;
+      let mut _0: f32;
+      let _2: f32;
+      let _3: usize;
+      let mut _4: bool;
+      let _6: usize;
+      let mut _7: bool;
+      let mut _8: f32;
+      let mut _9: f32;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      scope 1 {
+          debug a => _2;
+          let _5: f32;
+          scope 2 {
+              debug b => _5;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+          _4 = Lt(copy _3, const N);
+          assert(move _4, "index out of bounds: the length is {} but the index is {}", const N, copy _3) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_5);
+          StorageLive(_6);
+          _6 = const 1_usize;
+          _7 = Lt(copy _6, const N);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", const N, copy _6) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+          _5 = copy _1[_6];
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = copy _2;
+          StorageLive(_10);
+          _10 = copy _2;
+          _8 = Mul(move _9, move _10);
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = copy _5;
+          StorageLive(_13);
+          _13 = copy _5;
+          _11 = Mul(move _12, move _13);
+          StorageDead(_13);
+          StorageDead(_12);
+          _0 = Add(move _8, move _11);
+          StorageDead(_11);
+          StorageDead(_8);
+          StorageDead(_5);
+          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..1c4d42d3bbe
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.rs
@@ -0,0 +1,25 @@
+// 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: PtrMetadata(
+    let a = x[0];
+    let b = x[1];
+    a * a + b * b
+}
+
+// EMIT_MIR combine_array_len.normN.InstSimplify-after-simplifycfg.diff
+fn normN<const N: usize>(x: [f32; N]) -> f32 {
+    // CHECK-LABEL: fn normN(
+    // CHECK-NOT: PtrMetadata(
+    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);
+    assert_eq!(normN([3.0, 4.0]), 5.0 * 5.0);
+}
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 08dee3697e0..5cf36b9aebf 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
@@ -7,18 +7,16 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _5: usize;
-      let mut _6: bool;
-      let mut _10: !;
+      let mut _8: !;
       scope 1 {
           debug v => _2;
+          let _5: &T;
+          let _6: &T;
           let _7: &T;
-          let _8: &T;
-          let _9: &T;
           scope 2 {
-              debug v1 => _7;
-              debug v2 => _8;
-              debug v3 => _9;
+              debug v1 => _5;
+              debug v2 => _6;
+              debug v3 => _7;
           }
       }
   
@@ -27,25 +25,23 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
-          nop;
-          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable;
+          _8 = 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)[0 of 3];
-          StorageLive(_8);
-          _8 = &(*_2)[1 of 3];
-          StorageLive(_9);
-          _9 = &(*_2)[2 of 3];
-          StorageDead(_9);
-          StorageDead(_8);
+          _7 = &(*_2)[2 of 3];
           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 aa44a2ad532..0598a3aa3f1 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
@@ -7,18 +7,16 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _5: usize;
-      let mut _6: bool;
-      let mut _10: !;
+      let mut _8: !;
       scope 1 {
           debug v => _2;
+          let _5: &T;
+          let _6: &T;
           let _7: &T;
-          let _8: &T;
-          let _9: &T;
           scope 2 {
-              debug v1 => _7;
-              debug v2 => _8;
-              debug v3 => _9;
+              debug v1 => _5;
+              debug v2 => _6;
+              debug v3 => _7;
           }
       }
   
@@ -27,25 +25,23 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
-          nop;
-          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
+          _8 = 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)[0 of 3];
-          StorageLive(_8);
-          _8 = &(*_2)[1 of 3];
-          StorageLive(_9);
-          _9 = &(*_2)[2 of 3];
-          StorageDead(_9);
-          StorageDead(_8);
+          _7 = &(*_2)[2 of 3];
           StorageDead(_7);
+          StorageDead(_6);
+          StorageDead(_5);
           StorageDead(_4);
           return;
       }
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff
index 180a7db0297..714a12804e6 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff
@@ -18,8 +18,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
           _4 = &_1;
@@ -41,8 +40,7 @@
       bb1: {
           StorageDead(_6);
           StorageDead(_5);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           StorageDead(_7);
           return;
       }
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff
index 180a7db0297..714a12804e6 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff
@@ -18,8 +18,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
           _4 = &_1;
@@ -41,8 +40,7 @@
       bb1: {
           StorageDead(_6);
           StorageDead(_5);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           StorageDead(_7);
           return;
       }
diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff
index 49964f8b49e..b236b22f067 100644
--- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff
@@ -17,8 +17,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
           _4 = &mut _1;
@@ -38,8 +37,7 @@
       bb1: {
           StorageDead(_6);
           StorageDead(_5);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           return;
       }
   }
diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff
index 49964f8b49e..b236b22f067 100644
--- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff
@@ -17,8 +17,7 @@
       }
   
       bb0: {
--         StorageLive(_2);
-+         nop;
+          StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
           _4 = &mut _1;
@@ -38,8 +37,7 @@
       bb1: {
           StorageDead(_6);
           StorageDead(_5);
--         StorageDead(_2);
-+         nop;
+          StorageDead(_2);
           return;
       }
   }
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
index 3da795b61f9..375b6096d88 100644
--- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -17,14 +17,15 @@
       let mut _15: std::ops::RangeFull;
       let mut _16: usize;
       let mut _17: usize;
-      let mut _18: bool;
-      let _23: &&mut u8;
-      let _24: &mut u8;
-      let mut _25: debuginfo::T;
+      let mut _18: usize;
+      let mut _19: bool;
+      let _24: &&mut u8;
+      let _25: &mut u8;
+      let mut _26: debuginfo::T;
       scope 1 {
           debug ref_mut_u8 => _1;
           let _3: &u8;
-          let mut _28: &debuginfo::T;
+          let mut _29: &debuginfo::T;
           scope 2 {
               debug field => _3;
               let _5: &u8;
@@ -32,22 +33,22 @@
 -                 debug reborrow => _5;
 +                 debug reborrow => _1;
                   let _9: &i32;
-                  let _22: &&&mut u8;
-                  let mut _27: &std::option::Option<i32>;
+                  let _23: &&&mut u8;
+                  let mut _28: &std::option::Option<i32>;
                   scope 4 {
                       debug variant_field => _9;
                   }
                   scope 5 {
-                      debug constant_index => _19;
-                      debug subslice => _20;
-                      debug constant_index_from_end => _21;
-                      let _19: &i32;
-                      let _20: &[i32];
-                      let _21: &i32;
-                      let mut _26: &[i32; 10];
+                      debug constant_index => _20;
+                      debug subslice => _21;
+                      debug constant_index_from_end => _22;
+                      let _20: &i32;
+                      let _21: &[i32];
+                      let _22: &i32;
+                      let mut _27: &[i32; 10];
                   }
                   scope 6 {
-                      debug multiple_borrow => _22;
+                      debug multiple_borrow => _23;
                   }
               }
           }
@@ -59,8 +60,8 @@
           _2 = const 5_u8;
           _1 = &mut _2;
           StorageLive(_3);
-          _28 = const debuginfo::promoted[2];
-          _3 = &((*_28).0: u8);
+          _29 = const debuginfo::promoted[2];
+          _3 = &((*_29).0: u8);
 -         StorageLive(_5);
 -         _5 = &(*_1);
 -         StorageLive(_6);
@@ -76,8 +77,8 @@
   
       bb2: {
           StorageLive(_9);
-          _27 = const debuginfo::promoted[1];
-          _9 = &(((*_27) as Some).0: i32);
+          _28 = const debuginfo::promoted[1];
+          _9 = &(((*_28) as Some).0: i32);
 -         _6 = const ();
           StorageDead(_9);
           goto -> bb4;
@@ -92,11 +93,11 @@
           StorageDead(_7);
 -         StorageDead(_6);
 -         StorageLive(_10);
--         StorageLive(_11);
+          StorageLive(_11);
 -         StorageLive(_12);
           StorageLive(_13);
-          _26 = const debuginfo::promoted[0];
-          _13 = &(*_26);
+          _27 = const debuginfo::promoted[0];
+          _13 = &(*_27);
           StorageLive(_15);
           _15 = RangeFull;
 -         _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> [return: bb5, unwind continue];
@@ -106,28 +107,28 @@
       bb5: {
           StorageDead(_15);
           StorageDead(_13);
--         _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];
+          _11 = &(*_12);
+          _17 = PtrMetadata(copy _11);
+          _16 = move _17;
+          _18 = const 3_usize;
+          _19 = Ge(move _16, move _18);
+          switchInt(move _19) -> [0: bb7, otherwise: bb6];
       }
   
       bb6: {
-          StorageLive(_19);
--         _19 = &(*_11)[1 of 3];
-+         _19 = &(*_12)[1 of 3];
           StorageLive(_20);
--         _20 = &(*_11)[2:-1];
-+         _20 = &(*_12)[2:-1];
+-         _20 = &(*_11)[1 of 3];
++         _20 = &(*_12)[1 of 3];
           StorageLive(_21);
--         _21 = &(*_11)[-1 of 3];
+-         _21 = &(*_11)[2:-1];
++         _21 = &(*_12)[2:-1];
+          StorageLive(_22);
+-         _22 = &(*_11)[-1 of 3];
 -         _10 = const ();
-+         _21 = &(*_12)[-1 of 3];
++         _22 = &(*_12)[-1 of 3];
+          StorageDead(_22);
           StorageDead(_21);
           StorageDead(_20);
-          StorageDead(_19);
           goto -> bb8;
       }
   
@@ -138,21 +139,21 @@
   
       bb8: {
 -         StorageDead(_12);
--         StorageDead(_11);
+          StorageDead(_11);
 -         StorageDead(_10);
-          StorageLive(_22);
           StorageLive(_23);
           StorageLive(_24);
           StorageLive(_25);
-          _25 = T(const 6_u8);
-          _24 = &mut (_25.0: u8);
+          StorageLive(_26);
+          _26 = T(const 6_u8);
+          _25 = &mut (_26.0: u8);
+          _24 = &_25;
           _23 = &_24;
-          _22 = &_23;
           _0 = const ();
+          StorageDead(_26);
           StorageDead(_25);
           StorageDead(_24);
           StorageDead(_23);
-          StorageDead(_22);
 -         StorageDead(_5);
           StorageDead(_3);
           StorageDead(_2);