about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-02-05 11:37:44 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-02-05 11:44:18 +0000
commit42c95146294c7773ca03e91e945fd545c6ce1ba2 (patch)
treef636d386b8f773ddbcd7ad540c72ea2ea103fc24
parente465d647b1286e9127dab4df091315588b44dba9 (diff)
downloadrust-42c95146294c7773ca03e91e945fd545c6ce1ba2.tar.gz
rust-42c95146294c7773ca03e91e945fd545c6ce1ba2.zip
Simplify construction of replacement map.
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs2
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs158
-rw-r--r--tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff52
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff13
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff10
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff16
-rw-r--r--tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff8
-rw-r--r--tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff69
-rw-r--r--tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff16
-rw-r--r--tests/mir-opt/sroa.rs2
-rw-r--r--tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff10
11 files changed, 196 insertions, 160 deletions
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 6bdbda909d7..90d07c81256 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -790,7 +790,7 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
 }
 
 /// Invokes `f` on all direct fields of `ty`.
-fn iter_fields<'tcx>(
+pub fn iter_fields<'tcx>(
     ty: Ty<'tcx>,
     tcx: TyCtxt<'tcx>,
     mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>),
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 462c3b4e918..3cfa0b16499 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -1,11 +1,12 @@
 use crate::MirPass;
-use rustc_data_structures::fx::{FxIndexMap, IndexEntry};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::value_analysis::iter_fields;
 
 pub struct ScalarReplacementOfAggregates;
 
@@ -125,6 +126,36 @@ fn escaping_locals(body: &Body<'_>) -> BitSet<Local> {
 #[derive(Default, Debug)]
 struct ReplacementMap<'tcx> {
     fields: FxIndexMap<PlaceRef<'tcx>, Local>,
+    /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage
+    /// and deinit statement and debuginfo.
+    fragments: IndexVec<Local, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
+}
+
+impl<'tcx> ReplacementMap<'tcx> {
+    fn gather_debug_info_fragments(
+        &self,
+        place: PlaceRef<'tcx>,
+    ) -> Option<Vec<VarDebugInfoFragment<'tcx>>> {
+        let mut fragments = Vec::new();
+        let Some(parts) = &self.fragments[place.local] else { return None };
+        for (proj, replacement_local) in parts {
+            if proj.starts_with(place.projection) {
+                fragments.push(VarDebugInfoFragment {
+                    projection: proj[place.projection.len()..].to_vec(),
+                    contents: Place::from(*replacement_local),
+                });
+            }
+        }
+        Some(fragments)
+    }
+
+    fn place_fragments(
+        &self,
+        place: Place<'tcx>,
+    ) -> Option<&Vec<(&'tcx [PlaceElem<'tcx>], Local)>> {
+        let local = place.as_local()?;
+        self.fragments[local].as_ref()
+    }
 }
 
 /// Compute the replacement of flattened places into locals.
@@ -136,53 +167,30 @@ fn compute_flattening<'tcx>(
     body: &mut Body<'tcx>,
     escaping: BitSet<Local>,
 ) -> ReplacementMap<'tcx> {
-    let mut visitor = PreFlattenVisitor {
-        tcx,
-        escaping,
-        local_decls: &mut body.local_decls,
-        map: Default::default(),
-    };
-    for (block, bbdata) in body.basic_blocks.iter_enumerated() {
-        visitor.visit_basic_block_data(block, bbdata);
-    }
-    return visitor.map;
-
-    struct PreFlattenVisitor<'tcx, 'll> {
-        tcx: TyCtxt<'tcx>,
-        local_decls: &'ll mut LocalDecls<'tcx>,
-        escaping: BitSet<Local>,
-        map: ReplacementMap<'tcx>,
-    }
+    let mut fields = FxIndexMap::default();
+    let mut fragments = IndexVec::from_elem(None::<Vec<_>>, &body.local_decls);
 
-    impl<'tcx, 'll> PreFlattenVisitor<'tcx, 'll> {
-        fn create_place(&mut self, place: PlaceRef<'tcx>) {
-            if self.escaping.contains(place.local) {
-                return;
-            }
-
-            match self.map.fields.entry(place) {
-                IndexEntry::Occupied(_) => {}
-                IndexEntry::Vacant(v) => {
-                    let ty = place.ty(&*self.local_decls, self.tcx).ty;
-                    let local = self.local_decls.push(LocalDecl {
-                        ty,
-                        user_ty: None,
-                        ..self.local_decls[place.local].clone()
-                    });
-                    v.insert(local);
-                }
-            }
-        }
-    }
-
-    impl<'tcx, 'll> Visitor<'tcx> for PreFlattenVisitor<'tcx, 'll> {
-        fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) {
-            if let &[PlaceElem::Field(..), ..] = &place.projection[..] {
-                let pr = PlaceRef { local: place.local, projection: &place.projection[..1] };
-                self.create_place(pr)
-            }
+    for local in body.local_decls.indices() {
+        if escaping.contains(local) {
+            continue;
         }
+        let decl = body.local_decls[local].clone();
+        let ty = decl.ty;
+        iter_fields(ty, tcx, |variant, field, field_ty| {
+            if variant.is_some() {
+                // Downcasts are currently not supported.
+                return;
+            };
+            let new_local =
+                body.local_decls.push(LocalDecl { ty: field_ty, user_ty: None, ..decl.clone() });
+            let place = Place::from(local)
+                .project_deeper(&[PlaceElem::Field(field, field_ty)], tcx)
+                .as_ref();
+            fields.insert(place, new_local);
+            fragments[local].get_or_insert_default().push((place.projection, new_local));
+        });
     }
+    ReplacementMap { fields, fragments }
 }
 
 /// Perform the replacement computed by `compute_flattening`.
@@ -200,18 +208,11 @@ fn replace_flattened_locals<'tcx>(
         return;
     }
 
-    let mut fragments = IndexVec::<_, Option<Vec<_>>>::from_elem(None, &body.local_decls);
-    for (k, v) in &replacements.fields {
-        fragments[k.local].get_or_insert_default().push((k.projection, *v));
-    }
-    debug!(?fragments);
-
     let mut visitor = ReplacementVisitor {
         tcx,
         local_decls: &body.local_decls,
         replacements,
         all_dead_locals,
-        fragments: &fragments,
         patch: MirPatch::new(body),
     };
     for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
@@ -237,30 +238,10 @@ struct ReplacementVisitor<'tcx, 'll> {
     replacements: ReplacementMap<'tcx>,
     /// This is used to check that we are not leaving references to replaced locals behind.
     all_dead_locals: BitSet<Local>,
-    /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage
-    /// and deinit statement and debuginfo.
-    fragments: &'ll IndexVec<Local, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
     patch: MirPatch<'tcx>,
 }
 
 impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
-    fn gather_debug_info_fragments(
-        &self,
-        place: PlaceRef<'tcx>,
-    ) -> Option<Vec<VarDebugInfoFragment<'tcx>>> {
-        let mut fragments = Vec::new();
-        let Some(parts) = &self.fragments[place.local] else { return None };
-        for (proj, replacement_local) in parts {
-            if proj.starts_with(place.projection) {
-                fragments.push(VarDebugInfoFragment {
-                    projection: proj[place.projection.len()..].to_vec(),
-                    contents: Place::from(*replacement_local),
-                });
-            }
-        }
-        Some(fragments)
-    }
-
     fn replace_place(&self, place: PlaceRef<'tcx>) -> Option<Place<'tcx>> {
         if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection {
             let pr = PlaceRef { local: place.local, projection: &place.projection[..1] };
@@ -270,14 +251,6 @@ impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
             None
         }
     }
-
-    fn place_fragments(
-        &self,
-        place: Place<'tcx>,
-    ) -> Option<&'ll Vec<(&'tcx [PlaceElem<'tcx>], Local)>> {
-        let local = place.as_local()?;
-        self.fragments[local].as_ref()
-    }
 }
 
 impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
@@ -285,10 +258,11 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
         self.tcx
     }
 
+    #[instrument(level = "trace", skip(self))]
     fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
         match statement.kind {
             StatementKind::StorageLive(l) => {
-                if let Some(final_locals) = &self.fragments[l] {
+                if let Some(final_locals) = &self.replacements.fragments[l] {
                     for &(_, fl) in final_locals {
                         self.patch.add_statement(location, StatementKind::StorageLive(fl));
                     }
@@ -297,7 +271,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
                 return;
             }
             StatementKind::StorageDead(l) => {
-                if let Some(final_locals) = &self.fragments[l] {
+                if let Some(final_locals) = &self.replacements.fragments[l] {
                     for &(_, fl) in final_locals {
                         self.patch.add_statement(location, StatementKind::StorageDead(fl));
                     }
@@ -306,7 +280,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
                 return;
             }
             StatementKind::Deinit(box place) => {
-                if let Some(final_locals) = self.place_fragments(place) {
+                if let Some(final_locals) = self.replacements.place_fragments(place) {
                     for &(_, fl) in final_locals {
                         self.patch
                             .add_statement(location, StatementKind::Deinit(Box::new(fl.into())));
@@ -317,7 +291,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
             }
 
             StatementKind::Assign(box (place, Rvalue::Aggregate(_, ref operands))) => {
-                if let Some(final_locals) = self.place_fragments(place) {
+                if let Some(final_locals) = self.replacements.place_fragments(place) {
                     for &(projection, fl) in final_locals {
                         let &[PlaceElem::Field(index, _)] = projection else { bug!() };
                         let index = index.as_usize();
@@ -333,7 +307,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
             }
 
             StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => {
-                if let Some(final_locals) = self.place_fragments(place) {
+                if let Some(final_locals) = self.replacements.place_fragments(place) {
                     for &(projection, fl) in final_locals {
                         let rvalue =
                             Rvalue::Use(Operand::Move(place.project_deeper(projection, self.tcx)));
@@ -353,9 +327,12 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
                     Operand::Move(rplace) => (rplace, false),
                     Operand::Constant(_) => bug!(),
                 };
-                if let Some(final_locals) = self.place_fragments(lhs) {
+                if let Some(final_locals) = self.replacements.place_fragments(lhs) {
                     for &(projection, fl) in final_locals {
                         let rplace = rplace.project_deeper(projection, self.tcx);
+                        debug!(?rplace);
+                        let rplace = self.replace_place(rplace.as_ref()).unwrap_or(rplace);
+                        debug!(?rplace);
                         let rvalue = if copy {
                             Rvalue::Use(Operand::Copy(rplace))
                         } else {
@@ -389,7 +366,9 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
             VarDebugInfoContents::Place(ref mut place) => {
                 if let Some(repl) = self.replace_place(place.as_ref()) {
                     *place = repl;
-                } else if let Some(fragments) = self.gather_debug_info_fragments(place.as_ref()) {
+                } else if let Some(fragments) =
+                    self.replacements.gather_debug_info_fragments(place.as_ref())
+                {
                     let ty = place.ty(self.local_decls, self.tcx).ty;
                     var_debug_info.value = VarDebugInfoContents::Composite { ty, fragments };
                 }
@@ -401,8 +380,9 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
                         if let Some(repl) = self.replace_place(fragment.contents.as_ref()) {
                             fragment.contents = repl;
                             true
-                        } else if let Some(frg) =
-                            self.gather_debug_info_fragments(fragment.contents.as_ref())
+                        } else if let Some(frg) = self
+                            .replacements
+                            .gather_debug_info_fragments(fragment.contents.as_ref())
                         {
                             new_fragments.extend(frg.into_iter().map(|mut f| {
                                 f.projection.splice(0..0, fragment.projection.iter().copied());
diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
index e14e586f34b..f1f53a48165 100644
--- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
+++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -8,8 +8,8 @@
       let mut _6: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16
       let mut _7: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20
       let mut _8: u8;                      // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24
-      let mut _13: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16
-      let mut _14: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22
+      let mut _12: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16
+      let mut _13: u32;                    // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22
       scope 1 {
 -         debug x => _1;                   // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10
 +         debug x => const 1_u8;           // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10
@@ -29,19 +29,21 @@
                       scope 5 {
 -                         debug s => _9;   // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
 +                         debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
-                          let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+                          let _14: bool;   // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+                          let _15: bool;   // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+                          let _16: u32;    // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
                           scope 6 {
-                              debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
-                              let _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+                              debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
+                              let _10: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
                               scope 7 {
-                                  debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10
-                                  let _15: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
-                                  let _16: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+                                  debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10
+                                  let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+                                  let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
                                   scope 8 {
-                                      debug p => Point{ .0 => _15, .1 => _16, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
-                                      let _12: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+                                      debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
+                                      let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
                                       scope 9 {
--                                         debug a => _12; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
+-                                         debug a => _11; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
 +                                         debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
                                       }
                                   }
@@ -67,17 +69,23 @@
                                            // mir::Constant
                                            // + span: $DIR/const_debuginfo.rs:14:13: 14:28
                                            // + literal: Const { ty: &str, val: Value(Slice(..)) }
-          StorageLive(_10);                // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
-          _10 = (const true, const false, const 123_u32); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
-          StorageLive(_11);                // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
-          _11 = Option::<u16>::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
-          _15 = const 32_u32;              // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
-          _16 = const 32_u32;              // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
-          StorageLive(_12);                // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
-          _12 = const 64_u32;              // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22
-          StorageDead(_12);                // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
-          StorageDead(_11);                // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2
-          StorageDead(_10);                // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+          StorageLive(_14);                // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+          StorageLive(_15);                // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+          StorageLive(_16);                // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+          _14 = const true;                // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+          _15 = const false;               // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+          _16 = const 123_u32;             // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+          StorageLive(_10);                // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
+          _10 = Option::<u16>::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
+          _17 = const 32_u32;              // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+          _18 = const 32_u32;              // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+          StorageLive(_11);                // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
+          _11 = const 64_u32;              // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22
+          StorageDead(_11);                // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
+          StorageDead(_10);                // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2
+          StorageDead(_14);                // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+          StorageDead(_15);                // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+          StorageDead(_16);                // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
           StorageDead(_9);                 // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2
           StorageDead(_4);                 // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2
           return;                          // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2
diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
index 0eb47087c9c..37fbcf9dd49 100644
--- a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff
@@ -6,9 +6,10 @@
       let mut _1: (i32, i32);              // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
-          let _2: (i32, i32);              // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+          let _2: i32;                     // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+          let _3: i32;                     // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
           scope 2 {
-              debug y => _2;               // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+              debug y => (i32, i32){ .0 => _2, .1 => _3, }; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
           }
       }
   
@@ -18,9 +19,13 @@
 +         _1 = const (42_i32, 43_i32);     // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
           (_1.1: i32) = const 99_i32;      // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13
           StorageLive(_2);                 // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
--         _2 = _1;                         // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
-+         _2 = const (42_i32, 99_i32);     // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
+          StorageLive(_3);                 // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+-         _2 = (_1.0: i32);                // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
+-         _3 = (_1.1: i32);                // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
++         _2 = const 42_i32;               // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
++         _3 = const 99_i32;               // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
           StorageDead(_2);                 // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
+          StorageDead(_3);                 // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
           StorageDead(_1);                 // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
           return;                          // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2
       }
diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
index 26a1c3c1aa9..134f0c080bf 100644
--- a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff
@@ -9,9 +9,10 @@
           let _2: &mut (i32, i32);         // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
           scope 2 {
               debug z => _2;               // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
-              let _3: (i32, i32);          // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+              let _3: i32;                 // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+              let _4: i32;                 // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
               scope 3 {
-                  debug y => _3;           // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+                  debug y => (i32, i32){ .0 => _3, .1 => _4, }; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
               }
           }
       }
@@ -23,8 +24,11 @@
           _2 = &mut _1;                    // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19
           ((*_2).1: i32) = const 99_i32;   // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13
           StorageLive(_3);                 // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
-          _3 = _1;                         // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14
+          StorageLive(_4);                 // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10
+          _3 = (_1.0: i32);                // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14
+          _4 = (_1.1: i32);                // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14
           StorageDead(_3);                 // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
+          StorageDead(_4);                 // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
           StorageDead(_2);                 // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
           StorageDead(_1);                 // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2
           return;                          // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2
diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
index 8bd589fb2c8..4010dd6c6d0 100644
--- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -10,13 +10,13 @@
           let mut _5: i32;                 // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
           let mut _6: i32;                 // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
           scope 2 {
-              debug x => (i32, i32){ .1 => _5, .0 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+              debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
               let _3: i32;                 // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
               scope 3 {
                   debug y => _3;           // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
                   let _4: i32;             // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
                   scope 4 {
-                      debug z => _6;       // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
+                      debug z => _5;       // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
                   }
               }
           }
@@ -31,17 +31,17 @@
       }
   
       bb1: {
-          StorageLive(_5);                 // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
-          _5 = const 2_i32;                // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
-          _6 = const 1_i32;                // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+          StorageLive(_6);                 // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+          _5 = const 1_i32;                // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+          _6 = const 2_i32;                // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
           StorageLive(_2);                 // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
           _2 = _1;                         // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
-          _5 = move _2;                    // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
+          _6 = move _2;                    // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
           StorageDead(_2);                 // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
           StorageLive(_3);                 // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
-          _3 = _5;                         // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
+          _3 = _6;                         // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
           StorageDead(_3);                 // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
-          StorageDead(_5);                 // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+          StorageDead(_6);                 // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
           StorageDead(_1);                 // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
           return;                          // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2
       }
diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
index 87271f24fc4..98cd020dade 100644
--- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
+++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
@@ -11,6 +11,7 @@
       let mut _7: bool;                    // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
       let mut _9: Point;                   // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
 +     let mut _10: u32;                    // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++     let mut _11: u32;                    // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
       scope 1 {
           debug x => _1;                   // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
           let _3: i32;                     // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
@@ -51,11 +52,14 @@
 -         _8 = (_9.1: u32);                // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
 -         StorageDead(_9);                 // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
 +         StorageLive(_10);                // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++         StorageLive(_11);                // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
 +         nop;                             // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
-+         _10 = const 42_u32;              // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++         _10 = const 12_u32;              // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++         _11 = const 42_u32;              // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
 +         nop;                             // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
-+         _8 = _10;                        // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++         _8 = _11;                        // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
 +         StorageDead(_10);                // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++         StorageDead(_11);                // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
 +         nop;                             // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
           nop;                             // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
           StorageDead(_8);                 // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
diff --git a/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff
index 72610de8eaf..b76e2d6d0f2 100644
--- a/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff
@@ -5,44 +5,65 @@
       debug x => _1;                       // in scope 0 at $DIR/sroa.rs:+0:11: +0:12
       let mut _0: ();                      // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19
       let _2: Foo;                         // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+     let _5: u8;                          // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+     let _6: &str;                        // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
       scope 1 {
--         debug y => _2;                   // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
-+         debug y => Foo{ .0 => _5, .2 => _6, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
+          debug y => _2;                   // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
           let _3: u8;                      // in scope 1 at $DIR/sroa.rs:+2:9: +2:10
           scope 2 {
               debug t => _3;               // in scope 2 at $DIR/sroa.rs:+2:9: +2:10
               let _4: &str;                // in scope 2 at $DIR/sroa.rs:+3:9: +3:10
               scope 3 {
                   debug u => _4;           // in scope 3 at $DIR/sroa.rs:+3:9: +3:10
+                  let _5: Foo;             // in scope 3 at $DIR/sroa.rs:+4:9: +4:10
++                 let _7: u8;              // in scope 3 at $DIR/sroa.rs:+4:9: +4:10
++                 let _8: ();              // in scope 3 at $DIR/sroa.rs:+4:9: +4:10
++                 let _9: &str;            // in scope 3 at $DIR/sroa.rs:+4:9: +4:10
++                 let _10: std::option::Option<isize>; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10
+                  scope 4 {
+-                     debug z => _5;       // in scope 4 at $DIR/sroa.rs:+4:9: +4:10
++                     debug z => Foo{ .0 => _7, .1 => _8, .2 => _9, .3 => _10, }; // in scope 4 at $DIR/sroa.rs:+4:9: +4:10
+                      let _6: ();          // in scope 4 at $DIR/sroa.rs:+5:9: +5:10
+                      scope 5 {
+                          debug a => _6;   // in scope 5 at $DIR/sroa.rs:+5:9: +5:10
+                      }
+                  }
               }
           }
       }
   
       bb0: {
--         StorageLive(_2);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
--         _2 = _1;                         // scope 0 at $DIR/sroa.rs:+1:13: +1:14
-+         StorageLive(_5);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+         StorageLive(_6);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+         nop;                             // scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+         _5 = (_1.0: u8);                 // scope 0 at $DIR/sroa.rs:+1:13: +1:14
-+         _6 = (_1.2: &str);               // scope 0 at $DIR/sroa.rs:+1:13: +1:14
-+         nop;                             // scope 0 at $DIR/sroa.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
+          _2 = _1;                         // scope 0 at $DIR/sroa.rs:+1:13: +1:14
           StorageLive(_3);                 // scope 1 at $DIR/sroa.rs:+2:9: +2:10
--         _3 = (_2.0: u8);                 // scope 1 at $DIR/sroa.rs:+2:13: +2:16
-+         _3 = _5;                         // scope 1 at $DIR/sroa.rs:+2:13: +2:16
+          _3 = (_2.0: u8);                 // scope 1 at $DIR/sroa.rs:+2:13: +2:16
           StorageLive(_4);                 // scope 2 at $DIR/sroa.rs:+3:9: +3:10
--         _4 = (_2.2: &str);               // scope 2 at $DIR/sroa.rs:+3:13: +3:16
-+         _4 = _6;                         // scope 2 at $DIR/sroa.rs:+3:13: +3:16
-          _0 = const ();                   // scope 0 at $DIR/sroa.rs:+0:19: +4:2
-          StorageDead(_4);                 // scope 2 at $DIR/sroa.rs:+4:1: +4:2
-          StorageDead(_3);                 // scope 1 at $DIR/sroa.rs:+4:1: +4:2
--         StorageDead(_2);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
-+         StorageDead(_5);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
-+         StorageDead(_6);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
-+         nop;                             // scope 0 at $DIR/sroa.rs:+4:1: +4:2
-          return;                          // scope 0 at $DIR/sroa.rs:+4:2: +4:2
+          _4 = (_2.2: &str);               // scope 2 at $DIR/sroa.rs:+3:13: +3:16
+-         StorageLive(_5);                 // scope 3 at $DIR/sroa.rs:+4:9: +4:10
+-         _5 = _2;                         // scope 3 at $DIR/sroa.rs:+4:13: +4:14
++         StorageLive(_7);                 // scope 3 at $DIR/sroa.rs:+4:9: +4:10
++         StorageLive(_8);                 // scope 3 at $DIR/sroa.rs:+4:9: +4:10
++         StorageLive(_9);                 // scope 3 at $DIR/sroa.rs:+4:9: +4:10
++         StorageLive(_10);                // scope 3 at $DIR/sroa.rs:+4:9: +4:10
++         nop;                             // scope 3 at $DIR/sroa.rs:+4:9: +4:10
++         _7 = (_2.0: u8);                 // scope 3 at $DIR/sroa.rs:+4:13: +4:14
++         _8 = (_2.1: ());                 // scope 3 at $DIR/sroa.rs:+4:13: +4:14
++         _9 = (_2.2: &str);               // scope 3 at $DIR/sroa.rs:+4:13: +4:14
++         _10 = (_2.3: std::option::Option<isize>); // scope 3 at $DIR/sroa.rs:+4:13: +4:14
++         nop;                             // scope 3 at $DIR/sroa.rs:+4:13: +4:14
+          StorageLive(_6);                 // scope 4 at $DIR/sroa.rs:+5:9: +5:10
+-         _6 = (_5.1: ());                 // scope 4 at $DIR/sroa.rs:+5:13: +5:16
++         _6 = _8;                         // scope 4 at $DIR/sroa.rs:+5:13: +5:16
+          _0 = const ();                   // scope 0 at $DIR/sroa.rs:+0:19: +6:2
+          StorageDead(_6);                 // scope 4 at $DIR/sroa.rs:+6:1: +6:2
+-         StorageDead(_5);                 // scope 3 at $DIR/sroa.rs:+6:1: +6:2
++         StorageDead(_7);                 // scope 3 at $DIR/sroa.rs:+6:1: +6:2
++         StorageDead(_8);                 // scope 3 at $DIR/sroa.rs:+6:1: +6:2
++         StorageDead(_9);                 // scope 3 at $DIR/sroa.rs:+6:1: +6:2
++         StorageDead(_10);                // scope 3 at $DIR/sroa.rs:+6:1: +6:2
++         nop;                             // scope 3 at $DIR/sroa.rs:+6:1: +6:2
+          StorageDead(_4);                 // scope 2 at $DIR/sroa.rs:+6:1: +6:2
+          StorageDead(_3);                 // scope 1 at $DIR/sroa.rs:+6:1: +6:2
+          StorageDead(_2);                 // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+          return;                          // scope 0 at $DIR/sroa.rs:+6:2: +6:2
       }
   }
   
diff --git a/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff
index 1a561a9edde..f0d62220dd6 100644
--- a/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff
@@ -6,10 +6,12 @@
       let mut _0: ();                      // return place in scope 0 at $DIR/sroa.rs:+0:24: +0:24
       let _2: Foo;                         // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
 +     let _5: u8;                          // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
-+     let _6: &str;                        // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
++     let _6: ();                          // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
++     let _7: &str;                        // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
++     let _8: std::option::Option<isize>;  // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
       scope 1 {
 -         debug y => _2;                   // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
-+         debug y => Foo{ .0 => _5, .2 => _6, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
++         debug y => Foo{ .0 => _5, .1 => _6, .2 => _7, .3 => _8, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10
           let _3: u8;                      // in scope 1 at $DIR/sroa.rs:+2:9: +2:10
           scope 2 {
               debug t => _3;               // in scope 2 at $DIR/sroa.rs:+2:9: +2:10
@@ -25,22 +27,28 @@
 -         _2 = (*_1);                      // scope 0 at $DIR/sroa.rs:+1:13: +1:15
 +         StorageLive(_5);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
 +         StorageLive(_6);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
++         StorageLive(_7);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
++         StorageLive(_8);                 // scope 0 at $DIR/sroa.rs:+1:9: +1:10
 +         nop;                             // scope 0 at $DIR/sroa.rs:+1:9: +1:10
 +         _5 = ((*_1).0: u8);              // scope 0 at $DIR/sroa.rs:+1:13: +1:15
-+         _6 = ((*_1).2: &str);            // scope 0 at $DIR/sroa.rs:+1:13: +1:15
++         _6 = ((*_1).1: ());              // scope 0 at $DIR/sroa.rs:+1:13: +1:15
++         _7 = ((*_1).2: &str);            // scope 0 at $DIR/sroa.rs:+1:13: +1:15
++         _8 = ((*_1).3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:13: +1:15
 +         nop;                             // scope 0 at $DIR/sroa.rs:+1:13: +1:15
           StorageLive(_3);                 // scope 1 at $DIR/sroa.rs:+2:9: +2:10
 -         _3 = (_2.0: u8);                 // scope 1 at $DIR/sroa.rs:+2:13: +2:16
 +         _3 = _5;                         // scope 1 at $DIR/sroa.rs:+2:13: +2:16
           StorageLive(_4);                 // scope 2 at $DIR/sroa.rs:+3:9: +3:10
 -         _4 = (_2.2: &str);               // scope 2 at $DIR/sroa.rs:+3:13: +3:16
-+         _4 = _6;                         // scope 2 at $DIR/sroa.rs:+3:13: +3:16
++         _4 = _7;                         // scope 2 at $DIR/sroa.rs:+3:13: +3:16
           _0 = const ();                   // scope 0 at $DIR/sroa.rs:+0:24: +4:2
           StorageDead(_4);                 // scope 2 at $DIR/sroa.rs:+4:1: +4:2
           StorageDead(_3);                 // scope 1 at $DIR/sroa.rs:+4:1: +4:2
 -         StorageDead(_2);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
 +         StorageDead(_5);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
 +         StorageDead(_6);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
++         StorageDead(_7);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
++         StorageDead(_8);                 // scope 0 at $DIR/sroa.rs:+4:1: +4:2
 +         nop;                             // scope 0 at $DIR/sroa.rs:+4:1: +4:2
           return;                          // scope 0 at $DIR/sroa.rs:+4:2: +4:2
       }
diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs
index b80f61600c2..471aac9f9d8 100644
--- a/tests/mir-opt/sroa.rs
+++ b/tests/mir-opt/sroa.rs
@@ -77,6 +77,8 @@ fn copies(x: Foo) {
     let y = x;
     let t = y.a;
     let u = y.c;
+    let z = y;
+    let a = z.b;
 }
 
 fn ref_copies(x: &Foo) {
diff --git a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
index ca3cb3d8ed1..2c63d8b266d 100644
--- a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
@@ -6,22 +6,26 @@
       let mut _0: f32;                     // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30
       let mut _2: structs::U;              // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
       let mut _3: f32;                     // in scope 0 at $DIR/sroa.rs:+6:18: +6:19
-+     let mut _4: f32;                     // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
++     let mut _4: usize;                   // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
++     let mut _5: f32;                     // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
   
       bb0: {
 -         StorageLive(_2);                 // scope 0 at $DIR/sroa.rs:+6:5: +6:21
 +         StorageLive(_4);                 // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++         StorageLive(_5);                 // scope 0 at $DIR/sroa.rs:+6:5: +6:21
 +         nop;                             // scope 0 at $DIR/sroa.rs:+6:5: +6:21
           StorageLive(_3);                 // scope 0 at $DIR/sroa.rs:+6:18: +6:19
           _3 = _1;                         // scope 0 at $DIR/sroa.rs:+6:18: +6:19
 -         _2 = U { _foo: const 0_usize, a: move _3 }; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
-+         _4 = move _3;                    // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++         _4 = const 0_usize;              // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++         _5 = move _3;                    // scope 0 at $DIR/sroa.rs:+6:5: +6:21
 +         nop;                             // scope 0 at $DIR/sroa.rs:+6:5: +6:21
           StorageDead(_3);                 // scope 0 at $DIR/sroa.rs:+6:20: +6:21
 -         _0 = (_2.1: f32);                // scope 0 at $DIR/sroa.rs:+6:5: +6:23
 -         StorageDead(_2);                 // scope 0 at $DIR/sroa.rs:+7:1: +7:2
-+         _0 = _4;                         // scope 0 at $DIR/sroa.rs:+6:5: +6:23
++         _0 = _5;                         // scope 0 at $DIR/sroa.rs:+6:5: +6:23
 +         StorageDead(_4);                 // scope 0 at $DIR/sroa.rs:+7:1: +7:2
++         StorageDead(_5);                 // scope 0 at $DIR/sroa.rs:+7:1: +7:2
 +         nop;                             // scope 0 at $DIR/sroa.rs:+7:1: +7:2
           return;                          // scope 0 at $DIR/sroa.rs:+7:2: +7:2
       }