diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
new file mode 100644
index 00000000000..182b3015dd7
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -0,0 +1,178 @@
+use rustc_index::bit_set::BitSet;
+use rustc_index::vec::IndexVec;
+use rustc_middle::mir::visit::*;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+use rustc_mir_dataflow::impls::borrowed_locals;
+
+use crate::ssa::SsaLocals;
+use crate::MirPass;
+
+/// Unify locals that copy each other.
+///
+/// We consider patterns of the form
+///   _a = rvalue
+///   _b = move? _a
+///   _c = move? _a
+///   _d = move? _c
+/// where each of the locals is only assigned once.
+///
+/// We want to replace all those locals by `_a`, either copied or moved.
+pub struct CopyProp;
+
+impl<'tcx> MirPass<'tcx> for CopyProp {
+    fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
+        sess.mir_opt_level() >= 4
+    }
+
+    #[instrument(level = "trace", skip(self, tcx, body))]
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        debug!(def_id = ?body.source.def_id());
+        propagate_ssa(tcx, body);
+    }
+}
+
+fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+    let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
+    let borrowed_locals = borrowed_locals(body);
+    let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals);
+
+    let fully_moved = fully_moved_locals(&ssa, body);
+    debug!(?fully_moved);
+
+    let mut storage_to_remove = BitSet::new_empty(fully_moved.domain_size());
+    for (local, &head) in ssa.copy_classes().iter_enumerated() {
+        if local != head {
+            storage_to_remove.insert(head);
+        }
+    }
+
+    let any_replacement = ssa.copy_classes().iter_enumerated().any(|(l, &h)| l != h);
+
+    Replacer {
+        tcx,
+        copy_classes: &ssa.copy_classes(),
+        fully_moved,
+        borrowed_locals,
+        storage_to_remove,
+    }
+    .visit_body_preserves_cfg(body);
+
+    if any_replacement {
+        crate::simplify::remove_unused_definitions(body);
+    }
+}
+
+/// `SsaLocals` computed equivalence classes between locals considering copy/move assignments.
+///
+/// This function also returns whether all the `move?` in the pattern are `move` and not copies.
+/// A local which is in the bitset can be replaced by `move _a`. Otherwise, it must be
+/// replaced by `copy _a`, as we cannot move multiple times from `_a`.
+///
+/// If an operand copies `_c`, it must happen before the assignment `_d = _c`, otherwise it is UB.
+/// This means that replacing it by a copy of `_a` if ok, since this copy happens before `_c` is
+/// moved, and therefore that `_d` is moved.
+#[instrument(level = "trace", skip(ssa, body))]
+fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> {
+    let mut fully_moved = BitSet::new_filled(body.local_decls.len());
+
+    for (_, rvalue) in ssa.assignments(body) {
+        let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place))
+            = rvalue
+        else { continue };
+
+        let Some(rhs) = place.as_local() else { continue };
+        if !ssa.is_ssa(rhs) {
+            continue;
+        }
+
+        if let Rvalue::Use(Operand::Copy(_)) | Rvalue::CopyForDeref(_) = rvalue {
+            fully_moved.remove(rhs);
+        }
+    }
+
+    ssa.meet_copy_equivalence(&mut fully_moved);
+
+    fully_moved
+}
+
+/// Utility to help performing subtitution of `*pattern` by `target`.
+struct Replacer<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    fully_moved: BitSet<Local>,
+    storage_to_remove: BitSet<Local>,
+    borrowed_locals: BitSet<Local>,
+    copy_classes: &'a IndexVec<Local, Local>,
+}
+
+impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn visit_local(&mut self, local: &mut Local, ctxt: PlaceContext, _: Location) {
+        let new_local = self.copy_classes[*local];
+        match ctxt {
+            // Do not modify the local in storage statements.
+            PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead) => {}
+            // The local should have been marked as non-SSA.
+            PlaceContext::MutatingUse(_) => assert_eq!(*local, new_local),
+            // We access the value.
+            _ => *local = new_local,
+        }
+    }
+
+    fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
+        if let Some(new_projection) = self.process_projection(&place.projection, loc) {
+            place.projection = self.tcx().intern_place_elems(&new_projection);
+        }
+
+        let observes_address = match ctxt {
+            PlaceContext::NonMutatingUse(
+                NonMutatingUseContext::SharedBorrow
+                | NonMutatingUseContext::ShallowBorrow
+                | NonMutatingUseContext::UniqueBorrow
+                | NonMutatingUseContext::AddressOf,
+            ) => true,
+            // For debuginfo, merging locals is ok.
+            PlaceContext::NonUse(NonUseContext::VarDebugInfo) => {
+                self.borrowed_locals.contains(place.local)
+            }
+            _ => false,
+        };
+        if observes_address && !place.is_indirect() {
+            // We observe the address of `place.local`. Do not replace it.
+        } else {
+            self.visit_local(
+                &mut place.local,
+                PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
+                loc,
+            )
+        }
+    }
+
+    fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
+        if let Operand::Move(place) = *operand
+            && let Some(local) = place.as_local()
+            && !self.fully_moved.contains(local)
+        {
+            *operand = Operand::Copy(place);
+        }
+        self.super_operand(operand, loc);
+    }
+
+    fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
+        if let StatementKind::StorageDead(l) = stmt.kind
+            && self.storage_to_remove.contains(l)
+        {
+            stmt.make_nop();
+        } else if let StatementKind::Assign(box (ref place, ref mut rvalue)) = stmt.kind
+            && place.as_local().is_some()
+        {
+            // Do not replace assignments.
+            self.visit_rvalue(rvalue, loc)
+        } else {
+            self.super_statement(stmt, loc);
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 20ffb0ab334..5c5baa68e58 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -328,7 +328,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
         match &statement.kind {
             StatementKind::Assign(box (dest, rvalue)) => {
                 match rvalue {
-                    Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => {
+                    Rvalue::CopyForDeref(place)
+                    | Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) => {
                         // These might've been turned into self-assignments by the replacement
                         // (this includes the original statement we wanted to eliminate).
                         if dest == place {
@@ -755,7 +756,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
         if let StatementKind::Assign(box (
             lhs,
-            Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)),
+            Rvalue::CopyForDeref(rhs) | Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)),
         )) = &statement.kind
         {
             let Some((src, dest)) = places_to_candidate_pair(*lhs, *rhs, self.body) else {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 6858fa8e524..abf89e550b1 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -54,6 +54,7 @@ mod const_debuginfo;
 mod const_goto;
 mod const_prop;
 mod const_prop_lint;
+mod copy_prop;
 mod coverage;
 mod ctfe_limit;
 mod dataflow_const_prop;
@@ -87,6 +88,7 @@ mod required_consts;
 mod reveal_all;
 mod separate_const_switch;
 mod shim;
+mod ssa;
 // This pass is public to allow external drivers to perform MIR cleanup
 pub mod simplify;
 mod simplify_branches;
@@ -563,6 +565,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             &instcombine::InstCombine,
             &separate_const_switch::SeparateConstSwitch,
             &simplify::SimplifyLocals::new("before-const-prop"),
+            &copy_prop::CopyProp,
             //
             // FIXME(#70073): This pass is responsible for both optimization as well as some lints.
             &const_prop::ConstProp,
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 7b6fa2baf2f..ced97b2c788 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -404,6 +404,18 @@ impl<'tcx> MirPass<'tcx> for SimplifyLocals {
     }
 }
 
+pub fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
+    // First, we're going to get a count of *actual* uses for every `Local`.
+    let mut used_locals = UsedLocals::new(body);
+
+    // Next, we're going to remove any `Local` with zero actual uses. When we remove those
+    // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals`
+    // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
+    // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
+    // fixedpoint where there are no more unused locals.
+    remove_unused_definitions_helper(&mut used_locals, body);
+}
+
 pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
     // First, we're going to get a count of *actual* uses for every `Local`.
     let mut used_locals = UsedLocals::new(body);
@@ -413,7 +425,7 @@ pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
     // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
     // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
     // fixedpoint where there are no more unused locals.
-    remove_unused_definitions(&mut used_locals, body);
+    remove_unused_definitions_helper(&mut used_locals, body);
 
     // Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s.
     let map = make_local_map(&mut body.local_decls, &used_locals);
@@ -548,7 +560,7 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
 }
 
 /// Removes unused definitions. Updates the used locals to reflect the changes made.
-fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>) {
+fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Body<'_>) {
     // The use counts are updated as we remove the statements. A local might become unused
     // during the retain operation, leading to a temporary inconsistency (storage statements or
     // definitions referencing the local might remain). For correctness it is crucial that this
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
new file mode 100644
index 00000000000..bc3fe65cf6c
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -0,0 +1,222 @@
+use either::Either;
+use rustc_data_structures::graph::dominators::Dominators;
+use rustc_index::bit_set::BitSet;
+use rustc_index::vec::IndexVec;
+use rustc_middle::middle::resolve_lifetime::Set1;
+use rustc_middle::mir::visit::*;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{ParamEnv, TyCtxt};
+
+#[derive(Debug)]
+pub struct SsaLocals {
+    /// Assignments to each local. This defines whether the local is SSA.
+    assignments: IndexVec<Local, Set1<LocationExtended>>,
+    /// We visit the body in reverse postorder, to ensure each local is assigned before it is used.
+    /// We remember the order in which we saw the assignments to compute the SSA values in a single
+    /// pass.
+    assignment_order: Vec<Local>,
+    /// Copy equivalence classes between locals. See `copy_classes` for documentation.
+    copy_classes: IndexVec<Local, Local>,
+}
+
+impl SsaLocals {
+    pub fn new<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        param_env: ParamEnv<'tcx>,
+        body: &Body<'tcx>,
+        borrowed_locals: &BitSet<Local>,
+    ) -> SsaLocals {
+        let assignment_order = Vec::new();
+
+        let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
+        let dominators = body.basic_blocks.dominators();
+        let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
+
+        for (local, decl) in body.local_decls.iter_enumerated() {
+            if matches!(body.local_kind(local), LocalKind::Arg) {
+                visitor.assignments[local] = Set1::One(LocationExtended::Arg);
+            }
+            if borrowed_locals.contains(local) && !decl.ty.is_freeze(tcx, param_env) {
+                visitor.assignments[local] = Set1::Many;
+            }
+        }
+
+        for (bb, data) in traversal::reverse_postorder(body) {
+            visitor.visit_basic_block_data(bb, data);
+        }
+
+        for var_debug_info in &body.var_debug_info {
+            visitor.visit_var_debug_info(var_debug_info);
+        }
+
+        debug!(?visitor.assignments);
+
+        visitor
+            .assignment_order
+            .retain(|&local| matches!(visitor.assignments[local], Set1::One(_)));
+        debug!(?visitor.assignment_order);
+
+        let copy_classes = compute_copy_classes(&visitor, body);
+
+        SsaLocals {
+            assignments: visitor.assignments,
+            assignment_order: visitor.assignment_order,
+            copy_classes,
+        }
+    }
+
+    pub fn is_ssa(&self, local: Local) -> bool {
+        matches!(self.assignments[local], Set1::One(_))
+    }
+
+    pub fn assignments<'a, 'tcx>(
+        &'a self,
+        body: &'a Body<'tcx>,
+    ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>)> + 'a {
+        self.assignment_order.iter().filter_map(|&local| {
+            if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
+                // `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))
+            } else {
+                None
+            }
+        })
+    }
+
+    /// Compute the equivalence classes for locals, based on copy statements.
+    ///
+    /// The returned vector maps each local to the one it copies. In the following case:
+    ///   _a = &mut _0
+    ///   _b = move? _a
+    ///   _c = move? _a
+    ///   _d = move? _c
+    /// We return the mapping
+    ///   _a => _a // not a copy so, represented by itself
+    ///   _b => _a
+    ///   _c => _a
+    ///   _d => _a // transitively through _c
+    ///
+    /// Exception: we do not see through the return place, as it cannot be substituted.
+    pub fn copy_classes(&self) -> &IndexVec<Local, Local> {
+        &self.copy_classes
+    }
+
+    /// Make a property uniform on a copy equivalence class by removing elements.
+    pub fn meet_copy_equivalence(&self, property: &mut BitSet<Local>) {
+        // Consolidate to have a local iff all its copies are.
+        //
+        // `copy_classes` defines equivalence classes between locals. The `local`s that recursively
+        // move/copy the same local all have the same `head`.
+        for (local, &head) in self.copy_classes.iter_enumerated() {
+            // If any copy does not have `property`, then the head is not.
+            if !property.contains(local) {
+                property.remove(head);
+            }
+        }
+        for (local, &head) in self.copy_classes.iter_enumerated() {
+            // If any copy does not have `property`, then the head doesn't either,
+            // then no copy has `property`.
+            if !property.contains(head) {
+                property.remove(local);
+            }
+        }
+
+        // Verify that we correctly computed equivalence classes.
+        #[cfg(debug_assertions)]
+        for (local, &head) in self.copy_classes.iter_enumerated() {
+            assert_eq!(property.contains(local), property.contains(head));
+        }
+    }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum LocationExtended {
+    Plain(Location),
+    Arg,
+}
+
+struct SsaVisitor {
+    dominators: Dominators<BasicBlock>,
+    assignments: IndexVec<Local, Set1<LocationExtended>>,
+    assignment_order: Vec<Local>,
+}
+
+impl<'tcx> Visitor<'tcx> for SsaVisitor {
+    fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
+        match ctxt {
+            PlaceContext::MutatingUse(MutatingUseContext::Store) => {
+                self.assignments[local].insert(LocationExtended::Plain(loc));
+                self.assignment_order.push(local);
+            }
+            // Anything can happen with raw pointers, so remove them.
+            PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
+            | PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many,
+            // Immutable borrows are taken into account in `SsaLocals::new` by
+            // removing non-freeze locals.
+            PlaceContext::NonMutatingUse(_) => {
+                let set = &mut self.assignments[local];
+                let assign_dominates = match *set {
+                    Set1::Empty | Set1::Many => false,
+                    Set1::One(LocationExtended::Arg) => true,
+                    Set1::One(LocationExtended::Plain(assign)) => {
+                        assign.successor_within_block().dominates(loc, &self.dominators)
+                    }
+                };
+                // We are visiting a use that is not dominated by an assignment.
+                // Either there is a cycle involved, or we are reading for uninitialized local.
+                // Bail out.
+                if !assign_dominates {
+                    *set = Set1::Many;
+                }
+            }
+            PlaceContext::NonUse(_) => {}
+        }
+    }
+}
+
+#[instrument(level = "trace", skip(ssa, body))]
+fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Local> {
+    let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len());
+
+    for &local in &ssa.assignment_order {
+        debug!(?local);
+
+        if local == RETURN_PLACE {
+            // `_0` is special, we cannot rename it.
+            continue;
+        }
+
+        // This is not SSA: mark that we don't know the value.
+        debug!(assignments = ?ssa.assignments[local]);
+        let Set1::One(LocationExtended::Plain(loc)) = ssa.assignments[local] else { continue };
+
+        // `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));
+
+        let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place))
+            = rvalue
+        else { continue };
+
+        let Some(rhs) = place.as_local() else { continue };
+        let Set1::One(_) = ssa.assignments[rhs] else { continue };
+
+        // We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been
+        // visited before `local`, and we just have to copy the representing local.
+        copies[local] = copies[rhs];
+    }
+
+    debug!(?copies);
+
+    // Invariant: `copies` must point to the head of an equivalence class.
+    #[cfg(debug_assertions)]
+    for &head in copies.iter() {
+        assert_eq!(copies[head], head);
+    }
+
+    copies
+}
diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
index dd548adde7e..5e587be1f16 100644
--- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
+++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -64,17 +64,8 @@
           _3 = const 3_u8;                 // scope 2 at $DIR/const_debuginfo.rs:+3:13: +3:16
           StorageLive(_4);                 // scope 3 at $DIR/const_debuginfo.rs:+4:9: +4:12
           StorageLive(_5);                 // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20
-          StorageLive(_6);                 // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16
-          _6 = const 1_u8;                 // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:16
-          StorageLive(_7);                 // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
-          _7 = const 2_u8;                 // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
           _5 = const 3_u8;                 // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:20
-          StorageDead(_7);                 // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
-          StorageDead(_6);                 // scope 3 at $DIR/const_debuginfo.rs:+4:19: +4:20
-          StorageLive(_8);                 // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
-          _8 = const 3_u8;                 // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
           _4 = const 6_u8;                 // scope 3 at $DIR/const_debuginfo.rs:+4:15: +4:24
-          StorageDead(_8);                 // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
           StorageDead(_5);                 // scope 3 at $DIR/const_debuginfo.rs:+4:23: +4:24
           StorageLive(_9);                 // scope 4 at $DIR/const_debuginfo.rs:+6:9: +6:10
           _9 = const "hello, world!";      // scope 4 at $DIR/const_debuginfo.rs:+6:13: +6:28
@@ -117,9 +108,6 @@
           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
-          StorageDead(_3);                 // scope 2 at $DIR/const_debuginfo.rs:+14:1: +14:2
-          StorageDead(_2);                 // scope 1 at $DIR/const_debuginfo.rs:+14:1: +14:2
-          StorageDead(_1);                 // scope 0 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/bad_op_mod_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
index 8485703e39f..e085a88b2da 100644
--- a/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff
@@ -21,32 +21,25 @@
           StorageLive(_1);                 // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:9: +1:10
           _1 = const 0_i32;                // scope 0 at $DIR/bad_op_mod_by_zero.rs:+1:13: +1:14
           StorageLive(_2);                 // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:9: +2:11
-          StorageLive(_3);                 // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
--         _3 = _1;                         // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
--         _4 = Eq(_3, const 0_i32);        // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+-         _4 = Eq(_1, const 0_i32);        // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 -         assert(!move _4, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
-+         _3 = const 0_i32;                // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
 +         _4 = const true;                 // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 +         assert(!const true, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
       }
   
       bb1: {
--         _5 = Eq(_3, const -1_i32);       // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+          _5 = Eq(_1, const -1_i32);       // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 -         _6 = Eq(const 1_i32, const i32::MIN); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 -         _7 = BitAnd(move _5, move _6);   // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
--         assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _3) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
-+         _5 = const false;                // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
+-         assert(!move _7, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _1) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 +         _6 = const false;                // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
 +         _7 = const false;                // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
-+         assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, const 0_i32) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
++         assert(!const false, "attempt to compute the remainder of `{} % {}`, which would overflow", const 1_i32, _1) -> bb2; // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
       }
   
       bb2: {
--         _2 = Rem(const 1_i32, move _3);  // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
-+         _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
-          StorageDead(_3);                 // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19
+          _2 = Rem(const 1_i32, _1);       // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19
           StorageDead(_2);                 // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
-          StorageDead(_1);                 // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2
           return;                          // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2
       }
   }
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
index 27e41d4869d..4bd0aa09872 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
@@ -23,16 +23,13 @@
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
           StorageLive(_2);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
-          StorageLive(_3);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           _8 = const _;                    // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
                                            // mir::Constant
                                            // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
                                            // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
-          _3 = _8;                         // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
-          _2 = &raw const (*_3);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+          _2 = &raw const (*_8);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           StorageDead(_2);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
-          StorageDead(_3);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
           StorageLive(_4);                 // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
           StorageLive(_5);                 // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
           _5 = const 3_usize;              // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
index 27e41d4869d..4bd0aa09872 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
@@ -23,16 +23,13 @@
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10
           StorageLive(_2);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
-          StorageLive(_3);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           _8 = const _;                    // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
                                            // mir::Constant
                                            // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
                                            // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
-          _3 = _8;                         // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
-          _2 = &raw const (*_3);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
+          _2 = &raw const (*_8);           // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35
           StorageDead(_2);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35
-          StorageDead(_3);                 // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36
           StorageLive(_4);                 // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15
           StorageLive(_5);                 // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
           _5 = const 3_usize;              // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24
diff --git a/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff b/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
index 0de80091753..549b4711e87 100644
--- a/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
+++ b/tests/mir-opt/const_prop/boolean_identities.test.ConstProp.diff
@@ -12,18 +12,12 @@
   
       bb0: {
           StorageLive(_3);                 // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
-          StorageLive(_4);                 // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
-          _4 = _2;                         // scope 0 at $DIR/boolean_identities.rs:+1:6: +1:7
--         _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
+-         _3 = BitOr(_2, const true);      // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
 +         _3 = const true;                 // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:15
-          StorageDead(_4);                 // scope 0 at $DIR/boolean_identities.rs:+1:14: +1:15
           StorageLive(_5);                 // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
-          StorageLive(_6);                 // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
-          _6 = _1;                         // scope 0 at $DIR/boolean_identities.rs:+1:19: +1:20
--         _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
-+         _5 = const false;                // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
-          StorageDead(_6);                 // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
+-         _5 = BitAnd(_1, const false);    // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
 -         _0 = BitAnd(move _3, move _5);   // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
++         _5 = const false;                // scope 0 at $DIR/boolean_identities.rs:+1:18: +1:29
 +         _0 = const false;                // scope 0 at $DIR/boolean_identities.rs:+1:5: +1:29
           StorageDead(_5);                 // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
           StorageDead(_3);                 // scope 0 at $DIR/boolean_identities.rs:+1:28: +1:29
diff --git a/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff b/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
index 629c8e60148..1cfe47d0a86 100644
--- a/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
+++ b/tests/mir-opt/const_prop/mult_by_zero.test.ConstProp.diff
@@ -7,11 +7,8 @@
       let mut _2: i32;                     // in scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
-          _2 = _1;                         // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:4
--         _0 = Mul(move _2, const 0_i32);  // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
+-         _0 = Mul(_1, const 0_i32);       // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
 +         _0 = const 0_i32;                // scope 0 at $DIR/mult_by_zero.rs:+1:3: +1:8
-          StorageDead(_2);                 // scope 0 at $DIR/mult_by_zero.rs:+1:7: +1:8
           return;                          // scope 0 at $DIR/mult_by_zero.rs:+2:2: +2:2
       }
   }
diff --git a/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff
index 8a73f0390e1..924a267f3d8 100644
--- a/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/ref_deref.main.ConstProp.diff
@@ -13,14 +13,13 @@
           StorageLive(_2);                 // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
           _4 = const _;                    // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
                                            // mir::Constant
-                                           // + span: $DIR/ref_deref.rs:6:6: 6:10
+                                           // + span: $DIR/ref_deref.rs:5:6: 5:10
                                            // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
-          _2 = _4;                         // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
--         _1 = (*_2);                      // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
-+         _1 = const 4_i32;                // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
+          _2 = &(*_4);                     // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
+          _1 = (*_2);                      // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
           StorageDead(_2);                 // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
           StorageDead(_1);                 // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
-          nop;                             // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
+          _0 = const ();                   // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
           return;                          // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
       }
   }
diff --git a/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
deleted file mode 100644
index 015ec4d078c..00000000000
--- a/tests/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `main` before PromoteTemps
-+ // MIR for `main` after PromoteTemps
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/ref_deref.rs:+0:11: +0:11
-      let _1: i32;                         // in scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
-      let mut _2: &i32;                    // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-      let _3: i32;                         // in scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
-+     let mut _4: &i32;                    // in scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
-          StorageLive(_2);                 // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
--         StorageLive(_3);                 // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
--         _3 = const 4_i32;                // scope 0 at $DIR/ref_deref.rs:+1:8: +1:9
--         _2 = &_3;                        // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-+         _4 = const _;                    // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-+                                          // mir::Constant
-+                                          // + span: $DIR/ref_deref.rs:6:6: 6:10
-+                                          // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
-+         _2 = &(*_4);                     // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10
-          _1 = (*_2);                      // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10
--         StorageDead(_3);                 // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
-          StorageDead(_2);                 // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
-          StorageDead(_1);                 // scope 0 at $DIR/ref_deref.rs:+1:10: +1:11
-          _0 = const ();                   // scope 0 at $DIR/ref_deref.rs:+0:11: +2:2
-          return;                          // scope 0 at $DIR/ref_deref.rs:+2:2: +2:2
-      }
-  }
-  
diff --git a/tests/mir-opt/const_prop/ref_deref.rs b/tests/mir-opt/const_prop/ref_deref.rs
index d2549c8b6aa..76e56916af0 100644
--- a/tests/mir-opt/const_prop/ref_deref.rs
+++ b/tests/mir-opt/const_prop/ref_deref.rs
@@ -1,5 +1,4 @@
-// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
-// EMIT_MIR ref_deref.main.PromoteTemps.diff
+// unit-test: ConstProp
 // EMIT_MIR ref_deref.main.ConstProp.diff
 
 fn main() {
diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
index ec3d9043315..59095b44837 100644
--- a/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
@@ -13,13 +13,13 @@
           StorageLive(_2);                 // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
           _4 = const _;                    // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
                                            // mir::Constant
-                                           // + span: $DIR/ref_deref_project.rs:6:6: 6:17
+                                           // + span: $DIR/ref_deref_project.rs:5:6: 5:17
                                            // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
           _2 = &((*_4).1: i32);            // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
           _1 = (*_2);                      // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
           StorageDead(_2);                 // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
           StorageDead(_1);                 // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
-          nop;                             // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
+          _0 = const ();                   // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
           return;                          // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
       }
   }
diff --git a/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff b/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
deleted file mode 100644
index cd0616e65ba..00000000000
--- a/tests/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-- // MIR for `main` before PromoteTemps
-+ // MIR for `main` after PromoteTemps
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/ref_deref_project.rs:+0:11: +0:11
-      let _1: i32;                         // in scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
-      let mut _2: &i32;                    // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-      let _3: (i32, i32);                  // in scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
-+     let mut _4: &(i32, i32);             // in scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
-          StorageLive(_2);                 // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
--         StorageLive(_3);                 // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
--         _3 = (const 4_i32, const 5_i32); // scope 0 at $DIR/ref_deref_project.rs:+1:8: +1:14
--         _2 = &(_3.1: i32);               // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-+         _4 = const _;                    // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-+                                          // mir::Constant
-+                                          // + span: $DIR/ref_deref_project.rs:6:6: 6:17
-+                                          // + literal: Const { ty: &(i32, i32), val: Unevaluated(main, [], Some(promoted[0])) }
-+         _2 = &((*_4).1: i32);            // scope 0 at $DIR/ref_deref_project.rs:+1:6: +1:17
-          _1 = (*_2);                      // scope 0 at $DIR/ref_deref_project.rs:+1:5: +1:17
--         StorageDead(_3);                 // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
-          StorageDead(_2);                 // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
-          StorageDead(_1);                 // scope 0 at $DIR/ref_deref_project.rs:+1:17: +1:18
-          _0 = const ();                   // scope 0 at $DIR/ref_deref_project.rs:+0:11: +2:2
-          return;                          // scope 0 at $DIR/ref_deref_project.rs:+2:2: +2:2
-      }
-  }
-  
diff --git a/tests/mir-opt/const_prop/ref_deref_project.rs b/tests/mir-opt/const_prop/ref_deref_project.rs
index 2fdd4e15319..04fc7f8daa1 100644
--- a/tests/mir-opt/const_prop/ref_deref_project.rs
+++ b/tests/mir-opt/const_prop/ref_deref_project.rs
@@ -1,5 +1,4 @@
-// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
-// EMIT_MIR ref_deref_project.main.PromoteTemps.diff
+// unit-test: ConstProp
 // EMIT_MIR ref_deref_project.main.ConstProp.diff
 
 fn main() {
diff --git a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
index d518eff04eb..e3f5b120a32 100644
--- a/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff
@@ -14,10 +14,7 @@
           StorageLive(_1);                 // scope 0 at $DIR/scalar_literal_propagation.rs:+1:9: +1:10
           _1 = const 1_u32;                // scope 0 at $DIR/scalar_literal_propagation.rs:+1:13: +1:14
           StorageLive(_2);                 // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
-          StorageLive(_3);                 // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
--         _3 = _1;                         // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
--         _2 = consume(move _3) -> bb1;    // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
-+         _3 = const 1_u32;                // scope 1 at $DIR/scalar_literal_propagation.rs:+2:13: +2:14
+-         _2 = consume(_1) -> bb1;         // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
 +         _2 = consume(const 1_u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:+2:5: +2:15
                                            // mir::Constant
                                            // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12
@@ -25,9 +22,7 @@
       }
   
       bb1: {
-          StorageDead(_3);                 // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15
           StorageDead(_2);                 // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16
-          StorageDead(_1);                 // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2
           return;                          // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2
       }
   }
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
index 9017fd18e48..b99b83b0cba 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -20,7 +20,7 @@
           StorageLive(_4);                 // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _9 = const _;                    // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
                                            // mir::Constant
-                                           // + span: $DIR/slice_len.rs:6:6: 6:19
+                                           // + span: $DIR/slice_len.rs:7:6: 7:19
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
@@ -33,7 +33,7 @@
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
   
       bb1: {
@@ -43,7 +43,7 @@
           StorageDead(_4);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
           StorageDead(_2);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
           StorageDead(_1);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
-          nop;                             // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+          _0 = const ();                   // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
           return;                          // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
       }
   }
diff --git a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
index 9017fd18e48..b99b83b0cba 100644
--- a/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -20,7 +20,7 @@
           StorageLive(_4);                 // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _9 = const _;                    // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
                                            // mir::Constant
-                                           // + span: $DIR/slice_len.rs:6:6: 6:19
+                                           // + span: $DIR/slice_len.rs:7:6: 7:19
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
@@ -33,7 +33,7 @@
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         assert(const true, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
   
       bb1: {
@@ -43,7 +43,7 @@
           StorageDead(_4);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
           StorageDead(_2);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
           StorageDead(_1);                 // scope 0 at $DIR/slice_len.rs:+1:33: +1:34
-          nop;                             // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
+          _0 = const ();                   // scope 0 at $DIR/slice_len.rs:+0:11: +2:2
           return;                          // scope 0 at $DIR/slice_len.rs:+2:2: +2:2
       }
   }
diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs
index eaaf34b960e..8183def0c63 100644
--- a/tests/mir-opt/const_prop/slice_len.rs
+++ b/tests/mir-opt/const_prop/slice_len.rs
@@ -1,4 +1,5 @@
-// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop
+// unit-test: ConstProp
+// compile-flags: -Zmir-enable-passes=+InstCombine
 // EMIT_MIR_FOR_EACH_BIT_WIDTH
 
 // EMIT_MIR slice_len.main.ConstProp.diff
diff --git a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
index ea9fec0aa15..b6b542fb794 100644
--- a/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
+++ b/tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff
@@ -4,15 +4,16 @@
   fn bar() -> () {
       let mut _0: ();                      // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10
       let mut _1: (i32,);                  // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
-      let mut _2: *mut i32;                // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
-      let mut _4: i32;                     // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
+      let _2: ();                          // in scope 0 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+      let mut _3: *mut i32;                // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+      let mut _5: i32;                     // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
       scope 1 {
           debug v => _1;                   // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
-          let _3: bool;                    // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+          let _4: bool;                    // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
           scope 2 {
           }
           scope 3 {
-              debug y => _3;               // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+              debug y => _4;               // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
           }
       }
   
@@ -20,16 +21,20 @@
           StorageLive(_1);                 // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
           Deinit(_1);                      // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
           (_1.0: i32) = const 1_i32;       // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
-          StorageLive(_2);                 // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
-          _2 = &raw mut (_1.0: i32);       // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
-          (*_2) = const 5_i32;             // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26
-          StorageDead(_2);                 // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27
-          StorageLive(_3);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
-          StorageLive(_4);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
-          _4 = (_1.0: i32);                // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18
-          _3 = Eq(move _4, const 5_i32);   // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25
-          StorageDead(_4);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25
-          StorageDead(_3);                 // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2
+          StorageLive(_2);                 // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+          StorageLive(_3);                 // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+          _3 = &raw mut (_1.0: i32);       // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
+          (*_3) = const 5_i32;             // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26
+          StorageDead(_3);                 // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27
+          _2 = const ();                   // scope 2 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
+          StorageDead(_2);                 // scope 1 at $DIR/const_prop_miscompile.rs:+4:5: +4:6
+          StorageLive(_4);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10
+          StorageLive(_5);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20
+          _5 = (_1.0: i32);                // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18
+          _4 = Eq(move _5, const 5_i32);   // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25
+          StorageDead(_5);                 // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25
+          _0 = const ();                   // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +6:2
+          StorageDead(_4);                 // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2
           StorageDead(_1);                 // scope 0 at $DIR/const_prop_miscompile.rs:+6:1: +6:2
           return;                          // scope 0 at $DIR/const_prop_miscompile.rs:+6:2: +6:2
       }
diff --git a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
index 043f4047417..e43735fd9e1 100644
--- a/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
+++ b/tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff
@@ -27,6 +27,7 @@
           _4 = (_1.0: i32);                // scope 1 at $DIR/const_prop_miscompile.rs:+3:15: +3:18
           _3 = Eq(move _4, const 5_i32);   // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:25
           StorageDead(_4);                 // scope 1 at $DIR/const_prop_miscompile.rs:+3:24: +3:25
+          _0 = const ();                   // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +4:2
           StorageDead(_3);                 // scope 1 at $DIR/const_prop_miscompile.rs:+4:1: +4:2
           StorageDead(_1);                 // scope 0 at $DIR/const_prop_miscompile.rs:+4:1: +4:2
           return;                          // scope 0 at $DIR/const_prop_miscompile.rs:+4:2: +4:2
diff --git a/tests/mir-opt/const_prop_miscompile.rs b/tests/mir-opt/const_prop_miscompile.rs
index bc54556b349..dbbe5ee0840 100644
--- a/tests/mir-opt/const_prop_miscompile.rs
+++ b/tests/mir-opt/const_prop_miscompile.rs
@@ -1,3 +1,4 @@
+// unit-test: ConstProp
 #![feature(raw_ref_op)]
 
 // EMIT_MIR const_prop_miscompile.foo.ConstProp.diff
diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
new file mode 100644
index 00000000000..b183865a9bc
--- /dev/null
+++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
@@ -0,0 +1,34 @@
+- // MIR for `f` before CopyProp
++ // MIR for `f` after CopyProp
+  
+  fn f() -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/borrowed_local.rs:+0:11: +0:15
+      let mut _1: u8;                      // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _2: &u8;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: u8;                      // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _4: &u8;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          _1 = const 5_u8;                 // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _2 = &_1;                        // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _3 = _1;                         // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _4 = &_3;                        // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _0 = cmp_ref(_2, _4) -> bb1;     // scope 0 at $DIR/borrowed_local.rs:+8:13: +8:45
+                                           // mir::Constant
+                                           // + span: $DIR/borrowed_local.rs:23:29: 23:36
+                                           // + literal: Const { ty: for<'a, 'b> fn(&'a u8, &'b u8) -> bool {cmp_ref}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+-         _0 = opaque::<u8>(_3) -> bb2;    // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
++         _0 = opaque::<u8>(_1) -> bb2;    // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
+                                           // mir::Constant
+                                           // + span: $DIR/borrowed_local.rs:27:28: 27:34
+                                           // + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          return;                          // scope 0 at $DIR/borrowed_local.rs:+15:13: +15:21
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs
new file mode 100644
index 00000000000..c4b980e2b35
--- /dev/null
+++ b/tests/mir-opt/copy-prop/borrowed_local.rs
@@ -0,0 +1,39 @@
+// unit-test: CopyProp
+
+#![feature(custom_mir, core_intrinsics)]
+#![allow(unused_assignments)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+fn opaque(_: impl Sized) -> bool { true }
+
+fn cmp_ref(a: &u8, b: &u8) -> bool {
+    std::ptr::eq(a as *const u8, b as *const u8)
+}
+
+#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
+fn f() -> bool {
+    mir!(
+        {
+            let a = 5_u8;
+            let r1 = &a;
+            let b = a;
+            // We cannot propagate the place `a`.
+            let r2 = &b;
+            Call(RET, next, cmp_ref(r1, r2))
+        }
+        next = {
+            // But we can propagate the value `a`.
+            Call(RET, ret, opaque(b))
+        }
+        ret = {
+            Return()
+        }
+    )
+}
+
+fn main() {
+    assert!(!f());
+}
+
+// EMIT_MIR borrowed_local.f.CopyProp.diff
diff --git a/tests/mir-opt/copy-prop/branch.foo.CopyProp.diff b/tests/mir-opt/copy-prop/branch.foo.CopyProp.diff
new file mode 100644
index 00000000000..8b116532d9f
--- /dev/null
+++ b/tests/mir-opt/copy-prop/branch.foo.CopyProp.diff
@@ -0,0 +1,65 @@
+- // MIR for `foo` before CopyProp
++ // MIR for `foo` after CopyProp
+  
+  fn foo() -> i32 {
+      let mut _0: i32;                     // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16
+      let _1: i32;                         // in scope 0 at $DIR/branch.rs:+1:9: +1:10
+      let mut _3: bool;                    // in scope 0 at $DIR/branch.rs:+3:16: +3:22
+      let _4: i32;                         // in scope 0 at $DIR/branch.rs:+6:9: +6:14
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/branch.rs:+1:9: +1:10
+          let _2: i32;                     // in scope 1 at $DIR/branch.rs:+3:9: +3:10
+          scope 2 {
+              debug y => _2;               // in scope 2 at $DIR/branch.rs:+3:9: +3:10
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/branch.rs:+1:9: +1:10
+          _1 = val() -> bb1;               // scope 0 at $DIR/branch.rs:+1:13: +1:18
+                                           // mir::Constant
+                                           // + span: $DIR/branch.rs:13:13: 13:16
+                                           // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageLive(_2);                 // scope 1 at $DIR/branch.rs:+3:9: +3:10
+          StorageLive(_3);                 // scope 1 at $DIR/branch.rs:+3:16: +3:22
+          _3 = cond() -> bb2;              // scope 1 at $DIR/branch.rs:+3:16: +3:22
+                                           // mir::Constant
+                                           // + span: $DIR/branch.rs:15:16: 15:20
+                                           // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          switchInt(move _3) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22
+      }
+  
+      bb3: {
+          _2 = _1;                         // scope 1 at $DIR/branch.rs:+4:9: +4:10
+          goto -> bb6;                     // scope 1 at $DIR/branch.rs:+3:13: +8:6
+      }
+  
+      bb4: {
+          StorageLive(_4);                 // scope 1 at $DIR/branch.rs:+6:9: +6:14
+          _4 = val() -> bb5;               // scope 1 at $DIR/branch.rs:+6:9: +6:14
+                                           // mir::Constant
+                                           // + span: $DIR/branch.rs:18:9: 18:12
+                                           // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+      }
+  
+      bb5: {
+          StorageDead(_4);                 // scope 1 at $DIR/branch.rs:+6:14: +6:15
+          _2 = _1;                         // scope 1 at $DIR/branch.rs:+7:9: +7:10
+          goto -> bb6;                     // scope 1 at $DIR/branch.rs:+3:13: +8:6
+      }
+  
+      bb6: {
+          StorageDead(_3);                 // scope 1 at $DIR/branch.rs:+8:5: +8:6
+          _0 = _2;                         // scope 2 at $DIR/branch.rs:+10:5: +10:6
+          StorageDead(_2);                 // scope 1 at $DIR/branch.rs:+11:1: +11:2
+          StorageDead(_1);                 // scope 0 at $DIR/branch.rs:+11:1: +11:2
+          return;                          // scope 0 at $DIR/branch.rs:+11:2: +11:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/branch.rs b/tests/mir-opt/copy-prop/branch.rs
new file mode 100644
index 00000000000..50b1e00fad4
--- /dev/null
+++ b/tests/mir-opt/copy-prop/branch.rs
@@ -0,0 +1,27 @@
+//! Tests that we bail out when there are multiple assignments to the same local.
+// unit-test: CopyProp
+fn val() -> i32 {
+    1
+}
+
+fn cond() -> bool {
+    true
+}
+
+// EMIT_MIR branch.foo.CopyProp.diff
+fn foo() -> i32 {
+    let x = val();
+
+    let y = if cond() {
+        x
+    } else {
+        val();
+        x
+    };
+
+    y
+}
+
+fn main() {
+    foo();
+}
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff
new file mode 100644
index 00000000000..69acebf7642
--- /dev/null
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff
@@ -0,0 +1,21 @@
+- // MIR for `arg_src` before CopyProp
++ // MIR for `arg_src` after CopyProp
+  
+  fn arg_src(_1: i32) -> i32 {
+      debug x => _1;                       // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17
+      let mut _0: i32;                     // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
+      let _2: i32;                         // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+      scope 1 {
+          debug y => _2;                   // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+          _2 = _1;                         // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+          _1 = const 123_i32;              // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
+          _0 = _2;                         // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+          StorageDead(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
+          return;                          // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.diff
new file mode 100644
index 00000000000..ac4e9a2bfa7
--- /dev/null
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.bar.CopyProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `bar` before CopyProp
++ // MIR for `bar` after CopyProp
+  
+  fn bar(_1: u8) -> () {
+      debug x => _1;                       // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+      let mut _0: ();                      // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+      let _2: u8;                          // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+      let mut _3: u8;                      // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+          StorageLive(_3);                 // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+          _3 = _1;                         // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+          _2 = dummy(move _3) -> bb1;      // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+                                           // mir::Constant
+                                           // + span: $DIR/copy_propagation_arg.rs:16:5: 16:10
+                                           // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
+          StorageDead(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+          _1 = const 5_u8;                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+          _0 = const ();                   // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+          return;                          // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.diff
new file mode 100644
index 00000000000..7ab6ebb7d53
--- /dev/null
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.baz.CopyProp.diff
@@ -0,0 +1,18 @@
+- // MIR for `baz` before CopyProp
++ // MIR for `baz` after CopyProp
+  
+  fn baz(_1: i32) -> i32 {
+      debug x => _1;                       // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+      let mut _0: i32;                     // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26
+      let mut _2: i32;                     // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+          _2 = _1;                         // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+          _1 = move _2;                    // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+          StorageDead(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+          _0 = _1;                         // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+          return;                          // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.diff
new file mode 100644
index 00000000000..0a3e985e7c2
--- /dev/null
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.foo.CopyProp.diff
@@ -0,0 +1,28 @@
+- // MIR for `foo` before CopyProp
++ // MIR for `foo` after CopyProp
+  
+  fn foo(_1: u8) -> () {
+      debug x => _1;                       // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+      let mut _0: ();                      // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
+      let mut _2: u8;                      // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+      let mut _3: u8;                      // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+          StorageLive(_3);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+          _3 = _1;                         // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
+          _2 = dummy(move _3) -> bb1;      // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+                                           // mir::Constant
+                                           // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14
+                                           // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+          _1 = move _2;                    // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
+          StorageDead(_2);                 // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+          _0 = const ();                   // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+          return;                          // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.rs b/tests/mir-opt/copy-prop/copy_propagation_arg.rs
new file mode 100644
index 00000000000..cc98985f1fd
--- /dev/null
+++ b/tests/mir-opt/copy-prop/copy_propagation_arg.rs
@@ -0,0 +1,40 @@
+// Check that CopyProp does not propagate an assignment to a function argument
+// (doing so can break usages of the original argument value)
+// unit-test: CopyProp
+fn dummy(x: u8) -> u8 {
+    x
+}
+
+// EMIT_MIR copy_propagation_arg.foo.CopyProp.diff
+fn foo(mut x: u8) {
+    // calling `dummy` to make a use of `x` that copyprop cannot eliminate
+    x = dummy(x); // this will assign a local to `x`
+}
+
+// EMIT_MIR copy_propagation_arg.bar.CopyProp.diff
+fn bar(mut x: u8) {
+    dummy(x);
+    x = 5;
+}
+
+// EMIT_MIR copy_propagation_arg.baz.CopyProp.diff
+fn baz(mut x: i32) -> i32 {
+    // self-assignment to a function argument should be eliminated
+    x = x;
+    x
+}
+
+// EMIT_MIR copy_propagation_arg.arg_src.CopyProp.diff
+fn arg_src(mut x: i32) -> i32 {
+    let y = x;
+    x = 123; // Don't propagate this assignment to `y`
+    y
+}
+
+fn main() {
+    // Make sure the function actually gets instantiated.
+    foo(0);
+    bar(0);
+    baz(0);
+    arg_src(0);
+}
diff --git a/tests/mir-opt/copy-prop/cycle.main.CopyProp.diff b/tests/mir-opt/copy-prop/cycle.main.CopyProp.diff
new file mode 100644
index 00000000000..bc5083e1ad0
--- /dev/null
+++ b/tests/mir-opt/copy-prop/cycle.main.CopyProp.diff
@@ -0,0 +1,60 @@
+- // MIR for `main` before CopyProp
++ // MIR for `main` after CopyProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11
+      let mut _1: i32;                     // in scope 0 at $DIR/cycle.rs:+1:9: +1:14
+      let mut _4: i32;                     // in scope 0 at $DIR/cycle.rs:+4:9: +4:10
+      let _5: ();                          // in scope 0 at $DIR/cycle.rs:+6:5: +6:12
+      let mut _6: i32;                     // in scope 0 at $DIR/cycle.rs:+6:10: +6:11
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
+          let _2: i32;                     // in scope 1 at $DIR/cycle.rs:+2:9: +2:10
+          scope 2 {
+              debug y => _2;               // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
+              let _3: i32;                 // in scope 2 at $DIR/cycle.rs:+3:9: +3:10
+              scope 3 {
+-                 debug z => _3;           // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
++                 debug z => _2;           // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/cycle.rs:+1:9: +1:14
+          _1 = val() -> bb1;               // scope 0 at $DIR/cycle.rs:+1:17: +1:22
+                                           // mir::Constant
+                                           // + span: $DIR/cycle.rs:9:17: 9:20
+                                           // + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageLive(_2);                 // scope 1 at $DIR/cycle.rs:+2:9: +2:10
+          _2 = _1;                         // scope 1 at $DIR/cycle.rs:+2:13: +2:14
+-         StorageLive(_3);                 // scope 2 at $DIR/cycle.rs:+3:9: +3:10
+-         _3 = _2;                         // scope 2 at $DIR/cycle.rs:+3:13: +3:14
+-         StorageLive(_4);                 // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+-         _4 = _3;                         // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+-         _1 = move _4;                    // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+-         StorageDead(_4);                 // scope 3 at $DIR/cycle.rs:+4:9: +4:10
++         _1 = _2;                         // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+          StorageLive(_5);                 // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+          StorageLive(_6);                 // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+          _6 = _1;                         // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+          _5 = std::mem::drop::<i32>(move _6) -> bb2; // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+                                           // mir::Constant
+                                           // + span: $DIR/cycle.rs:14:5: 14:9
+                                           // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_6);                 // scope 3 at $DIR/cycle.rs:+6:11: +6:12
+          StorageDead(_5);                 // scope 3 at $DIR/cycle.rs:+6:12: +6:13
+          _0 = const ();                   // scope 0 at $DIR/cycle.rs:+0:11: +7:2
+-         StorageDead(_3);                 // scope 2 at $DIR/cycle.rs:+7:1: +7:2
+-         StorageDead(_2);                 // scope 1 at $DIR/cycle.rs:+7:1: +7:2
+          StorageDead(_1);                 // scope 0 at $DIR/cycle.rs:+7:1: +7:2
+          return;                          // scope 0 at $DIR/cycle.rs:+7:2: +7:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/cycle.rs b/tests/mir-opt/copy-prop/cycle.rs
new file mode 100644
index 00000000000..b74c397269d
--- /dev/null
+++ b/tests/mir-opt/copy-prop/cycle.rs
@@ -0,0 +1,15 @@
+//! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code.
+// unit-test: CopyProp
+fn val() -> i32 {
+    1
+}
+
+// EMIT_MIR cycle.main.CopyProp.diff
+fn main() {
+    let mut x = val();
+    let y = x;
+    let z = y;
+    x = z;
+
+    drop(x);
+}
diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.mir b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.mir
new file mode 100644
index 00000000000..918817da56c
--- /dev/null
+++ b/tests/mir-opt/copy-prop/dead_stores_79191.f.CopyProp.after.mir
@@ -0,0 +1,30 @@
+// MIR for `f` after CopyProp
+
+fn f(_1: usize) -> usize {
+    debug a => _1;                       // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11
+    let mut _0: usize;                   // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28
+    let _2: usize;                       // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+    let mut _3: usize;                   // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+    let mut _4: usize;                   // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+    scope 1 {
+        debug b => _2;                   // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+        _2 = _1;                         // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14
+        _1 = const 5_usize;              // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10
+        _1 = _2;                         // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10
+        StorageLive(_4);                 // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+        _4 = _1;                         // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+        _0 = id::<usize>(move _4) -> bb1; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10
+                                         // mir::Constant
+                                         // + span: $DIR/dead_stores_79191.rs:12:5: 12:7
+                                         // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageDead(_4);                 // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10
+        return;                          // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2
+    }
+}
diff --git a/tests/mir-opt/copy-prop/dead_stores_79191.rs b/tests/mir-opt/copy-prop/dead_stores_79191.rs
new file mode 100644
index 00000000000..e3493b8b7a1
--- /dev/null
+++ b/tests/mir-opt/copy-prop/dead_stores_79191.rs
@@ -0,0 +1,17 @@
+// unit-test: CopyProp
+
+fn id<T>(x: T) -> T {
+    x
+}
+
+// EMIT_MIR dead_stores_79191.f.CopyProp.after.mir
+fn f(mut a: usize) -> usize {
+    let b = a;
+    a = 5;
+    a = b;
+    id(a)
+}
+
+fn main() {
+    f(0);
+}
diff --git a/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.mir b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.mir
new file mode 100644
index 00000000000..cf21fadd437
--- /dev/null
+++ b/tests/mir-opt/copy-prop/dead_stores_better.f.CopyProp.after.mir
@@ -0,0 +1,30 @@
+// MIR for `f` after CopyProp
+
+fn f(_1: usize) -> usize {
+    debug a => _1;                       // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15
+    let mut _0: usize;                   // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32
+    let _2: usize;                       // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+    let mut _3: usize;                   // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10
+    let mut _4: usize;                   // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9
+    scope 1 {
+        debug b => _2;                   // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10
+    }
+
+    bb0: {
+        StorageLive(_2);                 // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+        _2 = _1;                         // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14
+        _1 = const 5_usize;              // scope 1 at $DIR/dead_stores_better.rs:+2:5: +2:10
+        _1 = _2;                         // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10
+        StorageLive(_4);                 // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+        _4 = _1;                         // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+        _0 = id::<usize>(move _4) -> bb1; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10
+                                         // mir::Constant
+                                         // + span: $DIR/dead_stores_better.rs:16:5: 16:7
+                                         // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+    }
+
+    bb1: {
+        StorageDead(_4);                 // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10
+        return;                          // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2
+    }
+}
diff --git a/tests/mir-opt/copy-prop/dead_stores_better.rs b/tests/mir-opt/copy-prop/dead_stores_better.rs
new file mode 100644
index 00000000000..8465b3c9853
--- /dev/null
+++ b/tests/mir-opt/copy-prop/dead_stores_better.rs
@@ -0,0 +1,21 @@
+// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates
+// that that pass enables this one to do more optimizations.
+
+// unit-test: CopyProp
+// compile-flags: -Zmir-enable-passes=+DeadStoreElimination
+
+fn id<T>(x: T) -> T {
+    x
+}
+
+// EMIT_MIR dead_stores_better.f.CopyProp.after.mir
+pub fn f(mut a: usize) -> usize {
+    let b = a;
+    a = 5;
+    a = b;
+    id(a)
+}
+
+fn main() {
+    f(0);
+}
diff --git a/tests/mir-opt/copy-prop/move_arg.f.CopyProp.diff b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.diff
new file mode 100644
index 00000000000..d76bf1cfe7e
--- /dev/null
+++ b/tests/mir-opt/copy-prop/move_arg.f.CopyProp.diff
@@ -0,0 +1,40 @@
+- // MIR for `f` before CopyProp
++ // MIR for `f` after CopyProp
+  
+  fn f(_1: T) -> () {
+      debug a => _1;                       // in scope 0 at $DIR/move_arg.rs:+0:19: +0:20
+      let mut _0: ();                      // return place in scope 0 at $DIR/move_arg.rs:+0:25: +0:25
+      let _2: T;                           // in scope 0 at $DIR/move_arg.rs:+1:9: +1:10
+      let _3: ();                          // in scope 0 at $DIR/move_arg.rs:+2:5: +2:12
+      let mut _4: T;                       // in scope 0 at $DIR/move_arg.rs:+2:7: +2:8
+      let mut _5: T;                       // in scope 0 at $DIR/move_arg.rs:+2:10: +2:11
+      scope 1 {
+-         debug b => _2;                   // in scope 1 at $DIR/move_arg.rs:+1:9: +1:10
++         debug b => _1;                   // in scope 1 at $DIR/move_arg.rs:+1:9: +1:10
+      }
+  
+      bb0: {
+-         StorageLive(_2);                 // scope 0 at $DIR/move_arg.rs:+1:9: +1:10
+-         _2 = _1;                         // scope 0 at $DIR/move_arg.rs:+1:13: +1:14
+          StorageLive(_3);                 // scope 1 at $DIR/move_arg.rs:+2:5: +2:12
+-         StorageLive(_4);                 // scope 1 at $DIR/move_arg.rs:+2:7: +2:8
+-         _4 = _1;                         // scope 1 at $DIR/move_arg.rs:+2:7: +2:8
+-         StorageLive(_5);                 // scope 1 at $DIR/move_arg.rs:+2:10: +2:11
+-         _5 = _2;                         // scope 1 at $DIR/move_arg.rs:+2:10: +2:11
+-         _3 = g::<T>(move _4, move _5) -> bb1; // scope 1 at $DIR/move_arg.rs:+2:5: +2:12
++         _3 = g::<T>(_1, _1) -> bb1;      // scope 1 at $DIR/move_arg.rs:+2:5: +2:12
+                                           // mir::Constant
+                                           // + span: $DIR/move_arg.rs:7:5: 7:6
+                                           // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+-         StorageDead(_5);                 // scope 1 at $DIR/move_arg.rs:+2:11: +2:12
+-         StorageDead(_4);                 // scope 1 at $DIR/move_arg.rs:+2:11: +2:12
+          StorageDead(_3);                 // scope 1 at $DIR/move_arg.rs:+2:12: +2:13
+          _0 = const ();                   // scope 0 at $DIR/move_arg.rs:+0:25: +3:2
+-         StorageDead(_2);                 // scope 0 at $DIR/move_arg.rs:+3:1: +3:2
+          return;                          // scope 0 at $DIR/move_arg.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/move_arg.rs b/tests/mir-opt/copy-prop/move_arg.rs
new file mode 100644
index 00000000000..40ae1d8f466
--- /dev/null
+++ b/tests/mir-opt/copy-prop/move_arg.rs
@@ -0,0 +1,15 @@
+// Test that we do not move multiple times from the same local.
+// unit-test: CopyProp
+
+// EMIT_MIR move_arg.f.CopyProp.diff
+pub fn f<T: Copy>(a: T) {
+    let b = a;
+    g(a, b);
+}
+
+#[inline(never)]
+pub fn g<T: Copy>(_: T, _: T) {}
+
+fn main() {
+    f(5)
+}
diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff b/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff
new file mode 100644
index 00000000000..61fdd6f8c05
--- /dev/null
+++ b/tests/mir-opt/copy-prop/mutate_through_pointer.f.CopyProp.diff
@@ -0,0 +1,19 @@
+- // MIR for `f` before CopyProp
++ // MIR for `f` after CopyProp
+  
+  fn f(_1: bool) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/mutate_through_pointer.rs:+0:18: +0:22
+      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: *const bool;             // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _4: *mut bool;               // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          _2 = _1;                         // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _3 = &raw const _2;              // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _4 = &raw mut (*_3);             // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          (*_4) = const false;             // scope 0 at $DIR/mutate_through_pointer.rs:+5:9: +5:20
+          _0 = _1;                         // scope 0 at $DIR/mutate_through_pointer.rs:+6:9: +6:16
+          return;                          // scope 0 at $DIR/mutate_through_pointer.rs:+7:9: +7:17
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/mutate_through_pointer.rs b/tests/mir-opt/copy-prop/mutate_through_pointer.rs
new file mode 100644
index 00000000000..609e49d6bc9
--- /dev/null
+++ b/tests/mir-opt/copy-prop/mutate_through_pointer.rs
@@ -0,0 +1,22 @@
+#![feature(custom_mir, core_intrinsics)]
+#![allow(unused_assignments)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
+fn f(c: bool) -> bool {
+    mir!({
+        let a = c;
+        let p = core::ptr::addr_of!(a);
+        let p2 = core::ptr::addr_of_mut!(*p);
+        *p2 = false;
+        RET = c;
+        Return()
+    })
+}
+
+fn main() {
+    assert_eq!(true, f(true));
+}
+
+// EMIT_MIR mutate_through_pointer.f.CopyProp.diff
diff --git a/tests/mir-opt/copy-prop/non_dominate.f.CopyProp.diff b/tests/mir-opt/copy-prop/non_dominate.f.CopyProp.diff
new file mode 100644
index 00000000000..9760fd3740f
--- /dev/null
+++ b/tests/mir-opt/copy-prop/non_dominate.f.CopyProp.diff
@@ -0,0 +1,29 @@
+- // MIR for `f` before CopyProp
++ // MIR for `f` after CopyProp
+  
+  fn f(_1: bool) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/non_dominate.rs:+0:18: +0:22
+      let mut _2: bool;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: bool;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          goto -> bb1;                     // scope 0 at $DIR/non_dominate.rs:+4:11: +4:20
+      }
+  
+      bb1: {
+          _3 = _1;                         // scope 0 at $DIR/non_dominate.rs:+5:17: +5:22
+          switchInt(_3) -> [0: bb3, otherwise: bb2]; // scope 0 at $DIR/non_dominate.rs:+5:24: +5:58
+      }
+  
+      bb2: {
+          _2 = _3;                         // scope 0 at $DIR/non_dominate.rs:+8:17: +8:22
+          _1 = const false;                // scope 0 at $DIR/non_dominate.rs:+8:24: +8:33
+          goto -> bb1;                     // scope 0 at $DIR/non_dominate.rs:+8:35: +8:44
+      }
+  
+      bb3: {
+          _0 = _2;                         // scope 0 at $DIR/non_dominate.rs:+9:17: +9:24
+          return;                          // scope 0 at $DIR/non_dominate.rs:+9:26: +9:34
+      }
+  }
+  
diff --git a/tests/mir-opt/copy-prop/non_dominate.rs b/tests/mir-opt/copy-prop/non_dominate.rs
new file mode 100644
index 00000000000..c0ea838e1c8
--- /dev/null
+++ b/tests/mir-opt/copy-prop/non_dominate.rs
@@ -0,0 +1,26 @@
+// unit-test: CopyProp
+
+#![feature(custom_mir, core_intrinsics)]
+#![allow(unused_assignments)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
+fn f(c: bool) -> bool {
+    mir!(
+        let a: bool;
+        let b: bool;
+        { Goto(bb1) }
+        bb1 = { b = c; match b { false => bb3, _ => bb2 }}
+        // This assignment to `a` does not dominate the use in `bb3`.
+        // It should not be replaced by `b`.
+        bb2 = { a = b; c = false; Goto(bb1) }
+        bb3 = { RET = a; Return() }
+    )
+}
+
+fn main() {
+    assert_eq!(true, f(true));
+}
+
+// EMIT_MIR non_dominate.f.CopyProp.diff
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
index 02aafd7acc4..6870d7d6c45 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
@@ -20,19 +20,11 @@
           _1 = const u8::MAX;              // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
           StorageLive(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
           _2 = const 1_u8;                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          _3 = const u8::MAX;              // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          _4 = const 1_u8;                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
           _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
           assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
       }
   
       bb1: {
-          StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          StorageDead(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          StorageDead(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
           return;                          // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
       }
   }
diff --git a/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir
index d7f66a6bf4d..1a7fb916e56 100644
--- a/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir
+++ b/tests/mir-opt/div_overflow.const_dividend.PreCodegen.after.mir
@@ -11,7 +11,7 @@ fn const_dividend(_1: i32) -> i32 {
     }
 
     bb1: {
-        _0 = Div(const 256_i32, move _1); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+        _0 = Div(const 256_i32, _1);     // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
         return;                          // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2
     }
 }
diff --git a/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir
index 7b7ab197825..5526a194be5 100644
--- a/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir
+++ b/tests/mir-opt/div_overflow.const_divisor.PreCodegen.after.mir
@@ -5,7 +5,7 @@ fn const_divisor(_1: i32) -> i32 {
     let mut _0: i32;                     // return place in scope 0 at $DIR/div_overflow.rs:+0:33: +0:36
 
     bb0: {
-        _0 = Div(move _1, const 256_i32); // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
+        _0 = Div(_1, const 256_i32);     // scope 0 at $DIR/div_overflow.rs:+1:5: +1:12
         return;                          // scope 0 at $DIR/div_overflow.rs:+2:2: +2:2
     }
 }
diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
index c1c2cde71ab..df9f8dcf1a4 100644
--- a/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
+++ b/tests/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
@@ -83,55 +83,39 @@
           _10 = ((_7 as Some).0: usize);   // scope 3 at $DIR/funky_arms.rs:+13:17: +13:26
           StorageLive(_11);                // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46
           _11 = &mut (*_1);                // scope 3 at $DIR/funky_arms.rs:+15:43: +15:46
-          StorageLive(_12);                // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51
-          _12 = _2;                        // scope 3 at $DIR/funky_arms.rs:+15:48: +15:51
           StorageLive(_13);                // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57
           _13 = _6;                        // scope 3 at $DIR/funky_arms.rs:+15:53: +15:57
           StorageLive(_14);                // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79
           StorageLive(_15);                // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
-          StorageLive(_16);                // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
-          _16 = _10;                       // scope 3 at $DIR/funky_arms.rs:+15:59: +15:68
-          _15 = move _16 as u32 (IntToInt); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
-          StorageDead(_16);                // scope 3 at $DIR/funky_arms.rs:+15:74: +15:75
+          _15 = _10 as u32 (IntToInt);     // scope 3 at $DIR/funky_arms.rs:+15:59: +15:75
           _14 = Add(move _15, const 1_u32); // scope 3 at $DIR/funky_arms.rs:+15:59: +15:79
           StorageDead(_15);                // scope 3 at $DIR/funky_arms.rs:+15:78: +15:79
-          StorageLive(_17);                // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86
-          _17 = _3;                        // scope 3 at $DIR/funky_arms.rs:+15:81: +15:86
-          _0 = float_to_exponential_common_exact::<T>(move _11, move _12, move _13, move _14, move _17) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87
+          _0 = float_to_exponential_common_exact::<T>(move _11, _2, move _13, move _14, _3) -> bb7; // scope 3 at $DIR/funky_arms.rs:+15:9: +15:87
                                            // mir::Constant
                                            // + span: $DIR/funky_arms.rs:26:9: 26:42
                                            // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, u32, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_exact::<T>}, val: Value(<ZST>) }
       }
   
       bb7: {
-          StorageDead(_17);                // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
           StorageDead(_14);                // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
           StorageDead(_13);                // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
-          StorageDead(_12);                // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
           StorageDead(_11);                // scope 3 at $DIR/funky_arms.rs:+15:86: +15:87
-          StorageDead(_10);                // scope 2 at $DIR/funky_arms.rs:+16:5: +16:6
           goto -> bb10;                    // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6
       }
   
       bb8: {
           StorageLive(_18);                // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49
           _18 = &mut (*_1);                // scope 2 at $DIR/funky_arms.rs:+17:46: +17:49
-          StorageLive(_19);                // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54
-          _19 = _2;                        // scope 2 at $DIR/funky_arms.rs:+17:51: +17:54
           StorageLive(_20);                // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60
           _20 = _6;                        // scope 2 at $DIR/funky_arms.rs:+17:56: +17:60
-          StorageLive(_21);                // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67
-          _21 = _3;                        // scope 2 at $DIR/funky_arms.rs:+17:62: +17:67
-          _0 = float_to_exponential_common_shortest::<T>(move _18, move _19, move _20, move _21) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68
+          _0 = float_to_exponential_common_shortest::<T>(move _18, _2, move _20, _3) -> bb9; // scope 2 at $DIR/funky_arms.rs:+17:9: +17:68
                                            // mir::Constant
                                            // + span: $DIR/funky_arms.rs:28:9: 28:45
                                            // + literal: Const { ty: for<'a, 'b, 'c> fn(&'a mut Formatter<'b>, &'c T, Sign, bool) -> Result<(), std::fmt::Error> {float_to_exponential_common_shortest::<T>}, val: Value(<ZST>) }
       }
   
       bb9: {
-          StorageDead(_21);                // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
           StorageDead(_20);                // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
-          StorageDead(_19);                // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
           StorageDead(_18);                // scope 2 at $DIR/funky_arms.rs:+17:67: +17:68
           goto -> bb10;                    // scope 2 at $DIR/funky_arms.rs:+13:5: +18:6
       }
diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff
index 8ea1a0757f2..64c3e47ff46 100644
--- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff
+++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -35,8 +35,8 @@
           _4 = &(*_2);                     // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24
 -         _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn_trait.rs:+2:5: +2:25
 +         StorageLive(_5);                 // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
-+         _5 = move _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
-+         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22
++         _5 = _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++         _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(_5) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22
                                            // mir::Constant
 -                                          // + span: $DIR/dyn_trait.rs:34:5: 34:22
 -                                          // + literal: Const { ty: for<'a> fn(&'a <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
index a71d73b7453..3fa9c3e88f6 100644
--- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
+++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -17,7 +17,7 @@
           _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
           StorageDead(_3);                 // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
 -         _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:16
-+         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22
++         _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(_2) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22
                                            // mir::Constant
 -                                          // + span: $DIR/dyn_trait.rs:27:5: 27:13
 -                                          // + literal: Const { ty: for<'a> fn(&'a (dyn Cache<V = <C as Cache>::V> + 'a)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
index 3502c25864b..20f737cc29f 100644
--- a/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
+++ b/tests/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
@@ -26,7 +26,7 @@ fn bar() -> bool {
         _3 = const 1_i32;                // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
         StorageLive(_4);                 // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
         _4 = const -1_i32;               // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
-        _0 = Eq(move _3, move _4);       // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:11
+        _0 = Eq(_3, _4);                 // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:11
         StorageDead(_4);                 // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
         StorageDead(_3);                 // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
         StorageDead(_2);                 // scope 1 at $DIR/inline_any_operand.rs:+2:12: +2:13
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.diff b/tests/mir-opt/inline/inline_generator.main.Inline.diff
index f27b64c3054..57574acf923 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.diff
@@ -92,7 +92,7 @@
 + 
 +     bb3: {
 +         StorageLive(_8);                 // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
-+         switchInt(move _7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
++         switchInt(_7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
 +     }
 + 
 +     bb4: {
@@ -118,7 +118,7 @@
 +         StorageLive(_8);                 // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
 +         StorageDead(_8);                 // scope 6 at $DIR/inline_generator.rs:15:38: 15:39
 +         Deinit(_1);                      // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
-+         ((_1 as Complete).0: bool) = move _7; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++         ((_1 as Complete).0: bool) = _7; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
 +         discriminant(_1) = 1;            // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
 +         _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
 +         discriminant((*_12)) = 1;        // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
diff --git a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
index 73aea719eed..b7c5bbecb68 100644
--- a/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
+++ b/tests/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
@@ -15,7 +15,7 @@ fn test2(_1: &dyn X) -> bool {
         _3 = &(*_1);                     // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
         _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
         StorageDead(_3);                 // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
-        _0 = <dyn X as X>::y(move _2) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10
+        _0 = <dyn X as X>::y(_2) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10
                                          // mir::Constant
                                          // + span: $DIR/inline_trait_method_2.rs:10:7: 10:8
                                          // + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.diff
index b2706e5a436..30bf2c0684e 100644
--- a/tests/mir-opt/issue_101973.inner.ConstProp.diff
+++ b/tests/mir-opt/issue_101973.inner.ConstProp.diff
@@ -15,7 +15,7 @@
       let mut _10: (u32, bool);            // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
       let mut _11: (u32, bool);            // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
       scope 1 (inlined imm8) {             // at $DIR/issue_101973.rs:14:5: 14:17
-          debug x => _5;                   // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14
+          debug x => _1;                   // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14
           let mut _12: u32;                // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27
           let mut _13: u32;                // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
           let mut _14: (u32, bool);        // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
@@ -34,17 +34,14 @@
           StorageLive(_2);                 // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
           StorageLive(_3);                 // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58
           StorageLive(_4);                 // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17
-          StorageLive(_5);                 // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
-          _5 = _1;                         // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
           StorageLive(_12);                // scope 2 at $DIR/issue_101973.rs:7:12: 7:27
           StorageLive(_13);                // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
-          _14 = CheckedShr(_5, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+          _14 = CheckedShr(_1, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
           assert(!move (_14.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
       }
   
       bb1: {
           _8 = move (_10.0: u32);          // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
-          StorageDead(_9);                 // scope 0 at $DIR/issue_101973.rs:+1:44: +1:45
           _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
           StorageDead(_8);                 // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52
           _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
@@ -54,11 +51,7 @@
       bb2: {
           _6 = move (_11.0: u32);          // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
           StorageDead(_7);                 // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57
-          StorageLive(_15);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          _15 = _4;                        // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          StorageLive(_16);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          _16 = _6;                        // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          _3 = rotate_right::<u32>(move _15, move _16) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          _3 = rotate_right::<u32>(_4, _6) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
                                            // mir::Constant
                                            // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
                                            // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) }
@@ -70,21 +63,14 @@
           StorageDead(_13);                // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
           _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27
           StorageDead(_12);                // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
-          StorageDead(_5);                 // scope 0 at $DIR/issue_101973.rs:+1:16: +1:17
           StorageLive(_6);                 // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
           StorageLive(_7);                 // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
           StorageLive(_8);                 // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
-          StorageLive(_9);                 // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
-          _9 = _1;                         // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
-          _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+          _10 = CheckedShr(_1, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
           assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
       }
   
       bb4: {
-          StorageDead(_16);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          StorageDead(_15);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-          StorageDead(_6);                 // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
-          StorageDead(_4);                 // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
           _2 = move _3 as i32 (IntToInt);  // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
           StorageDead(_3);                 // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65
           _0 = move _2 as i64 (IntToInt);  // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
index c24543daeac..c14780052fb 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -29,24 +29,11 @@
   
       bb0: {
           StorageLive(_2);                 // scope 0 at $DIR/issue_76432.rs:+1:9: +1:10
-          StorageLive(_3);                 // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           StorageLive(_4);                 // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           StorageLive(_5);                 // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
-          StorageLive(_6);                 // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22
-          _6 = _1;                         // scope 0 at $DIR/issue_76432.rs:+1:21: +1:22
-          StorageLive(_7);                 // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25
-          _7 = _1;                         // scope 0 at $DIR/issue_76432.rs:+1:24: +1:25
-          StorageLive(_8);                 // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28
-          _8 = _1;                         // scope 0 at $DIR/issue_76432.rs:+1:27: +1:28
-          _5 = [move _6, move _7, move _8]; // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
-          StorageDead(_8);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
-          StorageDead(_7);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
-          StorageDead(_6);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
+          _5 = [_1, _1, _1];               // scope 0 at $DIR/issue_76432.rs:+1:20: +1:29
           _4 = &_5;                        // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          _3 = _4;                         // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          StorageDead(_3);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
-          StorageDead(_4);                 // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30
+          _2 = _4 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           _9 = Len((*_2));                 // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
           _10 = const 3_usize;             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
 -         _11 = Eq(move _9, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
diff --git a/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
index 701c2ad705a..dee1d538395 100644
--- a/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
+++ b/tests/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
@@ -5,27 +5,23 @@ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
     debug slice => _2;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:50: +0:55
     let mut _0: u8;                      // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:70: +0:72
     let mut _3: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-    let mut _4: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-    let mut _5: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-    let mut _6: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-    let mut _7: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+    let mut _4: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+    let mut _5: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+    let mut _6: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
 
     bb0: {
         StorageLive(_3);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-        StorageLive(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-        _4 = _1;                         // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-        StorageLive(_5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-        _5 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-        _3 = Lt(move _4, move _5);       // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-        StorageDead(_5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+        StorageLive(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+        _4 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+        _3 = Lt(_1, move _4);            // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
         StorageDead(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
         switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
     }
 
     bb1: {
-        _6 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-        _7 = Lt(_1, _6);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        _5 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        _6 = Lt(_1, _5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
     }
 
     bb2: {
diff --git a/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
index 0440cfce289..e35fe758ab1 100644
--- a/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
+++ b/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
@@ -5,30 +5,26 @@ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
     debug slice => _2;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:54: +0:59
     let mut _0: u8;                      // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:78: +0:80
     let mut _3: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-    let mut _4: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-    let mut _5: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-    let mut _6: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-    let mut _7: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-    let _8: usize;                       // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
-    let mut _9: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
-    let mut _10: bool;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+    let mut _4: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+    let mut _5: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+    let mut _6: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+    let _7: usize;                       // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+    let mut _8: usize;                   // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+    let mut _9: bool;                    // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
 
     bb0: {
         StorageLive(_3);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-        StorageLive(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-        _4 = _1;                         // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
-        StorageLive(_5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-        _5 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
-        _3 = Lt(move _4, move _5);       // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
-        StorageDead(_5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
+        StorageLive(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+        _4 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
+        _3 = Lt(_1, move _4);            // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
         StorageDead(_4);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
         switchInt(move _3) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
     }
 
     bb1: {
-        _6 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-        _7 = Lt(_1, _6);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        _5 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        _6 = Lt(_1, _5);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
     }
 
     bb2: {
@@ -37,16 +33,16 @@ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
     }
 
     bb3: {
-        StorageLive(_8);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
-        _8 = const 0_usize;              // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
-        _9 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
-        _10 = Lt(const 0_usize, _9);     // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
-        assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+        StorageLive(_7);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+        _7 = const 0_usize;              // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+        _8 = const N;                    // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+        _9 = Lt(const 0_usize, _8);      // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
     }
 
     bb4: {
-        (*_2)[_8] = const 42_u8;         // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
-        StorageDead(_8);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
+        (*_2)[_7] = const 42_u8;         // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
+        StorageDead(_7);                 // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
         _0 = const 42_u8;                // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11
         goto -> bb5;                     // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
     }
diff --git a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir
index 916f99049c6..760f48d956d 100644
--- a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir
+++ b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir
@@ -37,7 +37,7 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
     bb3: {
         _5 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
         StorageLive(_4);                 // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
-        _4 = Add(move _5, const 1_i32);  // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
+        _4 = Add(_5, const 1_i32);       // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
         Deinit(_0);                      // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
         ((_0 as Some).0: i32) = move _4; // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
         discriminant(_0) = 1;            // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
diff --git a/tests/mir-opt/simplify_match.main.ConstProp.diff b/tests/mir-opt/simplify_match.main.ConstProp.diff
index 70bfbf1b3e3..35ffc4963cb 100644
--- a/tests/mir-opt/simplify_match.main.ConstProp.diff
+++ b/tests/mir-opt/simplify_match.main.ConstProp.diff
@@ -10,13 +10,9 @@
       }
   
       bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/simplify_match.rs:+1:11: +1:31
           StorageLive(_2);                 // scope 0 at $DIR/simplify_match.rs:+1:17: +1:18
           _2 = const false;                // scope 0 at $DIR/simplify_match.rs:+1:21: +1:26
--         _1 = _2;                         // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29
-+         _1 = const false;                // scope 1 at $DIR/simplify_match.rs:+1:28: +1:29
-          StorageDead(_2);                 // scope 0 at $DIR/simplify_match.rs:+1:30: +1:31
--         switchInt(_1) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
+-         switchInt(_2) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
 +         switchInt(const false) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_match.rs:+1:5: +1:31
       }
   
@@ -32,7 +28,6 @@
       }
   
       bb3: {
-          StorageDead(_1);                 // scope 0 at $DIR/simplify_match.rs:+5:1: +5:2
           return;                          // scope 0 at $DIR/simplify_match.rs:+5:2: +5:2
       }
   }
diff --git a/tests/mir-opt/slice_filter.rs b/tests/mir-opt/slice_filter.rs
new file mode 100644
index 00000000000..97c18af31de
--- /dev/null
+++ b/tests/mir-opt/slice_filter.rs
@@ -0,0 +1,18 @@
+fn main() {
+    let input = vec![];
+    let _variant_a_result = variant_a(&input);
+    let _variant_b_result = variant_b(&input);
+}
+
+pub fn variant_a(input: &[(usize, usize, usize, usize)]) -> usize {
+    input.iter().filter(|(a, b, c, d)| a <= c && d <= b || c <= a && b <= d).count()
+}
+
+pub fn variant_b(input: &[(usize, usize, usize, usize)]) -> usize {
+    input.iter().filter(|&&(a, b, c, d)| a <= c && d <= b || c <= a && b <= d).count()
+}
+
+// EMIT_MIR slice_filter.variant_a-{closure#0}.CopyProp.diff
+// EMIT_MIR slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
+// EMIT_MIR slice_filter.variant_b-{closure#0}.CopyProp.diff
+// EMIT_MIR slice_filter.variant_b-{closure#0}.DestinationPropagation.diff
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
new file mode 100644
index 00000000000..d1f6fd97dc7
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
@@ -0,0 +1,279 @@
+- // MIR for `variant_a::{closure#0}` before CopyProp
++ // MIR for `variant_a::{closure#0}` after CopyProp
+  
+  fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40
+      let _3: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+      let _4: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+      let _5: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+      let _6: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+      let mut _7: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
+      let mut _8: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
+      let mut _9: &&usize;                 // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41
+      let mut _10: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+      let _11: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+      let mut _12: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
+      let mut _13: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51
+      let mut _14: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+      let _15: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+      let mut _16: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
+      let mut _17: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
+      let mut _18: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61
+      let mut _19: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+      let _20: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+      let mut _21: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
+      let mut _22: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71
+      let mut _23: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+      let _24: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+      let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      scope 1 {
+          debug a => _3;                   // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
+          debug b => _4;                   // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
+          debug c => _5;                   // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
+          debug d => _6;                   // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
+          scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
+              debug self => _9;            // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _10;          // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _29: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _30: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _31: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _32: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug self => _29;       // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug other => _30;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug self => _31;       // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug other => _32;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _33: usize;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _34: usize;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66
+              debug self => _18;           // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _19;          // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _35: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _36: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _37: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _38: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug self => _35;       // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug other => _36;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug self => _37;       // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug other => _38;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _39: usize;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _40: usize;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56
+              debug self => _13;           // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _14;          // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _41: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _42: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _43: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _44: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug self => _41;       // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug other => _42;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug self => _43;       // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug other => _44;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _45: usize;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _46: usize;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76
+              debug self => _22;           // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _23;          // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _47: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _48: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _49: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _50: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug self => _47;       // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-                 debug other => _48;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug self => _49;       // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++                 debug other => _50;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _51: usize;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _52: usize;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          _25 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          _3 = &((*_25).0: usize);         // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          StorageLive(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          _26 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          _4 = &((*_26).1: usize);         // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          StorageLive(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          _27 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          _5 = &((*_27).2: usize);         // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          StorageLive(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+          _28 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+          _6 = &((*_28).3: usize);         // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+          StorageLive(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+          StorageLive(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
+          StorageLive(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+          _9 = &_3;                        // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+          StorageLive(_10);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageLive(_11);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          _11 = _5;                        // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          _10 = &_11;                      // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+-         StorageLive(_29);                // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _31 = deref_copy (*_9);          // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _29 = _31;                       // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageLive(_30);                // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _32 = deref_copy (*_10);         // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _30 = _32;                       // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_33);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _33 = (*_29);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _33 = (*_31);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_34);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _34 = (*_30);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _34 = (*_32);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _8 = Le(move _33, move _34);     // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_34);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_33);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_30);                // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_29);                // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_11);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageDead(_10);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageDead(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+      }
+  
+      bb1: {
+          _0 = const true;                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  
+      bb2: {
+          StorageLive(_16);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          StorageLive(_17);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
+          StorageLive(_18);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+          _18 = &_5;                       // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+          StorageLive(_19);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageLive(_20);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          _20 = _3;                        // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          _19 = &_20;                      // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+-         StorageLive(_35);                // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _37 = deref_copy (*_18);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _35 = _37;                       // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageLive(_36);                // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _38 = deref_copy (*_19);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _36 = _38;                       // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_39);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _39 = (*_35);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _39 = (*_37);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_40);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _40 = (*_36);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _40 = (*_38);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _17 = Le(move _39, move _40);    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_40);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_39);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_36);                // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_35);                // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_20);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageDead(_19);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageDead(_18);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb3: {
+          StorageDead(_16);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageDead(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageDead(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageDead(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageDead(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+          return;                          // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
+      }
+  
+      bb4: {
+          _7 = const false;                // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+          StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          goto -> bb2;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+      }
+  
+      bb5: {
+          StorageLive(_12);                // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+          StorageLive(_13);                // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+          _13 = &_6;                       // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+          StorageLive(_14);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageLive(_15);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _15 = _4;                        // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _14 = &_15;                      // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+-         StorageLive(_41);                // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _43 = deref_copy (*_13);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _41 = _43;                       // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageLive(_42);                // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _44 = deref_copy (*_14);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _42 = _44;                       // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_45);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _45 = (*_41);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _45 = (*_43);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_46);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _46 = (*_42);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _46 = (*_44);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _12 = Le(move _45, move _46);    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_46);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_45);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_42);                // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_41);                // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_15);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_14);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_13);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _7 = move _12;                   // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+          StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  
+      bb6: {
+          _16 = const false;               // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb7: {
+          StorageLive(_21);                // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+          StorageLive(_22);                // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+          _22 = &_4;                       // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+          StorageLive(_23);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageLive(_24);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _24 = _6;                        // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _23 = &_24;                      // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageLive(_47);                // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _49 = deref_copy (*_22);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _47 = _49;                       // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageLive(_48);                // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _50 = deref_copy (*_23);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _48 = _50;                       // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_51);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _51 = (*_47);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _51 = (*_49);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_52);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _52 = (*_48);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _52 = (*_50);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _21 = Le(move _51, move _52);    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_52);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_51);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_48);                // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         StorageDead(_47);                // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_24);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_23);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_22);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _16 = move _21;                  // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb8: {
+          StorageDead(_21);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_17);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _0 = move _16;                   // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  }
+  
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
new file mode 100644
index 00000000000..259cd411896
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
@@ -0,0 +1,241 @@
+- // MIR for `variant_a::{closure#0}` before DestinationPropagation
++ // MIR for `variant_a::{closure#0}` after DestinationPropagation
+  
+  fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40
+      let _3: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+      let _4: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+      let _5: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+      let _6: &usize;                      // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+      let mut _7: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
+      let mut _8: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
+      let mut _9: &&usize;                 // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41
+      let mut _10: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+      let _11: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
+      let mut _12: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
+      let mut _13: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51
+      let mut _14: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+      let _15: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
+      let mut _16: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
+      let mut _17: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
+      let mut _18: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61
+      let mut _19: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+      let _20: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
+      let mut _21: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
+      let mut _22: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71
+      let mut _23: &&usize;                // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+      let _24: &usize;                     // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+      let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
+      scope 1 {
+          debug a => _3;                   // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
+          debug b => _4;                   // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
+          debug c => _5;                   // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
+          debug d => _6;                   // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
+          scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
+              debug self => _9;            // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _10;          // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _29: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _30: &usize;         // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug self => _29;       // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug other => _30;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _31: usize;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _32: usize;      // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66
+              debug self => _18;           // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _19;          // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _33: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _34: &usize;         // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug self => _33;       // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug other => _34;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _35: usize;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _36: usize;      // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56
+              debug self => _13;           // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _14;          // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _37: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _38: &usize;         // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug self => _37;       // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug other => _38;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _39: usize;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _40: usize;      // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+          scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76
+              debug self => _22;           // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              debug other => _23;          // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _41: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              let mut _42: &usize;         // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug self => _41;       // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  debug other => _42;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _43: usize;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+                  let mut _44: usize;      // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          _25 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          _3 = &((*_25).0: usize);         // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          StorageLive(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          _26 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          _4 = &((*_26).1: usize);         // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+          StorageLive(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          _27 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          _5 = &((*_27).2: usize);         // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+          StorageLive(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+          _28 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+          _6 = &((*_28).3: usize);         // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+-         StorageLive(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+          StorageLive(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
+          StorageLive(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+          _9 = &_3;                        // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
+          StorageLive(_10);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageLive(_11);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          _11 = _5;                        // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          _10 = &_11;                      // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          _29 = deref_copy (*_9);          // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _30 = deref_copy (*_10);         // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_31);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _31 = (*_29);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_32);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _32 = (*_30);                    // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _8 = Le(move _31, move _32);     // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_32);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_31);                // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_11);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageDead(_10);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          StorageDead(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+          switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+      }
+  
+      bb1: {
+          _0 = const true;                 // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  
+      bb2: {
+-         StorageLive(_16);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          StorageLive(_17);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
+          StorageLive(_18);                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+          _18 = &_5;                       // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
+          StorageLive(_19);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageLive(_20);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          _20 = _3;                        // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          _19 = &_20;                      // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          _33 = deref_copy (*_18);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _34 = deref_copy (*_19);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_35);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _35 = (*_33);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_36);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _36 = (*_34);                    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _17 = Le(move _35, move _36);    // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_36);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_35);                // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_20);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageDead(_19);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          StorageDead(_18);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+          switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb3: {
+-         StorageDead(_16);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+-         StorageDead(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          return;                          // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
+      }
+  
+      bb4: {
+-         StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          goto -> bb2;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+      }
+  
+      bb5: {
+-         StorageLive(_12);                // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+          StorageLive(_13);                // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+          _13 = &_6;                       // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
+          StorageLive(_14);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageLive(_15);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _15 = _4;                        // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _14 = &_15;                      // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          _37 = deref_copy (*_13);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _38 = deref_copy (*_14);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_39);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _39 = (*_37);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_40);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _40 = (*_38);                    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _12 = Le(move _39, move _40);    // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_40);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_39);                // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_15);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_14);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_13);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+-         _7 = move _12;                   // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+-         StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+-         switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
++         switchInt(move _12) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  
+      bb6: {
+-         _16 = const false;               // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
++         _0 = const false;                // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb7: {
+-         StorageLive(_21);                // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+          StorageLive(_22);                // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+          _22 = &_4;                       // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
+          StorageLive(_23);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageLive(_24);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _24 = _6;                        // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _23 = &_24;                      // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          _41 = deref_copy (*_22);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _42 = deref_copy (*_23);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_43);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _43 = (*_41);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageLive(_44);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _44 = (*_42);                    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _21 = Le(move _43, move _44);    // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _0 = Le(move _43, move _44);     // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_44);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_43);                // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          StorageDead(_24);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_23);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_22);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+-         _16 = move _21;                  // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
+      }
+  
+      bb8: {
+-         StorageDead(_21);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+          StorageDead(_17);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+-         _0 = move _16;                   // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
+      }
+  }
+  
diff --git a/tests/mir-opt/slice_filter.variant_b-{closure#0}.CopyProp.diff b/tests/mir-opt/slice_filter.variant_b-{closure#0}.CopyProp.diff
new file mode 100644
index 00000000000..c3b8e7d2eba
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_b-{closure#0}.CopyProp.diff
@@ -0,0 +1,139 @@
+- // MIR for `variant_b::{closure#0}` before CopyProp
++ // MIR for `variant_b::{closure#0}` after CopyProp
+  
+  fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:12:25: 12:41], _2: &&(usize, usize, usize, usize)) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/slice_filter.rs:+0:42: +0:42
+      let _3: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+      let _4: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+      let _5: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+      let _6: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+      let mut _7: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:58
+      let mut _8: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:48
+      let mut _9: usize;                   // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:43
+      let mut _10: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:47: +0:48
+      let mut _11: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:58
+      let mut _12: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:53
+      let mut _13: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:57: +0:58
+      let mut _14: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:78
+      let mut _15: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:68
+      let mut _16: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:63
+      let mut _17: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:67: +0:68
+      let mut _18: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:78
+      let mut _19: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:73
+      let mut _20: usize;                  // in scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+      let mut _21: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _22: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _23: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _24: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      scope 1 {
+          debug a => _3;                   // in scope 1 at $DIR/slice_filter.rs:+0:29: +0:30
+          debug b => _4;                   // in scope 1 at $DIR/slice_filter.rs:+0:32: +0:33
+          debug c => _5;                   // in scope 1 at $DIR/slice_filter.rs:+0:35: +0:36
+          debug d => _6;                   // in scope 1 at $DIR/slice_filter.rs:+0:38: +0:39
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          _21 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          _3 = ((*_21).0: usize);          // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          StorageLive(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          _22 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          _4 = ((*_22).1: usize);          // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          StorageLive(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          _23 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          _5 = ((*_23).2: usize);          // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          StorageLive(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+          _24 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+          _6 = ((*_24).3: usize);          // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+          StorageLive(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+          StorageLive(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+-         StorageLive(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:43
+-         _9 = _3;                         // scope 1 at $DIR/slice_filter.rs:+0:42: +0:43
+-         StorageLive(_10);                // scope 1 at $DIR/slice_filter.rs:+0:47: +0:48
+-         _10 = _5;                        // scope 1 at $DIR/slice_filter.rs:+0:47: +0:48
+-         _8 = Le(move _9, move _10);      // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+-         StorageDead(_10);                // scope 1 at $DIR/slice_filter.rs:+0:47: +0:48
+-         StorageDead(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:47: +0:48
++         _8 = Le(_3, _5);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+          switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+      }
+  
+      bb1: {
+          _0 = const true;                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  
+      bb2: {
+          StorageLive(_14);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          StorageLive(_15);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+-         StorageLive(_16);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:63
+-         _16 = _5;                        // scope 1 at $DIR/slice_filter.rs:+0:62: +0:63
+-         StorageLive(_17);                // scope 1 at $DIR/slice_filter.rs:+0:67: +0:68
+-         _17 = _3;                        // scope 1 at $DIR/slice_filter.rs:+0:67: +0:68
+-         _15 = Le(move _16, move _17);    // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+-         StorageDead(_17);                // scope 1 at $DIR/slice_filter.rs:+0:67: +0:68
+-         StorageDead(_16);                // scope 1 at $DIR/slice_filter.rs:+0:67: +0:68
++         _15 = Le(_5, _3);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+          switchInt(move _15) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb3: {
+          StorageDead(_14);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+          StorageDead(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
+          return;                          // scope 0 at $DIR/slice_filter.rs:+0:78: +0:78
+      }
+  
+      bb4: {
+          _7 = const false;                // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+          StorageDead(_11);                // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          goto -> bb2;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+      }
+  
+      bb5: {
+          StorageLive(_11);                // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+-         StorageLive(_12);                // scope 1 at $DIR/slice_filter.rs:+0:52: +0:53
+-         _12 = _6;                        // scope 1 at $DIR/slice_filter.rs:+0:52: +0:53
+-         StorageLive(_13);                // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+-         _13 = _4;                        // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+-         _11 = Le(move _12, move _13);    // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+-         StorageDead(_13);                // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+-         StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
++         _11 = Le(_6, _4);                // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+          _7 = move _11;                   // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+          StorageDead(_11);                // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  
+      bb6: {
+          _14 = const false;               // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb7: {
+          StorageLive(_18);                // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+-         StorageLive(_19);                // scope 1 at $DIR/slice_filter.rs:+0:72: +0:73
+-         _19 = _4;                        // scope 1 at $DIR/slice_filter.rs:+0:72: +0:73
+-         StorageLive(_20);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         _20 = _6;                        // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         _18 = Le(move _19, move _20);    // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+-         StorageDead(_20);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_19);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
++         _18 = Le(_4, _6);                // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+          _14 = move _18;                  // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb8: {
+          StorageDead(_18);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+          StorageDead(_15);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+          _0 = move _14;                   // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  }
+  
diff --git a/tests/mir-opt/slice_filter.variant_b-{closure#0}.DestinationPropagation.diff b/tests/mir-opt/slice_filter.variant_b-{closure#0}.DestinationPropagation.diff
new file mode 100644
index 00000000000..a43e84d29c7
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_b-{closure#0}.DestinationPropagation.diff
@@ -0,0 +1,113 @@
+- // MIR for `variant_b::{closure#0}` before DestinationPropagation
++ // MIR for `variant_b::{closure#0}` after DestinationPropagation
+  
+  fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:12:25: 12:41], _2: &&(usize, usize, usize, usize)) -> bool {
+      let mut _0: bool;                    // return place in scope 0 at $DIR/slice_filter.rs:+0:42: +0:42
+      let _3: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+      let _4: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+      let _5: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+      let _6: usize;                       // in scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+      let mut _7: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:58
+      let mut _8: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:48
+      let mut _9: bool;                    // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:58
+      let mut _10: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:78
+      let mut _11: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:68
+      let mut _12: bool;                   // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:78
+      let mut _13: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _14: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _15: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      let mut _16: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
+      scope 1 {
+          debug a => _3;                   // in scope 1 at $DIR/slice_filter.rs:+0:29: +0:30
+          debug b => _4;                   // in scope 1 at $DIR/slice_filter.rs:+0:32: +0:33
+          debug c => _5;                   // in scope 1 at $DIR/slice_filter.rs:+0:35: +0:36
+          debug d => _6;                   // in scope 1 at $DIR/slice_filter.rs:+0:38: +0:39
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          _13 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          _3 = ((*_13).0: usize);          // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
+          StorageLive(_4);                 // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          _14 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          _4 = ((*_14).1: usize);          // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
+          StorageLive(_5);                 // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          _15 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          _5 = ((*_15).2: usize);          // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
+          StorageLive(_6);                 // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+          _16 = deref_copy (*_2);          // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+          _6 = ((*_16).3: usize);          // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
+-         StorageLive(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+          StorageLive(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+          _8 = Le(_3, _5);                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
+          switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+      }
+  
+      bb1: {
+          _0 = const true;                 // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  
+      bb2: {
+-         StorageLive(_10);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          StorageLive(_11);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+          _11 = Le(_5, _3);                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
+          switchInt(move _11) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb3: {
+-         StorageDead(_10);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         StorageDead(_7);                 // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+          return;                          // scope 0 at $DIR/slice_filter.rs:+0:78: +0:78
+      }
+  
+      bb4: {
+-         StorageDead(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          goto -> bb2;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+      }
+  
+      bb5: {
+-         StorageLive(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+          _9 = Le(_6, _4);                 // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
+-         _7 = move _9;                    // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
+-         StorageDead(_9);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+          StorageDead(_8);                 // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
+-         switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
++         switchInt(move _9) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  
+      bb6: {
+-         _10 = const false;               // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
++         _0 = const false;                // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb7: {
+-         StorageLive(_12);                // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+-         _12 = Le(_4, _6);                // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
+-         _10 = move _12;                  // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
++         _0 = Le(_4, _6);                 // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+          goto -> bb8;                     // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
+      }
+  
+      bb8: {
+-         StorageDead(_12);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+          StorageDead(_11);                // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
+-         _0 = move _10;                   // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+          goto -> bb3;                     // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
+      }
+  }
+  
diff --git a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
index b254bfeb7c9..7c67d2abcf7 100644
--- a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
+++ b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
@@ -5,11 +5,11 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
     let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
     let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
     let mut _3: isize;                   // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
-    let mut _4: T;                       // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
-    let mut _5: E;                       // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+    let _4: T;                           // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+    let _5: E;                           // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
     let mut _6: isize;                   // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
     let _7: T;                           // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
-    let mut _8: E;                       // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+    let _8: E;                           // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
     scope 1 {
         debug v => _4;                   // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
     }
@@ -30,6 +30,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb1: {
+        StorageLive(_5);                 // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
         _5 = move ((_1 as Err).0: E);    // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
         Deinit(_2);                      // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
         ((_2 as Break).0: E) = move _5;  // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
@@ -39,6 +40,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb2: {
+        StorageLive(_4);                 // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
         _4 = move ((_1 as Ok).0: T);     // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
         Deinit(_2);                      // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
         ((_2 as Continue).0: T) = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
@@ -48,6 +50,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb3: {
+        StorageLive(_8);                 // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
         _8 = move ((_2 as Break).0: E);  // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
         Deinit(_0);                      // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
         ((_0 as Err).0: E) = move _8;    // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
@@ -61,6 +64,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb5: {
+        StorageLive(_7);                 // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
         _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
         Deinit(_0);                      // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
         ((_0 as Ok).0: T) = move _7;     // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
diff --git a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
index cdbc0681cb8..4a838e14026 100644
--- a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
+++ b/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
@@ -5,7 +5,7 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
     let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
     let mut _2: isize;                   // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
     let _3: T;                           // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
-    let mut _4: E;                       // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+    let _4: E;                           // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
     scope 1 {
         debug v => _3;                   // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
     }
@@ -19,6 +19,7 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb1: {
+        StorageLive(_4);                 // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
         _4 = move ((_1 as Err).0: E);    // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
         Deinit(_0);                      // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
         ((_0 as Err).0: E) = move _4;    // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
@@ -31,6 +32,7 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb3: {
+        StorageLive(_3);                 // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
         _3 = move ((_1 as Ok).0: T);     // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
         Deinit(_0);                      // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
         ((_0 as Ok).0: T) = move _3;     // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
diff --git a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir
index b95d91b13dd..318119bd477 100644
--- a/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -4,9 +4,7 @@ fn while_loop(_1: bool) -> () {
     debug c => _1;                       // in scope 0 at $DIR/while_storage.rs:+0:15: +0:16
     let mut _0: ();                      // return place in scope 0 at $DIR/while_storage.rs:+0:24: +0:24
     let mut _2: bool;                    // in scope 0 at $DIR/while_storage.rs:+1:11: +1:22
-    let mut _3: bool;                    // in scope 0 at $DIR/while_storage.rs:+1:20: +1:21
-    let mut _4: bool;                    // in scope 0 at $DIR/while_storage.rs:+2:12: +2:23
-    let mut _5: bool;                    // in scope 0 at $DIR/while_storage.rs:+2:21: +2:22
+    let mut _3: bool;                    // in scope 0 at $DIR/while_storage.rs:+2:12: +2:23
 
     bb0: {
         goto -> bb1;                     // scope 0 at $DIR/while_storage.rs:+1:5: +5:6
@@ -14,41 +12,35 @@ fn while_loop(_1: bool) -> () {
 
     bb1: {
         StorageLive(_2);                 // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
-        StorageLive(_3);                 // scope 0 at $DIR/while_storage.rs:+1:20: +1:21
-        _3 = _1;                         // scope 0 at $DIR/while_storage.rs:+1:20: +1:21
-        _2 = get_bool(move _3) -> bb2;   // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
+        _2 = get_bool(_1) -> bb2;        // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
                                          // mir::Constant
                                          // + span: $DIR/while_storage.rs:10:11: 10:19
                                          // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
     }
 
     bb2: {
-        StorageDead(_3);                 // scope 0 at $DIR/while_storage.rs:+1:21: +1:22
         switchInt(move _2) -> [0: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
     }
 
     bb3: {
-        StorageLive(_4);                 // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
-        StorageLive(_5);                 // scope 0 at $DIR/while_storage.rs:+2:21: +2:22
-        _5 = _1;                         // scope 0 at $DIR/while_storage.rs:+2:21: +2:22
-        _4 = get_bool(move _5) -> bb4;   // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
+        StorageLive(_3);                 // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
+        _3 = get_bool(_1) -> bb4;        // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
                                          // mir::Constant
                                          // + span: $DIR/while_storage.rs:11:12: 11:20
                                          // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
     }
 
     bb4: {
-        StorageDead(_5);                 // scope 0 at $DIR/while_storage.rs:+2:22: +2:23
-        switchInt(move _4) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
+        switchInt(move _3) -> [0: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
     }
 
     bb5: {
-        StorageDead(_4);                 // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
+        StorageDead(_3);                 // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
         goto -> bb7;                     // scope 0 at no-location
     }
 
     bb6: {
-        StorageDead(_4);                 // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
+        StorageDead(_3);                 // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
         StorageDead(_2);                 // scope 0 at $DIR/while_storage.rs:+5:5: +5:6
         goto -> bb1;                     // scope 0 at $DIR/while_storage.rs:+1:5: +5:6
     }