about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2024-11-21 17:59:43 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2025-01-08 18:46:30 -0800
commit8dcc676c9283b040d1ef6d66f156ff2212544b10 (patch)
tree845110d0bc935ff32d70963c479d3f0f60925ff0
parente26ff2f9086fc449b963df578f8641c31846abe6 (diff)
downloadrust-8dcc676c9283b040d1ef6d66f156ff2212544b10.tar.gz
rust-8dcc676c9283b040d1ef6d66f156ff2212544b10.zip
[mir-opt] GVN some more transmute cases
We already did `Transmute`-then-`PtrToPtr`; this adds the nearly-identical `PtrToPtr`-then-`Transmute`.

It also adds `transmute(Foo(x))` → `transmute(x)`, when `Foo` is a single-field transparent type.  That's useful for things like `NonNull { pointer: p }.as_ptr()`.

Found these as I was looking at MCP807-related changes.
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs56
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs23
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff81
-rw-r--r--tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff81
-rw-r--r--tests/mir-opt/gvn.rs50
-rw-r--r--tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff115
-rw-r--r--tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff115
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff87
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir2
-rw-r--r--tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir2
-rw-r--r--tests/mir-opt/inline/unsized_argument.caller.Inline.diff2
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff83
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff30
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.rs25
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir182
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir132
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir116
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir116
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir130
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir130
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir46
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir46
30 files changed, 1034 insertions, 648 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 283ed94b615..ca70dc36da0 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1368,7 +1368,19 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
 
         let mut was_updated = false;
 
-        // If that cast just casts away the metadata again,
+        // Transmuting `*const T` <=> `*mut T` is just a pointer cast,
+        // which we might be able to merge with other ones later.
+        if let Transmute = kind
+            && let ty::RawPtr(from_pointee, _) = from.kind()
+            && let ty::RawPtr(to_pointee, _) = to.kind()
+            && from_pointee == to_pointee
+        {
+            *kind = PtrToPtr;
+            was_updated = true;
+        }
+
+        // If a cast just casts away the metadata again, then we can get it by
+        // casting the original thin pointer passed to `from_raw_parts`
         if let PtrToPtr = kind
             && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) =
                 self.get(value)
@@ -1397,6 +1409,28 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         }
 
+        // Aggregate-then-Transmute can just transmute the original field value,
+        // so long as the type is transparent over only that one single field.
+        if let Transmute = kind
+            && let Value::Aggregate(
+                AggregateTy::Def(aggregate_did, aggregate_args),
+                FIRST_VARIANT,
+                field_values,
+            ) = self.get(value)
+            && let [single_field_value] = **field_values
+            && let adt = self.tcx.adt_def(aggregate_did)
+            && adt.is_struct()
+            && adt.repr().transparent()
+        {
+            let field_ty = adt.non_enum_variant().single_field().ty(self.tcx, aggregate_args);
+            from = field_ty;
+            value = single_field_value;
+            was_updated = true;
+            if field_ty == to {
+                return Some(single_field_value);
+            }
+        }
+
         // PtrToPtr-then-Transmute can just transmute the original, so long as the
         // PtrToPtr didn't change metadata (and thus the size of the pointer)
         if let Transmute = kind
@@ -1416,6 +1450,26 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         }
 
+        // PtrToPtr-then-Transmute can just transmute the original, so long as the
+        // PtrToPtr didn't change metadata (and thus the size of the pointer)
+        if let PtrToPtr = kind
+            && let Value::Cast {
+                kind: Transmute,
+                value: inner_value,
+                from: inner_from,
+                to: _inner_to,
+            } = *self.get(value)
+            && self.pointers_have_same_metadata(from, to)
+        {
+            *kind = Transmute;
+            from = inner_from;
+            value = inner_value;
+            was_updated = true;
+            if inner_from == to {
+                return Some(inner_value);
+            }
+        }
+
         if was_updated && let Some(op) = self.try_as_operand(value, location) {
             *operand = op;
         }
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 1a65affe812..9e024508c58 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -173,29 +173,6 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
                     *kind = CastKind::IntToInt;
                     return;
                 }
-
-                // Transmuting a transparent struct/union to a field's type is a projection
-                if let ty::Adt(adt_def, args) = operand_ty.kind()
-                    && adt_def.repr().transparent()
-                    && (adt_def.is_struct() || adt_def.is_union())
-                    && let Some(place) = operand.place()
-                {
-                    let variant = adt_def.non_enum_variant();
-                    for (i, field) in variant.fields.iter_enumerated() {
-                        let field_ty = field.ty(self.tcx, args);
-                        if field_ty == *cast_ty {
-                            let place = place
-                                .project_deeper(&[ProjectionElem::Field(i, *cast_ty)], self.tcx);
-                            let operand = if operand.is_move() {
-                                Operand::Move(place)
-                            } else {
-                                Operand::Copy(place)
-                            };
-                            *rvalue = Rvalue::Use(operand);
-                            return;
-                        }
-                    }
-                }
             }
         }
     }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index 4097e060f4d..5ea9902b262 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -51,7 +51,6 @@
           StorageLive(_7);
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -79,6 +78,7 @@
           _11 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
           StorageDead(_5);
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index ff44d0df5e3..cc5a41a7f63 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -51,7 +51,6 @@
           StorageLive(_7);
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -83,6 +82,7 @@
           _11 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
           StorageDead(_5);
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index 3662c3b59d2..3d398fbea79 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -51,7 +51,6 @@
           StorageLive(_7);
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -79,6 +78,7 @@
           _11 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
           StorageDead(_5);
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index 68dee57dee9..dc99c3f7a8c 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -51,7 +51,6 @@
           StorageLive(_7);
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -83,6 +82,7 @@
           _11 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
           StorageDead(_5);
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index e62fcb66e3a..6a3ec543069 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -53,7 +53,6 @@
 -         _6 = copy _7 as *mut [bool; 0] (Transmute);
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -67,7 +66,7 @@
   
       bb2: {
           StorageLive(_10);
--         _10 = copy _6 as *mut () (PtrToPtr);
+-         _10 = copy _7 as *mut () (Transmute);
 -         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
 +         _10 = const {0x1 as *mut ()};
 +         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
@@ -80,11 +79,12 @@
   
       bb4: {
           StorageDead(_8);
--         _11 = copy _6 as *const [bool; 0] (PtrToPtr);
+-         _11 = copy _7 as *const [bool; 0] (Transmute);
 -         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
 +         _11 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
 +         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index 8183abd315a..9471ad47cd9 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -53,7 +53,6 @@
 -         _6 = copy _7 as *mut [bool; 0] (Transmute);
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -71,7 +70,7 @@
   
       bb3: {
           StorageLive(_10);
--         _10 = copy _6 as *mut () (PtrToPtr);
+-         _10 = copy _7 as *mut () (Transmute);
 -         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
 +         _10 = const {0x1 as *mut ()};
 +         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
@@ -84,11 +83,12 @@
   
       bb5: {
           StorageDead(_8);
--         _11 = copy _6 as *const [bool; 0] (PtrToPtr);
+-         _11 = copy _7 as *const [bool; 0] (Transmute);
 -         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
 +         _11 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
 +         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index 4fa6ef29e06..187927b8eca 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -53,7 +53,6 @@
 -         _6 = copy _7 as *mut [bool; 0] (Transmute);
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -67,7 +66,7 @@
   
       bb2: {
           StorageLive(_10);
--         _10 = copy _6 as *mut () (PtrToPtr);
+-         _10 = copy _7 as *mut () (Transmute);
 -         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
 +         _10 = const {0x1 as *mut ()};
 +         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
@@ -80,11 +79,12 @@
   
       bb4: {
           StorageDead(_8);
--         _11 = copy _6 as *const [bool; 0] (PtrToPtr);
+-         _11 = copy _7 as *const [bool; 0] (Transmute);
 -         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
 +         _11 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
 +         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index 75329204563..031c021ba5a 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -53,7 +53,6 @@
 -         _6 = copy _7 as *mut [bool; 0] (Transmute);
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
-          StorageDead(_7);
           StorageLive(_11);
           StorageLive(_8);
           _8 = UbChecks();
@@ -71,7 +70,7 @@
   
       bb3: {
           StorageLive(_10);
--         _10 = copy _6 as *mut () (PtrToPtr);
+-         _10 = copy _7 as *mut () (Transmute);
 -         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
 +         _10 = const {0x1 as *mut ()};
 +         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
@@ -84,11 +83,12 @@
   
       bb5: {
           StorageDead(_8);
--         _11 = copy _6 as *const [bool; 0] (PtrToPtr);
+-         _11 = copy _7 as *const [bool; 0] (Transmute);
 -         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
 +         _11 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
           StorageDead(_11);
+          StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
 +         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff
new file mode 100644
index 00000000000..161141ebc64
--- /dev/null
+++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-abort.diff
@@ -0,0 +1,81 @@
+- // MIR for `aggregate_struct_then_transmute` before GVN
++ // MIR for `aggregate_struct_then_transmute` after GVN
+  
+  fn aggregate_struct_then_transmute(_1: u16) -> () {
+      debug id => _1;
+      let mut _0: ();
+      let _2: MyId;
+      let mut _3: u16;
+      let _4: ();
+      let mut _5: u16;
+      let mut _6: MyId;
+      let mut _8: u16;
+      let mut _9: std::marker::PhantomData<std::string::String>;
+      let _10: ();
+      let mut _11: u16;
+      let mut _12: TypedId<std::string::String>;
+      scope 1 {
+          debug a => _2;
+          let _7: TypedId<std::string::String>;
+          scope 2 {
+              debug b => _7;
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_2);
++         nop;
+          StorageLive(_3);
+          _3 = copy _1;
+-         _2 = MyId(move _3);
++         _2 = MyId(copy _1);
+          StorageDead(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+-         _6 = move _2;
+-         _5 = move _6 as u16 (Transmute);
++         _6 = copy _2;
++         _5 = copy _1;
+          StorageDead(_6);
+-         _4 = opaque::<u16>(move _5) -> [return: bb1, unwind unreachable];
++         _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+-         StorageLive(_7);
++         nop;
+          StorageLive(_8);
+          _8 = copy _1;
+          StorageLive(_9);
+-         _9 = PhantomData::<String>;
+-         _7 = TypedId::<String>(move _8, move _9);
++         _9 = const PhantomData::<String>;
++         _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+-         _12 = move _7;
+-         _11 = move _12 as u16 (Transmute);
++         _12 = copy _7;
++         _11 = copy _7 as u16 (Transmute);
+          StorageDead(_12);
+          _10 = opaque::<u16>(move _11) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+-         StorageDead(_7);
+-         StorageDead(_2);
++         nop;
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..a9d9f2c82c8
--- /dev/null
+++ b/tests/mir-opt/gvn.aggregate_struct_then_transmute.GVN.panic-unwind.diff
@@ -0,0 +1,81 @@
+- // MIR for `aggregate_struct_then_transmute` before GVN
++ // MIR for `aggregate_struct_then_transmute` after GVN
+  
+  fn aggregate_struct_then_transmute(_1: u16) -> () {
+      debug id => _1;
+      let mut _0: ();
+      let _2: MyId;
+      let mut _3: u16;
+      let _4: ();
+      let mut _5: u16;
+      let mut _6: MyId;
+      let mut _8: u16;
+      let mut _9: std::marker::PhantomData<std::string::String>;
+      let _10: ();
+      let mut _11: u16;
+      let mut _12: TypedId<std::string::String>;
+      scope 1 {
+          debug a => _2;
+          let _7: TypedId<std::string::String>;
+          scope 2 {
+              debug b => _7;
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_2);
++         nop;
+          StorageLive(_3);
+          _3 = copy _1;
+-         _2 = MyId(move _3);
++         _2 = MyId(copy _1);
+          StorageDead(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+-         _6 = move _2;
+-         _5 = move _6 as u16 (Transmute);
++         _6 = copy _2;
++         _5 = copy _1;
+          StorageDead(_6);
+-         _4 = opaque::<u16>(move _5) -> [return: bb1, unwind continue];
++         _4 = opaque::<u16>(copy _1) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+-         StorageLive(_7);
++         nop;
+          StorageLive(_8);
+          _8 = copy _1;
+          StorageLive(_9);
+-         _9 = PhantomData::<String>;
+-         _7 = TypedId::<String>(move _8, move _9);
++         _9 = const PhantomData::<String>;
++         _7 = TypedId::<String>(copy _1, const PhantomData::<String>);
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+-         _12 = move _7;
+-         _11 = move _12 as u16 (Transmute);
++         _12 = copy _7;
++         _11 = copy _7 as u16 (Transmute);
+          StorageDead(_12);
+          _10 = opaque::<u16>(move _11) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+-         StorageDead(_7);
+-         StorageDead(_2);
++         nop;
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 19b58a917f8..5fc252de0e5 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -12,7 +12,7 @@
 #![allow(unused)]
 
 use std::intrinsics::mir::*;
-use std::marker::Freeze;
+use std::marker::{Freeze, PhantomData};
 use std::mem::transmute;
 
 struct S<T>(T);
@@ -933,6 +933,20 @@ fn cast_pointer_eq(p1: *mut u8, p2: *mut u32, p3: *mut u32, p4: *mut [u32]) {
     // CHECK: _0 = const ();
 }
 
+unsafe fn aggregate_struct_then_transmute(id: u16) {
+    // CHECK: opaque::<u16>(copy _1)
+    let a = MyId(id);
+    opaque(std::intrinsics::transmute::<_, u16>(a));
+
+    // GVN can't do this yet because it doesn't know which field is the ZST,
+    // but future changes might enable it.
+    // CHECK: [[AGG:_.+]] = TypedId::<String>(copy _1, const PhantomData::<String>);
+    // CHECK: [[INT:_.+]] = copy [[AGG]] as u16 (Transmute);
+    // CHECK: opaque::<u16>(move [[INT]])
+    let b = TypedId::<String>(id, PhantomData);
+    opaque(std::intrinsics::transmute::<_, u16>(b));
+}
+
 // Transmuting can skip a pointer cast so long as it wasn't a fat-to-thin cast.
 unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
     // CHECK-LABEL: fn cast_pointer_then_transmute
@@ -946,6 +960,28 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) {
     let fat_addr: usize = std::intrinsics::transmute(fat as *const ());
 }
 
+unsafe fn transmute_then_cast_pointer(addr: usize, fat: *mut [u8]) {
+    // CHECK-LABEL: fn transmute_then_cast_pointer
+
+    // This is roughly what `NonNull::dangling` does
+    // CHECK: [[CPTR:_.+]] = copy _1 as *const u8 (Transmute);
+    // CHECK: takes_const_ptr::<u8>(move [[CPTR]])
+    let p: *mut u8 = std::intrinsics::transmute(addr);
+    takes_const_ptr(p);
+
+    // This cast is fat-to-thin, so can't be merged with the transmute
+    // CHECK: [[FAT:_.+]] = move {{.+}} as *const [i32] (Transmute);
+    // CHECK: [[THIN:_.+]] = copy [[FAT]] as *const i32 (PtrToPtr);
+    // CHECK: takes_const_ptr::<i32>(move [[THIN]])
+    let q = std::intrinsics::transmute::<&mut [i32], *const [i32]>(&mut [1, 2, 3]);
+    takes_const_ptr(q as *const i32);
+
+    // CHECK: [[TPTR:_.+]] = copy _2 as *const u8 (PtrToPtr);
+    // CHECK: takes_const_ptr::<u8>(move [[TPTR]])
+    let w = std::intrinsics::transmute::<*mut [u8], *const [u8]>(fat);
+    takes_const_ptr(w as *const u8);
+}
+
 #[custom_mir(dialect = "analysis")]
 fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool {
     // CHECK-LABEL: fn remove_casts_must_change_both_sides(
@@ -1002,6 +1038,16 @@ fn identity<T>(x: T) -> T {
     x
 }
 
+#[inline(never)]
+fn takes_const_ptr<T>(_: *const T) {}
+
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_end(55555)]
+struct MyId(u16);
+
+#[repr(transparent)]
+struct TypedId<T>(u16, PhantomData<T>);
+
 // EMIT_MIR gvn.subexpression_elimination.GVN.diff
 // EMIT_MIR gvn.wrap_unwrap.GVN.diff
 // EMIT_MIR gvn.repeated_index.GVN.diff
@@ -1034,5 +1080,7 @@ fn identity<T>(x: T) -> T {
 // EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
 // EMIT_MIR gvn.generic_cast_metadata.GVN.diff
 // EMIT_MIR gvn.cast_pointer_eq.GVN.diff
+// EMIT_MIR gvn.aggregate_struct_then_transmute.GVN.diff
 // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff
+// EMIT_MIR gvn.transmute_then_cast_pointer.GVN.diff
 // EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff
diff --git a/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff
new file mode 100644
index 00000000000..0bec425dd99
--- /dev/null
+++ b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-abort.diff
@@ -0,0 +1,115 @@
+- // MIR for `transmute_then_cast_pointer` before GVN
++ // MIR for `transmute_then_cast_pointer` after GVN
+  
+  fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
+      debug addr => _1;
+      debug fat => _2;
+      let mut _0: ();
+      let _3: *mut u8;
+      let mut _4: usize;
+      let _5: ();
+      let mut _6: *const u8;
+      let mut _7: *mut u8;
+      let mut _9: &mut [i32];
+      let mut _10: &mut [i32; 3];
+      let mut _11: &mut [i32; 3];
+      let mut _12: [i32; 3];
+      let _13: ();
+      let mut _14: *const i32;
+      let mut _15: *const [i32];
+      let mut _17: *mut [u8];
+      let _18: ();
+      let mut _19: *const u8;
+      let mut _20: *const [u8];
+      scope 1 {
+          debug p => _3;
+          let _8: *const [i32];
+          scope 2 {
+              debug q => _8;
+              let _16: *const [u8];
+              scope 3 {
+                  debug w => _16;
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);
++         nop;
+          StorageLive(_4);
+          _4 = copy _1;
+-         _3 = move _4 as *mut u8 (Transmute);
++         _3 = copy _1 as *mut u8 (Transmute);
+          StorageDead(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = copy _3;
+-         _6 = move _7 as *const u8 (PtrToPtr);
++         _6 = copy _1 as *const u8 (Transmute);
+          StorageDead(_7);
+          _5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_6);
+          StorageDead(_5);
+-         StorageLive(_8);
++         nop;
+          StorageLive(_9);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = [const 1_i32, const 2_i32, const 3_i32];
+          _11 = &mut _12;
+          _10 = &mut (*_11);
+          _9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
+          StorageDead(_10);
+          _8 = move _9 as *const [i32] (Transmute);
+          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = copy _8;
+-         _14 = move _15 as *const i32 (PtrToPtr);
++         _14 = copy _8 as *const i32 (PtrToPtr);
+          StorageDead(_15);
+          _13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_14);
+          StorageDead(_13);
+-         StorageLive(_16);
++         nop;
+          StorageLive(_17);
+          _17 = copy _2;
+-         _16 = move _17 as *const [u8] (Transmute);
++         _16 = copy _2 as *const [u8] (PtrToPtr);
+          StorageDead(_17);
+          StorageLive(_18);
+          StorageLive(_19);
+          StorageLive(_20);
+          _20 = copy _16;
+-         _19 = move _20 as *const u8 (PtrToPtr);
++         _19 = copy _2 as *const u8 (PtrToPtr);
+          StorageDead(_20);
+          _18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_19);
+          StorageDead(_18);
+          _0 = const ();
+-         StorageDead(_16);
+-         StorageDead(_8);
+-         StorageDead(_3);
++         nop;
++         nop;
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..14f2fe08a86
--- /dev/null
+++ b/tests/mir-opt/gvn.transmute_then_cast_pointer.GVN.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `transmute_then_cast_pointer` before GVN
++ // MIR for `transmute_then_cast_pointer` after GVN
+  
+  fn transmute_then_cast_pointer(_1: usize, _2: *mut [u8]) -> () {
+      debug addr => _1;
+      debug fat => _2;
+      let mut _0: ();
+      let _3: *mut u8;
+      let mut _4: usize;
+      let _5: ();
+      let mut _6: *const u8;
+      let mut _7: *mut u8;
+      let mut _9: &mut [i32];
+      let mut _10: &mut [i32; 3];
+      let mut _11: &mut [i32; 3];
+      let mut _12: [i32; 3];
+      let _13: ();
+      let mut _14: *const i32;
+      let mut _15: *const [i32];
+      let mut _17: *mut [u8];
+      let _18: ();
+      let mut _19: *const u8;
+      let mut _20: *const [u8];
+      scope 1 {
+          debug p => _3;
+          let _8: *const [i32];
+          scope 2 {
+              debug q => _8;
+              let _16: *const [u8];
+              scope 3 {
+                  debug w => _16;
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);
++         nop;
+          StorageLive(_4);
+          _4 = copy _1;
+-         _3 = move _4 as *mut u8 (Transmute);
++         _3 = copy _1 as *mut u8 (Transmute);
+          StorageDead(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = copy _3;
+-         _6 = move _7 as *const u8 (PtrToPtr);
++         _6 = copy _1 as *const u8 (Transmute);
+          StorageDead(_7);
+          _5 = takes_const_ptr::<u8>(move _6) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_6);
+          StorageDead(_5);
+-         StorageLive(_8);
++         nop;
+          StorageLive(_9);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = [const 1_i32, const 2_i32, const 3_i32];
+          _11 = &mut _12;
+          _10 = &mut (*_11);
+          _9 = move _10 as &mut [i32] (PointerCoercion(Unsize, Implicit));
+          StorageDead(_10);
+          _8 = move _9 as *const [i32] (Transmute);
+          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = copy _8;
+-         _14 = move _15 as *const i32 (PtrToPtr);
++         _14 = copy _8 as *const i32 (PtrToPtr);
+          StorageDead(_15);
+          _13 = takes_const_ptr::<i32>(move _14) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_14);
+          StorageDead(_13);
+-         StorageLive(_16);
++         nop;
+          StorageLive(_17);
+          _17 = copy _2;
+-         _16 = move _17 as *const [u8] (Transmute);
++         _16 = copy _2 as *const [u8] (PtrToPtr);
+          StorageDead(_17);
+          StorageLive(_18);
+          StorageLive(_19);
+          StorageLive(_20);
+          _20 = copy _16;
+-         _19 = move _20 as *const u8 (PtrToPtr);
++         _19 = copy _2 as *const u8 (PtrToPtr);
+          StorageDead(_20);
+          _18 = takes_const_ptr::<u8>(move _19) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_19);
+          StorageDead(_18);
+          _0 = const ();
+-         StorageDead(_16);
+-         StorageDead(_8);
+-         StorageDead(_3);
++         nop;
++         nop;
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
index 581244074b3..4337e0da183 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
@@ -11,10 +11,43 @@
 +     scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
 +         let mut _6: &mut std::vec::Vec<A>;
 +         let mut _7: ();
++         scope 2 (inlined <Vec<A> as Drop>::drop) {
++             let mut _8: *mut [A];
++             let mut _9: *mut A;
++             let mut _10: usize;
++             scope 3 (inlined Vec::<A>::as_mut_ptr) {
++                 scope 4 (inlined alloc::raw_vec::RawVec::<A>::ptr) {
++                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<A>) {
++                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<A>) {
++                             let mut _11: std::ptr::NonNull<u8>;
++                             scope 7 (inlined Unique::<u8>::cast::<A>) {
++                                 scope 8 (inlined NonNull::<u8>::cast::<A>) {
++                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
++                                     }
++                                 }
++                             }
++                             scope 10 (inlined Unique::<A>::as_non_null_ptr) {
++                             }
++                         }
++                         scope 11 (inlined NonNull::<A>::as_ptr) {
++                         }
++                     }
++                 }
++             }
++             scope 12 (inlined slice_from_raw_parts_mut::<A>) {
++                 scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
++                 }
++             }
++             scope 14 (inlined std::ptr::drop_in_place::<[A]> - shim(Some([A]))) {
++                 let mut _12: usize;
++                 let mut _13: *mut A;
++                 let mut _14: bool;
++             }
++         }
 +     }
-+     scope 2 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
-+         let mut _8: isize;
-+         let mut _9: isize;
++     scope 15 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++         let mut _15: isize;
++         let mut _16: isize;
 +     }
   
       bb0: {
@@ -25,7 +58,21 @@
 +         StorageLive(_6);
 +         StorageLive(_7);
 +         _6 = &mut (*_4);
-+         _7 = <Vec<A> as Drop>::drop(move _6) -> [return: bb2, unwind unreachable];
++         StorageLive(_10);
++         StorageLive(_8);
++         StorageLive(_9);
++         StorageLive(_11);
++         _11 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
++         _9 = copy _11 as *mut A (Transmute);
++         StorageDead(_11);
++         _10 = copy ((*_6).1: usize);
++         _8 = *mut [A] from (copy _9, copy _10);
++         StorageDead(_9);
++         StorageLive(_12);
++         StorageLive(_13);
++         StorageLive(_14);
++         _12 = const 0_usize;
++         goto -> bb4;
       }
   
       bb1: {
@@ -36,25 +83,41 @@
           StorageLive(_5);
           _5 = copy _2;
 -         _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
-+         StorageLive(_8);
-+         StorageLive(_9);
-+         _8 = discriminant((*_5));
-+         switchInt(move _8) -> [0: bb3, otherwise: bb4];
++         StorageLive(_15);
++         StorageLive(_16);
++         _15 = discriminant((*_5));
++         switchInt(move _15) -> [0: bb5, otherwise: bb6];
       }
   
       bb2: {
++         StorageDead(_14);
++         StorageDead(_13);
++         StorageDead(_12);
++         StorageDead(_8);
++         StorageDead(_10);
 +         drop(((*_4).0: alloc::raw_vec::RawVec<A>)) -> [return: bb1, unwind unreachable];
 +     }
 + 
 +     bb3: {
-+         StorageDead(_9);
-+         StorageDead(_8);
++         _13 = &raw mut (*_8)[_12];
++         _12 = Add(move _12, const 1_usize);
++         drop((*_13)) -> [return: bb4, unwind unreachable];
++     }
++ 
++     bb4: {
++         _14 = Eq(copy _12, copy _10);
++         switchInt(move _14) -> [0: bb3, otherwise: bb2];
++     }
++ 
++     bb5: {
++         StorageDead(_16);
++         StorageDead(_15);
           StorageDead(_5);
           return;
 +     }
 + 
-+     bb4: {
-+         drop((((*_5) as Some).0: B)) -> [return: bb3, unwind unreachable];
++     bb6: {
++         drop((((*_5) as Some).0: B)) -> [return: bb5, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
index 02aadfc1de0..103475b608c 100644
--- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -20,7 +20,7 @@ fn b(_1: &mut Box<T>) -> &mut T {
         StorageLive(_5);
         StorageLive(_6);
         _5 = copy (*_4);
-        _6 = copy (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
+        _6 = copy ((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
         _3 = &mut (*_6);
         StorageDead(_6);
         StorageDead(_5);
diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
index 1ea347510fd..babb26808ce 100644
--- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -18,7 +18,7 @@ fn d(_1: &Box<T>) -> &T {
         StorageLive(_4);
         StorageLive(_5);
         _4 = copy (*_3);
-        _5 = copy (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T);
+        _5 = copy ((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>) as *const T (Transmute);
         _2 = &(*_5);
         StorageDead(_5);
         StorageDead(_4);
diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
index 70671e2089a..644d6d320de 100644
--- a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
+++ b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff
@@ -12,7 +12,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = move _1;
-          _4 = copy (((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>).0: *const [i32]);
+          _4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute);
           _2 = callee(move (*_4)) -> [return: bb1, unwind: bb3];
       }
   
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff
deleted file mode 100644
index 9844aa2a64e..00000000000
--- a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff
+++ /dev/null
@@ -1,83 +0,0 @@
-- // MIR for `adt_transmutes` before InstSimplify-after-simplifycfg
-+ // MIR for `adt_transmutes` after InstSimplify-after-simplifycfg
-  
-  fn adt_transmutes() -> () {
-      let mut _0: ();
-      let _1: u8;
-      let mut _2: std::option::Option<std::num::NonZero<u8>>;
-      let mut _4: std::num::Wrapping<i16>;
-      let mut _6: std::num::Wrapping<i16>;
-      let mut _8: Union32;
-      let mut _10: Union32;
-      let mut _12: std::mem::MaybeUninit<std::string::String>;
-      scope 1 {
-          debug _a => _1;
-          let _3: i16;
-          scope 2 {
-              debug _a => _3;
-              let _5: u16;
-              scope 3 {
-                  debug _a => _5;
-                  let _7: u32;
-                  scope 4 {
-                      debug _a => _7;
-                      let _9: i32;
-                      scope 5 {
-                          debug _a => _9;
-                          let _11: std::mem::ManuallyDrop<std::string::String>;
-                          scope 6 {
-                              debug _a => _11;
-                          }
-                      }
-                  }
-              }
-          }
-      }
-  
-      bb0: {
-          StorageLive(_1);
-          StorageLive(_2);
-          _2 = Option::<NonZero<u8>>::Some(const std::num::NonZero::<u8>::MAX);
-          _1 = move _2 as u8 (Transmute);
-          StorageDead(_2);
-          StorageLive(_3);
-          StorageLive(_4);
-          _4 = Wrapping::<i16>(const 0_i16);
--         _3 = move _4 as i16 (Transmute);
-+         _3 = move (_4.0: i16);
-          StorageDead(_4);
-          StorageLive(_5);
-          StorageLive(_6);
-          _6 = Wrapping::<i16>(const 0_i16);
-          _5 = move _6 as u16 (Transmute);
-          StorageDead(_6);
-          StorageLive(_7);
-          StorageLive(_8);
-          _8 = Union32 { u32: const 0_i32 };
-          _7 = move _8 as u32 (Transmute);
-          StorageDead(_8);
-          StorageLive(_9);
-          StorageLive(_10);
-          _10 = Union32 { u32: const 0_u32 };
-          _9 = move _10 as i32 (Transmute);
-          StorageDead(_10);
-          StorageLive(_11);
-          StorageLive(_12);
-          _12 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _11 = move _12 as std::mem::ManuallyDrop<std::string::String> (Transmute);
-+         _11 = move (_12.1: std::mem::ManuallyDrop<std::string::String>);
-          StorageDead(_12);
-          _0 = const ();
-          StorageDead(_11);
-          StorageDead(_9);
-          StorageDead(_7);
-          StorageDead(_5);
-          StorageDead(_3);
-          StorageDead(_1);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff
new file mode 100644
index 00000000000..66a29629591
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff
@@ -0,0 +1,30 @@
+- // MIR for `keep_transparent_transmute` before InstSimplify-after-simplifycfg
++ // MIR for `keep_transparent_transmute` after InstSimplify-after-simplifycfg
+  
+  fn keep_transparent_transmute() -> () {
+      let mut _0: ();
+      let _1: i16;
+      let mut _3: std::num::Wrapping<i16>;
+      scope 1 {
+          debug _a => _1;
+          let _2: i16;
+          scope 2 {
+              debug _a => _2;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          _1 = const keep_transparent_transmute::{constant#0} as i16 (Transmute);
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = Wrapping::<i16>(const 0_i16);
+          _2 = move _3 as i16 (Transmute);
+          StorageDead(_3);
+          _0 = const ();
+          StorageDead(_2);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.rs b/tests/mir-opt/instsimplify/combine_transmutes.rs
index 8a670301825..c12f307ca0e 100644
--- a/tests/mir-opt/instsimplify/combine_transmutes.rs
+++ b/tests/mir-opt/instsimplify/combine_transmutes.rs
@@ -43,22 +43,19 @@ pub unsafe fn integer_transmutes() {
     }
 }
 
-// EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify-after-simplifycfg.diff
-pub unsafe fn adt_transmutes() {
-    // CHECK-LABEL: fn adt_transmutes(
-    // CHECK: as u8 (Transmute);
-    // CHECK: ({{_.*}}.0: i16);
-    // CHECK: as u16 (Transmute);
-    // CHECK: as u32 (Transmute);
-    // CHECK: as i32 (Transmute);
-    // CHECK: ({{_.*}}.1: std::mem::ManuallyDrop<std::string::String>);
+// EMIT_MIR combine_transmutes.keep_transparent_transmute.InstSimplify-after-simplifycfg.diff
+pub unsafe fn keep_transparent_transmute() {
+    // CHECK-LABEL: fn keep_transparent_transmute(
+    // CHECK-NOT: .{{[0-9]+}}: i16
+    // CHECK: as i16 (Transmute);
+    // CHECK-NOT: .{{[0-9]+}}: i16
+    // CHECK: as i16 (Transmute);
+    // CHECK-NOT: .{{[0-9]+}}: i16
 
-    let _a: u8 = transmute(Some(std::num::NonZero::<u8>::MAX));
+    // Transmutes should not be converted to field accesses, because MCP#807
+    // bans projections into `[rustc_layout_scalar_valid_range_*]` types.
+    let _a: i16 = transmute(const { std::num::NonZero::new(12345_i16).unwrap() });
     let _a: i16 = transmute(std::num::Wrapping(0_i16));
-    let _a: u16 = transmute(std::num::Wrapping(0_i16));
-    let _a: u32 = transmute(Union32 { i32: 0 });
-    let _a: i32 = transmute(Union32 { u32: 0 });
-    let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit());
 }
 
 pub union Union32 {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index a3308cc5df1..9494b8a2add 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _23: std::option::Option<(usize, &T)>;
-    let mut _26: &impl Fn(usize, &T);
-    let mut _27: (usize, &T);
-    let _28: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _21: std::option::Option<(usize, &T)>;
+    let mut _24: &impl Fn(usize, &T);
+    let mut _25: (usize, &T);
+    let _26: ();
     scope 1 {
-        debug iter => _15;
-        let _24: usize;
-        let _25: &T;
+        debug iter => _13;
+        let _22: usize;
+        let _23: &T;
         scope 2 {
-            debug i => _24;
-            debug x => _25;
+            debug i => _22;
+            debug x => _23;
         }
         scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _16: &mut std::slice::Iter<'_, T>;
-            let mut _17: std::option::Option<&T>;
-            let mut _21: (usize, bool);
-            let mut _22: (usize, &T);
+            let mut _14: &mut std::slice::Iter<'_, T>;
+            let mut _15: std::option::Option<&T>;
+            let mut _19: (usize, bool);
+            let mut _20: (usize, &T);
             scope 19 {
-                let _20: usize;
+                let _18: usize;
                 scope 24 {
                 }
             }
@@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 }
             }
             scope 25 (inlined <Option<&T> as Try>::branch) {
-                let mut _18: isize;
-                let _19: &T;
+                let mut _16: isize;
+                let _17: &T;
                 scope 26 {
                 }
             }
@@ -50,14 +50,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -73,8 +72,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -89,82 +87,74 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb0: {
-        StorageLive(_13);
+        StorageLive(_11);
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_12);
-        _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
         StorageDead(_3);
-        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
-        StorageDead(_13);
-        StorageLive(_15);
-        _15 = copy _14;
+        _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
+        StorageDead(_11);
+        StorageLive(_13);
+        _13 = copy _12;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_23);
-        StorageLive(_20);
         StorageLive(_21);
-        StorageLive(_17);
-        StorageLive(_16);
-        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
-        _17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
+        StorageLive(_18);
+        StorageLive(_19);
+        StorageLive(_15);
+        StorageLive(_14);
+        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
+        _15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_16);
-        StorageLive(_18);
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
+        StorageDead(_14);
+        StorageLive(_16);
+        _16 = discriminant(_15);
+        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
     }
 
     bb6: {
+        StorageDead(_16);
+        StorageDead(_15);
+        StorageDead(_19);
         StorageDead(_18);
-        StorageDead(_17);
         StorageDead(_21);
-        StorageDead(_20);
-        StorageDead(_23);
-        StorageDead(_15);
+        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -173,35 +163,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _19 = move ((_17 as Some).0: &T);
-        StorageDead(_18);
-        StorageDead(_17);
-        _20 = copy (_15.1: usize);
-        _21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
-        assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
+        _17 = move ((_15 as Some).0: &T);
+        StorageDead(_16);
+        StorageDead(_15);
+        _18 = copy (_13.1: usize);
+        _19 = AddWithOverflow(copy (_13.1: usize), const 1_usize);
+        assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
     }
 
     bb9: {
-        (_15.1: usize) = move (_21.0: usize);
-        StorageLive(_22);
-        _22 = (copy _20, copy _19);
-        _23 = Option::<(usize, &T)>::Some(move _22);
-        StorageDead(_22);
-        StorageDead(_21);
+        (_13.1: usize) = move (_19.0: usize);
+        StorageLive(_20);
+        _20 = (copy _18, copy _17);
+        _21 = Option::<(usize, &T)>::Some(move _20);
         StorageDead(_20);
-        _24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
-        _25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_26);
-        _26 = &_2;
-        StorageLive(_27);
-        _27 = (copy _24, copy _25);
-        _28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
+        StorageDead(_19);
+        StorageDead(_18);
+        _22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
+        _23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_24);
+        _24 = &_2;
+        StorageLive(_25);
+        _25 = (copy _22, copy _23);
+        _26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
     }
 
     bb10: {
-        StorageDead(_27);
-        StorageDead(_26);
-        StorageDead(_23);
+        StorageDead(_25);
+        StorageDead(_24);
+        StorageDead(_21);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 2a837fabd4c..c9b9798bf33 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _17: std::option::Option<(usize, &T)>;
-    let mut _18: isize;
-    let mut _21: &impl Fn(usize, &T);
-    let mut _22: (usize, &T);
-    let _23: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _15: std::option::Option<(usize, &T)>;
+    let mut _16: isize;
+    let mut _19: &impl Fn(usize, &T);
+    let mut _20: (usize, &T);
+    let _21: ();
     scope 1 {
-        debug iter => _15;
-        let _19: usize;
-        let _20: &T;
+        debug iter => _13;
+        let _17: usize;
+        let _18: &T;
         scope 2 {
-            debug i => _19;
-            debug x => _20;
+            debug i => _17;
+            debug x => _18;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -64,72 +62,64 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb0: {
-        StorageLive(_13);
+        StorageLive(_11);
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_12);
-        _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
         StorageDead(_3);
-        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
-        StorageDead(_13);
-        StorageLive(_15);
-        _15 = copy _14;
+        _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
+        StorageDead(_11);
+        StorageLive(_13);
+        _13 = copy _12;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_17);
-        _16 = &mut _15;
-        _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
+        StorageLive(_15);
+        _14 = &mut _13;
+        _15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _16 = discriminant(_15);
+        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_17);
         StorageDead(_15);
+        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -138,19 +128,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
-        _20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_21);
-        _21 = &_2;
-        StorageLive(_22);
-        _22 = (copy _19, copy _20);
-        _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
+        _17 = copy (((_15 as Some).0: (usize, &T)).0: usize);
+        _18 = copy (((_15 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_19);
+        _19 = &_2;
+        StorageLive(_20);
+        _20 = (copy _17, copy _18);
+        _21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_21);
-        StorageDead(_17);
+        StorageDead(_20);
+        StorageDead(_19);
+        StorageDead(_15);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 063045caebb..ac6fe0ac547 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::slice::Iter<'_, T>;
-    let mut _15: &mut std::slice::Iter<'_, T>;
-    let mut _16: std::option::Option<&T>;
-    let mut _17: isize;
-    let mut _19: &impl Fn(&T);
-    let mut _20: (&T,);
-    let _21: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::slice::Iter<'_, T>;
+    let mut _13: &mut std::slice::Iter<'_, T>;
+    let mut _14: std::option::Option<&T>;
+    let mut _15: isize;
+    let mut _17: &impl Fn(&T);
+    let mut _18: (&T,);
+    let _19: ();
     scope 1 {
-        debug iter => _14;
-        let _18: &T;
+        debug iter => _12;
+        let _16: &T;
         scope 2 {
-            debug x => _18;
+            debug x => _16;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -58,68 +56,60 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
 
     bb0: {
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
+        StorageDead(_3);
         StorageLive(_12);
         _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
-        StorageDead(_3);
-        StorageLive(_14);
-        _14 = copy _13;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_16);
-        _15 = &mut _14;
-        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
+        StorageLive(_14);
+        _13 = &mut _12;
+        _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        _17 = discriminant(_16);
-        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _15 = discriminant(_14);
+        switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_16);
         StorageDead(_14);
+        StorageDead(_12);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -128,18 +118,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _18 = copy ((_16 as Some).0: &T);
-        StorageLive(_19);
-        _19 = &_2;
-        StorageLive(_20);
-        _20 = (copy _18,);
-        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
+        _16 = copy ((_14 as Some).0: &T);
+        StorageLive(_17);
+        _17 = &_2;
+        StorageLive(_18);
+        _18 = (copy _16,);
+        _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_16);
+        StorageDead(_18);
+        StorageDead(_17);
+        StorageDead(_14);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index d401ed8fcf3..bc2403fc544 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::slice::Iter<'_, T>;
-    let mut _15: &mut std::slice::Iter<'_, T>;
-    let mut _16: std::option::Option<&T>;
-    let mut _17: isize;
-    let mut _19: &impl Fn(&T);
-    let mut _20: (&T,);
-    let _21: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::slice::Iter<'_, T>;
+    let mut _13: &mut std::slice::Iter<'_, T>;
+    let mut _14: std::option::Option<&T>;
+    let mut _15: isize;
+    let mut _17: &impl Fn(&T);
+    let mut _18: (&T,);
+    let _19: ();
     scope 1 {
-        debug iter => _14;
-        let _18: &T;
+        debug iter => _12;
+        let _16: &T;
         scope 2 {
-            debug x => _18;
+            debug x => _16;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -45,8 +44,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -58,68 +56,60 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
 
     bb0: {
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
+        StorageDead(_3);
         StorageLive(_12);
         _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
-        StorageDead(_3);
-        StorageLive(_14);
-        _14 = copy _13;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_16);
-        _15 = &mut _14;
-        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
+        StorageLive(_14);
+        _13 = &mut _12;
+        _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        _17 = discriminant(_16);
-        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _15 = discriminant(_14);
+        switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_16);
         StorageDead(_14);
+        StorageDead(_12);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -128,18 +118,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _18 = copy ((_16 as Some).0: &T);
-        StorageLive(_19);
-        _19 = &_2;
-        StorageLive(_20);
-        _20 = (copy _18,);
-        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
+        _16 = copy ((_14 as Some).0: &T);
+        StorageLive(_17);
+        _17 = &_2;
+        StorageLive(_18);
+        _18 = (copy _16,);
+        _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_16);
+        StorageDead(_18);
+        StorageDead(_17);
+        StorageDead(_14);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index deb12c4f1c2..0eac3342ff7 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _17: std::option::Option<&T>;
-    let mut _18: isize;
-    let mut _20: &impl Fn(&T);
-    let mut _21: (&T,);
-    let _22: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _15: std::option::Option<&T>;
+    let mut _16: isize;
+    let mut _18: &impl Fn(&T);
+    let mut _19: (&T,);
+    let _20: ();
     scope 1 {
-        debug iter => _15;
-        let _19: &T;
+        debug iter => _13;
+        let _17: &T;
         scope 2 {
-            debug x => _19;
+            debug x => _17;
         }
         scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _16: &mut std::slice::Iter<'_, T>;
+            let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -64,74 +62,66 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb0: {
-        StorageLive(_13);
+        StorageLive(_11);
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_12);
-        _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
         StorageDead(_3);
-        _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
-        StorageDead(_13);
-        StorageLive(_15);
-        _15 = copy _14;
+        _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
+        StorageDead(_11);
+        StorageLive(_13);
+        _13 = copy _12;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_17);
-        StorageLive(_16);
-        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
-        _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
+        StorageLive(_15);
+        StorageLive(_14);
+        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
+        _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_16);
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_14);
+        _16 = discriminant(_15);
+        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_17);
         StorageDead(_15);
+        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -140,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _19 = copy ((_17 as Some).0: &T);
-        StorageLive(_20);
-        _20 = &_2;
-        StorageLive(_21);
-        _21 = (copy _19,);
-        _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
+        _17 = copy ((_15 as Some).0: &T);
+        StorageLive(_18);
+        _18 = &_2;
+        StorageLive(_19);
+        _19 = (copy _17,);
+        _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_21);
-        StorageDead(_20);
-        StorageDead(_17);
+        StorageDead(_19);
+        StorageDead(_18);
+        StorageDead(_15);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index acd5323eb7a..376dc716382 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _17: std::option::Option<&T>;
-    let mut _18: isize;
-    let mut _20: &impl Fn(&T);
-    let mut _21: (&T,);
-    let _22: ();
+    let mut _11: std::slice::Iter<'_, T>;
+    let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _15: std::option::Option<&T>;
+    let mut _16: isize;
+    let mut _18: &impl Fn(&T);
+    let mut _19: (&T,);
+    let _20: ();
     scope 1 {
-        debug iter => _15;
-        let _19: &T;
+        debug iter => _13;
+        let _17: &T;
         scope 2 {
-            debug x => _19;
+            debug x => _17;
         }
         scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _16: &mut std::slice::Iter<'_, T>;
+            let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _5: std::ptr::NonNull<[T]>;
-            let mut _9: *mut T;
-            let mut _10: *mut T;
-            let mut _12: *const T;
+            let mut _7: *mut T;
+            let mut _8: *mut T;
+            let mut _10: *const T;
             scope 5 {
-                let _8: std::ptr::NonNull<T>;
+                let _6: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _11: *const T;
+                    let _9: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -48,8 +47,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _6: *mut [T];
-                    let mut _7: *const T;
+                    let mut _5: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -64,74 +62,66 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb0: {
-        StorageLive(_13);
+        StorageLive(_11);
         StorageLive(_3);
-        StorageLive(_8);
-        _3 = PtrMetadata(copy _1);
+        StorageLive(_6);
         StorageLive(_5);
-        StorageLive(_4);
+        _3 = PtrMetadata(copy _1);
         _4 = &raw const (*_1);
-        _5 = NonNull::<[T]> { pointer: move _4 };
-        StorageDead(_4);
-        StorageLive(_6);
-        StorageLive(_7);
-        _6 = copy _5 as *mut [T] (Transmute);
-        _7 = copy _6 as *const T (PtrToPtr);
-        _8 = NonNull::<T> { pointer: move _7 };
-        StorageDead(_7);
-        StorageDead(_6);
-        StorageDead(_5);
-        StorageLive(_11);
+        _5 = copy _4 as *const T (PtrToPtr);
+        _6 = NonNull::<T> { pointer: copy _5 };
+        StorageLive(_9);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_10);
-        StorageLive(_9);
-        _9 = copy _8 as *mut T (Transmute);
-        _10 = Offset(copy _9, copy _3);
-        StorageDead(_9);
-        _11 = move _10 as *const T (PtrToPtr);
-        StorageDead(_10);
+        StorageLive(_8);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (PtrToPtr);
+        _8 = Offset(copy _7, copy _3);
+        StorageDead(_7);
+        _9 = move _8 as *const T (PtrToPtr);
+        StorageDead(_8);
         goto -> bb3;
     }
 
     bb2: {
-        _11 = copy _3 as *const T (Transmute);
+        _9 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_12);
-        _12 = copy _11;
-        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_8);
+        StorageLive(_10);
+        _10 = copy _9;
+        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_10);
+        StorageDead(_9);
+        StorageDead(_5);
+        StorageDead(_6);
         StorageDead(_3);
-        _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
-        StorageDead(_13);
-        StorageLive(_15);
-        _15 = copy _14;
+        _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
+        StorageDead(_11);
+        StorageLive(_13);
+        _13 = copy _12;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_17);
-        StorageLive(_16);
-        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
-        _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
+        StorageLive(_15);
+        StorageLive(_14);
+        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
+        _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        StorageDead(_16);
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_14);
+        _16 = discriminant(_15);
+        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_17);
         StorageDead(_15);
+        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -140,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _19 = copy ((_17 as Some).0: &T);
-        StorageLive(_20);
-        _20 = &_2;
-        StorageLive(_21);
-        _21 = (copy _19,);
-        _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
+        _17 = copy ((_15 as Some).0: &T);
+        StorageLive(_18);
+        _18 = &_2;
+        StorageLive(_19);
+        _19 = (copy _17,);
+        _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_21);
-        StorageDead(_20);
-        StorageDead(_17);
+        StorageDead(_19);
+        StorageDead(_18);
+        StorageDead(_15);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
index 3f0d60b46f4..927deabd253 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _7: *const u8;
-            let mut _8: usize;
+            let mut _3: *const u8;
+            let mut _4: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
-                let mut _6: *mut u8;
                 scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                        let mut _5: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             let mut _2: std::ptr::NonNull<u8>;
                             scope 7 (inlined Unique::<u8>::cast::<u8>) {
                                 scope 8 (inlined NonNull::<u8>::cast::<u8>) {
-                                    let mut _3: *mut u8;
-                                    let mut _4: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
                                     }
                                 }
@@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _7;
-                debug len => _8;
-                let _9: *const [u8];
+                debug data => _3;
+                debug len => _4;
+                let _5: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _7;
-                    debug len => _8;
+                    debug data => _3;
+                    debug len => _4;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _7;
+                        debug data_pointer => _3;
                     }
                 }
             }
@@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
-        StorageLive(_6);
-        StorageLive(_7);
-        StorageLive(_5);
         StorageLive(_2);
-        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         StorageLive(_3);
+        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+        _3 = copy _2 as *const u8 (Transmute);
         StorageLive(_4);
-        _3 = copy _2 as *mut u8 (Transmute);
-        _4 = copy _3 as *const u8 (PtrToPtr);
-        _5 = NonNull::<u8> { pointer: move _4 };
+        _4 = copy ((*_1).1: usize);
+        StorageLive(_5);
+        _5 = *const [u8] from (copy _3, copy _4);
+        _0 = &(*_5);
+        StorageDead(_5);
         StorageDead(_4);
         StorageDead(_3);
         StorageDead(_2);
-        _6 = copy _5 as *mut u8 (Transmute);
-        StorageDead(_5);
-        _7 = copy _6 as *const u8 (PtrToPtr);
-        StorageLive(_8);
-        _8 = copy ((*_1).1: usize);
-        StorageLive(_9);
-        _9 = *const [u8] from (copy _7, copy _8);
-        _0 = &(*_9);
-        StorageDead(_9);
-        StorageDead(_8);
-        StorageDead(_7);
-        StorageDead(_6);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
index 3f0d60b46f4..927deabd253 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -7,20 +7,16 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _7: *const u8;
-            let mut _8: usize;
+            let mut _3: *const u8;
+            let mut _4: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
-                let mut _6: *mut u8;
                 scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                        let mut _5: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             let mut _2: std::ptr::NonNull<u8>;
                             scope 7 (inlined Unique::<u8>::cast::<u8>) {
                                 scope 8 (inlined NonNull::<u8>::cast::<u8>) {
-                                    let mut _3: *mut u8;
-                                    let mut _4: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
                                     }
                                 }
@@ -34,9 +30,9 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _7;
-                debug len => _8;
-                let _9: *const [u8];
+                debug data => _3;
+                debug len => _4;
+                let _5: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -46,10 +42,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _7;
-                    debug len => _8;
+                    debug data => _3;
+                    debug len => _4;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _7;
+                        debug data_pointer => _3;
                     }
                 }
             }
@@ -57,31 +53,19 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
-        StorageLive(_6);
-        StorageLive(_7);
-        StorageLive(_5);
         StorageLive(_2);
-        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         StorageLive(_3);
+        _2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+        _3 = copy _2 as *const u8 (Transmute);
         StorageLive(_4);
-        _3 = copy _2 as *mut u8 (Transmute);
-        _4 = copy _3 as *const u8 (PtrToPtr);
-        _5 = NonNull::<u8> { pointer: move _4 };
+        _4 = copy ((*_1).1: usize);
+        StorageLive(_5);
+        _5 = *const [u8] from (copy _3, copy _4);
+        _0 = &(*_5);
+        StorageDead(_5);
         StorageDead(_4);
         StorageDead(_3);
         StorageDead(_2);
-        _6 = copy _5 as *mut u8 (Transmute);
-        StorageDead(_5);
-        _7 = copy _6 as *const u8 (PtrToPtr);
-        StorageLive(_8);
-        _8 = copy ((*_1).1: usize);
-        StorageLive(_9);
-        _9 = *const [u8] from (copy _7, copy _8);
-        _0 = &(*_9);
-        StorageDead(_9);
-        StorageDead(_8);
-        StorageDead(_7);
-        StorageDead(_6);
         return;
     }
 }