about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-05-09 21:54:34 +0000
committerbors <bors@rust-lang.org>2023-05-09 21:54:34 +0000
commit50dff955a9367a4efc72b831549e368992807beb (patch)
tree0d973073cd55b4edb93eba8fe93059950a456c0f /tests
parent2f6bc5d259e7ab25ddfdd33de53b892770218918 (diff)
parentbde213cfe5490d67717fc022b04f03a57e5daa7f (diff)
downloadrust-50dff955a9367a4efc72b831549e368992807beb.tar.gz
rust-50dff955a9367a4efc72b831549e368992807beb.zip
Auto merge of #106285 - cjgillot:refprop-ssa, r=JakobDegen
Implement SSA-based reference propagation

Rust has a tendency to create a lot of short-lived borrows, in particular for method calls. This PR aims to remove those short-lived borrows with a const-propagation dedicated to pointers to local places.

This pass aims to transform the following pattern:
```
  _1 = &raw? mut? PLACE;
  _3 = *_1;
  _4 = &raw? mut? *_1;
```

Into
```
  _1 = &raw? mut? PLACE;
  _3 = PLACE;
  _4 = &raw? mut? PLACE;
```

where `PLACE` is a direct or an indirect place expression.

By removing indirection, this pass should help both dest-prop and const-prop to handle more cases.
This optimization is distinct from const-prop and dataflow const-prop since the borrow-reborrow patterns needs to preserve borrowck invariants, especially the uniqueness property of mutable references.

The pointed-to places are computed using a SSA analysis. We suppose that removable borrows are typically temporaries from autoref, so they are by construction assigned only once, and a SSA analysis is enough to catch them. For each local, we store both where and how it is used, in order to efficiently compute the all-or-nothing property. Thanks to `Derefer`, we only have to track locals, not places in general.

---

There are 3 properties that need to be upheld for this transformation to be legal:
- place constness: `PLACE` must refer to the same memory wherever it appears;
- pointer liveness: we must not introduce dereferences of dangling pointers;
- `&mut` borrow uniqueness.

## Constness

If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where:
- `LOCAL` is SSA;
- all projections in `PROJECTIONS` are constant (no dereference and no indexing).

If `PLACE` is a direct projection of a local, we consider it as constant if:
- the local is always live, or it has a single `StorageLive` that dominates all uses;
- all projections are constant.

# Liveness

When performing a substitution, we must take care not to introduce uses of dangling locals.

Using a dangling borrow is UB. Therefore, we assume that for any use of `*x`, where `x` is a borrow, the pointed-to memory is live.

Limitations:
- occurrences of `*x` in an `&raw mut? *x` are accepted;
- raw pointers are allowed to be dangling.

In those 2 case, we do not substitute anything, to be on the safe side.

**Open question:** we do not differentiate borrows of ZST and non-ZST. The UB rules may be
different depending on the layout. Having a different treatment would effectively prevent this
pass from running on polymorphic MIR, which defeats the purpose of MIR opts.

## Uniqueness

For `&mut` borrows, we also need to preserve the uniqueness property:
we must avoid creating a state where we interleave uses of `*_1` and `_2`.
To do it, we only perform full substitution of mutable borrows:
we replace either all or none of the occurrences of `*_1`.

Some care has to be taken when `_1` is copied in other locals.
```
   _1 = &raw? mut? _2;
   _3 = *_1;
   _4 = _1
   _5 = *_4
```
In such cases, fully substituting `_1` means fully substituting all of the copies.

For immutable borrows, we do not need to preserve such uniqueness property,
so we perform all the possible substitutions without removing the `_1 = &_2` statement.
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff3
-rw-r--r--tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff38
-rw-r--r--tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff56
-rw-r--r--tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff27
-rw-r--r--tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff24
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff375
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff431
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff372
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff378
-rw-r--r--tests/mir-opt/reference_prop.rs456
-rw-r--r--tests/mir-opt/slice_filter.rs2
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff16
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff104
-rw-r--r--tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff247
-rw-r--r--tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff103
15 files changed, 2586 insertions, 46 deletions
diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
index 2a0bff57db9..51707e71661 100644
--- a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
+++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff
@@ -20,8 +20,7 @@
       }
   
       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
+          _0 = opaque::<u8>(_3) -> bb2;    // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
                                            // mir::Constant
                                            // + span: $DIR/borrowed_local.rs:28:28: 28:34
                                            // + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }
diff --git a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
new file mode 100644
index 00000000000..8edc83cbf67
--- /dev/null
+++ b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff
@@ -0,0 +1,38 @@
+- // MIR for `dominate_storage` before ReferencePropagation
++ // MIR for `dominate_storage` after ReferencePropagation
+  
+  fn dominate_storage() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
+      let mut _1: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _2: &i32;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _4: bool;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _5: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _6: bool;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          goto -> bb1;                     // scope 0 at $DIR/reference_prop.rs:+8:11: +8:20
+      }
+  
+      bb1: {
+          _1 = const 5_i32;                // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
+          _2 = &_1;                        // scope 0 at $DIR/reference_prop.rs:+11:13: +11:19
+          goto -> bb2;                     // scope 0 at $DIR/reference_prop.rs:+12:13: +12:22
+      }
+  
+      bb2: {
+          _5 = (*_2);                      // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _0 = opaque::<i32>(_5) -> bb3;   // scope 0 at $DIR/reference_prop.rs:+16:13: +16:38
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:383:28: 383:34
+                                           // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          StorageDead(_1);                 // scope 0 at $DIR/reference_prop.rs:+19:13: +19:27
+          StorageLive(_1);                 // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
+          _6 = const true;                 // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          switchInt(_6) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:47
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
new file mode 100644
index 00000000000..920755bdd1d
--- /dev/null
+++ b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff
@@ -0,0 +1,56 @@
+- // MIR for `maybe_dead` before ReferencePropagation
++ // MIR for `maybe_dead` after ReferencePropagation
+  
+  fn maybe_dead(_1: bool) -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:24: +0:24
+      let mut _2: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _4: &i32;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _5: &mut i32;                // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _6: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _7: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _8: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/reference_prop.rs:+7:13: +7:27
+          StorageLive(_3);                 // scope 0 at $DIR/reference_prop.rs:+8:13: +8:27
+          _2 = const 5_i32;                // scope 0 at $DIR/reference_prop.rs:+9:13: +9:18
+          _3 = const 5_i32;                // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
+          _4 = &_2;                        // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _5 = &mut _3;                    // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          (*_5) = const 7_i32;             // scope 0 at $DIR/reference_prop.rs:+14:13: +14:19
+-         _6 = (*_4);                      // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
++         _6 = _2;                         // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          switchInt(_1) -> [1: bb1, otherwise: bb2]; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:46
+      }
+  
+      bb1: {
+          StorageDead(_2);                 // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
+          StorageDead(_3);                 // scope 0 at $DIR/reference_prop.rs:+21:13: +21:27
+          _0 = opaque::<i32>(_6) -> bb2;   // scope 0 at $DIR/reference_prop.rs:+22:13: +22:38
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:417:28: 417:34
+                                           // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          _7 = (*_4);                      // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _0 = opaque::<i32>(_7) -> bb3;   // scope 0 at $DIR/reference_prop.rs:+27:13: +27:38
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:422:28: 422:34
+                                           // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          _8 = (*_5);                      // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _0 = opaque::<i32>(_8) -> bb4;   // scope 0 at $DIR/reference_prop.rs:+33:13: +33:43
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:428:33: 428:39
+                                           // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb4: {
+          return;                          // scope 0 at $DIR/reference_prop.rs:+36:13: +36:21
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
new file mode 100644
index 00000000000..07bfdf0b2f1
--- /dev/null
+++ b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff
@@ -0,0 +1,27 @@
+- // MIR for `multiple_storage` before ReferencePropagation
++ // MIR for `multiple_storage` after ReferencePropagation
+  
+  fn multiple_storage() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
+      let mut _1: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _2: &i32;                    // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: i32;                     // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/reference_prop.rs:+6:13: +6:27
+          _1 = const 5_i32;                // scope 0 at $DIR/reference_prop.rs:+7:13: +7:18
+          _2 = &_1;                        // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          StorageDead(_1);                 // scope 0 at $DIR/reference_prop.rs:+9:13: +9:27
+          StorageLive(_1);                 // scope 0 at $DIR/reference_prop.rs:+10:13: +10:27
+          _3 = (*_2);                      // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+          _0 = opaque::<i32>(_3) -> bb1;   // scope 0 at $DIR/reference_prop.rs:+14:13: +14:43
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:357:33: 357:39
+                                           // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          return;                          // scope 0 at $DIR/reference_prop.rs:+18:13: +18:21
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff
new file mode 100644
index 00000000000..a7d505c6906
--- /dev/null
+++ b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff
@@ -0,0 +1,24 @@
+- // MIR for `read_through_raw` before ReferencePropagation
++ // MIR for `read_through_raw` after ReferencePropagation
+  
+  fn read_through_raw(_1: &mut usize) -> usize {
+      let mut _0: usize;                   // return place in scope 0 at $DIR/reference_prop.rs:+0:39: +0:44
+      let mut _2: &mut usize;              // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _3: &mut usize;              // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _4: *mut usize;              // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+      let mut _5: *mut usize;              // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+  
+      bb0: {
+          _2 = &mut (*_1);                 // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25
+-         _3 = &mut (*_2);                 // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
+-         _4 = &raw mut (*_2);             // scope 0 at $DIR/reference_prop.rs:+12:13: +12:30
+-         _5 = &raw mut (*_3);             // scope 0 at $DIR/reference_prop.rs:+13:13: +13:30
+-         _0 = (*_4);                      // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
+-         _0 = (*_5);                      // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
++         _3 = &mut (*_1);                 // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
++         _0 = (*_2);                      // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
++         _0 = (*_3);                      // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
+          return;                          // scope 0 at $DIR/reference_prop.rs:+17:13: +17:21
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
new file mode 100644
index 00000000000..e41fc28461a
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff
@@ -0,0 +1,375 @@
+- // MIR for `reference_propagation` before ReferencePropagation
++ // MIR for `reference_propagation` after ReferencePropagation
+  
+  fn reference_propagation(_1: &T, _2: &T) -> () {
+      debug single => _1;                  // in scope 0 at $DIR/reference_prop.rs:+0:39: +0:45
+      debug multiple => _2;                // in scope 0 at $DIR/reference_prop.rs:+0:54: +0:66
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:75: +0:75
+      let _3: ();                          // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+      let _4: usize;                       // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
+      let _7: ();                          // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+      let mut _8: ();                      // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+      let _9: ();                          // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+      let _10: usize;                      // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
+      let mut _13: &usize;                 // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
+      let _14: &usize;                     // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
+      let _16: ();                         // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+      let mut _17: ();                     // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+      let _18: ();                         // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+      let _19: usize;                      // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
+      let _23: ();                         // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
+      let mut _24: ();                     // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
+      let _25: ();                         // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+      let _26: usize;                      // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
+      let _30: ();                         // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
+      let mut _31: ();                     // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
+      let _32: ();                         // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+      let _33: usize;                      // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
+      let _36: ();                         // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+      let mut _37: &usize;                 // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+      let _38: ();                         // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+      let _39: usize;                      // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
+      let _45: ();                         // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+      let mut _46: &usize;                 // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+      let _47: ();                         // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+      let _48: &T;                         // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+      let _50: ();                         // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+      let mut _51: ();                     // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+      let _52: &T;                         // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+      let mut _53: &T;                     // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
+      let _54: &T;                         // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
+      let _56: ();                         // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+      let mut _57: ();                     // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+      scope 1 {
+          debug a => _4;                   // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+          let _5: &usize;                  // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+          scope 2 {
+              debug b => _5;               // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+              let _6: usize;               // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+              scope 3 {
+                  debug c => _6;           // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+              }
+          }
+      }
+      scope 4 {
+          debug a => _10;                  // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:14
+          let _11: usize;                  // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
+          scope 5 {
+              debug a2 => _11;             // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:15
+              let mut _12: &usize;         // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+              scope 6 {
+                  debug b => _12;          // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
+                  let _15: usize;          // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+                  scope 7 {
+                      debug c => _15;      // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
+                  }
+              }
+          }
+      }
+      scope 8 {
+          debug a => _19;                  // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:14
+          let _20: &usize;                 // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+          scope 9 {
+              debug b => _20;              // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
+              let _21: &&usize;            // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+              scope 10 {
+                  debug d => _21;          // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
+                  let _22: usize;          // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+                  scope 11 {
+                      debug c => _22;      // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
+                  }
+              }
+          }
+      }
+      scope 12 {
+          debug a => _26;                  // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:14
+          let mut _27: &usize;             // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+          scope 13 {
+              debug b => _27;              // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
+              let _28: &mut &usize;        // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+              scope 14 {
+                  debug d => _28;          // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
+                  let _29: usize;          // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+                  scope 15 {
+                      debug c => _29;      // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
+                  }
+              }
+          }
+      }
+      scope 16 {
+          debug a => _33;                  // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:14
+          let _34: &usize;                 // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+          scope 17 {
+              debug b => _34;              // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
+              let _35: usize;              // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+              scope 18 {
+                  debug c => _35;          // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
+              }
+          }
+      }
+      scope 19 {
+          debug a => _39;                  // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:14
+          let _40: &usize;                 // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+          scope 20 {
+              debug b1 => _40;             // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
+              let _41: usize;              // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+              scope 21 {
+                  debug c => _41;          // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
+                  let _42: &usize;         // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+                  scope 22 {
+                      debug b2 => _42;     // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
+                      let _43: usize;      // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+                      scope 23 {
+                          debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
+                          let _44: &usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+                          scope 24 {
+                              debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
+                          }
+                      }
+                  }
+              }
+          }
+      }
+      scope 25 {
+          debug a => _48;                  // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
+          let _49: T;                      // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+          scope 26 {
+              debug b => _49;              // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
+          }
+      }
+      scope 27 {
+          debug a => _52;                  // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
+          let _55: T;                      // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+          scope 28 {
+              debug b => _55;              // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);                 // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageLive(_4);                 // scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
+          _4 = const 5_usize;              // scope 0 at $DIR/reference_prop.rs:+3:17: +3:24
+          StorageLive(_5);                 // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+          _5 = &_4;                        // scope 1 at $DIR/reference_prop.rs:+4:17: +4:19
+          StorageLive(_6);                 // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+-         _6 = (*_5);                      // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
++         _6 = _4;                         // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+          StorageLive(_7);                 // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+          StorageLive(_8);                 // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+          _8 = ();                         // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+          _7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:16:9: 16:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_8);                 // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
+          StorageDead(_7);                 // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
+-         _3 = const ();                   // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageDead(_6);                 // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_5);                 // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_4);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageDead(_3);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageLive(_9);                 // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageLive(_10);                // scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
+          _10 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+11:17: +11:24
+          StorageLive(_11);                // scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
+          _11 = const 7_usize;             // scope 4 at $DIR/reference_prop.rs:+12:18: +12:25
+          StorageLive(_12);                // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+          _12 = &_10;                      // scope 5 at $DIR/reference_prop.rs:+13:21: +13:23
+          StorageLive(_13);                // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+-         StorageLive(_14);                // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+-         _14 = &_11;                      // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+-         _13 = &(*_14);                   // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
++         _13 = &_11;                      // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+          _12 = move _13;                  // scope 6 at $DIR/reference_prop.rs:+14:9: +14:16
+          StorageDead(_13);                // scope 6 at $DIR/reference_prop.rs:+14:15: +14:16
+-         StorageDead(_14);                // scope 6 at $DIR/reference_prop.rs:+14:16: +14:17
+          StorageLive(_15);                // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+          _15 = (*_12);                    // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
+          StorageLive(_16);                // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+          StorageLive(_17);                // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+          _17 = ();                        // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+          _16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:27:9: 27:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_17);                // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
+          StorageDead(_16);                // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
+-         _9 = const ();                   // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageDead(_15);                // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_12);                // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_11);                // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_10);                // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageDead(_9);                 // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageLive(_18);                // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageLive(_19);                // scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
+          _19 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+22:17: +22:24
+          StorageLive(_20);                // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+          _20 = &_19;                      // scope 8 at $DIR/reference_prop.rs:+23:17: +23:19
+          StorageLive(_21);                // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+          _21 = &_20;                      // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
+          StorageLive(_22);                // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+          _22 = (*_20);                    // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
+          StorageLive(_23);                // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
+          StorageLive(_24);                // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
+          _24 = ();                        // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
+          _23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:36:9: 36:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          StorageDead(_24);                // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
+          StorageDead(_23);                // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20
+-         _18 = const ();                  // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageDead(_22);                // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_21);                // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_20);                // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_19);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageDead(_18);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageLive(_25);                // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageLive(_26);                // scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
+          _26 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+31:17: +31:24
+          StorageLive(_27);                // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+          _27 = &_26;                      // scope 12 at $DIR/reference_prop.rs:+32:21: +32:23
+          StorageLive(_28);                // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+          _28 = &mut _27;                  // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23
+          StorageLive(_29);                // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+          _29 = (*_27);                    // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
+          StorageLive(_30);                // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
+          StorageLive(_31);                // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
+          _31 = ();                        // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
+          _30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:45:9: 45:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb4: {
+          StorageDead(_31);                // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
+          StorageDead(_30);                // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20
+-         _25 = const ();                  // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageDead(_29);                // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_28);                // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_27);                // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_26);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageDead(_25);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageLive(_32);                // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageLive(_33);                // scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
+          _33 = const 7_usize;             // scope 0 at $DIR/reference_prop.rs:+40:17: +40:24
+          StorageLive(_34);                // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+          _34 = &_33;                      // scope 16 at $DIR/reference_prop.rs:+41:17: +41:19
+          StorageLive(_35);                // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+-         _35 = (*_34);                    // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
++         _35 = _33;                       // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
+          StorageLive(_36);                // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+          StorageLive(_37);                // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+          _37 = _34;                       // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+          _36 = opaque::<&usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:53:9: 53:15
+                                           // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
+      }
+  
+      bb5: {
+          StorageDead(_37);                // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
+          StorageDead(_36);                // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
+-         _32 = const ();                  // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageDead(_35);                // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_34);                // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_33);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageDead(_32);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageLive(_38);                // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageLive(_39);                // scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
+          _39 = const 7_usize;             // scope 0 at $DIR/reference_prop.rs:+48:17: +48:24
+          StorageLive(_40);                // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+          _40 = &_39;                      // scope 19 at $DIR/reference_prop.rs:+49:18: +49:20
+          StorageLive(_41);                // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+-         _41 = (*_40);                    // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
++         _41 = _39;                       // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
+          StorageLive(_42);                // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+          _42 = _40;                       // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
+          StorageLive(_43);                // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+-         _43 = (*_42);                    // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
++         _43 = _39;                       // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
+          StorageLive(_44);                // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+          _44 = _42;                       // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
+          StorageLive(_45);                // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+          StorageLive(_46);                // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+          _46 = _44;                       // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+          _45 = opaque::<&usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:66:9: 66:15
+                                           // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
+      }
+  
+      bb6: {
+          StorageDead(_46);                // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
+          StorageDead(_45);                // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
+-         _38 = const ();                  // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageDead(_44);                // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_43);                // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_42);                // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_41);                // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_40);                // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_39);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageDead(_38);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageLive(_47);                // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageLive(_48);                // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+          _48 = &(*_1);                    // scope 0 at $DIR/reference_prop.rs:+61:17: +61:25
+          StorageLive(_49);                // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+-         _49 = (*_48);                    // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
++         _49 = (*_1);                     // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+          StorageLive(_50);                // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+          StorageLive(_51);                // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+          _51 = ();                        // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+          _50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:73:9: 73:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb7: {
+          StorageDead(_51);                // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
+          StorageDead(_50);                // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
+-         _47 = const ();                  // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageDead(_49);                // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageDead(_48);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+-         StorageDead(_47);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageLive(_52);                // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+          _52 = &(*_2);                    // scope 0 at $DIR/reference_prop.rs:+68:17: +68:27
+          StorageLive(_53);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+-         StorageLive(_54);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+-         _54 = &(*_1);                    // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+-         _53 = &(*_54);                   // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
++         _53 = &(*_1);                    // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+          _2 = move _53;                   // scope 27 at $DIR/reference_prop.rs:+69:9: +69:28
+          StorageDead(_53);                // scope 27 at $DIR/reference_prop.rs:+69:27: +69:28
+-         StorageDead(_54);                // scope 27 at $DIR/reference_prop.rs:+69:28: +69:29
+          StorageLive(_55);                // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+          _55 = (*_52);                    // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
+          StorageLive(_56);                // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+          StorageLive(_57);                // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+          _57 = ();                        // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+          _56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:81:9: 81:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb8: {
+          StorageDead(_57);                // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
+          StorageDead(_56);                // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
+          _0 = const ();                   // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+          StorageDead(_55);                // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
+          StorageDead(_52);                // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+          return;                          // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
new file mode 100644
index 00000000000..712727915d0
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
@@ -0,0 +1,431 @@
+- // MIR for `reference_propagation_const_ptr` before ReferencePropagation
++ // MIR for `reference_propagation_const_ptr` after ReferencePropagation
+  
+  fn reference_propagation_const_ptr(_1: *const T, _2: *const T) -> () {
+      debug single => _1;                  // in scope 0 at $DIR/reference_prop.rs:+0:45: +0:51
+      debug multiple => _2;                // in scope 0 at $DIR/reference_prop.rs:+0:63: +0:75
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
+      let _3: ();                          // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+      let _7: ();                          // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+      let mut _8: ();                      // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+      let _9: ();                          // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+      let mut _13: *const usize;           // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:26
+      let _15: ();                         // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+      let mut _16: ();                     // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+      let _17: ();                         // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+      let _22: ();                         // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
+      let mut _23: ();                     // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
+      let _24: ();                         // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+      let _29: ();                         // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
+      let mut _30: ();                     // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
+      let _31: ();                         // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+      let _35: ();                         // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+      let mut _36: *const usize;           // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+      let _37: ();                         // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+      let _44: ();                         // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+      let mut _45: *const usize;           // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+      let _46: ();                         // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+      let _49: ();                         // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+      let mut _50: ();                     // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+      let _51: ();                         // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+      let mut _53: *const T;               // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:38
+      let _55: ();                         // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+      let mut _56: ();                     // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+      let _61: ();                         // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
+      let mut _62: ();                     // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
+      scope 1 {
+          let _4: usize;                   // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+          scope 2 {
+              debug a => _4;               // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
+              let _5: *const usize;        // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+              scope 3 {
+                  debug b => _5;           // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
+                  let _6: usize;           // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+                  scope 4 {
+                      debug c => _6;       // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
+                  }
+              }
+          }
+      }
+      scope 5 {
+          let _10: usize;                  // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
+          scope 6 {
+              debug a => _10;              // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:14
+              let _11: usize;              // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
+              scope 7 {
+                  debug a2 => _11;         // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:15
+                  let mut _12: *const usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+                  scope 8 {
+                      debug b => _12;      // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
+                      let _14: usize;      // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+                      scope 9 {
+                          debug c => _14;  // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 10 {
+          let _18: usize;                  // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
+          scope 11 {
+              debug a => _18;              // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:14
+              let _19: *const usize;       // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+              scope 12 {
+                  debug b => _19;          // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
+                  let _20: &*const usize;  // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+                  scope 13 {
+                      debug d => _20;      // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
+                      let _21: usize;      // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+                      scope 14 {
+                          debug c => _21;  // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 15 {
+          let _25: usize;                  // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
+          scope 16 {
+              debug a => _25;              // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:14
+              let mut _26: *const usize;   // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+              scope 17 {
+                  debug b => _26;          // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
+                  let _27: &mut *const usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+                  scope 18 {
+                      debug d => _27;      // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
+                      let _28: usize;      // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+                      scope 19 {
+                          debug c => _28;  // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 20 {
+          let _32: usize;                  // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
+          scope 21 {
+              debug a => _32;              // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:14
+              let _33: *const usize;       // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+              scope 22 {
+                  debug b => _33;          // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
+                  let _34: usize;          // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+                  scope 23 {
+                      debug c => _34;      // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
+                  }
+              }
+          }
+      }
+      scope 24 {
+          let _38: usize;                  // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
+          scope 25 {
+              debug a => _38;              // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:14
+              let _39: *const usize;       // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+              scope 26 {
+                  debug b1 => _39;         // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
+                  let _40: usize;          // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+                  scope 27 {
+                      debug c => _40;      // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
+                      let _41: *const usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+                      scope 28 {
+                          debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
+                          let _42: usize;  // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+                          scope 29 {
+                              debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
+                              let _43: *const usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+                              scope 30 {
+                                  debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
+                              }
+                          }
+                      }
+                  }
+              }
+          }
+      }
+      scope 31 {
+          let _47: *const T;               // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+          scope 32 {
+              debug a => _47;              // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
+              let _48: T;                  // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+              scope 33 {
+                  debug b => _48;          // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
+              }
+          }
+      }
+      scope 34 {
+          let _52: *const T;               // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+          scope 35 {
+              debug a => _52;              // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
+              let _54: T;                  // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+              scope 36 {
+                  debug b => _54;          // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
+              }
+          }
+      }
+      scope 37 {
+          let _57: usize;                  // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
+          scope 38 {
+              debug a => _57;              // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:14
+              let _58: *const usize;       // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+              scope 39 {
+                  debug b => _58;          // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
+                  let _59: *const usize;   // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+                  scope 40 {
+                      debug c => _59;      // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
+                      let _60: usize;      // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+                      scope 41 {
+                          debug e => _60;  // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);                 // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageLive(_4);                 // scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
+          _4 = const 5_usize;              // scope 1 at $DIR/reference_prop.rs:+3:17: +3:24
+          StorageLive(_5);                 // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+          _5 = &raw const _4;              // scope 2 at $DIR/reference_prop.rs:+4:17: +4:29
+          StorageLive(_6);                 // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+-         _6 = (*_5);                      // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
++         _6 = _4;                         // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+          StorageLive(_7);                 // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+          StorageLive(_8);                 // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+          _8 = ();                         // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+          _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:166:9: 166:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_8);                 // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
+          StorageDead(_7);                 // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
+-         _3 = const ();                   // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageDead(_6);                 // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_5);                 // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_4);                 // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageDead(_3);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageLive(_9);                 // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageLive(_10);                // scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
+          _10 = const 5_usize;             // scope 5 at $DIR/reference_prop.rs:+11:17: +11:24
+          StorageLive(_11);                // scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
+          _11 = const 7_usize;             // scope 6 at $DIR/reference_prop.rs:+12:18: +12:25
+          StorageLive(_12);                // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+          _12 = &raw const _10;            // scope 7 at $DIR/reference_prop.rs:+13:21: +13:33
+          StorageLive(_13);                // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
+          _13 = &raw const _11;            // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
+          _12 = move _13;                  // scope 8 at $DIR/reference_prop.rs:+14:9: +14:26
+          StorageDead(_13);                // scope 8 at $DIR/reference_prop.rs:+14:25: +14:26
+          StorageLive(_14);                // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+          _14 = (*_12);                    // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
+          StorageLive(_15);                // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+          StorageLive(_16);                // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+          _16 = ();                        // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+          _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:177:9: 177:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_16);                // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
+          StorageDead(_15);                // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
+-         _9 = const ();                   // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageDead(_14);                // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_12);                // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_11);                // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_10);                // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageDead(_9);                 // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageLive(_17);                // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageLive(_18);                // scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
+          _18 = const 5_usize;             // scope 10 at $DIR/reference_prop.rs:+22:17: +22:24
+          StorageLive(_19);                // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+          _19 = &raw const _18;            // scope 11 at $DIR/reference_prop.rs:+23:17: +23:29
+          StorageLive(_20);                // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+          _20 = &_19;                      // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
+          StorageLive(_21);                // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+          _21 = (*_19);                    // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
+          StorageLive(_22);                // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
+          StorageLive(_23);                // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
+          _23 = ();                        // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
+          _22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:186:9: 186:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          StorageDead(_23);                // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
+          StorageDead(_22);                // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20
+-         _17 = const ();                  // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageDead(_21);                // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_20);                // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_19);                // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_18);                // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageDead(_17);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageLive(_24);                // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageLive(_25);                // scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
+          _25 = const 5_usize;             // scope 15 at $DIR/reference_prop.rs:+31:17: +31:24
+          StorageLive(_26);                // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+          _26 = &raw const _25;            // scope 16 at $DIR/reference_prop.rs:+32:21: +32:33
+          StorageLive(_27);                // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+          _27 = &mut _26;                  // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23
+          StorageLive(_28);                // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+          _28 = (*_26);                    // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
+          StorageLive(_29);                // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
+          StorageLive(_30);                // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
+          _30 = ();                        // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
+          _29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:195:9: 195:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb4: {
+          StorageDead(_30);                // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
+          StorageDead(_29);                // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20
+-         _24 = const ();                  // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageDead(_28);                // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_27);                // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_26);                // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_25);                // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageDead(_24);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageLive(_31);                // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageLive(_32);                // scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
+          _32 = const 7_usize;             // scope 20 at $DIR/reference_prop.rs:+40:17: +40:24
+          StorageLive(_33);                // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+          _33 = &raw const _32;            // scope 21 at $DIR/reference_prop.rs:+41:17: +41:29
+          StorageLive(_34);                // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+-         _34 = (*_33);                    // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
++         _34 = _32;                       // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
+          StorageLive(_35);                // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+          StorageLive(_36);                // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+          _36 = _33;                       // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+          _35 = opaque::<*const usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:203:9: 203:15
+                                           // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
+      }
+  
+      bb5: {
+          StorageDead(_36);                // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
+          StorageDead(_35);                // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
+-         _31 = const ();                  // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageDead(_34);                // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_33);                // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_32);                // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageDead(_31);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageLive(_37);                // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageLive(_38);                // scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
+          _38 = const 7_usize;             // scope 24 at $DIR/reference_prop.rs:+48:17: +48:24
+          StorageLive(_39);                // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+          _39 = &raw const _38;            // scope 25 at $DIR/reference_prop.rs:+49:18: +49:30
+          StorageLive(_40);                // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+-         _40 = (*_39);                    // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
++         _40 = _38;                       // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
+          StorageLive(_41);                // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+          _41 = _39;                       // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
+          StorageLive(_42);                // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+-         _42 = (*_41);                    // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
++         _42 = _38;                       // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
+          StorageLive(_43);                // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+          _43 = _41;                       // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
+          StorageLive(_44);                // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+          StorageLive(_45);                // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+          _45 = _43;                       // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+          _44 = opaque::<*const usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:216:9: 216:15
+                                           // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
+      }
+  
+      bb6: {
+          StorageDead(_45);                // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
+          StorageDead(_44);                // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
+-         _37 = const ();                  // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageDead(_43);                // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_42);                // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_41);                // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_40);                // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_39);                // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_38);                // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageDead(_37);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageLive(_46);                // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageLive(_47);                // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+          _47 = &raw const (*_1);          // scope 31 at $DIR/reference_prop.rs:+61:17: +61:35
+          StorageLive(_48);                // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+-         _48 = (*_47);                    // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
++         _48 = (*_1);                     // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+          StorageLive(_49);                // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+          StorageLive(_50);                // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+          _50 = ();                        // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+          _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:223:9: 223:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb7: {
+          StorageDead(_50);                // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
+          StorageDead(_49);                // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
+-         _46 = const ();                  // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageDead(_48);                // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageDead(_47);                // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
+-         StorageDead(_46);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+-         StorageLive(_51);                // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+          StorageLive(_52);                // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+          _52 = &raw const (*_2);          // scope 34 at $DIR/reference_prop.rs:+68:17: +68:37
+          StorageLive(_53);                // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
+          _53 = &raw const (*_1);          // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
+          _2 = move _53;                   // scope 35 at $DIR/reference_prop.rs:+69:9: +69:38
+          StorageDead(_53);                // scope 35 at $DIR/reference_prop.rs:+69:37: +69:38
+          StorageLive(_54);                // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+          _54 = (*_52);                    // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
+          StorageLive(_55);                // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+          StorageLive(_56);                // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+          _56 = ();                        // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+          _55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:231:9: 231:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb8: {
+          StorageDead(_56);                // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
+          StorageDead(_55);                // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
+-         _51 = const ();                  // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
+          StorageDead(_54);                // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
+          StorageDead(_52);                // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
+-         StorageDead(_51);                // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+          StorageLive(_57);                // scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
+          _57 = const 13_usize;            // scope 37 at $DIR/reference_prop.rs:+76:17: +76:25
+          StorageLive(_58);                // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
+          _58 = &raw const _57;            // scope 38 at $DIR/reference_prop.rs:+77:17: +77:29
+          StorageLive(_59);                // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
+-         _59 = &raw const (*_58);         // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30
++         _59 = &raw const _57;            // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30
+          StorageLive(_60);                // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
+-         _60 = (*_59);                    // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
++         _60 = _57;                       // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
+          StorageLive(_61);                // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+          StorageLive(_62);                // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+          _62 = ();                        // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
+          _61 = opaque::<()>(move _62) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:240:9: 240:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb9: {
+          StorageDead(_62);                // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19
+          StorageDead(_61);                // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20
+          _0 = const ();                   // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6
+          StorageDead(_60);                // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6
+          StorageDead(_59);                // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6
+          StorageDead(_58);                // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6
+          StorageDead(_57);                // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6
+          return;                          // scope 0 at $DIR/reference_prop.rs:+82:2: +82:2
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
new file mode 100644
index 00000000000..44ddbbc3066
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff
@@ -0,0 +1,372 @@
+- // MIR for `reference_propagation_mut` before ReferencePropagation
++ // MIR for `reference_propagation_mut` after ReferencePropagation
+  
+  fn reference_propagation_mut(_1: &mut T, _2: &mut T) -> () {
+      debug single => _1;                  // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
+      debug multiple => _2;                // in scope 0 at $DIR/reference_prop.rs:+0:62: +0:74
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
+      let _3: ();                          // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+      let mut _4: usize;                   // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
+      let _7: ();                          // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+      let mut _8: ();                      // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+      let _9: ();                          // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+      let mut _10: usize;                  // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
+      let mut _13: &mut usize;             // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
+      let mut _14: &mut usize;             // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
+      let _16: ();                         // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+      let mut _17: ();                     // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+      let _18: ();                         // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+      let mut _19: usize;                  // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
+      let _23: ();                         // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
+      let mut _24: ();                     // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
+      let _25: ();                         // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+      let mut _26: usize;                  // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
+      let _30: ();                         // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
+      let mut _31: ();                     // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
+      let _32: ();                         // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+      let mut _33: usize;                  // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
+      let _36: ();                         // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+      let mut _37: &mut usize;             // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+      let _38: ();                         // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+      let mut _39: usize;                  // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
+      let _45: ();                         // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+      let mut _46: &mut usize;             // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+      let _47: ();                         // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+      let _48: &mut T;                     // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+      let _50: ();                         // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+      let mut _51: ();                     // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+      let _52: &mut T;                     // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+      let mut _53: &mut T;                 // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
+      let mut _54: &mut T;                 // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
+      let _56: ();                         // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+      let mut _57: ();                     // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+      scope 1 {
+          debug a => _4;                   // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+          let _5: &mut usize;              // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+          scope 2 {
+              debug b => _5;               // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+              let _6: usize;               // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+              scope 3 {
+                  debug c => _6;           // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+              }
+          }
+      }
+      scope 4 {
+          debug a => _10;                  // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:18
+          let mut _11: usize;              // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
+          scope 5 {
+              debug a2 => _11;             // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:19
+              let mut _12: &mut usize;     // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+              scope 6 {
+                  debug b => _12;          // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
+                  let _15: usize;          // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+                  scope 7 {
+                      debug c => _15;      // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
+                  }
+              }
+          }
+      }
+      scope 8 {
+          debug a => _19;                  // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:18
+          let _20: &mut usize;             // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+          scope 9 {
+              debug b => _20;              // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
+              let _21: &&mut usize;        // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+              scope 10 {
+                  debug d => _21;          // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
+                  let _22: usize;          // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+                  scope 11 {
+                      debug c => _22;      // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
+                  }
+              }
+          }
+      }
+      scope 12 {
+          debug a => _26;                  // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:18
+          let mut _27: &mut usize;         // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+          scope 13 {
+              debug b => _27;              // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
+              let _28: &mut &mut usize;    // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+              scope 14 {
+                  debug d => _28;          // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
+                  let _29: usize;          // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+                  scope 15 {
+                      debug c => _29;      // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
+                  }
+              }
+          }
+      }
+      scope 16 {
+          debug a => _33;                  // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:18
+          let _34: &mut usize;             // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+          scope 17 {
+              debug b => _34;              // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
+              let _35: usize;              // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+              scope 18 {
+                  debug c => _35;          // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
+              }
+          }
+      }
+      scope 19 {
+          debug a => _39;                  // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:18
+          let _40: &mut usize;             // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+          scope 20 {
+              debug b1 => _40;             // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
+              let _41: usize;              // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+              scope 21 {
+                  debug c => _41;          // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
+                  let _42: &mut usize;     // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+                  scope 22 {
+                      debug b2 => _42;     // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
+                      let _43: usize;      // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+                      scope 23 {
+                          debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
+                          let _44: &mut usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+                          scope 24 {
+                              debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
+                          }
+                      }
+                  }
+              }
+          }
+      }
+      scope 25 {
+          debug a => _48;                  // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
+          let _49: T;                      // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+          scope 26 {
+              debug b => _49;              // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
+          }
+      }
+      scope 27 {
+          debug a => _52;                  // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
+          let _55: T;                      // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+          scope 28 {
+              debug b => _55;              // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);                 // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageLive(_4);                 // scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
+          _4 = const 5_usize;              // scope 0 at $DIR/reference_prop.rs:+3:21: +3:28
+          StorageLive(_5);                 // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
+          _5 = &mut _4;                    // scope 1 at $DIR/reference_prop.rs:+4:17: +4:23
+          StorageLive(_6);                 // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
+-         _6 = (*_5);                      // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
++         _6 = _4;                         // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+          StorageLive(_7);                 // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+          StorageLive(_8);                 // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+          _8 = ();                         // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
+          _7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:91:9: 91:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_8);                 // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
+          StorageDead(_7);                 // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
+-         _3 = const ();                   // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageDead(_6);                 // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_5);                 // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_4);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageDead(_3);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageLive(_9);                 // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageLive(_10);                // scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
+          _10 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+11:21: +11:28
+          StorageLive(_11);                // scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
+          _11 = const 7_usize;             // scope 4 at $DIR/reference_prop.rs:+12:22: +12:29
+          StorageLive(_12);                // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
+          _12 = &mut _10;                  // scope 5 at $DIR/reference_prop.rs:+13:21: +13:27
+          StorageLive(_13);                // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+-         StorageLive(_14);                // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+-         _14 = &mut _11;                  // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+-         _13 = &mut (*_14);               // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
++         _13 = &mut _11;                  // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+          _12 = move _13;                  // scope 6 at $DIR/reference_prop.rs:+14:9: +14:20
+          StorageDead(_13);                // scope 6 at $DIR/reference_prop.rs:+14:19: +14:20
+-         StorageDead(_14);                // scope 6 at $DIR/reference_prop.rs:+14:20: +14:21
+          StorageLive(_15);                // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
+          _15 = (*_12);                    // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
+          StorageLive(_16);                // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+          StorageLive(_17);                // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+          _17 = ();                        // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
+          _16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:102:9: 102:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_17);                // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
+          StorageDead(_16);                // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
+-         _9 = const ();                   // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageDead(_15);                // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_12);                // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_11);                // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_10);                // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageDead(_9);                 // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageLive(_18);                // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageLive(_19);                // scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
+          _19 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+22:21: +22:28
+          StorageLive(_20);                // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
+          _20 = &mut _19;                  // scope 8 at $DIR/reference_prop.rs:+23:17: +23:23
+          StorageLive(_21);                // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
+          _21 = &_20;                      // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
+          StorageLive(_22);                // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
+          _22 = (*_20);                    // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
+          StorageLive(_23);                // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
+          StorageLive(_24);                // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
+          _24 = ();                        // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
+          _23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:111:9: 111:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          StorageDead(_24);                // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
+          StorageDead(_23);                // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20
+-         _18 = const ();                  // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageDead(_22);                // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_21);                // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_20);                // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_19);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageDead(_18);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageLive(_25);                // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageLive(_26);                // scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
+          _26 = const 5_usize;             // scope 0 at $DIR/reference_prop.rs:+31:21: +31:28
+          StorageLive(_27);                // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
+          _27 = &mut _26;                  // scope 12 at $DIR/reference_prop.rs:+32:21: +32:27
+          StorageLive(_28);                // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
+          _28 = &mut _27;                  // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23
+          StorageLive(_29);                // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
+          _29 = (*_27);                    // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
+          StorageLive(_30);                // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
+          StorageLive(_31);                // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
+          _31 = ();                        // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
+          _30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:120:9: 120:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb4: {
+          StorageDead(_31);                // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
+          StorageDead(_30);                // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20
+-         _25 = const ();                  // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageDead(_29);                // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_28);                // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_27);                // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_26);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageDead(_25);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageLive(_32);                // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageLive(_33);                // scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
+          _33 = const 7_usize;             // scope 0 at $DIR/reference_prop.rs:+40:21: +40:28
+          StorageLive(_34);                // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
+          _34 = &mut _33;                  // scope 16 at $DIR/reference_prop.rs:+41:17: +41:23
+          StorageLive(_35);                // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
+          _35 = (*_34);                    // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
+          StorageLive(_36);                // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+          StorageLive(_37);                // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+          _37 = move _34;                  // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
+          _36 = opaque::<&mut usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:128:9: 128:15
+                                           // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
+      }
+  
+      bb5: {
+          StorageDead(_37);                // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
+          StorageDead(_36);                // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
+-         _32 = const ();                  // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageDead(_35);                // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_34);                // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_33);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageDead(_32);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageLive(_38);                // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageLive(_39);                // scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
+          _39 = const 7_usize;             // scope 0 at $DIR/reference_prop.rs:+48:21: +48:28
+          StorageLive(_40);                // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
+          _40 = &mut _39;                  // scope 19 at $DIR/reference_prop.rs:+49:18: +49:24
+          StorageLive(_41);                // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
+          _41 = (*_40);                    // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
+          StorageLive(_42);                // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
+          _42 = move _40;                  // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
+          StorageLive(_43);                // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
+          _43 = (*_42);                    // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
+          StorageLive(_44);                // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
+          _44 = move _42;                  // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
+          StorageLive(_45);                // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+          StorageLive(_46);                // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+          _46 = move _44;                  // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
+          _45 = opaque::<&mut usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:141:9: 141:15
+                                           // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
+      }
+  
+      bb6: {
+          StorageDead(_46);                // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
+          StorageDead(_45);                // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
+-         _38 = const ();                  // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageDead(_44);                // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_43);                // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_42);                // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_41);                // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_40);                // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_39);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageDead(_38);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageLive(_47);                // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageLive(_48);                // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
+          _48 = &mut (*_1);                // scope 0 at $DIR/reference_prop.rs:+61:17: +61:29
+          StorageLive(_49);                // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
+-         _49 = (*_48);                    // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
++         _49 = (*_1);                     // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+          StorageLive(_50);                // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+          StorageLive(_51);                // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+          _51 = ();                        // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
+          _50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:148:9: 148:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb7: {
+          StorageDead(_51);                // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
+          StorageDead(_50);                // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
+-         _47 = const ();                  // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageDead(_49);                // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageDead(_48);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+-         StorageDead(_47);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageLive(_52);                // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
+          _52 = &mut (*_2);                // scope 0 at $DIR/reference_prop.rs:+68:17: +68:31
+          StorageLive(_53);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+-         StorageLive(_54);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+-         _54 = &mut (*_1);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+-         _53 = &mut (*_54);               // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
++         _53 = &mut (*_1);                // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+          _2 = move _53;                   // scope 27 at $DIR/reference_prop.rs:+69:9: +69:32
+          StorageDead(_53);                // scope 27 at $DIR/reference_prop.rs:+69:31: +69:32
+-         StorageDead(_54);                // scope 27 at $DIR/reference_prop.rs:+69:32: +69:33
+          StorageLive(_55);                // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
+          _55 = (*_52);                    // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
+          StorageLive(_56);                // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+          StorageLive(_57);                // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+          _57 = ();                        // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
+          _56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:156:9: 156:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb8: {
+          StorageDead(_57);                // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
+          StorageDead(_56);                // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
+          _0 = const ();                   // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
+          StorageDead(_55);                // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
+          StorageDead(_52);                // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
+          return;                          // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
new file mode 100644
index 00000000000..c55b5eb4bed
--- /dev/null
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
@@ -0,0 +1,378 @@
+- // MIR for `reference_propagation_mut_ptr` before ReferencePropagation
++ // MIR for `reference_propagation_mut_ptr` after ReferencePropagation
+  
+  fn reference_propagation_mut_ptr(_1: *mut T, _2: *mut T) -> () {
+      debug single => _1;                  // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
+      debug multiple => _2;                // in scope 0 at $DIR/reference_prop.rs:+0:59: +0:71
+      let mut _0: ();                      // return place in scope 0 at $DIR/reference_prop.rs:+0:81: +0:81
+      let _3: ();                          // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+      let _7: ();                          // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
+      let mut _8: ();                      // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
+      let _9: ();                          // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+      let mut _13: *mut usize;             // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:24
+      let _15: ();                         // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
+      let mut _16: ();                     // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
+      let _17: ();                         // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+      let _22: ();                         // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
+      let mut _23: ();                     // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
+      let _24: ();                         // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+      let _29: ();                         // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
+      let mut _30: ();                     // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
+      let _31: ();                         // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+      let _35: ();                         // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
+      let mut _36: *mut usize;             // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
+      let _37: ();                         // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+      let _44: ();                         // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
+      let mut _45: *mut usize;             // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
+      let _46: ();                         // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+      let _49: ();                         // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
+      let mut _50: ();                     // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
+      let mut _52: *mut T;                 // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:36
+      let _54: ();                         // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
+      let mut _55: ();                     // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
+      scope 1 {
+          let mut _4: usize;               // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+          scope 2 {
+              debug a => _4;               // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:18
+              let _5: *mut usize;          // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+              scope 3 {
+                  debug b => _5;           // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
+                  let _6: usize;           // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+                  scope 4 {
+                      debug c => _6;       // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
+                  }
+              }
+          }
+      }
+      scope 5 {
+          let mut _10: usize;              // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
+          scope 6 {
+              debug a => _10;              // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:18
+              let mut _11: usize;          // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
+              scope 7 {
+                  debug a2 => _11;         // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:19
+                  let mut _12: *mut usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+                  scope 8 {
+                      debug b => _12;      // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
+                      let _14: usize;      // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+                      scope 9 {
+                          debug c => _14;  // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 10 {
+          let mut _18: usize;              // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
+          scope 11 {
+              debug a => _18;              // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:18
+              let _19: *mut usize;         // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+              scope 12 {
+                  debug b => _19;          // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
+                  let _20: &*mut usize;    // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+                  scope 13 {
+                      debug d => _20;      // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
+                      let _21: usize;      // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+                      scope 14 {
+                          debug c => _21;  // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 15 {
+          let mut _25: usize;              // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
+          scope 16 {
+              debug a => _25;              // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:18
+              let mut _26: *mut usize;     // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+              scope 17 {
+                  debug b => _26;          // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
+                  let _27: &mut *mut usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+                  scope 18 {
+                      debug d => _27;      // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
+                      let _28: usize;      // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+                      scope 19 {
+                          debug c => _28;  // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
+                      }
+                  }
+              }
+          }
+      }
+      scope 20 {
+          let mut _32: usize;              // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
+          scope 21 {
+              debug a => _32;              // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:18
+              let _33: *mut usize;         // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+              scope 22 {
+                  debug b => _33;          // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
+                  let _34: usize;          // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+                  scope 23 {
+                      debug c => _34;      // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
+                  }
+              }
+          }
+      }
+      scope 24 {
+          let mut _38: usize;              // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
+          scope 25 {
+              debug a => _38;              // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:18
+              let _39: *mut usize;         // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+              scope 26 {
+                  debug b1 => _39;         // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
+                  let _40: usize;          // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+                  scope 27 {
+                      debug c => _40;      // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
+                      let _41: *mut usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+                      scope 28 {
+                          debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
+                          let _42: usize;  // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+                          scope 29 {
+                              debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
+                              let _43: *mut usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+                              scope 30 {
+                                  debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
+                              }
+                          }
+                      }
+                  }
+              }
+          }
+      }
+      scope 31 {
+          let _47: *mut T;                 // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+          scope 32 {
+              debug a => _47;              // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
+              let _48: T;                  // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+              scope 33 {
+                  debug b => _48;          // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
+              }
+          }
+      }
+      scope 34 {
+          let _51: *mut T;                 // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+          scope 35 {
+              debug a => _51;              // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
+              let _53: T;                  // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+              scope 36 {
+                  debug b => _53;          // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_3);                 // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageLive(_4);                 // scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
+          _4 = const 5_usize;              // scope 1 at $DIR/reference_prop.rs:+3:21: +3:28
+          StorageLive(_5);                 // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
+          _5 = &raw mut _4;                // scope 2 at $DIR/reference_prop.rs:+4:17: +4:27
+          StorageLive(_6);                 // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
+-         _6 = (*_5);                      // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
++         _6 = _4;                         // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+          StorageLive(_7);                 // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+          StorageLive(_8);                 // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+          _8 = ();                         // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
+          _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:250:9: 250:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_8);                 // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
+          StorageDead(_7);                 // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
+-         _3 = const ();                   // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
+          StorageDead(_6);                 // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_5);                 // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
+          StorageDead(_4);                 // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageDead(_3);                 // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
+-         StorageLive(_9);                 // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageLive(_10);                // scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
+          _10 = const 5_usize;             // scope 5 at $DIR/reference_prop.rs:+11:21: +11:28
+          StorageLive(_11);                // scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
+          _11 = const 7_usize;             // scope 6 at $DIR/reference_prop.rs:+12:22: +12:29
+          StorageLive(_12);                // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
+          _12 = &raw mut _10;              // scope 7 at $DIR/reference_prop.rs:+13:21: +13:31
+          StorageLive(_13);                // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
+          _13 = &raw mut _11;              // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
+          _12 = move _13;                  // scope 8 at $DIR/reference_prop.rs:+14:9: +14:24
+          StorageDead(_13);                // scope 8 at $DIR/reference_prop.rs:+14:23: +14:24
+          StorageLive(_14);                // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
+          _14 = (*_12);                    // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
+          StorageLive(_15);                // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+          StorageLive(_16);                // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+          _16 = ();                        // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
+          _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:261:9: 261:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_16);                // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
+          StorageDead(_15);                // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
+-         _9 = const ();                   // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
+          StorageDead(_14);                // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_12);                // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_11);                // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
+          StorageDead(_10);                // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageDead(_9);                 // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
+-         StorageLive(_17);                // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageLive(_18);                // scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
+          _18 = const 5_usize;             // scope 10 at $DIR/reference_prop.rs:+22:21: +22:28
+          StorageLive(_19);                // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
+          _19 = &raw mut _18;              // scope 11 at $DIR/reference_prop.rs:+23:17: +23:27
+          StorageLive(_20);                // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
+          _20 = &_19;                      // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
+          StorageLive(_21);                // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
+          _21 = (*_19);                    // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
+          StorageLive(_22);                // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
+          StorageLive(_23);                // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
+          _23 = ();                        // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
+          _22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:270:9: 270:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          StorageDead(_23);                // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
+          StorageDead(_22);                // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20
+-         _17 = const ();                  // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
+          StorageDead(_21);                // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_20);                // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_19);                // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
+          StorageDead(_18);                // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageDead(_17);                // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
+-         StorageLive(_24);                // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageLive(_25);                // scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
+          _25 = const 5_usize;             // scope 15 at $DIR/reference_prop.rs:+31:21: +31:28
+          StorageLive(_26);                // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
+          _26 = &raw mut _25;              // scope 16 at $DIR/reference_prop.rs:+32:21: +32:31
+          StorageLive(_27);                // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
+          _27 = &mut _26;                  // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23
+          StorageLive(_28);                // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
+          _28 = (*_26);                    // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
+          StorageLive(_29);                // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
+          StorageLive(_30);                // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
+          _30 = ();                        // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
+          _29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:279:9: 279:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb4: {
+          StorageDead(_30);                // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
+          StorageDead(_29);                // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20
+-         _24 = const ();                  // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
+          StorageDead(_28);                // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_27);                // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_26);                // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
+          StorageDead(_25);                // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageDead(_24);                // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
+-         StorageLive(_31);                // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageLive(_32);                // scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
+          _32 = const 7_usize;             // scope 20 at $DIR/reference_prop.rs:+40:21: +40:28
+          StorageLive(_33);                // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
+          _33 = &raw mut _32;              // scope 21 at $DIR/reference_prop.rs:+41:17: +41:27
+          StorageLive(_34);                // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
+          _34 = (*_33);                    // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
+          StorageLive(_35);                // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+          StorageLive(_36);                // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+          _36 = _33;                       // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
+          _35 = opaque::<*mut usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:287:9: 287:15
+                                           // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
+      }
+  
+      bb5: {
+          StorageDead(_36);                // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
+          StorageDead(_35);                // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
+-         _31 = const ();                  // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
+          StorageDead(_34);                // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_33);                // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
+          StorageDead(_32);                // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageDead(_31);                // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
+-         StorageLive(_37);                // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageLive(_38);                // scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
+          _38 = const 7_usize;             // scope 24 at $DIR/reference_prop.rs:+48:21: +48:28
+          StorageLive(_39);                // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
+          _39 = &raw mut _38;              // scope 25 at $DIR/reference_prop.rs:+49:18: +49:28
+          StorageLive(_40);                // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
+          _40 = (*_39);                    // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
+          StorageLive(_41);                // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
+          _41 = _39;                       // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
+          StorageLive(_42);                // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
+          _42 = (*_41);                    // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
+          StorageLive(_43);                // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
+          _43 = _41;                       // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
+          StorageLive(_44);                // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+          StorageLive(_45);                // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+          _45 = _43;                       // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
+          _44 = opaque::<*mut usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:300:9: 300:15
+                                           // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
+      }
+  
+      bb6: {
+          StorageDead(_45);                // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
+          StorageDead(_44);                // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
+-         _37 = const ();                  // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
+          StorageDead(_43);                // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_42);                // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_41);                // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_40);                // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_39);                // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
+          StorageDead(_38);                // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageDead(_37);                // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
+-         StorageLive(_46);                // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageLive(_47);                // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
+          _47 = &raw mut (*_1);            // scope 31 at $DIR/reference_prop.rs:+61:17: +61:33
+          StorageLive(_48);                // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
+-         _48 = (*_47);                    // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
++         _48 = (*_1);                     // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+          StorageLive(_49);                // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+          StorageLive(_50);                // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+          _50 = ();                        // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
+          _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:307:9: 307:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb7: {
+          StorageDead(_50);                // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
+          StorageDead(_49);                // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
+-         _46 = const ();                  // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
+          StorageDead(_48);                // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageDead(_47);                // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
+-         StorageDead(_46);                // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
+          StorageLive(_51);                // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
+          _51 = &raw mut (*_2);            // scope 34 at $DIR/reference_prop.rs:+68:17: +68:35
+          StorageLive(_52);                // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
+          _52 = &raw mut (*_1);            // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
+          _2 = move _52;                   // scope 35 at $DIR/reference_prop.rs:+69:9: +69:36
+          StorageDead(_52);                // scope 35 at $DIR/reference_prop.rs:+69:35: +69:36
+          StorageLive(_53);                // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
+          _53 = (*_51);                    // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
+          StorageLive(_54);                // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+          StorageLive(_55);                // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+          _55 = ();                        // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
+          _54 = opaque::<()>(move _55) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
+                                           // mir::Constant
+                                           // + span: $DIR/reference_prop.rs:315:9: 315:15
+                                           // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
+      }
+  
+      bb8: {
+          StorageDead(_55);                // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
+          StorageDead(_54);                // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
+          _0 = const ();                   // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
+          StorageDead(_53);                // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
+          StorageDead(_51);                // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
+          return;                          // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
+      }
+  }
+  
diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs
new file mode 100644
index 00000000000..e3e5d791464
--- /dev/null
+++ b/tests/mir-opt/reference_prop.rs
@@ -0,0 +1,456 @@
+// unit-test: ReferencePropagation
+// needs-unwind
+
+#![feature(raw_ref_op)]
+#![feature(core_intrinsics, custom_mir)]
+
+#[inline(never)]
+fn opaque(_: impl Sized) {}
+
+fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
+    // Propagation through a reference.
+    {
+        let a = 5_usize;
+        let b = &a; // This borrow is only used once.
+        let c = *b; // This should be optimized.
+        opaque(()); // We use opaque to separate cases into basic blocks in the MIR.
+    }
+
+    // Propagation through a two references.
+    {
+        let a = 5_usize;
+        let a2 = 7_usize;
+        let mut b = &a;
+        b = &a2;
+        // `b` is assigned twice, so we cannot propagate it.
+        let c = *b;
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    {
+        let a = 5_usize;
+        let b = &a;
+        let d = &b;
+        let c = *b; // `b` is immutably borrowed, we know its value, but do not propagate it
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    {
+        let a = 5_usize;
+        let mut b = &a;
+        let d = &mut b;
+        let c = *b; // `b` is mutably borrowed, we cannot know its value.
+        opaque(());
+    }
+
+    // Propagation through an escaping borrow.
+    {
+        let a = 7_usize;
+        let b = &a;
+        let c = *b;
+        opaque(b); // `b` escapes here, but we can still replace immutable borrow
+    }
+
+    // Propagation through a transitively escaping borrow.
+    {
+        let a = 7_usize;
+        let b1 = &a;
+        let c = *b1;
+        let b2 = b1;
+        let c2 = *b2;
+        let b3 = b2;
+        // `b3` escapes here, so we can only replace immutable borrow,
+        // for either `b`, `b2` or `b3`.
+        opaque(b3);
+    }
+
+    // Propagation a reborrow of an argument.
+    {
+        let a = &*single;
+        let b = *a; // This should be optimized as `*single`.
+        opaque(());
+    }
+
+    // Propagation a reborrow of a mutated argument.
+    {
+        let a = &*multiple;
+        multiple = &*single;
+        let b = *a; // This should not be optimized.
+        opaque(());
+    }
+}
+
+fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a mut T) {
+    // Propagation through a reference.
+    {
+        let mut a = 5_usize;
+        let b = &mut a; // This borrow is only used once.
+        let c = *b; // This should be optimized.
+        opaque(());
+    }
+
+    // Propagation through a two references.
+    {
+        let mut a = 5_usize;
+        let mut a2 = 7_usize;
+        let mut b = &mut a;
+        b = &mut a2;
+        // `b` is assigned twice, so we cannot propagate it.
+        let c = *b;
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    {
+        let mut a = 5_usize;
+        let b = &mut a;
+        let d = &b;
+        let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    {
+        let mut a = 5_usize;
+        let mut b = &mut a;
+        let d = &mut b;
+        let c = *b; // `b` is mutably borrowed, we cannot know its value.
+        opaque(());
+    }
+
+    // Propagation through an escaping borrow.
+    {
+        let mut a = 7_usize;
+        let b = &mut a;
+        let c = *b;
+        opaque(b); // `b` escapes here, so we can only replace immutable borrow
+    }
+
+    // Propagation through a transitively escaping borrow.
+    {
+        let mut a = 7_usize;
+        let b1 = &mut a;
+        let c = *b1;
+        let b2 = b1;
+        let c2 = *b2;
+        let b3 = b2;
+        // `b3` escapes here, so we can only replace immutable borrow,
+        // for either `b`, `b2` or `b3`.
+        opaque(b3);
+    }
+
+    // Propagation a reborrow of an argument.
+    {
+        let a = &mut *single;
+        let b = *a; // This should be optimized as `*single`.
+        opaque(());
+    }
+
+    // Propagation a reborrow of a mutated argument.
+    {
+        let a = &mut *multiple;
+        multiple = &mut *single;
+        let b = *a; // This should not be optimized.
+        opaque(());
+    }
+}
+
+fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *const T) {
+    // Propagation through a reference.
+    unsafe {
+        let a = 5_usize;
+        let b = &raw const a; // This borrow is only used once.
+        let c = *b; // This should be optimized.
+        opaque(());
+    }
+
+    // Propagation through a two references.
+    unsafe {
+        let a = 5_usize;
+        let a2 = 7_usize;
+        let mut b = &raw const a;
+        b = &raw const a2;
+        // `b` is assigned twice, so we cannot propagate it.
+        let c = *b;
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    unsafe {
+        let a = 5_usize;
+        let b = &raw const a;
+        let d = &b;
+        let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    unsafe {
+        let a = 5_usize;
+        let mut b = &raw const a;
+        let d = &mut b;
+        let c = *b; // `b` is mutably borrowed, we cannot know its value.
+        opaque(());
+    }
+
+    // Propagation through an escaping borrow.
+    unsafe {
+        let a = 7_usize;
+        let b = &raw const a;
+        let c = *b;
+        opaque(b); // `b` escapes here, so we can only replace immutable borrow
+    }
+
+    // Propagation through a transitively escaping borrow.
+    unsafe {
+        let a = 7_usize;
+        let b1 = &raw const a;
+        let c = *b1;
+        let b2 = b1;
+        let c2 = *b2;
+        let b3 = b2;
+        // `b3` escapes here, so we can only replace immutable borrow,
+        // for either `b`, `b2` or `b3`.
+        opaque(b3);
+    }
+
+    // Propagation a reborrow of an argument.
+    unsafe {
+        let a = &raw const *single;
+        let b = *a; // This should be optimized as `*single`.
+        opaque(());
+    }
+
+    // Propagation a reborrow of a mutated argument.
+    unsafe {
+        let a = &raw const *multiple;
+        multiple = &raw const *single;
+        let b = *a; // This should not be optimized.
+        opaque(());
+    }
+
+    // Propagation through a reborrow.
+    unsafe {
+        let a = 13_usize;
+        let b = &raw const a;
+        let c = &raw const *b;
+        let e = *c;
+        opaque(());
+    }
+}
+
+fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) {
+    // Propagation through a reference.
+    unsafe {
+        let mut a = 5_usize;
+        let b = &raw mut a; // This borrow is only used once.
+        let c = *b; // This should be optimized.
+        opaque(());
+    }
+
+    // Propagation through a two references.
+    unsafe {
+        let mut a = 5_usize;
+        let mut a2 = 7_usize;
+        let mut b = &raw mut a;
+        b = &raw mut a2;
+        // `b` is assigned twice, so we cannot propagate it.
+        let c = *b;
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    unsafe {
+        let mut a = 5_usize;
+        let b = &raw mut a;
+        let d = &b;
+        let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
+        opaque(());
+    }
+
+    // Propagation through a borrowed reference.
+    unsafe {
+        let mut a = 5_usize;
+        let mut b = &raw mut a;
+        let d = &mut b;
+        let c = *b; // `b` is mutably borrowed, we cannot know its value.
+        opaque(());
+    }
+
+    // Propagation through an escaping borrow.
+    unsafe {
+        let mut a = 7_usize;
+        let b = &raw mut a;
+        let c = *b;
+        opaque(b); // `b` escapes here, so we can only replace immutable borrow
+    }
+
+    // Propagation through a transitively escaping borrow.
+    unsafe {
+        let mut a = 7_usize;
+        let b1 = &raw mut a;
+        let c = *b1;
+        let b2 = b1;
+        let c2 = *b2;
+        let b3 = b2;
+        // `b3` escapes here, so we can only replace immutable borrow,
+        // for either `b`, `b2` or `b3`.
+        opaque(b3);
+    }
+
+    // Propagation a reborrow of an argument.
+    unsafe {
+        let a = &raw mut *single;
+        let b = *a; // This should be optimized as `*single`.
+        opaque(());
+    }
+
+    // Propagation a reborrow of a mutated argument.
+    unsafe {
+        let a = &raw mut *multiple;
+        multiple = &raw mut *single;
+        let b = *a; // This should not be optimized.
+        opaque(());
+    }
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn read_through_raw(x: &mut usize) -> usize {
+    use std::intrinsics::mir::*;
+
+    mir!(
+        let r1: &mut usize;
+        let r2: &mut usize;
+        let p1: *mut usize;
+        let p2: *mut usize;
+
+        {
+            r1 = &mut *x;
+            r2 = &mut *r1;
+            p1 = &raw mut *r1;
+            p2 = &raw mut *r2;
+
+            RET = *p1;
+            RET = *p2;
+            Return()
+        }
+    )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn multiple_storage() {
+    use std::intrinsics::mir::*;
+
+    mir!(
+        let x: i32;
+        {
+            StorageLive(x);
+            x = 5;
+            let z = &x;
+            StorageDead(x);
+            StorageLive(x);
+            // As there are multiple `StorageLive` statements for `x`, we cannot know if this `z`'s
+            // pointer address is the address of `x`, so do nothing.
+            let y = *z;
+            Call(RET, retblock, opaque(y))
+        }
+
+        retblock = {
+            Return()
+        }
+    )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn dominate_storage() {
+    use std::intrinsics::mir::*;
+
+    mir!(
+        let x: i32;
+        let r: &i32;
+        let c: i32;
+        let d: bool;
+        { Goto(bb0) }
+        bb0 = {
+            x = 5;
+            r = &x;
+            Goto(bb1)
+        }
+        bb1 = {
+            let c = *r;
+            Call(RET, bb2, opaque(c))
+        }
+        bb2 = {
+            StorageDead(x);
+            StorageLive(x);
+            let d = true;
+            match d { false => bb2, _ => bb0 }
+        }
+    )
+}
+
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+fn maybe_dead(m: bool) {
+    use std::intrinsics::mir::*;
+
+    mir!(
+        let x: i32;
+        let y: i32;
+        {
+            StorageLive(x);
+            StorageLive(y);
+            x = 5;
+            y = 5;
+            let a = &x;
+            let b = &mut y;
+            // As we don't replace `b` in `bb2`, we cannot replace it here either.
+            *b = 7;
+            // But this can still be replaced.
+            let u = *a;
+            match m { true => bb1, _ => bb2 }
+        }
+        bb1 = {
+            StorageDead(x);
+            StorageDead(y);
+            Call(RET, bb2, opaque(u))
+        }
+        bb2 = {
+            // As `x` may be `StorageDead`, `a` may be dangling, so we do nothing.
+            let z = *a;
+            Call(RET, bb3, opaque(z))
+        }
+        bb3 = {
+            // As `y` may be `StorageDead`, `b` may be dangling, so we do nothing.
+            // This implies that we also do not substitute `b` in `bb0`.
+            let t = *b;
+            Call(RET, retblock, opaque(t))
+        }
+        retblock = {
+            Return()
+        }
+    )
+}
+
+fn main() {
+    let mut x = 5_usize;
+    let mut y = 7_usize;
+    reference_propagation(&x, &y);
+    reference_propagation_mut(&mut x, &mut y);
+    reference_propagation_const_ptr(&raw const x, &raw const y);
+    reference_propagation_mut_ptr(&raw mut x, &raw mut y);
+    read_through_raw(&mut x);
+    multiple_storage();
+    dominate_storage();
+    maybe_dead(true);
+}
+
+// EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_mut.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
+// EMIT_MIR reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
+// EMIT_MIR reference_prop.read_through_raw.ReferencePropagation.diff
+// EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff
+// EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff
+// EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff
diff --git a/tests/mir-opt/slice_filter.rs b/tests/mir-opt/slice_filter.rs
index 97c18af31de..be32f40f132 100644
--- a/tests/mir-opt/slice_filter.rs
+++ b/tests/mir-opt/slice_filter.rs
@@ -12,7 +12,9 @@ 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}.ReferencePropagation.diff
 // 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}.ReferencePropagation.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
index 3bb0358ffe3..60e5056c7a9 100644
--- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff
@@ -101,16 +101,16 @@
       }
   
       bb0: {
--         StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+          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
+          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
+          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
+          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
@@ -184,10 +184,10 @@
       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
+          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
       }
   
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
index 294c3272f4f..7ad1ccf28a6 100644
--- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
@@ -30,10 +30,14 @@
       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
+-         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
++         debug a => _20;                  // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
++         debug b => _15;                  // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
++         debug c => _11;                  // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
++         debug d => _24;                  // 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
@@ -85,25 +89,38 @@
       }
   
       bb0: {
+-         StorageLive(_3);                 // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
++         nop;                             // 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
+-         _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
++         _20 = &((*_25).0: usize);        // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
++         nop;                             // 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
+-         _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
++         _15 = &((*_26).1: usize);        // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
++         nop;                             // 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
+-         _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
++         _11 = &((*_27).2: usize);        // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
++         nop;                             // 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
+-         _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
++         _24 = &((*_28).3: usize);        // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
 +         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(_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
+-         _29 = deref_copy _3;             // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
++         _29 = deref_copy _20;            // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _30 = deref_copy _11;            // 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
@@ -111,7 +128,8 @@
           _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(_11);                // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
++         nop;                             // 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
@@ -127,13 +145,14 @@
 +         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(_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
+-         _33 = deref_copy _5;             // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
++         _33 = deref_copy _11;            // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _34 = deref_copy _20;            // 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
@@ -141,7 +160,8 @@
           _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(_20);                // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
++         nop;                             // 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
@@ -150,8 +170,16 @@
       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
 +         nop;                             // 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 0 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
           return;                          // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
       }
   
@@ -166,13 +194,14 @@
 -         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(_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
+-         _37 = deref_copy _6;             // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
++         _37 = deref_copy _24;            // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _38 = deref_copy _15;            // 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
@@ -180,7 +209,8 @@
           _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(_15);                // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
++         nop;                             // 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
@@ -202,13 +232,14 @@
 -         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(_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
+-         _41 = deref_copy _4;             // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         _41 = deref_copy _15;            // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+          _42 = deref_copy _24;            // 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
@@ -217,7 +248,8 @@
 +         _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(_24);                // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
++         nop;                             // 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
diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
new file mode 100644
index 00000000000..f6350b3812a
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
@@ -0,0 +1,247 @@
+- // MIR for `variant_a::{closure#0}` before ReferencePropagation
++ // MIR for `variant_a::{closure#0}` after ReferencePropagation
+  
+  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
+      let mut _31: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _32: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _37: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _38: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _43: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _44: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _49: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      let mut _50: &usize;                 // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
+      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 _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
+              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
+                  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
+              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
+                  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
+              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
+                  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
+-         _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
++         _29 = deref_copy _3;             // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _30 = deref_copy _11;            // 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
+          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
+          _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(_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
+-         _35 = deref_copy (*_18);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _36 = deref_copy (*_19);         // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _35 = deref_copy _5;             // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _36 = deref_copy _20;            // 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
+          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
+          _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(_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
+-         _41 = deref_copy (*_13);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _42 = deref_copy (*_14);         // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _41 = deref_copy _6;             // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _42 = deref_copy _15;            // 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
+          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
+          _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(_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
+-         _47 = deref_copy (*_22);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+-         _48 = deref_copy (*_23);         // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _47 = deref_copy _4;             // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
++         _48 = deref_copy _24;            // 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
+          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
+          _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(_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_b-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
new file mode 100644
index 00000000000..d1241c6b024
--- /dev/null
+++ b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
@@ -0,0 +1,103 @@
+- // MIR for `variant_b::{closure#0}` before ReferencePropagation
++ // MIR for `variant_b::{closure#0}` after ReferencePropagation
+  
+  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: {
+          _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
+          _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
+          _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
+          _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
+          _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
+          _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
+          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
+          _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
+          _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
+      }
+  }
+