From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- .../cast.main.DataflowConstProp.diff | 37 +++++++ src/test/mir-opt/dataflow-const-prop/cast.rs | 7 ++ .../checked.main.DataflowConstProp.diff | 80 +++++++++++++++ src/test/mir-opt/dataflow-const-prop/checked.rs | 13 +++ .../enum.main.DataflowConstProp.diff | 61 +++++++++++ src/test/mir-opt/dataflow-const-prop/enum.rs | 13 +++ .../if.main.DataflowConstProp.diff | 112 +++++++++++++++++++++ src/test/mir-opt/dataflow-const-prop/if.rs | 11 ++ .../inherit_overflow.main.DataflowConstProp.diff | 45 +++++++++ .../dataflow-const-prop/inherit_overflow.rs | 8 ++ .../issue_81605.f.DataflowConstProp.diff | 35 +++++++ .../mir-opt/dataflow-const-prop/issue_81605.rs | 10 ++ .../ref_without_sb.main.DataflowConstProp.diff | 55 ++++++++++ .../mir-opt/dataflow-const-prop/ref_without_sb.rs | 17 ++++ .../repr_transparent.main.DataflowConstProp.diff | 44 ++++++++ .../dataflow-const-prop/repr_transparent.rs | 12 +++ .../self_assign.main.DataflowConstProp.diff | 46 +++++++++ .../mir-opt/dataflow-const-prop/self_assign.rs | 12 +++ .../self_assign_add.main.DataflowConstProp.diff | 23 +++++ .../mir-opt/dataflow-const-prop/self_assign_add.rs | 8 ++ .../sibling_ptr.main.DataflowConstProp.diff | 56 +++++++++++ .../mir-opt/dataflow-const-prop/sibling_ptr.rs | 11 ++ .../struct.main.DataflowConstProp.diff | 52 ++++++++++ src/test/mir-opt/dataflow-const-prop/struct.rs | 11 ++ .../terminator.main.DataflowConstProp.diff | 40 ++++++++ src/test/mir-opt/dataflow-const-prop/terminator.rs | 10 ++ .../tuple.main.DataflowConstProp.diff | 75 ++++++++++++++ src/test/mir-opt/dataflow-const-prop/tuple.rs | 9 ++ 28 files changed, 913 insertions(+) create mode 100644 src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/cast.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/checked.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/enum.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/if.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/issue_81605.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/repr_transparent.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/self_assign.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/self_assign_add.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/struct.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/terminator.rs create mode 100644 src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff create mode 100644 src/test/mir-opt/dataflow-const-prop/tuple.rs (limited to 'src/test/mir-opt/dataflow-const-prop') diff --git a/src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff new file mode 100644 index 000000000..bf9ab8669 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/cast.rs b/src/test/mir-opt/dataflow-const-prop/cast.rs new file mode 100644 index 000000000..484403f7f --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff new file mode 100644 index 000000000..a4ebd0c8c --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/checked.rs b/src/test/mir-opt/dataflow-const-prop/checked.rs new file mode 100644 index 000000000..0738a4ee5 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff new file mode 100644 index 000000000..2ced794e6 --- /dev/null +++ b/src/test/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_isize: bb3, 1_isize: 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/src/test/mir-opt/dataflow-const-prop/enum.rs b/src/test/mir-opt/dataflow-const-prop/enum.rs new file mode 100644 index 000000000..13288577d --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff new file mode 100644 index 000000000..26808c70f --- /dev/null +++ b/src/test/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) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22 ++ switchInt(const true) -> [false: 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) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22 ++ switchInt(const true) -> [false: 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/src/test/mir-opt/dataflow-const-prop/if.rs b/src/test/mir-opt/dataflow-const-prop/if.rs new file mode 100644 index 000000000..34fc35790 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff new file mode 100644 index 000000000..bf4557ed3 --- /dev/null +++ b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff @@ -0,0 +1,45 @@ +- // 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 + let mut _3: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + scope 1 { + } + scope 2 (inlined ::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47 + debug self => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug other => _3; // 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; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _6: (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 + StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _2 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _3 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _4 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _5 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _6 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + assert(!move (_6.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: { +- _1 = move (_6.0: u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL ++ _1 = const 0_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48 + nop; // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2 + return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs new file mode 100644 index 000000000..2f2d9d010 --- /dev/null +++ b/src/test/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 _ = ::add(255, 1); +} diff --git a/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff new file mode 100644 index 000000000..881d80f7c --- /dev/null +++ b/src/test/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) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16 ++ switchInt(const true) -> [false: 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/src/test/mir-opt/dataflow-const-prop/issue_81605.rs b/src/test/mir-opt/dataflow-const-prop/issue_81605.rs new file mode 100644 index 000000000..d75e2a28b --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff new file mode 100644 index 000000000..158f187f1 --- /dev/null +++ b/src/test/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::(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::}, val: Value() } + } + + 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() } + } + + 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/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs new file mode 100644 index 000000000..2fd480b09 --- /dev/null +++ b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs @@ -0,0 +1,17 @@ +// unit-test: DataflowConstProp + +#[inline(never)] +fn escape(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/src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff new file mode 100644 index 000000000..f66b00a9a --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/repr_transparent.rs b/src/test/mir-opt/dataflow-const-prop/repr_transparent.rs new file mode 100644 index 000000000..4ce0ca4df --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff new file mode 100644 index 000000000..df08eff94 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/self_assign.rs b/src/test/mir-opt/dataflow-const-prop/self_assign.rs new file mode 100644 index 000000000..8de2195f9 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff new file mode 100644 index 000000000..c09e4061e --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/self_assign_add.rs b/src/test/mir-opt/dataflow-const-prop/self_assign_add.rs new file mode 100644 index 000000000..e32827624 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff new file mode 100644 index 000000000..8126d4b85 --- /dev/null +++ b/src/test/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::::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::::add}, val: Value() } + } + + 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/src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs new file mode 100644 index 000000000..87ef00d18 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff new file mode 100644 index 000000000..cfb2706c1 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/struct.rs b/src/test/mir-opt/dataflow-const-prop/struct.rs new file mode 100644 index 000000000..841b279e0 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff new file mode 100644 index 000000000..8018400e7 --- /dev/null +++ b/src/test/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() } + } + + 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/src/test/mir-opt/dataflow-const-prop/terminator.rs b/src/test/mir-opt/dataflow-const-prop/terminator.rs new file mode 100644 index 000000000..d151f666a --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff new file mode 100644 index 000000000..e028def00 --- /dev/null +++ b/src/test/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/src/test/mir-opt/dataflow-const-prop/tuple.rs b/src/test/mir-opt/dataflow-const-prop/tuple.rs new file mode 100644 index 000000000..92c70eab0 --- /dev/null +++ b/src/test/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; +} -- cgit v1.2.3