about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs155
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff18
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff18
-rw-r--r--tests/mir-opt/gvn.references.GVN.panic-abort.diff76
-rw-r--r--tests/mir-opt/gvn.references.GVN.panic-unwind.diff98
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.rs7
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-abort.diff39
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-unwind.diff39
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff30
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff30
13 files changed, 396 insertions, 127 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 60ff1dd0d78..eaa1c70a5e9 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -66,6 +66,7 @@ use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut};
 use rustc_span::DUMMY_SP;
 use rustc_target::abi::{self, Abi, Size, VariantIdx, FIRST_VARIANT};
+use std::borrow::Cow;
 
 use crate::dataflow_const_prop::DummyMachine;
 use crate::ssa::{AssignedValue, SsaLocals};
@@ -461,6 +462,87 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         Some(op)
     }
 
+    fn project(
+        &mut self,
+        place: PlaceRef<'tcx>,
+        value: VnIndex,
+        proj: PlaceElem<'tcx>,
+    ) -> Option<VnIndex> {
+        let proj = match proj {
+            ProjectionElem::Deref => {
+                let ty = place.ty(self.local_decls, self.tcx).ty;
+                if let Some(Mutability::Not) = ty.ref_mutability()
+                    && let Some(pointee_ty) = ty.builtin_deref(true)
+                    && pointee_ty.ty.is_freeze(self.tcx, self.param_env)
+                {
+                    // An immutable borrow `_x` always points to the same value for the
+                    // lifetime of the borrow, so we can merge all instances of `*_x`.
+                    ProjectionElem::Deref
+                } else {
+                    return None;
+                }
+            }
+            ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index),
+            ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty),
+            ProjectionElem::Index(idx) => {
+                let idx = self.locals[idx]?;
+                ProjectionElem::Index(idx)
+            }
+            ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
+                ProjectionElem::ConstantIndex { offset, min_length, from_end }
+            }
+            ProjectionElem::Subslice { from, to, from_end } => {
+                ProjectionElem::Subslice { from, to, from_end }
+            }
+            ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
+            ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
+        };
+
+        Some(self.insert(Value::Projection(value, proj)))
+    }
+
+    /// Simplify the projection chain if we know better.
+    #[instrument(level = "trace", skip(self))]
+    fn simplify_place_projection(&mut self, place: &mut Place<'tcx>, location: Location) {
+        // If the projection is indirect, we treat the local as a value, so can replace it with
+        // another local.
+        if place.is_indirect()
+            && let Some(base) = self.locals[place.local]
+            && let Some(new_local) = self.try_as_local(base, location)
+        {
+            place.local = new_local;
+            self.reused_locals.insert(new_local);
+        }
+
+        let mut projection = Cow::Borrowed(&place.projection[..]);
+
+        for i in 0..projection.len() {
+            let elem = projection[i];
+            if let ProjectionElem::Index(idx) = elem
+                && let Some(idx) = self.locals[idx]
+            {
+                if let Some(offset) = self.evaluated[idx].as_ref()
+                    && let Ok(offset) = self.ecx.read_target_usize(offset)
+                {
+                    projection.to_mut()[i] = ProjectionElem::ConstantIndex {
+                        offset,
+                        min_length: offset + 1,
+                        from_end: false,
+                    };
+                } else if let Some(new_idx) = self.try_as_local(idx, location) {
+                    projection.to_mut()[i] = ProjectionElem::Index(new_idx);
+                    self.reused_locals.insert(new_idx);
+                }
+            }
+        }
+
+        if projection.is_owned() {
+            place.projection = self.tcx.mk_place_elems(&projection);
+        }
+
+        trace!(?place);
+    }
+
     /// Represent the *value* which would be read from `place`, and point `place` to a preexisting
     /// place with the same value (if that already exists).
     #[instrument(level = "trace", skip(self), ret)]
@@ -469,6 +551,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         place: &mut Place<'tcx>,
         location: Location,
     ) -> Option<VnIndex> {
+        self.simplify_place_projection(place, location);
+
         // Invariant: `place` and `place_ref` point to the same value, even if they point to
         // different memory locations.
         let mut place_ref = place.as_ref();
@@ -483,53 +567,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 place_ref = PlaceRef { local, projection: &place.projection[index..] };
             }
 
-            let proj = match proj {
-                ProjectionElem::Deref => {
-                    let ty = Place::ty_from(
-                        place.local,
-                        &place.projection[..index],
-                        self.local_decls,
-                        self.tcx,
-                    )
-                    .ty;
-                    if let Some(Mutability::Not) = ty.ref_mutability()
-                        && let Some(pointee_ty) = ty.builtin_deref(true)
-                        && pointee_ty.ty.is_freeze(self.tcx, self.param_env)
-                    {
-                        // An immutable borrow `_x` always points to the same value for the
-                        // lifetime of the borrow, so we can merge all instances of `*_x`.
-                        ProjectionElem::Deref
-                    } else {
-                        return None;
-                    }
-                }
-                ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty),
-                ProjectionElem::Index(idx) => {
-                    let idx = self.locals[idx]?;
-                    ProjectionElem::Index(idx)
-                }
-                ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
-                    ProjectionElem::ConstantIndex { offset, min_length, from_end }
-                }
-                ProjectionElem::Subslice { from, to, from_end } => {
-                    ProjectionElem::Subslice { from, to, from_end }
-                }
-                ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index),
-                ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
-                ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
-            };
-            value = self.insert(Value::Projection(value, proj));
+            let base = PlaceRef { local: place.local, projection: &place.projection[..index] };
+            value = self.project(base, value, proj)?;
         }
 
-        if let Some(local) = self.try_as_local(value, location)
-            && local != place.local
-        // in case we had no projection to begin with.
-        {
-            *place = local.into();
-            self.reused_locals.insert(local);
-        } else if place_ref.local != place.local
-            || place_ref.projection.len() < place.projection.len()
-        {
+        if let Some(new_local) = self.try_as_local(value, location) {
+            place_ref = PlaceRef { local: new_local, projection: &[] };
+        }
+
+        if place_ref.local != place.local || place_ref.projection.len() < place.projection.len() {
             // By the invariant on `place_ref`.
             *place = place_ref.project_deeper(&[], self.tcx);
             self.reused_locals.insert(place_ref.local);
@@ -545,7 +591,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         location: Location,
     ) -> Option<VnIndex> {
         match *operand {
-            Operand::Constant(ref constant) => Some(self.insert(Value::Constant(constant.const_))),
+            Operand::Constant(ref mut constant) => {
+                let const_ = constant.const_.normalize(self.tcx, self.param_env);
+                Some(self.insert(Value::Constant(const_)))
+            }
             Operand::Copy(ref mut place) | Operand::Move(ref mut place) => {
                 let value = self.simplify_place_value(place, location)?;
                 if let Some(const_) = self.try_as_constant(value) {
@@ -595,11 +644,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let ty = rvalue.ty(self.local_decls, self.tcx);
                 Value::Aggregate(ty, variant_index, fields?)
             }
-            Rvalue::Ref(_, borrow_kind, place) => {
-                return self.new_pointer(place, AddressKind::Ref(borrow_kind));
+            Rvalue::Ref(_, borrow_kind, ref mut place) => {
+                self.simplify_place_projection(place, location);
+                return self.new_pointer(*place, AddressKind::Ref(borrow_kind));
             }
-            Rvalue::AddressOf(mutbl, place) => {
-                return self.new_pointer(place, AddressKind::Address(mutbl));
+            Rvalue::AddressOf(mutbl, ref mut place) => {
+                self.simplify_place_projection(place, location);
+                return self.new_pointer(*place, AddressKind::Address(mutbl));
             }
 
             // Operations.
@@ -757,6 +808,10 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
         self.tcx
     }
 
+    fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) {
+        self.simplify_place_projection(place, location);
+    }
+
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
         self.simplify_operand(operand, location);
     }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 4ec91a55f1d..bdd5bf702c8 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -2,6 +2,7 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(box_patterns)]
+#![feature(cow_is_borrowed)]
 #![feature(decl_macro)]
 #![feature(is_sorted)]
 #![feature(let_chains)]
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
index 46bf13985da..a587b1e6b1d 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
@@ -72,7 +72,8 @@
       bb2: {
           StorageDead(_7);
           StorageDead(_6);
-          StorageLive(_8);
+-         StorageLive(_8);
++         nop;
           _8 = &raw const (*_1);
           StorageLive(_9);
           StorageLive(_10);
@@ -92,7 +93,8 @@
       bb4: {
           StorageDead(_12);
           StorageDead(_11);
-          StorageLive(_13);
+-         StorageLive(_13);
++         nop;
           _13 = &raw mut (*_1);
           StorageLive(_14);
           StorageLive(_15);
@@ -112,7 +114,8 @@
       bb6: {
           StorageDead(_17);
           StorageDead(_16);
-          StorageLive(_18);
+-         StorageLive(_18);
++         nop;
           _18 = &(*_1);
           StorageLive(_19);
 -         StorageLive(_20);
@@ -188,9 +191,12 @@
           StorageDead(_32);
           StorageDead(_31);
           _0 = const ();
-          StorageDead(_18);
-          StorageDead(_13);
-          StorageDead(_8);
+-         StorageDead(_18);
+-         StorageDead(_13);
+-         StorageDead(_8);
++         nop;
++         nop;
++         nop;
           return;
       }
   }
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
index 3e731ead859..6fdda5e9988 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
@@ -72,7 +72,8 @@
       bb2: {
           StorageDead(_7);
           StorageDead(_6);
-          StorageLive(_8);
+-         StorageLive(_8);
++         nop;
           _8 = &raw const (*_1);
           StorageLive(_9);
           StorageLive(_10);
@@ -92,7 +93,8 @@
       bb4: {
           StorageDead(_12);
           StorageDead(_11);
-          StorageLive(_13);
+-         StorageLive(_13);
++         nop;
           _13 = &raw mut (*_1);
           StorageLive(_14);
           StorageLive(_15);
@@ -112,7 +114,8 @@
       bb6: {
           StorageDead(_17);
           StorageDead(_16);
-          StorageLive(_18);
+-         StorageLive(_18);
++         nop;
           _18 = &(*_1);
           StorageLive(_19);
 -         StorageLive(_20);
@@ -188,9 +191,12 @@
           StorageDead(_32);
           StorageDead(_31);
           _0 = const ();
-          StorageDead(_18);
-          StorageDead(_13);
-          StorageDead(_8);
+-         StorageDead(_18);
+-         StorageDead(_13);
+-         StorageDead(_8);
++         nop;
++         nop;
++         nop;
           return;
       }
   }
diff --git a/tests/mir-opt/gvn.references.GVN.panic-abort.diff b/tests/mir-opt/gvn.references.GVN.panic-abort.diff
index b7ad4ab1fd3..88543172565 100644
--- a/tests/mir-opt/gvn.references.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.references.GVN.panic-abort.diff
@@ -20,6 +20,24 @@
       let mut _15: *mut impl Sized;
       let _16: ();
       let mut _17: *mut impl Sized;
+      let _18: &mut impl Sized;
+      let mut _20: S<&mut impl Sized>;
+      let mut _21: &mut impl Sized;
+      let _22: ();
+      let mut _23: &impl Sized;
+      let _24: ();
+      let mut _25: &mut impl Sized;
+      let _26: ();
+      let mut _27: *const impl Sized;
+      let _28: ();
+      let mut _29: *mut impl Sized;
+      scope 1 {
+          debug r => _18;
+          let _19: &mut impl Sized;
+          scope 2 {
+              debug s => _19;
+          }
+      }
   
       bb0: {
           StorageLive(_2);
@@ -94,11 +112,65 @@
       bb8: {
           StorageDead(_17);
           StorageDead(_16);
-          _0 = const ();
-          drop(_1) -> [return: bb9, unwind unreachable];
+-         StorageLive(_18);
++         nop;
+          _18 = &mut _1;
+-         StorageLive(_19);
++         nop;
+          StorageLive(_20);
+          StorageLive(_21);
+-         _21 = move _18;
+-         _20 = S::<&mut impl Sized>(move _21);
++         _21 = _18;
++         _20 = S::<&mut impl Sized>(_18);
+          StorageDead(_21);
+          _19 = move (_20.0: &mut impl Sized);
+          StorageDead(_20);
+          StorageLive(_22);
+          StorageLive(_23);
+          _23 = &(*_19);
+          _22 = opaque::<&impl Sized>(move _23) -> [return: bb9, unwind unreachable];
       }
   
       bb9: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_24);
+          StorageLive(_25);
+          _25 = &mut (*_19);
+          _24 = opaque::<&mut impl Sized>(move _25) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+          StorageDead(_25);
+          StorageDead(_24);
+          StorageLive(_26);
+          StorageLive(_27);
+          _27 = &raw const (*_19);
+          _26 = opaque::<*const impl Sized>(move _27) -> [return: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_28);
+          StorageLive(_29);
+          _29 = &raw mut (*_19);
+          _28 = opaque::<*mut impl Sized>(move _29) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+          StorageDead(_29);
+          StorageDead(_28);
+          _0 = const ();
+-         StorageDead(_19);
+-         StorageDead(_18);
++         nop;
++         nop;
+          drop(_1) -> [return: bb13, unwind unreachable];
+      }
+  
+      bb13: {
           return;
       }
   }
diff --git a/tests/mir-opt/gvn.references.GVN.panic-unwind.diff b/tests/mir-opt/gvn.references.GVN.panic-unwind.diff
index 08ed4c629a6..106b453fe80 100644
--- a/tests/mir-opt/gvn.references.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.references.GVN.panic-unwind.diff
@@ -20,12 +20,30 @@
       let mut _15: *mut impl Sized;
       let _16: ();
       let mut _17: *mut impl Sized;
+      let _18: &mut impl Sized;
+      let mut _20: S<&mut impl Sized>;
+      let mut _21: &mut impl Sized;
+      let _22: ();
+      let mut _23: &impl Sized;
+      let _24: ();
+      let mut _25: &mut impl Sized;
+      let _26: ();
+      let mut _27: *const impl Sized;
+      let _28: ();
+      let mut _29: *mut impl Sized;
+      scope 1 {
+          debug r => _18;
+          let _19: &mut impl Sized;
+          scope 2 {
+              debug s => _19;
+          }
+      }
   
       bb0: {
           StorageLive(_2);
           StorageLive(_3);
           _3 = &_1;
-          _2 = opaque::<&impl Sized>(move _3) -> [return: bb1, unwind: bb10];
+          _2 = opaque::<&impl Sized>(move _3) -> [return: bb1, unwind: bb14];
       }
   
       bb1: {
@@ -34,7 +52,7 @@
           StorageLive(_4);
           StorageLive(_5);
           _5 = &_1;
-          _4 = opaque::<&impl Sized>(move _5) -> [return: bb2, unwind: bb10];
+          _4 = opaque::<&impl Sized>(move _5) -> [return: bb2, unwind: bb14];
       }
   
       bb2: {
@@ -43,7 +61,7 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = &mut _1;
-          _6 = opaque::<&mut impl Sized>(move _7) -> [return: bb3, unwind: bb10];
+          _6 = opaque::<&mut impl Sized>(move _7) -> [return: bb3, unwind: bb14];
       }
   
       bb3: {
@@ -52,7 +70,7 @@
           StorageLive(_8);
           StorageLive(_9);
           _9 = &mut _1;
-          _8 = opaque::<&mut impl Sized>(move _9) -> [return: bb4, unwind: bb10];
+          _8 = opaque::<&mut impl Sized>(move _9) -> [return: bb4, unwind: bb14];
       }
   
       bb4: {
@@ -61,7 +79,7 @@
           StorageLive(_10);
           StorageLive(_11);
           _11 = &raw const _1;
-          _10 = opaque::<*const impl Sized>(move _11) -> [return: bb5, unwind: bb10];
+          _10 = opaque::<*const impl Sized>(move _11) -> [return: bb5, unwind: bb14];
       }
   
       bb5: {
@@ -70,7 +88,7 @@
           StorageLive(_12);
           StorageLive(_13);
           _13 = &raw const _1;
-          _12 = opaque::<*const impl Sized>(move _13) -> [return: bb6, unwind: bb10];
+          _12 = opaque::<*const impl Sized>(move _13) -> [return: bb6, unwind: bb14];
       }
   
       bb6: {
@@ -79,7 +97,7 @@
           StorageLive(_14);
           StorageLive(_15);
           _15 = &raw mut _1;
-          _14 = opaque::<*mut impl Sized>(move _15) -> [return: bb7, unwind: bb10];
+          _14 = opaque::<*mut impl Sized>(move _15) -> [return: bb7, unwind: bb14];
       }
   
       bb7: {
@@ -88,25 +106,79 @@
           StorageLive(_16);
           StorageLive(_17);
           _17 = &raw mut _1;
-          _16 = opaque::<*mut impl Sized>(move _17) -> [return: bb8, unwind: bb10];
+          _16 = opaque::<*mut impl Sized>(move _17) -> [return: bb8, unwind: bb14];
       }
   
       bb8: {
           StorageDead(_17);
           StorageDead(_16);
-          _0 = const ();
-          drop(_1) -> [return: bb9, unwind: bb11];
+-         StorageLive(_18);
++         nop;
+          _18 = &mut _1;
+-         StorageLive(_19);
++         nop;
+          StorageLive(_20);
+          StorageLive(_21);
+-         _21 = move _18;
+-         _20 = S::<&mut impl Sized>(move _21);
++         _21 = _18;
++         _20 = S::<&mut impl Sized>(_18);
+          StorageDead(_21);
+          _19 = move (_20.0: &mut impl Sized);
+          StorageDead(_20);
+          StorageLive(_22);
+          StorageLive(_23);
+          _23 = &(*_19);
+          _22 = opaque::<&impl Sized>(move _23) -> [return: bb9, unwind: bb14];
       }
   
       bb9: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_24);
+          StorageLive(_25);
+          _25 = &mut (*_19);
+          _24 = opaque::<&mut impl Sized>(move _25) -> [return: bb10, unwind: bb14];
+      }
+  
+      bb10: {
+          StorageDead(_25);
+          StorageDead(_24);
+          StorageLive(_26);
+          StorageLive(_27);
+          _27 = &raw const (*_19);
+          _26 = opaque::<*const impl Sized>(move _27) -> [return: bb11, unwind: bb14];
+      }
+  
+      bb11: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_28);
+          StorageLive(_29);
+          _29 = &raw mut (*_19);
+          _28 = opaque::<*mut impl Sized>(move _29) -> [return: bb12, unwind: bb14];
+      }
+  
+      bb12: {
+          StorageDead(_29);
+          StorageDead(_28);
+          _0 = const ();
+-         StorageDead(_19);
+-         StorageDead(_18);
++         nop;
++         nop;
+          drop(_1) -> [return: bb13, unwind: bb15];
+      }
+  
+      bb13: {
           return;
       }
   
-      bb10 (cleanup): {
-          drop(_1) -> [return: bb11, unwind terminate(cleanup)];
+      bb14 (cleanup): {
+          drop(_1) -> [return: bb15, unwind terminate(cleanup)];
       }
   
-      bb11 (cleanup): {
+      bb15 (cleanup): {
           resume;
       }
   }
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
index 6e542d7f964..91af1ccc33a 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -40,7 +40,8 @@
       }
   
       bb1: {
-          _6 = _3[_7];
+-         _6 = _3[_7];
++         _6 = _3[0 of 1];
           _5 = opaque::<T>(move _6) -> [return: bb2, unwind unreachable];
       }
   
@@ -61,7 +62,8 @@
       }
   
       bb3: {
-          _11 = _3[_12];
+-         _11 = _3[_12];
++         _11 = _3[_2];
           _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
index a07cd49ec7c..f887094b509 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -40,7 +40,8 @@
       }
   
       bb1: {
-          _6 = _3[_7];
+-         _6 = _3[_7];
++         _6 = _3[0 of 1];
           _5 = opaque::<T>(move _6) -> [return: bb2, unwind continue];
       }
   
@@ -61,7 +62,8 @@
       }
   
       bb3: {
-          _11 = _3[_12];
+-         _11 = _3[_12];
++         _11 = _3[_2];
           _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
       }
   
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index fd24edc676c..3633f9c23cd 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -192,6 +192,13 @@ fn references(mut x: impl Sized) {
     opaque(&raw const x); // should not reuse a
     opaque(&raw mut x);
     opaque(&raw mut x); // should not reuse a
+
+    let r = &mut x;
+    let s = S(r).0; // Obfuscate `r`.
+    opaque(&*s); // This is `&*r`.
+    opaque(&mut *s); // This is `&*r`.
+    opaque(&raw const *s); // This is `&*r`.
+    opaque(&raw mut *s); // This is `&*r`.
 }
 
 fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
index 98255c42007..6168476d6f2 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -125,7 +125,8 @@
           StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
-          _14 = &(*_4);
+-         _14 = &(*_4);
++         _14 = &(*_1);
           _13 = core::str::<impl str>::as_ptr(move _14) -> [return: bb4, unwind unreachable];
       }
   
@@ -135,9 +136,11 @@
           _8 = (move _9, move _12);
           StorageDead(_12);
           StorageDead(_9);
-          StorageLive(_15);
+-         StorageLive(_15);
++         nop;
           _15 = (_8.0: &*const u8);
-          StorageLive(_16);
+-         StorageLive(_16);
++         nop;
           _16 = (_8.1: &*const u8);
           StorageLive(_17);
           StorageLive(_18);
@@ -153,8 +156,10 @@
           StorageDead(_18);
           _7 = const ();
           StorageDead(_17);
-          StorageDead(_16);
-          StorageDead(_15);
+-         StorageDead(_16);
+-         StorageDead(_15);
++         nop;
++         nop;
           StorageDead(_13);
           StorageDead(_10);
           StorageDead(_8);
@@ -184,11 +189,13 @@
 -         _23 = move _21;
 +         _23 = const core::panicking::AssertKind::Eq;
           StorageLive(_24);
-          StorageLive(_25);
+-         StorageLive(_25);
++         nop;
           _25 = &(*_15);
           _24 = &(*_25);
           StorageLive(_26);
-          StorageLive(_27);
+-         StorageLive(_27);
++         nop;
           _27 = &(*_16);
           _26 = &(*_27);
           StorageLive(_28);
@@ -225,9 +232,11 @@
           _34 = (move _35, move _38);
           StorageDead(_38);
           StorageDead(_35);
-          StorageLive(_41);
+-         StorageLive(_41);
++         nop;
           _41 = (_34.0: &*const u8);
-          StorageLive(_42);
+-         StorageLive(_42);
++         nop;
           _42 = (_34.1: &*const u8);
           StorageLive(_43);
           StorageLive(_44);
@@ -243,8 +252,10 @@
           StorageDead(_44);
           _33 = const ();
           StorageDead(_43);
-          StorageDead(_42);
-          StorageDead(_41);
+-         StorageDead(_42);
+-         StorageDead(_41);
++         nop;
++         nop;
           StorageDead(_39);
           StorageDead(_36);
           StorageDead(_34);
@@ -270,11 +281,13 @@
 -         _49 = move _47;
 +         _49 = const core::panicking::AssertKind::Eq;
           StorageLive(_50);
-          StorageLive(_51);
+-         StorageLive(_51);
++         nop;
           _51 = &(*_41);
           _50 = &(*_51);
           StorageLive(_52);
-          StorageLive(_53);
+-         StorageLive(_53);
++         nop;
           _53 = &(*_42);
           _52 = &(*_53);
           StorageLive(_54);
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
index 0f79cc409f3..f6003885808 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -125,7 +125,8 @@
           StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
-          _14 = &(*_4);
+-         _14 = &(*_4);
++         _14 = &(*_1);
           _13 = core::str::<impl str>::as_ptr(move _14) -> [return: bb4, unwind continue];
       }
   
@@ -135,9 +136,11 @@
           _8 = (move _9, move _12);
           StorageDead(_12);
           StorageDead(_9);
-          StorageLive(_15);
+-         StorageLive(_15);
++         nop;
           _15 = (_8.0: &*const u8);
-          StorageLive(_16);
+-         StorageLive(_16);
++         nop;
           _16 = (_8.1: &*const u8);
           StorageLive(_17);
           StorageLive(_18);
@@ -153,8 +156,10 @@
           StorageDead(_18);
           _7 = const ();
           StorageDead(_17);
-          StorageDead(_16);
-          StorageDead(_15);
+-         StorageDead(_16);
+-         StorageDead(_15);
++         nop;
++         nop;
           StorageDead(_13);
           StorageDead(_10);
           StorageDead(_8);
@@ -184,11 +189,13 @@
 -         _23 = move _21;
 +         _23 = const core::panicking::AssertKind::Eq;
           StorageLive(_24);
-          StorageLive(_25);
+-         StorageLive(_25);
++         nop;
           _25 = &(*_15);
           _24 = &(*_25);
           StorageLive(_26);
-          StorageLive(_27);
+-         StorageLive(_27);
++         nop;
           _27 = &(*_16);
           _26 = &(*_27);
           StorageLive(_28);
@@ -225,9 +232,11 @@
           _34 = (move _35, move _38);
           StorageDead(_38);
           StorageDead(_35);
-          StorageLive(_41);
+-         StorageLive(_41);
++         nop;
           _41 = (_34.0: &*const u8);
-          StorageLive(_42);
+-         StorageLive(_42);
++         nop;
           _42 = (_34.1: &*const u8);
           StorageLive(_43);
           StorageLive(_44);
@@ -243,8 +252,10 @@
           StorageDead(_44);
           _33 = const ();
           StorageDead(_43);
-          StorageDead(_42);
-          StorageDead(_41);
+-         StorageDead(_42);
+-         StorageDead(_41);
++         nop;
++         nop;
           StorageDead(_39);
           StorageDead(_36);
           StorageDead(_34);
@@ -270,11 +281,13 @@
 -         _49 = move _47;
 +         _49 = const core::panicking::AssertKind::Eq;
           StorageLive(_50);
-          StorageLive(_51);
+-         StorageLive(_51);
++         nop;
           _51 = &(*_41);
           _50 = &(*_51);
           StorageLive(_52);
-          StorageLive(_53);
+-         StorageLive(_53);
++         nop;
           _53 = &(*_42);
           _52 = &(*_53);
           StorageLive(_54);
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
index 6c8513e3281..41f29959c95 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
@@ -737,7 +737,8 @@
           StorageDead(_125);
           StorageDead(_126);
           StorageDead(_124);
-          StorageLive(_128);
+-         StorageLive(_128);
++         nop;
           _128 = &_3;
           StorageLive(_129);
 -         StorageLive(_130);
@@ -778,7 +779,8 @@
       bb32: {
           StorageDead(_134);
           StorageDead(_133);
-          StorageLive(_137);
+-         StorageLive(_137);
++         nop;
           _137 = &mut _3;
           StorageLive(_138);
           StorageLive(_139);
@@ -813,7 +815,8 @@
           StorageDead(_143);
           StorageDead(_142);
           StorageLive(_146);
-          StorageLive(_147);
+-         StorageLive(_147);
++         nop;
           _147 = &raw const _3;
           StorageLive(_148);
           StorageLive(_149);
@@ -847,7 +850,8 @@
       bb36: {
           StorageDead(_153);
           StorageDead(_152);
-          StorageLive(_156);
+-         StorageLive(_156);
++         nop;
           _156 = &raw mut _3;
           StorageLive(_157);
           StorageLive(_158);
@@ -882,10 +886,13 @@
           StorageDead(_162);
           StorageDead(_161);
           _146 = const ();
-          StorageDead(_156);
-          StorageDead(_147);
+-         StorageDead(_156);
+-         StorageDead(_147);
++         nop;
++         nop;
           StorageDead(_146);
-          StorageLive(_165);
+-         StorageLive(_165);
++         nop;
           _165 = &_3;
           StorageLive(_166);
 -         StorageLive(_167);
@@ -927,9 +934,12 @@
           StorageDead(_171);
           StorageDead(_170);
           _0 = const ();
-          StorageDead(_165);
-          StorageDead(_137);
-          StorageDead(_128);
+-         StorageDead(_165);
+-         StorageDead(_137);
+-         StorageDead(_128);
++         nop;
++         nop;
++         nop;
           return;
       }
   }
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
index fb2c089827d..ca928986cf6 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
@@ -737,7 +737,8 @@
           StorageDead(_125);
           StorageDead(_126);
           StorageDead(_124);
-          StorageLive(_128);
+-         StorageLive(_128);
++         nop;
           _128 = &_3;
           StorageLive(_129);
 -         StorageLive(_130);
@@ -778,7 +779,8 @@
       bb32: {
           StorageDead(_134);
           StorageDead(_133);
-          StorageLive(_137);
+-         StorageLive(_137);
++         nop;
           _137 = &mut _3;
           StorageLive(_138);
           StorageLive(_139);
@@ -813,7 +815,8 @@
           StorageDead(_143);
           StorageDead(_142);
           StorageLive(_146);
-          StorageLive(_147);
+-         StorageLive(_147);
++         nop;
           _147 = &raw const _3;
           StorageLive(_148);
           StorageLive(_149);
@@ -847,7 +850,8 @@
       bb36: {
           StorageDead(_153);
           StorageDead(_152);
-          StorageLive(_156);
+-         StorageLive(_156);
++         nop;
           _156 = &raw mut _3;
           StorageLive(_157);
           StorageLive(_158);
@@ -882,10 +886,13 @@
           StorageDead(_162);
           StorageDead(_161);
           _146 = const ();
-          StorageDead(_156);
-          StorageDead(_147);
+-         StorageDead(_156);
+-         StorageDead(_147);
++         nop;
++         nop;
           StorageDead(_146);
-          StorageLive(_165);
+-         StorageLive(_165);
++         nop;
           _165 = &_3;
           StorageLive(_166);
 -         StorageLive(_167);
@@ -927,9 +934,12 @@
           StorageDead(_171);
           StorageDead(_170);
           _0 = const ();
-          StorageDead(_165);
-          StorageDead(_137);
-          StorageDead(_128);
+-         StorageDead(_165);
+-         StorageDead(_137);
+-         StorageDead(_128);
++         nop;
++         nop;
++         nop;
           return;
       }
   }