about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-07-20 17:03:44 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-10-08 16:05:26 +0000
commit37f080edbc763f0add0552427d303b247055fc15 (patch)
treec73805cc762310e04c31b492d223fe1bd90217d4
parent4f4a413fe6931d0ad9d3ac6bd20ff36398961e64 (diff)
downloadrust-37f080edbc763f0add0552427d303b247055fc15.tar.gz
rust-37f080edbc763f0add0552427d303b247055fc15.zip
Also consider call and yield as MIR SSA.
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs37
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs77
-rw-r--r--tests/mir-opt/copy-prop/calls.multiple_edges.CopyProp.diff21
-rw-r--r--tests/mir-opt/copy-prop/calls.nrvo.CopyProp.diff24
-rw-r--r--tests/mir-opt/copy-prop/calls.rs43
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff4
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir58
-rw-r--r--tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir46
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir6
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir6
-rw-r--r--tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff22
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs2
13 files changed, 224 insertions, 124 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 56bdc5a171a..c7529b954fe 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -63,7 +63,7 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
 
-use crate::ssa::SsaLocals;
+use crate::ssa::{AssignedValue, SsaLocals};
 use crate::MirPass;
 
 pub struct GVN;
@@ -87,21 +87,28 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let dominators = body.basic_blocks.dominators().clone();
 
     let mut state = VnState::new(tcx, param_env, &ssa, &dominators, &body.local_decls);
-    for arg in body.args_iter() {
-        if ssa.is_ssa(arg) {
-            let value = state.new_opaque().unwrap();
-            state.assign(arg, value);
-        }
-    }
-
-    ssa.for_each_assignment_mut(&mut body.basic_blocks, |local, rvalue, location| {
-        let value = state.simplify_rvalue(rvalue, location).or_else(|| state.new_opaque()).unwrap();
-        // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
-        // reusable if we have an exact type match.
-        if state.local_decls[local].ty == rvalue.ty(state.local_decls, tcx) {
+    ssa.for_each_assignment_mut(
+        body.basic_blocks.as_mut_preserves_cfg(),
+        |local, value, location| {
+            let value = match value {
+                // We do not know anything of this assigned value.
+                AssignedValue::Arg | AssignedValue::Terminator(_) => None,
+                // Try to get some insight.
+                AssignedValue::Rvalue(rvalue) => {
+                    let value = state.simplify_rvalue(rvalue, location);
+                    // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
+                    // reusable if we have an exact type match.
+                    if state.local_decls[local].ty != rvalue.ty(state.local_decls, tcx) {
+                        return;
+                    }
+                    value
+                }
+            };
+            // `next_opaque` is `Some`, so `new_opaque` must return `Some`.
+            let value = value.or_else(|| state.new_opaque()).unwrap();
             state.assign(local, value);
-        }
-    });
+        },
+    );
 
     // Stop creating opaques during replacement as it is useless.
     state.next_opaque = None;
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index fad58930e3a..8dc7b60c4e5 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -5,7 +5,6 @@
 //! As a consequence of rule 2, we consider that borrowed locals are not SSA, even if they are
 //! `Freeze`, as we do not track that the assignment dominates all uses of the borrow.
 
-use either::Either;
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_index::bit_set::BitSet;
 use rustc_index::{IndexSlice, IndexVec};
@@ -27,6 +26,12 @@ pub struct SsaLocals {
     direct_uses: IndexVec<Local, u32>,
 }
 
+pub enum AssignedValue<'a, 'tcx> {
+    Arg,
+    Rvalue(&'a mut Rvalue<'tcx>),
+    Terminator(&'a mut TerminatorKind<'tcx>),
+}
+
 impl SsaLocals {
     pub fn new<'tcx>(body: &Body<'tcx>) -> SsaLocals {
         let assignment_order = Vec::with_capacity(body.local_decls.len());
@@ -39,6 +44,7 @@ impl SsaLocals {
 
         for local in body.args_iter() {
             visitor.assignments[local] = Set1::One(DefLocation::Argument);
+            visitor.assignment_order.push(local);
         }
 
         // For SSA assignments, a RPO visit will see the assignment before it sees any use.
@@ -105,8 +111,8 @@ impl SsaLocals {
     ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
         self.assignment_order.iter().filter_map(|&local| {
             if let Set1::One(DefLocation::Body(loc)) = self.assignments[local] {
+                let stmt = body.stmt_at(loc).left()?;
                 // `loc` must point to a direct assignment to `local`.
-                let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
                 let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
                 assert_eq!(target.as_local(), Some(local));
                 Some((local, rvalue, loc))
@@ -118,18 +124,33 @@ impl SsaLocals {
 
     pub fn for_each_assignment_mut<'tcx>(
         &self,
-        basic_blocks: &mut BasicBlocks<'tcx>,
-        mut f: impl FnMut(Local, &mut Rvalue<'tcx>, Location),
+        basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
+        mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location),
     ) {
         for &local in &self.assignment_order {
-            if let Set1::One(DefLocation::Body(loc)) = self.assignments[local] {
-                // `loc` must point to a direct assignment to `local`.
-                let bbs = basic_blocks.as_mut_preserves_cfg();
-                let bb = &mut bbs[loc.block];
-                let stmt = &mut bb.statements[loc.statement_index];
-                let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else { bug!() };
-                assert_eq!(target.as_local(), Some(local));
-                f(local, rvalue, loc)
+            match self.assignments[local] {
+                Set1::One(DefLocation::Argument) => f(
+                    local,
+                    AssignedValue::Arg,
+                    Location { block: START_BLOCK, statement_index: 0 },
+                ),
+                Set1::One(DefLocation::Body(loc)) => {
+                    let bb = &mut basic_blocks[loc.block];
+                    let value = if loc.statement_index < bb.statements.len() {
+                        // `loc` must point to a direct assignment to `local`.
+                        let stmt = &mut bb.statements[loc.statement_index];
+                        let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else {
+                            bug!()
+                        };
+                        assert_eq!(target.as_local(), Some(local));
+                        AssignedValue::Rvalue(rvalue)
+                    } else {
+                        let term = bb.terminator_mut();
+                        AssignedValue::Terminator(&mut term.kind)
+                    };
+                    f(local, value, loc)
+                }
+                _ => {}
             }
         }
     }
@@ -228,8 +249,22 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
     }
 
     fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
-        if place.projection.first() == Some(&PlaceElem::Deref) {
-            // Do not do anything for storage statements and debuginfo.
+        let location = match ctxt {
+            PlaceContext::MutatingUse(
+                MutatingUseContext::Store | MutatingUseContext::Call | MutatingUseContext::Yield,
+            ) => Some(DefLocation::Body(loc)),
+            _ => None,
+        };
+        if let Some(location) = location
+            && let Some(local) = place.as_local()
+        {
+            self.assignments[local].insert(location);
+            if let Set1::One(_) = self.assignments[local] {
+                // Only record if SSA-like, to avoid growing the vector needlessly.
+                self.assignment_order.push(local);
+            }
+        } else if place.projection.first() == Some(&PlaceElem::Deref) {
+            // Do not do anything for debuginfo.
             if ctxt.is_use() {
                 // Only change the context if it is a real use, not a "use" in debuginfo.
                 let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
@@ -237,25 +272,11 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
                 self.visit_projection(place.as_ref(), new_ctxt, loc);
                 self.check_dominates(place.local, loc);
             }
-            return;
         } else {
             self.visit_projection(place.as_ref(), ctxt, loc);
             self.visit_local(place.local, ctxt, loc);
         }
     }
-
-    fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, loc: Location) {
-        if let Some(local) = place.as_local() {
-            self.assignments[local].insert(DefLocation::Body(loc));
-            if let Set1::One(_) = self.assignments[local] {
-                // Only record if SSA-like, to avoid growing the vector needlessly.
-                self.assignment_order.push(local);
-            }
-        } else {
-            self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc);
-        }
-        self.visit_rvalue(rvalue, loc);
-    }
 }
 
 #[instrument(level = "trace", skip(ssa, body))]
diff --git a/tests/mir-opt/copy-prop/calls.multiple_edges.CopyProp.diff b/tests/mir-opt/copy-prop/calls.multiple_edges.CopyProp.diff
new file mode 100644
index 00000000000..4d56a8b25d3
--- /dev/null
+++ b/tests/mir-opt/copy-prop/calls.multiple_edges.CopyProp.diff
@@ -0,0 +1,21 @@
+- // MIR for `multiple_edges` before CopyProp
++ // MIR for `multiple_edges` after CopyProp
+  
+  fn multiple_edges(_1: bool) -> u8 {
+      let mut _0: u8;
+      let mut _2: u8;
+  
+      bb0: {
+          switchInt(_1) -> [1: bb1, otherwise: bb2];
+      }
+  
+      bb1: {
+          _2 = dummy(const 13_u8) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          _0 = _2;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/calls.nrvo.CopyProp.diff b/tests/mir-opt/copy-prop/calls.nrvo.CopyProp.diff
new file mode 100644
index 00000000000..b5d56909b0d
--- /dev/null
+++ b/tests/mir-opt/copy-prop/calls.nrvo.CopyProp.diff
@@ -0,0 +1,24 @@
+- // MIR for `nrvo` before CopyProp
++ // MIR for `nrvo` after CopyProp
+  
+  fn nrvo() -> u8 {
+      let mut _0: u8;
+      let _1: u8;
+      scope 1 {
+-         debug y => _1;
++         debug y => _0;
+      }
+  
+      bb0: {
+-         StorageLive(_1);
+-         _1 = dummy(const 5_u8) -> [return: bb1, unwind continue];
++         _0 = dummy(const 5_u8) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         _0 = _1;
+-         StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/calls.rs b/tests/mir-opt/copy-prop/calls.rs
new file mode 100644
index 00000000000..c1f86f1f412
--- /dev/null
+++ b/tests/mir-opt/copy-prop/calls.rs
@@ -0,0 +1,43 @@
+// Check that CopyProp does propagate return values of call terminators.
+// unit-test: CopyProp
+// needs-unwind
+
+#![feature(custom_mir, core_intrinsics)]
+use std::intrinsics::mir::*;
+
+#[inline(never)]
+fn dummy(x: u8) -> u8 {
+    x
+}
+
+// EMIT_MIR calls.nrvo.CopyProp.diff
+fn nrvo() -> u8 {
+    let y = dummy(5); // this should get NRVO
+    y
+}
+
+// EMIT_MIR calls.multiple_edges.CopyProp.diff
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn multiple_edges(t: bool) -> u8 {
+    mir! {
+        let x: u8;
+        {
+            match t { true => bbt, _ => ret }
+        }
+        bbt = {
+            Call(x = dummy(13), ret)
+        }
+        ret = {
+            // `x` is not assigned on the `bb0 -> ret` edge,
+            // so should not be marked as SSA for merging with `_0`.
+            RET = x;
+            Return()
+        }
+    }
+}
+
+fn main() {
+    // Make sure the function actually gets instantiated.
+    nrvo();
+    multiple_edges(false);
+}
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
index 7d5553b2f37..da45ebcb4d8 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
@@ -8,11 +8,11 @@
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
-+         let mut _4: !;
++         let _4: !;
 +         let mut _5: &fn() -> ! {sleep};
-+         let mut _6: !;
 +         scope 2 {
 +             debug a => _4;
++             let _6: !;
 +             scope 3 {
 +                 debug b => _6;
 +             }
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index 9f8c5806c90..d65c65e5fd0 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -10,10 +10,10 @@
 +         let mut _3: &fn() -> ! {sleep};
 +         let _4: !;
 +         let mut _5: &fn() -> ! {sleep};
-+         let mut _6: !;
 +         let mut _7: !;
 +         scope 2 {
 +             debug a => _4;
++             let _6: !;
 +             scope 3 {
 +                 debug b => _6;
 +             }
diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
index 2fbe5088268..8dbb688999a 100644
--- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir
@@ -6,21 +6,20 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
     let mut _0: ();
     let mut _3: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
     let mut _4: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
-    let mut _5: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
-    let mut _6: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
-    let mut _9: std::option::Option<U>;
-    let mut _10: isize;
-    let _12: ();
+    let mut _5: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
+    let mut _8: std::option::Option<U>;
+    let mut _9: isize;
+    let _11: ();
     scope 1 {
-        debug iter => _5;
-        let _11: U;
+        debug iter => _4;
+        let _10: U;
         scope 2 {
-            debug x => _11;
+            debug x => _10;
         }
         scope 4 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as Iterator>::next) {
-            debug self => _6;
-            let mut _7: &mut impl Iterator<Item = T>;
-            let mut _8: &mut impl Fn(T) -> Option<U>;
+            debug self => _5;
+            let mut _6: &mut impl Iterator<Item = T>;
+            let mut _7: &mut impl Fn(T) -> Option<U>;
         }
     }
     scope 3 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as IntoIterator>::into_iter) {
@@ -28,54 +27,49 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
     }
 
     bb0: {
-        StorageLive(_4);
-        StorageLive(_3);
         _3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
+        StorageLive(_4);
         _4 = move _3;
-        StorageDead(_3);
-        StorageLive(_5);
-        _5 = move _4;
         goto -> bb2;
     }
 
     bb2: {
-        StorageLive(_9);
-        _6 = &mut _5;
-        StorageLive(_7);
-        _7 = &mut (_5.0: impl Iterator<Item = T>);
         StorageLive(_8);
-        _8 = &mut (_5.1: impl Fn(T) -> Option<U>);
-        _9 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _7, move _8) -> [return: bb3, unwind: bb9];
+        _5 = &mut _4;
+        StorageLive(_6);
+        _6 = &mut (_4.0: impl Iterator<Item = T>);
+        StorageLive(_7);
+        _7 = &mut (_4.1: impl Fn(T) -> Option<U>);
+        _8 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _6, move _7) -> [return: bb3, unwind: bb9];
     }
 
     bb3: {
-        StorageDead(_8);
         StorageDead(_7);
-        _10 = discriminant(_9);
-        switchInt(move _10) -> [0: bb4, 1: bb6, otherwise: bb8];
+        StorageDead(_6);
+        _9 = discriminant(_8);
+        switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8];
     }
 
     bb4: {
-        StorageDead(_9);
-        drop(_5) -> [return: bb5, unwind continue];
+        StorageDead(_8);
+        drop(_4) -> [return: bb5, unwind continue];
     }
 
     bb5: {
-        StorageDead(_5);
         StorageDead(_4);
         return;
     }
 
     bb6: {
-        _11 = move ((_9 as Some).0: U);
-        _12 = opaque::<U>(move _11) -> [return: bb7, unwind: bb9];
+        _10 = move ((_8 as Some).0: U);
+        _11 = opaque::<U>(move _10) -> [return: bb7, unwind: bb9];
     }
 
     bb7: {
-        StorageDead(_9);
+        StorageDead(_8);
         goto -> bb2;
     }
 
@@ -84,7 +78,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
     }
 
     bb9 (cleanup): {
-        drop(_5) -> [return: bb10, unwind terminate(cleanup)];
+        drop(_4) -> [return: bb10, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
index c30df7425d2..30bdc131090 100644
--- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
@@ -6,16 +6,15 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
     let mut _0: ();
     let mut _3: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
     let mut _4: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
-    let mut _5: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
-    let mut _6: &mut std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
-    let mut _7: std::option::Option<U>;
-    let mut _8: isize;
-    let _10: ();
+    let mut _5: &mut std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
+    let mut _6: std::option::Option<U>;
+    let mut _7: isize;
+    let _9: ();
     scope 1 {
-        debug iter => _5;
-        let _9: U;
+        debug iter => _4;
+        let _8: U;
         scope 2 {
-            debug x => _9;
+            debug x => _8;
         }
     }
     scope 3 (inlined <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as IntoIterator>::into_iter) {
@@ -23,50 +22,45 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
     }
 
     bb0: {
-        StorageLive(_4);
-        StorageLive(_3);
         _3 = <impl Iterator<Item = T> as Iterator>::map::<U, impl Fn(T) -> U>(move _1, move _2) -> [return: bb1, unwind continue];
     }
 
     bb1: {
+        StorageLive(_4);
         _4 = move _3;
-        StorageDead(_3);
-        StorageLive(_5);
-        _5 = move _4;
         goto -> bb2;
     }
 
     bb2: {
-        StorageLive(_7);
         StorageLive(_6);
-        _6 = &mut _5;
-        _7 = <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next(move _6) -> [return: bb3, unwind: bb9];
+        StorageLive(_5);
+        _5 = &mut _4;
+        _6 = <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next(move _5) -> [return: bb3, unwind: bb9];
     }
 
     bb3: {
-        StorageDead(_6);
-        _8 = discriminant(_7);
-        switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8];
+        StorageDead(_5);
+        _7 = discriminant(_6);
+        switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb8];
     }
 
     bb4: {
-        StorageDead(_7);
-        drop(_5) -> [return: bb5, unwind continue];
+        StorageDead(_6);
+        drop(_4) -> [return: bb5, unwind continue];
     }
 
     bb5: {
-        StorageDead(_5);
         StorageDead(_4);
         return;
     }
 
     bb6: {
-        _9 = move ((_7 as Some).0: U);
-        _10 = opaque::<U>(move _9) -> [return: bb7, unwind: bb9];
+        _8 = move ((_6 as Some).0: U);
+        _9 = opaque::<U>(move _8) -> [return: bb7, unwind: bb9];
     }
 
     bb7: {
-        StorageDead(_7);
+        StorageDead(_6);
         goto -> bb2;
     }
 
@@ -75,7 +69,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
     }
 
     bb9 (cleanup): {
-        drop(_5) -> [return: bb10, unwind terminate(cleanup)];
+        drop(_4) -> [return: bb10, unwind terminate(cleanup)];
     }
 
     bb10 (cleanup): {
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir
index df6d2263dc3..d97c96ac8a0 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir
@@ -7,17 +7,13 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
     scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
         debug self => _1;
         debug index => _2;
-        let _3: &[u32];
     }
 
     bb0: {
-        StorageLive(_3);
-        _3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind unreachable];
+        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        _0 = _3;
-        StorageDead(_3);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
index cc1795c3f97..4a976002fa5 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir
@@ -7,17 +7,13 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
     scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
         debug self => _1;
         debug index => _2;
-        let _3: &[u32];
     }
 
     bb0: {
-        StorageLive(_3);
-        _3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
+        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
     }
 
     bb1: {
-        _0 = _3;
-        StorageDead(_3);
         return;
     }
 }
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
index 8fe361f2be4..1648f5dd8ca 100644
--- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -92,8 +92,8 @@
           StorageDead(_7);
 -         StorageDead(_6);
 -         StorageLive(_10);
-          StorageLive(_11);
-          StorageLive(_12);
+-         StorageLive(_11);
+-         StorageLive(_12);
           StorageLive(_13);
           _26 = const _;
           _13 = &(*_26);
@@ -105,8 +105,9 @@
       bb5: {
           StorageDead(_15);
           StorageDead(_13);
-          _11 = &(*_12);
-          _16 = Len((*_11));
+-         _11 = &(*_12);
+-         _16 = Len((*_11));
++         _16 = Len((*_12));
           _17 = const 3_usize;
           _18 = Ge(move _16, move _17);
           switchInt(move _18) -> [0: bb7, otherwise: bb6];
@@ -114,12 +115,15 @@
   
       bb6: {
           StorageLive(_19);
-          _19 = &(*_11)[1 of 3];
+-         _19 = &(*_11)[1 of 3];
++         _19 = &(*_12)[1 of 3];
           StorageLive(_20);
-          _20 = &(*_11)[2:-1];
+-         _20 = &(*_11)[2:-1];
++         _20 = &(*_12)[2:-1];
           StorageLive(_21);
-          _21 = &(*_11)[-1 of 3];
+-         _21 = &(*_11)[-1 of 3];
 -         _10 = const ();
++         _21 = &(*_12)[-1 of 3];
           StorageDead(_21);
           StorageDead(_20);
           StorageDead(_19);
@@ -132,8 +136,8 @@
       }
   
       bb8: {
-          StorageDead(_12);
-          StorageDead(_11);
+-         StorageDead(_12);
+-         StorageDead(_11);
 -         StorageDead(_10);
           StorageLive(_22);
           StorageLive(_23);
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index d482f62ff06..a626854e3c1 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -58,7 +58,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
 
     let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
     let body = foo_bar.body();
-    assert_eq!(body.locals.len(), 7);
+    assert_eq!(body.locals.len(), 5);
     assert_eq!(body.blocks.len(), 4);
     let block = &body.blocks[0];
     match &block.terminator.kind {