about summary refs log tree commit diff
path: root/tests/mir-opt/dataflow-const-prop
diff options
context:
space:
mode:
Diffstat (limited to 'tests/mir-opt/dataflow-const-prop')
-rw-r--r--tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff37
-rw-r--r--tests/mir-opt/dataflow-const-prop/cast.rs7
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff80
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.rs13
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff61
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.rs13
-rw-r--r--tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff112
-rw-r--r--tests/mir-opt/dataflow-const-prop/if.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff39
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.rs8
-rw-r--r--tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff35
-rw-r--r--tests/mir-opt/dataflow-const-prop/issue_81605.rs10
-rw-r--r--tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff55
-rw-r--r--tests/mir-opt/dataflow-const-prop/ref_without_sb.rs17
-rw-r--r--tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff44
-rw-r--r--tests/mir-opt/dataflow-const-prop/repr_transparent.rs12
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff46
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign.rs12
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff23
-rw-r--r--tests/mir-opt/dataflow-const-prop/self_assign_add.rs8
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff56
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff52
-rw-r--r--tests/mir-opt/dataflow-const-prop/struct.rs11
-rw-r--r--tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff40
-rw-r--r--tests/mir-opt/dataflow-const-prop/terminator.rs10
-rw-r--r--tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff75
-rw-r--r--tests/mir-opt/dataflow-const-prop/tuple.rs9
28 files changed, 907 insertions, 0 deletions
diff --git a/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..bf9ab866938
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
+      let _1: i32;                         // in scope 0 at $DIR/cast.rs:+1:9: +1:10
+      let mut _3: u8;                      // in scope 0 at $DIR/cast.rs:+2:13: +2:20
+      let mut _4: i32;                     // in scope 0 at $DIR/cast.rs:+2:13: +2:14
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/cast.rs:+1:9: +1:10
+          let _2: u8;                      // in scope 1 at $DIR/cast.rs:+2:9: +2:10
+          scope 2 {
+              debug b => _2;               // in scope 2 at $DIR/cast.rs:+2:9: +2:10
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/cast.rs:+1:9: +1:10
+          _1 = const 257_i32;              // scope 0 at $DIR/cast.rs:+1:13: +1:16
+          StorageLive(_2);                 // scope 1 at $DIR/cast.rs:+2:9: +2:10
+          StorageLive(_3);                 // scope 1 at $DIR/cast.rs:+2:13: +2:20
+          StorageLive(_4);                 // scope 1 at $DIR/cast.rs:+2:13: +2:14
+-         _4 = _1;                         // scope 1 at $DIR/cast.rs:+2:13: +2:14
+-         _3 = move _4 as u8 (IntToInt);   // scope 1 at $DIR/cast.rs:+2:13: +2:20
++         _4 = const 257_i32;              // scope 1 at $DIR/cast.rs:+2:13: +2:14
++         _3 = const 1_u8;                 // scope 1 at $DIR/cast.rs:+2:13: +2:20
+          StorageDead(_4);                 // scope 1 at $DIR/cast.rs:+2:19: +2:20
+-         _2 = Add(move _3, const 1_u8);   // scope 1 at $DIR/cast.rs:+2:13: +2:24
++         _2 = const 2_u8;                 // scope 1 at $DIR/cast.rs:+2:13: +2:24
+          StorageDead(_3);                 // scope 1 at $DIR/cast.rs:+2:23: +2:24
+          _0 = const ();                   // scope 0 at $DIR/cast.rs:+0:11: +3:2
+          StorageDead(_2);                 // scope 1 at $DIR/cast.rs:+3:1: +3:2
+          StorageDead(_1);                 // scope 0 at $DIR/cast.rs:+3:1: +3:2
+          return;                          // scope 0 at $DIR/cast.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/cast.rs b/tests/mir-opt/dataflow-const-prop/cast.rs
new file mode 100644
index 00000000000..484403f7f0e
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/cast.rs
@@ -0,0 +1,7 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR cast.main.DataflowConstProp.diff
+fn main() {
+    let a = 257;
+    let b = a as u8 + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..a4ebd0c8c18
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
@@ -0,0 +1,80 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/checked.rs:+0:11: +0:11
+      let _1: i32;                         // in scope 0 at $DIR/checked.rs:+1:9: +1:10
+      let mut _4: i32;                     // in scope 0 at $DIR/checked.rs:+3:13: +3:14
+      let mut _5: i32;                     // in scope 0 at $DIR/checked.rs:+3:17: +3:18
+      let mut _6: (i32, bool);             // in scope 0 at $DIR/checked.rs:+3:13: +3:18
+      let mut _9: i32;                     // in scope 0 at $DIR/checked.rs:+6:13: +6:14
+      let mut _10: (i32, bool);            // in scope 0 at $DIR/checked.rs:+6:13: +6:18
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/checked.rs:+1:9: +1:10
+          let _2: i32;                     // in scope 1 at $DIR/checked.rs:+2:9: +2:10
+          scope 2 {
+              debug b => _2;               // in scope 2 at $DIR/checked.rs:+2:9: +2:10
+              let _3: i32;                 // in scope 2 at $DIR/checked.rs:+3:9: +3:10
+              scope 3 {
+                  debug c => _3;           // in scope 3 at $DIR/checked.rs:+3:9: +3:10
+                  let _7: i32;             // in scope 3 at $DIR/checked.rs:+5:9: +5:10
+                  scope 4 {
+                      debug d => _7;       // in scope 4 at $DIR/checked.rs:+5:9: +5:10
+                      let _8: i32;         // in scope 4 at $DIR/checked.rs:+6:9: +6:10
+                      scope 5 {
+                          debug e => _8;   // in scope 5 at $DIR/checked.rs:+6:9: +6:10
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/checked.rs:+1:9: +1:10
+          _1 = const 1_i32;                // scope 0 at $DIR/checked.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 1 at $DIR/checked.rs:+2:9: +2:10
+          _2 = const 2_i32;                // scope 1 at $DIR/checked.rs:+2:13: +2:14
+          StorageLive(_3);                 // scope 2 at $DIR/checked.rs:+3:9: +3:10
+          StorageLive(_4);                 // scope 2 at $DIR/checked.rs:+3:13: +3:14
+-         _4 = _1;                         // scope 2 at $DIR/checked.rs:+3:13: +3:14
++         _4 = const 1_i32;                // scope 2 at $DIR/checked.rs:+3:13: +3:14
+          StorageLive(_5);                 // scope 2 at $DIR/checked.rs:+3:17: +3:18
+-         _5 = _2;                         // scope 2 at $DIR/checked.rs:+3:17: +3:18
+-         _6 = CheckedAdd(_4, _5);         // scope 2 at $DIR/checked.rs:+3:13: +3:18
+-         assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
++         _5 = const 2_i32;                // scope 2 at $DIR/checked.rs:+3:17: +3:18
++         _6 = CheckedAdd(const 1_i32, const 2_i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18
++         assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
+      }
+  
+      bb1: {
+-         _3 = move (_6.0: i32);           // scope 2 at $DIR/checked.rs:+3:13: +3:18
++         _3 = const 3_i32;                // scope 2 at $DIR/checked.rs:+3:13: +3:18
+          StorageDead(_5);                 // scope 2 at $DIR/checked.rs:+3:17: +3:18
+          StorageDead(_4);                 // scope 2 at $DIR/checked.rs:+3:17: +3:18
+          StorageLive(_7);                 // scope 3 at $DIR/checked.rs:+5:9: +5:10
+          _7 = const _;                    // scope 3 at $DIR/checked.rs:+5:13: +5:21
+          StorageLive(_8);                 // scope 4 at $DIR/checked.rs:+6:9: +6:10
+          StorageLive(_9);                 // scope 4 at $DIR/checked.rs:+6:13: +6:14
+-         _9 = _7;                         // scope 4 at $DIR/checked.rs:+6:13: +6:14
+-         _10 = CheckedAdd(_9, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
+-         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
++         _9 = const i32::MAX;             // scope 4 at $DIR/checked.rs:+6:13: +6:14
++         _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
++         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
+      }
+  
+      bb2: {
+-         _8 = move (_10.0: i32);          // scope 4 at $DIR/checked.rs:+6:13: +6:18
++         _8 = const i32::MIN;             // scope 4 at $DIR/checked.rs:+6:13: +6:18
+          StorageDead(_9);                 // scope 4 at $DIR/checked.rs:+6:17: +6:18
+          _0 = const ();                   // scope 0 at $DIR/checked.rs:+0:11: +7:2
+          StorageDead(_8);                 // scope 4 at $DIR/checked.rs:+7:1: +7:2
+          StorageDead(_7);                 // scope 3 at $DIR/checked.rs:+7:1: +7:2
+          StorageDead(_3);                 // scope 2 at $DIR/checked.rs:+7:1: +7:2
+          StorageDead(_2);                 // scope 1 at $DIR/checked.rs:+7:1: +7:2
+          StorageDead(_1);                 // scope 0 at $DIR/checked.rs:+7:1: +7:2
+          return;                          // scope 0 at $DIR/checked.rs:+7:2: +7:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/checked.rs b/tests/mir-opt/dataflow-const-prop/checked.rs
new file mode 100644
index 00000000000..0738a4ee53b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/checked.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+// compile-flags: -Coverflow-checks=on
+
+// EMIT_MIR checked.main.DataflowConstProp.diff
+#[allow(arithmetic_overflow)]
+fn main() {
+    let a = 1;
+    let b = 2;
+    let c = a + b;
+
+    let d = i32::MAX;
+    let e = d + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..fce18fae436
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/enum.rs:+0:11: +0:11
+      let _1: E;                           // in scope 0 at $DIR/enum.rs:+1:9: +1:10
+      let mut _3: isize;                   // in scope 0 at $DIR/enum.rs:+2:23: +2:31
+      scope 1 {
+          debug e => _1;                   // in scope 1 at $DIR/enum.rs:+1:9: +1:10
+          let _2: i32;                     // in scope 1 at $DIR/enum.rs:+2:9: +2:10
+          let _4: i32;                     // in scope 1 at $DIR/enum.rs:+2:29: +2:30
+          let _5: i32;                     // in scope 1 at $DIR/enum.rs:+2:44: +2:45
+          scope 2 {
+              debug x => _2;               // in scope 2 at $DIR/enum.rs:+2:9: +2:10
+          }
+          scope 3 {
+              debug x => _4;               // in scope 3 at $DIR/enum.rs:+2:29: +2:30
+          }
+          scope 4 {
+              debug x => _5;               // in scope 4 at $DIR/enum.rs:+2:44: +2:45
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/enum.rs:+1:9: +1:10
+          Deinit(_1);                      // scope 0 at $DIR/enum.rs:+1:13: +1:21
+          ((_1 as V1).0: i32) = const 0_i32; // scope 0 at $DIR/enum.rs:+1:13: +1:21
+          discriminant(_1) = 0;            // scope 0 at $DIR/enum.rs:+1:13: +1:21
+          StorageLive(_2);                 // scope 1 at $DIR/enum.rs:+2:9: +2:10
+          _3 = discriminant(_1);           // scope 1 at $DIR/enum.rs:+2:19: +2:20
+          switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20
+      }
+  
+      bb1: {
+          StorageLive(_5);                 // scope 1 at $DIR/enum.rs:+2:44: +2:45
+          _5 = ((_1 as V2).0: i32);        // scope 1 at $DIR/enum.rs:+2:44: +2:45
+          _2 = _5;                         // scope 4 at $DIR/enum.rs:+2:50: +2:51
+          StorageDead(_5);                 // scope 1 at $DIR/enum.rs:+2:50: +2:51
+          goto -> bb4;                     // scope 1 at $DIR/enum.rs:+2:50: +2:51
+      }
+  
+      bb2: {
+          unreachable;                     // scope 1 at $DIR/enum.rs:+2:19: +2:20
+      }
+  
+      bb3: {
+          StorageLive(_4);                 // scope 1 at $DIR/enum.rs:+2:29: +2:30
+          _4 = ((_1 as V1).0: i32);        // scope 1 at $DIR/enum.rs:+2:29: +2:30
+          _2 = _4;                         // scope 3 at $DIR/enum.rs:+2:35: +2:36
+          StorageDead(_4);                 // scope 1 at $DIR/enum.rs:+2:35: +2:36
+          goto -> bb4;                     // scope 1 at $DIR/enum.rs:+2:35: +2:36
+      }
+  
+      bb4: {
+          _0 = const ();                   // scope 0 at $DIR/enum.rs:+0:11: +3:2
+          StorageDead(_2);                 // scope 1 at $DIR/enum.rs:+3:1: +3:2
+          StorageDead(_1);                 // scope 0 at $DIR/enum.rs:+3:1: +3:2
+          return;                          // scope 0 at $DIR/enum.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs
new file mode 100644
index 00000000000..13288577dea
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/enum.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+
+// Not trackable, because variants could be aliased.
+enum E {
+    V1(i32),
+    V2(i32)
+}
+
+// EMIT_MIR enum.main.DataflowConstProp.diff
+fn main() {
+    let e = E::V1(0);
+    let x = match e { E::V1(x) => x, E::V2(x) => x };
+}
diff --git a/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..32489b4bd6b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
@@ -0,0 +1,112 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/if.rs:+0:11: +0:11
+      let _1: i32;                         // in scope 0 at $DIR/if.rs:+1:9: +1:10
+      let mut _3: bool;                    // in scope 0 at $DIR/if.rs:+2:16: +2:22
+      let mut _4: i32;                     // in scope 0 at $DIR/if.rs:+2:16: +2:17
+      let mut _6: i32;                     // in scope 0 at $DIR/if.rs:+3:13: +3:14
+      let mut _8: bool;                    // in scope 0 at $DIR/if.rs:+5:16: +5:22
+      let mut _9: i32;                     // in scope 0 at $DIR/if.rs:+5:16: +5:17
+      let mut _10: i32;                    // in scope 0 at $DIR/if.rs:+5:36: +5:37
+      let mut _12: i32;                    // in scope 0 at $DIR/if.rs:+6:13: +6:14
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/if.rs:+1:9: +1:10
+          let _2: i32;                     // in scope 1 at $DIR/if.rs:+2:9: +2:10
+          scope 2 {
+              debug b => _2;               // in scope 2 at $DIR/if.rs:+2:9: +2:10
+              let _5: i32;                 // in scope 2 at $DIR/if.rs:+3:9: +3:10
+              scope 3 {
+                  debug c => _5;           // in scope 3 at $DIR/if.rs:+3:9: +3:10
+                  let _7: i32;             // in scope 3 at $DIR/if.rs:+5:9: +5:10
+                  scope 4 {
+                      debug d => _7;       // in scope 4 at $DIR/if.rs:+5:9: +5:10
+                      let _11: i32;        // in scope 4 at $DIR/if.rs:+6:9: +6:10
+                      scope 5 {
+                          debug e => _11;  // in scope 5 at $DIR/if.rs:+6:9: +6:10
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/if.rs:+1:9: +1:10
+          _1 = const 1_i32;                // scope 0 at $DIR/if.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 1 at $DIR/if.rs:+2:9: +2:10
+          StorageLive(_3);                 // scope 1 at $DIR/if.rs:+2:16: +2:22
+          StorageLive(_4);                 // scope 1 at $DIR/if.rs:+2:16: +2:17
+-         _4 = _1;                         // scope 1 at $DIR/if.rs:+2:16: +2:17
+-         _3 = Eq(move _4, const 1_i32);   // scope 1 at $DIR/if.rs:+2:16: +2:22
++         _4 = const 1_i32;                // scope 1 at $DIR/if.rs:+2:16: +2:17
++         _3 = const true;                 // scope 1 at $DIR/if.rs:+2:16: +2:22
+          StorageDead(_4);                 // scope 1 at $DIR/if.rs:+2:21: +2:22
+-         switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
++         switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
+      }
+  
+      bb1: {
+          _2 = const 2_i32;                // scope 1 at $DIR/if.rs:+2:25: +2:26
+          goto -> bb3;                     // scope 1 at $DIR/if.rs:+2:13: +2:39
+      }
+  
+      bb2: {
+          _2 = const 3_i32;                // scope 1 at $DIR/if.rs:+2:36: +2:37
+          goto -> bb3;                     // scope 1 at $DIR/if.rs:+2:13: +2:39
+      }
+  
+      bb3: {
+          StorageDead(_3);                 // scope 1 at $DIR/if.rs:+2:38: +2:39
+          StorageLive(_5);                 // scope 2 at $DIR/if.rs:+3:9: +3:10
+          StorageLive(_6);                 // scope 2 at $DIR/if.rs:+3:13: +3:14
+-         _6 = _2;                         // scope 2 at $DIR/if.rs:+3:13: +3:14
+-         _5 = Add(move _6, const 1_i32);  // scope 2 at $DIR/if.rs:+3:13: +3:18
++         _6 = const 2_i32;                // scope 2 at $DIR/if.rs:+3:13: +3:14
++         _5 = const 3_i32;                // scope 2 at $DIR/if.rs:+3:13: +3:18
+          StorageDead(_6);                 // scope 2 at $DIR/if.rs:+3:17: +3:18
+          StorageLive(_7);                 // scope 3 at $DIR/if.rs:+5:9: +5:10
+          StorageLive(_8);                 // scope 3 at $DIR/if.rs:+5:16: +5:22
+          StorageLive(_9);                 // scope 3 at $DIR/if.rs:+5:16: +5:17
+-         _9 = _1;                         // scope 3 at $DIR/if.rs:+5:16: +5:17
+-         _8 = Eq(move _9, const 1_i32);   // scope 3 at $DIR/if.rs:+5:16: +5:22
++         _9 = const 1_i32;                // scope 3 at $DIR/if.rs:+5:16: +5:17
++         _8 = const true;                 // scope 3 at $DIR/if.rs:+5:16: +5:22
+          StorageDead(_9);                 // scope 3 at $DIR/if.rs:+5:21: +5:22
+-         switchInt(move _8) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
++         switchInt(const true) -> [0: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
+      }
+  
+      bb4: {
+-         _7 = _1;                         // scope 3 at $DIR/if.rs:+5:25: +5:26
++         _7 = const 1_i32;                // scope 3 at $DIR/if.rs:+5:25: +5:26
+          goto -> bb6;                     // scope 3 at $DIR/if.rs:+5:13: +5:43
+      }
+  
+      bb5: {
+          StorageLive(_10);                // scope 3 at $DIR/if.rs:+5:36: +5:37
+          _10 = _1;                        // scope 3 at $DIR/if.rs:+5:36: +5:37
+          _7 = Add(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:36: +5:41
+          StorageDead(_10);                // scope 3 at $DIR/if.rs:+5:40: +5:41
+          goto -> bb6;                     // scope 3 at $DIR/if.rs:+5:13: +5:43
+      }
+  
+      bb6: {
+          StorageDead(_8);                 // scope 3 at $DIR/if.rs:+5:42: +5:43
+          StorageLive(_11);                // scope 4 at $DIR/if.rs:+6:9: +6:10
+          StorageLive(_12);                // scope 4 at $DIR/if.rs:+6:13: +6:14
+-         _12 = _7;                        // scope 4 at $DIR/if.rs:+6:13: +6:14
+-         _11 = Add(move _12, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18
++         _12 = const 1_i32;               // scope 4 at $DIR/if.rs:+6:13: +6:14
++         _11 = const 2_i32;               // scope 4 at $DIR/if.rs:+6:13: +6:18
+          StorageDead(_12);                // scope 4 at $DIR/if.rs:+6:17: +6:18
+          _0 = const ();                   // scope 0 at $DIR/if.rs:+0:11: +7:2
+          StorageDead(_11);                // scope 4 at $DIR/if.rs:+7:1: +7:2
+          StorageDead(_7);                 // scope 3 at $DIR/if.rs:+7:1: +7:2
+          StorageDead(_5);                 // scope 2 at $DIR/if.rs:+7:1: +7:2
+          StorageDead(_2);                 // scope 1 at $DIR/if.rs:+7:1: +7:2
+          StorageDead(_1);                 // scope 0 at $DIR/if.rs:+7:1: +7:2
+          return;                          // scope 0 at $DIR/if.rs:+7:2: +7:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/if.rs b/tests/mir-opt/dataflow-const-prop/if.rs
new file mode 100644
index 00000000000..34fc35790c1
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/if.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR if.main.DataflowConstProp.diff
+fn main() {
+    let a = 1;
+    let b = if a == 1 { 2 } else { 3 };
+    let c = b + 1;
+
+    let d = if a == 1 { a } else { a + 1 };
+    let e = d + 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..02aafd7acc4
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
@@ -0,0 +1,39 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11
+      let mut _1: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      let mut _2: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      scope 1 {
+      }
+      scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47
+          debug self => _1;                // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          debug other => _2;               // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          let mut _3: u8;                  // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          let mut _4: u8;                  // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          let mut _5: (u8, bool);          // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          _1 = const u8::MAX;              // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageLive(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          _2 = const 1_u8;                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          _3 = const u8::MAX;              // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          _4 = const 1_u8;                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+      }
+  
+      bb1: {
+          StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          StorageDead(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageDead(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          return;                          // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
new file mode 100644
index 00000000000..2f2d9d0102d
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Zunsound-mir-opts
+
+// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
+fn main() {
+    // After inlining, this will contain a `CheckedBinaryOp`. The overflow
+    // must be ignored by the constant propagation to avoid triggering a panic.
+    let _ = <u8 as std::ops::Add>::add(255, 1);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
new file mode 100644
index 00000000000..5a87884977c
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `f` before DataflowConstProp
++ // MIR for `f` after DataflowConstProp
+  
+  fn f() -> usize {
+      let mut _0: usize;                   // return place in scope 0 at $DIR/issue_81605.rs:+0:11: +0:16
+      let mut _1: usize;                   // in scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+      let mut _2: bool;                    // in scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+          StorageLive(_2);                 // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+          _2 = const true;                 // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+-         switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
++         switchInt(const true) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+      }
+  
+      bb1: {
+          _1 = const 1_usize;              // scope 0 at $DIR/issue_81605.rs:+1:19: +1:20
+          goto -> bb3;                     // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+      }
+  
+      bb2: {
+          _1 = const 2_usize;              // scope 0 at $DIR/issue_81605.rs:+1:30: +1:31
+          goto -> bb3;                     // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+      }
+  
+      bb3: {
+          StorageDead(_2);                 // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+-         _0 = Add(const 1_usize, move _1); // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
++         _0 = const 2_usize;              // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
+          StorageDead(_1);                 // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+          return;                          // scope 0 at $DIR/issue_81605.rs:+2:2: +2:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/issue_81605.rs b/tests/mir-opt/dataflow-const-prop/issue_81605.rs
new file mode 100644
index 00000000000..d75e2a28bef
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/issue_81605.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR issue_81605.f.DataflowConstProp.diff
+fn f() -> usize {
+    1 + if true { 1 } else { 2 }
+}
+
+fn main() {
+    f();
+}
diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..158f187f157
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
@@ -0,0 +1,55 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/ref_without_sb.rs:+0:11: +0:11
+      let mut _1: i32;                     // in scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+      let _2: ();                          // in scope 0 at $DIR/ref_without_sb.rs:+2:5: +2:15
+      let mut _3: &i32;                    // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+      let _4: &i32;                        // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+      let _5: ();                          // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14
+          let _6: i32;                     // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+          scope 2 {
+              debug b => _6;               // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+          _1 = const 0_i32;                // scope 0 at $DIR/ref_without_sb.rs:+1:17: +1:18
+          StorageLive(_2);                 // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+          StorageLive(_3);                 // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+          StorageLive(_4);                 // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+          _4 = &_1;                        // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+          _3 = &(*_4);                     // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+          _2 = escape::<i32>(move _3) -> bb1; // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+                                           // mir::Constant
+                                           // + span: $DIR/ref_without_sb.rs:12:5: 12:11
+                                           // + literal: Const { ty: for<'a> fn(&'a i32) {escape::<i32>}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 1 at $DIR/ref_without_sb.rs:+2:14: +2:15
+          StorageDead(_4);                 // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+          StorageDead(_2);                 // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+          _1 = const 1_i32;                // scope 1 at $DIR/ref_without_sb.rs:+3:5: +3:10
+          StorageLive(_5);                 // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+          _5 = some_function() -> bb2;     // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+                                           // mir::Constant
+                                           // + span: $DIR/ref_without_sb.rs:14:5: 14:18
+                                           // + literal: Const { ty: fn() {some_function}, val: Value(<ZST>) }
+      }
+  
+      bb2: {
+          StorageDead(_5);                 // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21
+          StorageLive(_6);                 // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+          _6 = _1;                         // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14
+          _0 = const ();                   // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2
+          StorageDead(_6);                 // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2
+          StorageDead(_1);                 // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2
+          return;                          // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs
new file mode 100644
index 00000000000..2fd480b0968
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/ref_without_sb.rs
@@ -0,0 +1,17 @@
+// unit-test: DataflowConstProp
+
+#[inline(never)]
+fn escape<T>(x: &T) {}
+
+#[inline(never)]
+fn some_function() {}
+
+// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
+fn main() {
+    let mut a = 0;
+    escape(&a);
+    a = 1;
+    some_function();
+    // This should currently not be propagated.
+    let b = a;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..f66b00a9a22
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
@@ -0,0 +1,44 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/repr_transparent.rs:+0:11: +0:11
+      let _1: I32;                         // in scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+      let mut _3: i32;                     // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:26
+      let mut _4: i32;                     // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:20
+      let mut _5: i32;                     // in scope 0 at $DIR/repr_transparent.rs:+2:23: +2:26
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/repr_transparent.rs:+1:9: +1:10
+          let _2: I32;                     // in scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+          scope 2 {
+              debug y => _2;               // in scope 2 at $DIR/repr_transparent.rs:+2:9: +2:10
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+          Deinit(_1);                      // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+          (_1.0: i32) = const 0_i32;       // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+          StorageLive(_2);                 // scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+          StorageLive(_3);                 // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+          StorageLive(_4);                 // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+-         _4 = (_1.0: i32);                // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
++         _4 = const 0_i32;                // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+          StorageLive(_5);                 // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+-         _5 = (_1.0: i32);                // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+-         _3 = Add(move _4, move _5);      // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
++         _5 = const 0_i32;                // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
++         _3 = const 0_i32;                // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+          StorageDead(_5);                 // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+          StorageDead(_4);                 // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+          Deinit(_2);                      // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+-         (_2.0: i32) = move _3;           // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
++         (_2.0: i32) = const 0_i32;       // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+          StorageDead(_3);                 // scope 1 at $DIR/repr_transparent.rs:+2:26: +2:27
+          _0 = const ();                   // scope 0 at $DIR/repr_transparent.rs:+0:11: +3:2
+          StorageDead(_2);                 // scope 1 at $DIR/repr_transparent.rs:+3:1: +3:2
+          StorageDead(_1);                 // scope 0 at $DIR/repr_transparent.rs:+3:1: +3:2
+          return;                          // scope 0 at $DIR/repr_transparent.rs:+3:2: +3:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/repr_transparent.rs b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs
new file mode 100644
index 00000000000..4ce0ca4dff4
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/repr_transparent.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// The struct has scalar ABI, but is not a scalar type.
+// Make sure that we handle this correctly.
+#[repr(transparent)]
+struct I32(i32);
+
+// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
+fn main() {
+    let x = I32(0);
+    let y = I32(x.0 + x.0);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..df08eff94cb
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
@@ -0,0 +1,46 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/self_assign.rs:+0:11: +0:11
+      let mut _1: i32;                     // in scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+      let mut _2: i32;                     // in scope 0 at $DIR/self_assign.rs:+2:9: +2:10
+      let mut _3: i32;                     // in scope 0 at $DIR/self_assign.rs:+3:9: +3:10
+      let mut _5: &i32;                    // in scope 0 at $DIR/self_assign.rs:+6:9: +6:10
+      let mut _6: i32;                     // in scope 0 at $DIR/self_assign.rs:+7:9: +7:11
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/self_assign.rs:+1:9: +1:14
+          let mut _4: &i32;                // in scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+          scope 2 {
+              debug b => _4;               // in scope 2 at $DIR/self_assign.rs:+5:9: +5:14
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+          _1 = const 0_i32;                // scope 0 at $DIR/self_assign.rs:+1:17: +1:18
+          StorageLive(_2);                 // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+          _2 = _1;                         // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+          _1 = Add(move _2, const 1_i32);  // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
+          StorageDead(_2);                 // scope 1 at $DIR/self_assign.rs:+2:13: +2:14
+          StorageLive(_3);                 // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+          _3 = _1;                         // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+          _1 = move _3;                    // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
+          StorageDead(_3);                 // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+          StorageLive(_4);                 // scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+          _4 = &_1;                        // scope 1 at $DIR/self_assign.rs:+5:17: +5:19
+          StorageLive(_5);                 // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+          _5 = _4;                         // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+          _4 = move _5;                    // scope 2 at $DIR/self_assign.rs:+6:5: +6:10
+          StorageDead(_5);                 // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+          StorageLive(_6);                 // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+          _6 = (*_4);                      // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+          _1 = move _6;                    // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
+          StorageDead(_6);                 // scope 2 at $DIR/self_assign.rs:+7:10: +7:11
+          _0 = const ();                   // scope 0 at $DIR/self_assign.rs:+0:11: +8:2
+          StorageDead(_4);                 // scope 1 at $DIR/self_assign.rs:+8:1: +8:2
+          StorageDead(_1);                 // scope 0 at $DIR/self_assign.rs:+8:1: +8:2
+          return;                          // scope 0 at $DIR/self_assign.rs:+8:2: +8:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign.rs b/tests/mir-opt/dataflow-const-prop/self_assign.rs
new file mode 100644
index 00000000000..8de2195f93b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign.main.DataflowConstProp.diff
+fn main() {
+    let mut a = 0;
+    a = a + 1;
+    a = a;
+
+    let mut b = &a;
+    b = b;
+    a = *b;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..c09e4061ede
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
@@ -0,0 +1,23 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/self_assign_add.rs:+0:11: +0:11
+      let mut _1: i32;                     // in scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/self_assign_add.rs:+1:9: +1:14
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+          _1 = const 0_i32;                // scope 0 at $DIR/self_assign_add.rs:+1:17: +1:18
+-         _1 = Add(_1, const 1_i32);       // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
+-         _1 = Add(_1, const 1_i32);       // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
++         _1 = const 1_i32;                // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
++         _1 = const 2_i32;                // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
+          _0 = const ();                   // scope 0 at $DIR/self_assign_add.rs:+0:11: +4:2
+          StorageDead(_1);                 // scope 0 at $DIR/self_assign_add.rs:+4:1: +4:2
+          return;                          // scope 0 at $DIR/self_assign_add.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/self_assign_add.rs b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs
new file mode 100644
index 00000000000..e3282762459
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/self_assign_add.rs
@@ -0,0 +1,8 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
+fn main() {
+    let mut a = 0;
+    a += 1;
+    a += 1;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..8126d4b8585
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/sibling_ptr.rs:+0:11: +0:11
+      let mut _1: (u8, u8);                // in scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+      let _2: ();                          // in scope 0 at $DIR/sibling_ptr.rs:+2:5: +5:6
+      let mut _4: *mut u8;                 // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:18
+      let mut _5: *mut u8;                 // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:11
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/sibling_ptr.rs:+1:9: +1:14
+          let _6: u8;                      // in scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+          scope 2 {
+              let _3: *mut u8;             // in scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+              scope 3 {
+                  debug p => _3;           // in scope 3 at $DIR/sibling_ptr.rs:+3:13: +3:14
+              }
+          }
+          scope 4 {
+              debug x1 => _6;              // in scope 4 at $DIR/sibling_ptr.rs:+6:9: +6:11
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+          Deinit(_1);                      // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+          (_1.0: u8) = const 0_u8;         // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+          (_1.1: u8) = const 0_u8;         // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+          StorageLive(_2);                 // scope 1 at $DIR/sibling_ptr.rs:+2:5: +5:6
+          StorageLive(_3);                 // scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+          _3 = &raw mut (_1.0: u8);        // scope 2 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+          StorageLive(_4);                 // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+          StorageLive(_5);                 // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+          _5 = _3;                         // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+          _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+                                           // mir::Constant
+                                           // + span: $DIR/sibling_ptr.rs:8:12: 8:15
+                                           // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::<impl *mut u8>::add}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_5);                 // scope 3 at $DIR/sibling_ptr.rs:+4:17: +4:18
+          (*_4) = const 1_u8;              // scope 3 at $DIR/sibling_ptr.rs:+4:9: +4:22
+          StorageDead(_4);                 // scope 3 at $DIR/sibling_ptr.rs:+4:22: +4:23
+          _2 = const ();                   // scope 2 at $DIR/sibling_ptr.rs:+2:5: +5:6
+          StorageDead(_3);                 // scope 2 at $DIR/sibling_ptr.rs:+5:5: +5:6
+          StorageDead(_2);                 // scope 1 at $DIR/sibling_ptr.rs:+5:5: +5:6
+          StorageLive(_6);                 // scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+          _6 = (_1.1: u8);                 // scope 1 at $DIR/sibling_ptr.rs:+6:14: +6:17
+          _0 = const ();                   // scope 0 at $DIR/sibling_ptr.rs:+0:11: +7:2
+          StorageDead(_6);                 // scope 1 at $DIR/sibling_ptr.rs:+7:1: +7:2
+          StorageDead(_1);                 // scope 0 at $DIR/sibling_ptr.rs:+7:1: +7:2
+          return;                          // scope 0 at $DIR/sibling_ptr.rs:+7:2: +7:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs
new file mode 100644
index 00000000000..87ef00d1829
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
+fn main() {
+    let mut x: (u8, u8) = (0, 0);
+    unsafe {
+        let p = std::ptr::addr_of_mut!(x.0);
+        *p.add(1) = 1;
+    }
+    let x1 = x.1;  // should not be propagated
+}
diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..cfb2706c167
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/struct.rs:+0:11: +0:11
+      let mut _1: S;                       // in scope 0 at $DIR/struct.rs:+1:9: +1:14
+      let mut _3: i32;                     // in scope 0 at $DIR/struct.rs:+2:13: +2:16
+      let mut _5: i32;                     // in scope 0 at $DIR/struct.rs:+4:13: +4:14
+      let mut _6: i32;                     // in scope 0 at $DIR/struct.rs:+4:17: +4:20
+      scope 1 {
+          debug s => _1;                   // in scope 1 at $DIR/struct.rs:+1:9: +1:14
+          let _2: i32;                     // in scope 1 at $DIR/struct.rs:+2:9: +2:10
+          scope 2 {
+              debug a => _2;               // in scope 2 at $DIR/struct.rs:+2:9: +2:10
+              let _4: i32;                 // in scope 2 at $DIR/struct.rs:+4:9: +4:10
+              scope 3 {
+                  debug b => _4;           // in scope 3 at $DIR/struct.rs:+4:9: +4:10
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/struct.rs:+1:9: +1:14
+          Deinit(_1);                      // scope 0 at $DIR/struct.rs:+1:17: +1:21
+          (_1.0: i32) = const 1_i32;       // scope 0 at $DIR/struct.rs:+1:17: +1:21
+          StorageLive(_2);                 // scope 1 at $DIR/struct.rs:+2:9: +2:10
+          StorageLive(_3);                 // scope 1 at $DIR/struct.rs:+2:13: +2:16
+-         _3 = (_1.0: i32);                // scope 1 at $DIR/struct.rs:+2:13: +2:16
+-         _2 = Add(move _3, const 2_i32);  // scope 1 at $DIR/struct.rs:+2:13: +2:20
++         _3 = const 1_i32;                // scope 1 at $DIR/struct.rs:+2:13: +2:16
++         _2 = const 3_i32;                // scope 1 at $DIR/struct.rs:+2:13: +2:20
+          StorageDead(_3);                 // scope 1 at $DIR/struct.rs:+2:19: +2:20
+          (_1.0: i32) = const 3_i32;       // scope 2 at $DIR/struct.rs:+3:5: +3:12
+          StorageLive(_4);                 // scope 2 at $DIR/struct.rs:+4:9: +4:10
+          StorageLive(_5);                 // scope 2 at $DIR/struct.rs:+4:13: +4:14
+-         _5 = _2;                         // scope 2 at $DIR/struct.rs:+4:13: +4:14
++         _5 = const 3_i32;                // scope 2 at $DIR/struct.rs:+4:13: +4:14
+          StorageLive(_6);                 // scope 2 at $DIR/struct.rs:+4:17: +4:20
+-         _6 = (_1.0: i32);                // scope 2 at $DIR/struct.rs:+4:17: +4:20
+-         _4 = Add(move _5, move _6);      // scope 2 at $DIR/struct.rs:+4:13: +4:20
++         _6 = const 3_i32;                // scope 2 at $DIR/struct.rs:+4:17: +4:20
++         _4 = const 6_i32;                // scope 2 at $DIR/struct.rs:+4:13: +4:20
+          StorageDead(_6);                 // scope 2 at $DIR/struct.rs:+4:19: +4:20
+          StorageDead(_5);                 // scope 2 at $DIR/struct.rs:+4:19: +4:20
+          _0 = const ();                   // scope 0 at $DIR/struct.rs:+0:11: +5:2
+          StorageDead(_4);                 // scope 2 at $DIR/struct.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/struct.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/struct.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/struct.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/struct.rs b/tests/mir-opt/dataflow-const-prop/struct.rs
new file mode 100644
index 00000000000..841b279e03e
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/struct.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+struct S(i32);
+
+// EMIT_MIR struct.main.DataflowConstProp.diff
+fn main() {
+    let mut s = S(1);
+    let a = s.0 + 2;
+    s.0 = 3;
+    let b = a + s.0;
+}
diff --git a/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..8018400e798
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
@@ -0,0 +1,40 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11
+      let _1: i32;                         // in scope 0 at $DIR/terminator.rs:+1:9: +1:10
+      let _2: ();                          // in scope 0 at $DIR/terminator.rs:+3:5: +3:15
+      let mut _3: i32;                     // in scope 0 at $DIR/terminator.rs:+3:9: +3:14
+      let mut _4: i32;                     // in scope 0 at $DIR/terminator.rs:+3:9: +3:10
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/terminator.rs:+1:9: +1:10
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/terminator.rs:+1:9: +1:10
+          _1 = const 1_i32;                // scope 0 at $DIR/terminator.rs:+1:13: +1:14
+          StorageLive(_2);                 // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+          StorageLive(_3);                 // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+          StorageLive(_4);                 // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+-         _4 = _1;                         // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+-         _3 = Add(move _4, const 1_i32);  // scope 1 at $DIR/terminator.rs:+3:9: +3:14
++         _4 = const 1_i32;                // scope 1 at $DIR/terminator.rs:+3:9: +3:10
++         _3 = const 2_i32;                // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+          StorageDead(_4);                 // scope 1 at $DIR/terminator.rs:+3:13: +3:14
+-         _2 = foo(move _3) -> bb1;        // scope 1 at $DIR/terminator.rs:+3:5: +3:15
++         _2 = foo(const 2_i32) -> bb1;    // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+                                           // mir::Constant
+                                           // + span: $DIR/terminator.rs:9:5: 9:8
+                                           // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+      }
+  
+      bb1: {
+          StorageDead(_3);                 // scope 1 at $DIR/terminator.rs:+3:14: +3:15
+          StorageDead(_2);                 // scope 1 at $DIR/terminator.rs:+3:15: +3:16
+          _0 = const ();                   // scope 0 at $DIR/terminator.rs:+0:11: +4:2
+          StorageDead(_1);                 // scope 0 at $DIR/terminator.rs:+4:1: +4:2
+          return;                          // scope 0 at $DIR/terminator.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/terminator.rs b/tests/mir-opt/dataflow-const-prop/terminator.rs
new file mode 100644
index 00000000000..d151f666a2d
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/terminator.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+fn foo(n: i32) {}
+
+// EMIT_MIR terminator.main.DataflowConstProp.diff
+fn main() {
+    let a = 1;
+    // Checks that we propagate into terminators.
+    foo(a + 1);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
new file mode 100644
index 00000000000..e028def00a1
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/tuple.rs:+0:11: +0:11
+      let mut _1: (i32, i32);              // in scope 0 at $DIR/tuple.rs:+1:9: +1:14
+      let mut _3: i32;                     // in scope 0 at $DIR/tuple.rs:+2:13: +2:22
+      let mut _4: i32;                     // in scope 0 at $DIR/tuple.rs:+2:13: +2:16
+      let mut _5: i32;                     // in scope 0 at $DIR/tuple.rs:+2:19: +2:22
+      let mut _7: i32;                     // in scope 0 at $DIR/tuple.rs:+4:13: +4:22
+      let mut _8: i32;                     // in scope 0 at $DIR/tuple.rs:+4:13: +4:16
+      let mut _9: i32;                     // in scope 0 at $DIR/tuple.rs:+4:19: +4:22
+      let mut _10: i32;                    // in scope 0 at $DIR/tuple.rs:+4:25: +4:26
+      scope 1 {
+          debug a => _1;                   // in scope 1 at $DIR/tuple.rs:+1:9: +1:14
+          let _2: i32;                     // in scope 1 at $DIR/tuple.rs:+2:9: +2:10
+          scope 2 {
+              debug b => _2;               // in scope 2 at $DIR/tuple.rs:+2:9: +2:10
+              let _6: i32;                 // in scope 2 at $DIR/tuple.rs:+4:9: +4:10
+              scope 3 {
+                  debug c => _6;           // in scope 3 at $DIR/tuple.rs:+4:9: +4:10
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/tuple.rs:+1:9: +1:14
+          Deinit(_1);                      // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+          (_1.0: i32) = const 1_i32;       // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+          (_1.1: i32) = const 2_i32;       // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+          StorageLive(_2);                 // scope 1 at $DIR/tuple.rs:+2:9: +2:10
+          StorageLive(_3);                 // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+          StorageLive(_4);                 // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+-         _4 = (_1.0: i32);                // scope 1 at $DIR/tuple.rs:+2:13: +2:16
++         _4 = const 1_i32;                // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+          StorageLive(_5);                 // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+-         _5 = (_1.1: i32);                // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+-         _3 = Add(move _4, move _5);      // scope 1 at $DIR/tuple.rs:+2:13: +2:22
++         _5 = const 2_i32;                // scope 1 at $DIR/tuple.rs:+2:19: +2:22
++         _3 = const 3_i32;                // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+          StorageDead(_5);                 // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+          StorageDead(_4);                 // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+-         _2 = Add(move _3, const 3_i32);  // scope 1 at $DIR/tuple.rs:+2:13: +2:26
++         _2 = const 6_i32;                // scope 1 at $DIR/tuple.rs:+2:13: +2:26
+          StorageDead(_3);                 // scope 1 at $DIR/tuple.rs:+2:25: +2:26
+          Deinit(_1);                      // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+          (_1.0: i32) = const 2_i32;       // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+          (_1.1: i32) = const 3_i32;       // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+          StorageLive(_6);                 // scope 2 at $DIR/tuple.rs:+4:9: +4:10
+          StorageLive(_7);                 // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+          StorageLive(_8);                 // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+-         _8 = (_1.0: i32);                // scope 2 at $DIR/tuple.rs:+4:13: +4:16
++         _8 = const 2_i32;                // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+          StorageLive(_9);                 // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+-         _9 = (_1.1: i32);                // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+-         _7 = Add(move _8, move _9);      // scope 2 at $DIR/tuple.rs:+4:13: +4:22
++         _9 = const 3_i32;                // scope 2 at $DIR/tuple.rs:+4:19: +4:22
++         _7 = const 5_i32;                // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+          StorageDead(_9);                 // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+          StorageDead(_8);                 // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+          StorageLive(_10);                // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+-         _10 = _2;                        // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+-         _6 = Add(move _7, move _10);     // scope 2 at $DIR/tuple.rs:+4:13: +4:26
++         _10 = const 6_i32;               // scope 2 at $DIR/tuple.rs:+4:25: +4:26
++         _6 = const 11_i32;               // scope 2 at $DIR/tuple.rs:+4:13: +4:26
+          StorageDead(_10);                // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+          StorageDead(_7);                 // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+          _0 = const ();                   // scope 0 at $DIR/tuple.rs:+0:11: +5:2
+          StorageDead(_6);                 // scope 2 at $DIR/tuple.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/tuple.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/tuple.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/tuple.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/tuple.rs b/tests/mir-opt/dataflow-const-prop/tuple.rs
new file mode 100644
index 00000000000..92c70eab0ff
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/tuple.rs
@@ -0,0 +1,9 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR tuple.main.DataflowConstProp.diff
+fn main() {
+    let mut a = (1, 2);
+    let b = a.0 + a.1 + 3;
+    a = (2, 3);
+    let c = a.0 + a.1 + b;
+}