summaryrefslogtreecommitdiffstats
path: root/tests/mir-opt/dataflow-const-prop
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/mir-opt/dataflow-const-prop
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
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 000000000..bf9ab8669
--- /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 000000000..484403f7f
--- /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 000000000..a4ebd0c8c
--- /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 000000000..0738a4ee5
--- /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 000000000..fce18fae4
--- /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 000000000..13288577d
--- /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 000000000..32489b4bd
--- /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 000000000..34fc35790
--- /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 000000000..02aafd7ac
--- /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 000000000..2f2d9d010
--- /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 000000000..5a8788497
--- /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 000000000..d75e2a28b
--- /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 000000000..158f187f1
--- /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 000000000..2fd480b09
--- /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 000000000..f66b00a9a
--- /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 000000000..4ce0ca4df
--- /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 000000000..df08eff94
--- /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 000000000..8de2195f9
--- /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 000000000..c09e4061e
--- /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 000000000..e32827624
--- /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 000000000..8126d4b85
--- /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 000000000..87ef00d18
--- /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 000000000..cfb2706c1
--- /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 000000000..841b279e0
--- /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 000000000..8018400e7
--- /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 000000000..d151f666a
--- /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 000000000..e028def00
--- /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 000000000..92c70eab0
--- /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;
+}