diff options
Diffstat (limited to 'tests')
21 files changed, 1635 insertions, 0 deletions
diff --git a/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..462cc207785 --- /dev/null +++ b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-abort.diff @@ -0,0 +1,57 @@ +- // MIR for `custom_discr` before JumpThreading ++ // MIR for `custom_discr` after JumpThreading + + fn custom_discr(_1: bool) -> u8 { + debug x => _1; + let mut _0: u8; + let mut _2: CustomDiscr; + let mut _3: bool; + let mut _4: u8; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + switchInt(move _3) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _2 = CustomDiscr::A; +- goto -> bb3; ++ goto -> bb7; + } + + bb2: { + _2 = CustomDiscr::B; + goto -> bb3; + } + + bb3: { + StorageDead(_3); + _4 = discriminant(_2); +- switchInt(move _4) -> [35: bb5, otherwise: bb4]; ++ goto -> bb4; + } + + bb4: { + _0 = const 13_u8; + goto -> bb6; + } + + bb5: { + _0 = const 5_u8; + goto -> bb6; + } + + bb6: { + StorageDead(_2); + return; ++ } ++ ++ bb7: { ++ StorageDead(_3); ++ _4 = discriminant(_2); ++ goto -> bb5; + } + } + diff --git a/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..462cc207785 --- /dev/null +++ b/tests/mir-opt/jump_threading.custom_discr.JumpThreading.panic-unwind.diff @@ -0,0 +1,57 @@ +- // MIR for `custom_discr` before JumpThreading ++ // MIR for `custom_discr` after JumpThreading + + fn custom_discr(_1: bool) -> u8 { + debug x => _1; + let mut _0: u8; + let mut _2: CustomDiscr; + let mut _3: bool; + let mut _4: u8; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + switchInt(move _3) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _2 = CustomDiscr::A; +- goto -> bb3; ++ goto -> bb7; + } + + bb2: { + _2 = CustomDiscr::B; + goto -> bb3; + } + + bb3: { + StorageDead(_3); + _4 = discriminant(_2); +- switchInt(move _4) -> [35: bb5, otherwise: bb4]; ++ goto -> bb4; + } + + bb4: { + _0 = const 13_u8; + goto -> bb6; + } + + bb5: { + _0 = const 5_u8; + goto -> bb6; + } + + bb6: { + StorageDead(_2); + return; ++ } ++ ++ bb7: { ++ StorageDead(_3); ++ _4 = discriminant(_2); ++ goto -> bb5; + } + } + diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..bad733268a3 --- /dev/null +++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-abort.diff @@ -0,0 +1,87 @@ +- // MIR for `dfa` before JumpThreading ++ // MIR for `dfa` after JumpThreading + + fn dfa() -> () { + let mut _0: (); + let mut _1: DFA; + let mut _2: !; + let mut _3: (); + let mut _4: isize; + let mut _5: DFA; + let mut _6: DFA; + let mut _7: DFA; + let mut _8: !; + scope 1 { + debug state => _1; + } + + bb0: { + StorageLive(_1); + _1 = DFA::A; + StorageLive(_2); +- goto -> bb1; ++ goto -> bb7; + } + + bb1: { + _4 = discriminant(_1); +- switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3]; ++ goto -> bb2; + } + + bb2: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3: { + unreachable; + } + + bb4: { + StorageLive(_5); + _5 = DFA::B; + _1 = move _5; + _3 = const (); + StorageDead(_5); +- goto -> bb1; ++ goto -> bb8; + } + + bb5: { + StorageLive(_6); + _6 = DFA::C; + _1 = move _6; + _3 = const (); + StorageDead(_6); +- goto -> bb1; ++ goto -> bb9; + } + + bb6: { + StorageLive(_7); + _7 = DFA::D; + _1 = move _7; + _3 = const (); + StorageDead(_7); + goto -> bb1; ++ } ++ ++ bb7: { ++ _4 = discriminant(_1); ++ goto -> bb4; ++ } ++ ++ bb8: { ++ _4 = discriminant(_1); ++ goto -> bb5; ++ } ++ ++ bb9: { ++ _4 = discriminant(_1); ++ goto -> bb6; + } + } + diff --git a/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..bad733268a3 --- /dev/null +++ b/tests/mir-opt/jump_threading.dfa.JumpThreading.panic-unwind.diff @@ -0,0 +1,87 @@ +- // MIR for `dfa` before JumpThreading ++ // MIR for `dfa` after JumpThreading + + fn dfa() -> () { + let mut _0: (); + let mut _1: DFA; + let mut _2: !; + let mut _3: (); + let mut _4: isize; + let mut _5: DFA; + let mut _6: DFA; + let mut _7: DFA; + let mut _8: !; + scope 1 { + debug state => _1; + } + + bb0: { + StorageLive(_1); + _1 = DFA::A; + StorageLive(_2); +- goto -> bb1; ++ goto -> bb7; + } + + bb1: { + _4 = discriminant(_1); +- switchInt(move _4) -> [0: bb4, 1: bb5, 2: bb6, 3: bb2, otherwise: bb3]; ++ goto -> bb2; + } + + bb2: { + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + + bb3: { + unreachable; + } + + bb4: { + StorageLive(_5); + _5 = DFA::B; + _1 = move _5; + _3 = const (); + StorageDead(_5); +- goto -> bb1; ++ goto -> bb8; + } + + bb5: { + StorageLive(_6); + _6 = DFA::C; + _1 = move _6; + _3 = const (); + StorageDead(_6); +- goto -> bb1; ++ goto -> bb9; + } + + bb6: { + StorageLive(_7); + _7 = DFA::D; + _1 = move _7; + _3 = const (); + StorageDead(_7); + goto -> bb1; ++ } ++ ++ bb7: { ++ _4 = discriminant(_1); ++ goto -> bb4; ++ } ++ ++ bb8: { ++ _4 = discriminant(_1); ++ goto -> bb5; ++ } ++ ++ bb9: { ++ _4 = discriminant(_1); ++ goto -> bb6; + } + } + diff --git a/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..d3f737b324c --- /dev/null +++ b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-abort.diff @@ -0,0 +1,57 @@ +- // MIR for `disappearing_bb` before JumpThreading ++ // MIR for `disappearing_bb` after JumpThreading + + fn disappearing_bb(_1: u8) -> u8 { + let mut _0: u8; + let mut _2: i8; + let mut _3: bool; + let mut _4: bool; + + bb0: { + _4 = const false; + _3 = const false; + _4 = const true; + _3 = const true; + switchInt(_1) -> [0: bb3, 1: bb3, 2: bb1, otherwise: bb2]; + } + + bb1: { + _3 = const false; +- goto -> bb4; ++ goto -> bb9; + } + + bb2: { + unreachable; + } + + bb3: { + _4 = const false; + goto -> bb4; + } + + bb4: { + switchInt(_3) -> [0: bb5, otherwise: bb7]; + } + + bb5: { + switchInt(_4) -> [0: bb6, otherwise: bb8]; + } + + bb6: { + return; + } + + bb7: { + goto -> bb5; + } + + bb8: { + goto -> bb6; ++ } ++ ++ bb9: { ++ goto -> bb5; + } + } + diff --git a/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..d3f737b324c --- /dev/null +++ b/tests/mir-opt/jump_threading.disappearing_bb.JumpThreading.panic-unwind.diff @@ -0,0 +1,57 @@ +- // MIR for `disappearing_bb` before JumpThreading ++ // MIR for `disappearing_bb` after JumpThreading + + fn disappearing_bb(_1: u8) -> u8 { + let mut _0: u8; + let mut _2: i8; + let mut _3: bool; + let mut _4: bool; + + bb0: { + _4 = const false; + _3 = const false; + _4 = const true; + _3 = const true; + switchInt(_1) -> [0: bb3, 1: bb3, 2: bb1, otherwise: bb2]; + } + + bb1: { + _3 = const false; +- goto -> bb4; ++ goto -> bb9; + } + + bb2: { + unreachable; + } + + bb3: { + _4 = const false; + goto -> bb4; + } + + bb4: { + switchInt(_3) -> [0: bb5, otherwise: bb7]; + } + + bb5: { + switchInt(_4) -> [0: bb6, otherwise: bb8]; + } + + bb6: { + return; + } + + bb7: { + goto -> bb5; + } + + bb8: { + goto -> bb6; ++ } ++ ++ bb9: { ++ goto -> bb5; + } + } + diff --git a/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..adcedfb3667 --- /dev/null +++ b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-abort.diff @@ -0,0 +1,45 @@ +- // MIR for `duplicate_chain` before JumpThreading ++ // MIR for `duplicate_chain` after JumpThreading + + fn duplicate_chain(_1: bool) -> u8 { + let mut _0: u8; + let mut _2: u8; + let mut _3: i32; + let mut _4: i32; + + bb0: { + switchInt(_1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + _2 = const 5_u8; + goto -> bb3; + } + + bb2: { + _2 = const 5_u8; + goto -> bb3; + } + + bb3: { + _3 = const 13_i32; + goto -> bb4; + } + + bb4: { + _4 = const 15_i32; +- switchInt(_2) -> [5: bb5, otherwise: bb6]; ++ goto -> bb5; + } + + bb5: { + _0 = const 7_u8; + return; + } + + bb6: { + _0 = const 9_u8; + return; + } + } + diff --git a/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..adcedfb3667 --- /dev/null +++ b/tests/mir-opt/jump_threading.duplicate_chain.JumpThreading.panic-unwind.diff @@ -0,0 +1,45 @@ +- // MIR for `duplicate_chain` before JumpThreading ++ // MIR for `duplicate_chain` after JumpThreading + + fn duplicate_chain(_1: bool) -> u8 { + let mut _0: u8; + let mut _2: u8; + let mut _3: i32; + let mut _4: i32; + + bb0: { + switchInt(_1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + _2 = const 5_u8; + goto -> bb3; + } + + bb2: { + _2 = const 5_u8; + goto -> bb3; + } + + bb3: { + _3 = const 13_i32; + goto -> bb4; + } + + bb4: { + _4 = const 15_i32; +- switchInt(_2) -> [5: bb5, otherwise: bb6]; ++ goto -> bb5; + } + + bb5: { + _0 = const 7_u8; + return; + } + + bb6: { + _0 = const 9_u8; + return; + } + } + diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..f17c9ba3f9f --- /dev/null +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -0,0 +1,139 @@ +- // MIR for `identity` before JumpThreading ++ // MIR for `identity` after JumpThreading + + fn identity(_1: Result<i32, i32>) -> Result<i32, i32> { + debug x => _1; + let mut _0: std::result::Result<i32, i32>; + let mut _2: i32; + let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; + let mut _4: std::result::Result<i32, i32>; + let mut _5: isize; + let _6: std::result::Result<std::convert::Infallible, i32>; + let mut _7: !; + let mut _8: std::result::Result<std::convert::Infallible, i32>; + let _9: i32; + scope 1 { + debug residual => _6; + scope 2 { + scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { + debug residual => _8; + let _14: i32; + let mut _15: i32; + scope 9 { + debug e => _14; + scope 10 (inlined <i32 as From<i32>>::from) { + debug t => _14; + } + } + } + } + } + scope 3 { + debug val => _9; + scope 4 { + } + } + scope 5 (inlined <Result<i32, i32> as Try>::branch) { + debug self => _4; + let mut _10: isize; + let _11: i32; + let _12: i32; + let mut _13: std::result::Result<std::convert::Infallible, i32>; + scope 6 { + debug v => _11; + } + scope 7 { + debug e => _12; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _4 = _1; + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _10 = discriminant(_4); + switchInt(move _10) -> [0: bb8, 1: bb6, otherwise: bb7]; + } + + bb1: { + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); +- switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; ++ goto -> bb2; + } + + bb2: { + StorageLive(_9); + _9 = ((_3 as Continue).0: i32); + _2 = _9; + StorageDead(_9); + _0 = Result::<i32, i32>::Ok(move _2); + StorageDead(_2); + StorageDead(_3); + goto -> bb5; + } + + bb3: { + unreachable; + } + + bb4: { + StorageLive(_6); + _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); + StorageLive(_8); + _8 = _6; + StorageLive(_14); + _14 = move ((_8 as Err).0: i32); + StorageLive(_15); + _15 = move _14; + _0 = Result::<i32, i32>::Err(move _15); + StorageDead(_15); + StorageDead(_14); + StorageDead(_8); + StorageDead(_6); + StorageDead(_2); + StorageDead(_3); + goto -> bb5; + } + + bb5: { + return; + } + + bb6: { + _12 = move ((_4 as Err).0: i32); + StorageLive(_13); + _13 = Result::<Infallible, i32>::Err(move _12); + _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13); + StorageDead(_13); +- goto -> bb1; ++ goto -> bb9; + } + + bb7: { + unreachable; + } + + bb8: { + _11 = move ((_4 as Ok).0: i32); + _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11); + goto -> bb1; ++ } ++ ++ bb9: { ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_4); ++ _5 = discriminant(_3); ++ goto -> bb4; + } + } + diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..f17c9ba3f9f --- /dev/null +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -0,0 +1,139 @@ +- // MIR for `identity` before JumpThreading ++ // MIR for `identity` after JumpThreading + + fn identity(_1: Result<i32, i32>) -> Result<i32, i32> { + debug x => _1; + let mut _0: std::result::Result<i32, i32>; + let mut _2: i32; + let mut _3: std::ops::ControlFlow<std::result::Result<std::convert::Infallible, i32>, i32>; + let mut _4: std::result::Result<i32, i32>; + let mut _5: isize; + let _6: std::result::Result<std::convert::Infallible, i32>; + let mut _7: !; + let mut _8: std::result::Result<std::convert::Infallible, i32>; + let _9: i32; + scope 1 { + debug residual => _6; + scope 2 { + scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { + debug residual => _8; + let _14: i32; + let mut _15: i32; + scope 9 { + debug e => _14; + scope 10 (inlined <i32 as From<i32>>::from) { + debug t => _14; + } + } + } + } + } + scope 3 { + debug val => _9; + scope 4 { + } + } + scope 5 (inlined <Result<i32, i32> as Try>::branch) { + debug self => _4; + let mut _10: isize; + let _11: i32; + let _12: i32; + let mut _13: std::result::Result<std::convert::Infallible, i32>; + scope 6 { + debug v => _11; + } + scope 7 { + debug e => _12; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _4 = _1; + StorageLive(_10); + StorageLive(_11); + StorageLive(_12); + _10 = discriminant(_4); + switchInt(move _10) -> [0: bb8, 1: bb6, otherwise: bb7]; + } + + bb1: { + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); +- switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; ++ goto -> bb2; + } + + bb2: { + StorageLive(_9); + _9 = ((_3 as Continue).0: i32); + _2 = _9; + StorageDead(_9); + _0 = Result::<i32, i32>::Ok(move _2); + StorageDead(_2); + StorageDead(_3); + goto -> bb5; + } + + bb3: { + unreachable; + } + + bb4: { + StorageLive(_6); + _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); + StorageLive(_8); + _8 = _6; + StorageLive(_14); + _14 = move ((_8 as Err).0: i32); + StorageLive(_15); + _15 = move _14; + _0 = Result::<i32, i32>::Err(move _15); + StorageDead(_15); + StorageDead(_14); + StorageDead(_8); + StorageDead(_6); + StorageDead(_2); + StorageDead(_3); + goto -> bb5; + } + + bb5: { + return; + } + + bb6: { + _12 = move ((_4 as Err).0: i32); + StorageLive(_13); + _13 = Result::<Infallible, i32>::Err(move _12); + _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13); + StorageDead(_13); +- goto -> bb1; ++ goto -> bb9; + } + + bb7: { + unreachable; + } + + bb8: { + _11 = move ((_4 as Ok).0: i32); + _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11); + goto -> bb1; ++ } ++ ++ bb9: { ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_4); ++ _5 = discriminant(_3); ++ goto -> bb4; + } + } + diff --git a/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..2ca03e439a0 --- /dev/null +++ b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-abort.diff @@ -0,0 +1,54 @@ +- // MIR for `multiple_match` before JumpThreading ++ // MIR for `multiple_match` after JumpThreading + + fn multiple_match(_1: u8) -> u8 { + let mut _0: u8; + let mut _2: u8; + let mut _3: u8; + + bb0: { + switchInt(_1) -> [3: bb1, otherwise: bb2]; + } + + bb1: { + _2 = _1; +- switchInt(_2) -> [3: bb3, otherwise: bb4]; ++ goto -> bb3; + } + + bb2: { + _3 = _1; +- switchInt(_3) -> [3: bb5, otherwise: bb6]; ++ goto -> bb6; + } + + bb3: { + _0 = const 5_u8; + return; + } + + bb4: { + _0 = const 7_u8; + return; + } + + bb5: { + _0 = const 9_u8; + return; + } + + bb6: { + switchInt(_3) -> [1: bb7, otherwise: bb8]; + } + + bb7: { + _0 = const 9_u8; + return; + } + + bb8: { + _0 = const 11_u8; + return; + } + } + diff --git a/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..2ca03e439a0 --- /dev/null +++ b/tests/mir-opt/jump_threading.multiple_match.JumpThreading.panic-unwind.diff @@ -0,0 +1,54 @@ +- // MIR for `multiple_match` before JumpThreading ++ // MIR for `multiple_match` after JumpThreading + + fn multiple_match(_1: u8) -> u8 { + let mut _0: u8; + let mut _2: u8; + let mut _3: u8; + + bb0: { + switchInt(_1) -> [3: bb1, otherwise: bb2]; + } + + bb1: { + _2 = _1; +- switchInt(_2) -> [3: bb3, otherwise: bb4]; ++ goto -> bb3; + } + + bb2: { + _3 = _1; +- switchInt(_3) -> [3: bb5, otherwise: bb6]; ++ goto -> bb6; + } + + bb3: { + _0 = const 5_u8; + return; + } + + bb4: { + _0 = const 7_u8; + return; + } + + bb5: { + _0 = const 9_u8; + return; + } + + bb6: { + switchInt(_3) -> [1: bb7, otherwise: bb8]; + } + + bb7: { + _0 = const 9_u8; + return; + } + + bb8: { + _0 = const 11_u8; + return; + } + } + diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..80a42263643 --- /dev/null +++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff @@ -0,0 +1,56 @@ +- // MIR for `mutable_ref` before JumpThreading ++ // MIR for `mutable_ref` after JumpThreading + + fn mutable_ref() -> bool { + let mut _0: bool; + let mut _1: i32; + let _3: (); + let mut _4: bool; + let mut _5: i32; + scope 1 { + debug x => _1; + let _2: *mut i32; + scope 2 { + debug a => _2; + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); + _1 = const 5_i32; + StorageLive(_2); + _2 = &raw mut _1; + _1 = const 7_i32; + StorageLive(_3); + (*_2) = const 8_i32; + _3 = const (); + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); + _5 = _1; + _4 = Eq(move _5, const 7_i32); + switchInt(move _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + StorageDead(_5); + _0 = const true; + goto -> bb3; + } + + bb2: { + StorageDead(_5); + _0 = const false; + goto -> bb3; + } + + bb3: { + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..80a42263643 --- /dev/null +++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff @@ -0,0 +1,56 @@ +- // MIR for `mutable_ref` before JumpThreading ++ // MIR for `mutable_ref` after JumpThreading + + fn mutable_ref() -> bool { + let mut _0: bool; + let mut _1: i32; + let _3: (); + let mut _4: bool; + let mut _5: i32; + scope 1 { + debug x => _1; + let _2: *mut i32; + scope 2 { + debug a => _2; + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); + _1 = const 5_i32; + StorageLive(_2); + _2 = &raw mut _1; + _1 = const 7_i32; + StorageLive(_3); + (*_2) = const 8_i32; + _3 = const (); + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); + _5 = _1; + _4 = Eq(move _5, const 7_i32); + switchInt(move _4) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + StorageDead(_5); + _0 = const true; + goto -> bb3; + } + + bb2: { + StorageDead(_5); + _0 = const false; + goto -> bb3; + } + + bb3: { + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..8821b47c345 --- /dev/null +++ b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-abort.diff @@ -0,0 +1,26 @@ +- // MIR for `mutate_discriminant` before JumpThreading ++ // MIR for `mutate_discriminant` after JumpThreading + + fn mutate_discriminant() -> u8 { + let mut _0: u8; + let mut _1: std::option::Option<NonZeroUsize>; + let mut _2: isize; + + bb0: { + discriminant(_1) = 1; + (((_1 as variant#1).0: NonZeroUsize).0: usize) = const 0_usize; + _2 = discriminant(_1); + switchInt(_2) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 1_u8; + return; + } + + bb2: { + _0 = const 2_u8; + unreachable; + } + } + diff --git a/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..8821b47c345 --- /dev/null +++ b/tests/mir-opt/jump_threading.mutate_discriminant.JumpThreading.panic-unwind.diff @@ -0,0 +1,26 @@ +- // MIR for `mutate_discriminant` before JumpThreading ++ // MIR for `mutate_discriminant` after JumpThreading + + fn mutate_discriminant() -> u8 { + let mut _0: u8; + let mut _1: std::option::Option<NonZeroUsize>; + let mut _2: isize; + + bb0: { + discriminant(_1) = 1; + (((_1 as variant#1).0: NonZeroUsize).0: usize) = const 0_usize; + _2 = discriminant(_1); + switchInt(_2) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + _0 = const 1_u8; + return; + } + + bb2: { + _0 = const 2_u8; + unreachable; + } + } + diff --git a/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..20f6861e8db --- /dev/null +++ b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-abort.diff @@ -0,0 +1,53 @@ +- // MIR for `renumbered_bb` before JumpThreading ++ // MIR for `renumbered_bb` after JumpThreading + + fn renumbered_bb(_1: bool) -> u8 { + let mut _0: u8; + let mut _2: bool; + let mut _3: bool; + + bb0: { + _3 = const false; + switchInt(_1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + _2 = const false; +- goto -> bb3; ++ goto -> bb8; + } + + bb2: { + _2 = _1; + _3 = _1; + goto -> bb3; + } + + bb3: { + switchInt(_2) -> [0: bb4, otherwise: bb5]; + } + + bb4: { + switchInt(_3) -> [0: bb6, otherwise: bb7]; + } + + bb5: { + _0 = const 7_u8; + return; + } + + bb6: { + _0 = const 9_u8; + return; + } + + bb7: { + _0 = const 11_u8; + return; ++ } ++ ++ bb8: { ++ goto -> bb4; + } + } + diff --git a/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..20f6861e8db --- /dev/null +++ b/tests/mir-opt/jump_threading.renumbered_bb.JumpThreading.panic-unwind.diff @@ -0,0 +1,53 @@ +- // MIR for `renumbered_bb` before JumpThreading ++ // MIR for `renumbered_bb` after JumpThreading + + fn renumbered_bb(_1: bool) -> u8 { + let mut _0: u8; + let mut _2: bool; + let mut _3: bool; + + bb0: { + _3 = const false; + switchInt(_1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + _2 = const false; +- goto -> bb3; ++ goto -> bb8; + } + + bb2: { + _2 = _1; + _3 = _1; + goto -> bb3; + } + + bb3: { + switchInt(_2) -> [0: bb4, otherwise: bb5]; + } + + bb4: { + switchInt(_3) -> [0: bb6, otherwise: bb7]; + } + + bb5: { + _0 = const 7_u8; + return; + } + + bb6: { + _0 = const 9_u8; + return; + } + + bb7: { + _0 = const 11_u8; + return; ++ } ++ ++ bb8: { ++ goto -> bb4; + } + } + diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs new file mode 100644 index 00000000000..00dd98d825f --- /dev/null +++ b/tests/mir-opt/jump_threading.rs @@ -0,0 +1,291 @@ +// unit-test: JumpThreading +// compile-flags: -Zmir-enable-passes=+Inline +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +#![feature(control_flow_enum)] +#![feature(try_trait_v2)] +#![feature(custom_mir, core_intrinsics, rustc_attrs)] + +use std::intrinsics::mir::*; +use std::ops::ControlFlow; + +fn too_complex(x: Result<i32, usize>) -> Option<i32> { + match { + match x { + Ok(v) => ControlFlow::Continue(v), + Err(r) => ControlFlow::Break(r), + } + } { + ControlFlow::Continue(v) => Some(v), + ControlFlow::Break(r) => None, + } +} + +fn identity(x: Result<i32, i32>) -> Result<i32, i32> { + Ok(x?) +} + +enum DFA { + A, + B, + C, + D, +} + +fn dfa() { + let mut state = DFA::A; + loop { + match state { + DFA::A => state = DFA::B, + DFA::B => state = DFA::C, + DFA::C => state = DFA::D, + DFA::D => return, + } + } +} + +#[repr(u8)] +enum CustomDiscr { + A = 35, + B = 73, + C = 99, +} + +fn custom_discr(x: bool) -> u8 { + match if x { CustomDiscr::A } else { CustomDiscr::B } { + CustomDiscr::A => 5, + _ => 13, + } +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn multiple_match(x: u8) -> u8 { + mir!( + { + match x { 3 => bb1, _ => bb2 } + } + bb1 = { + // We know `x == 3`, so we can take `bb3`. + let y = x; + match y { 3 => bb3, _ => bb4 } + } + bb2 = { + // We know `x != 3`, so we can take `bb6`. + let z = x; + match z { 3 => bb5, _ => bb6 } + } + bb3 = { + RET = 5; + Return() + } + bb4 = { + RET = 7; + Return() + } + bb5 = { + RET = 9; + Return() + } + bb6 = { + // We know `z != 3`, so we CANNOT take `bb7`. + match z { 1 => bb7, _ => bb8 } + } + bb7 = { + RET = 9; + Return() + } + bb8 = { + RET = 11; + Return() + } + ) +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn duplicate_chain(x: bool) -> u8 { + mir!( + let a: u8; + { + match x { true => bb1, _ => bb2 } + } + bb1 = { + a = 5; + Goto(bb3) + } + bb2 = { + a = 5; + Goto(bb3) + } + // Verify that we do not create multiple copied of `bb3`. + bb3 = { + let b = 13; + Goto(bb4) + } + bb4 = { + let c = 15; + match a { 5 => bb5, _ => bb6 } + } + bb5 = { + RET = 7; + Return() + } + bb6 = { + RET = 9; + Return() + } + ) +} + +#[rustc_layout_scalar_valid_range_start(1)] +#[rustc_nonnull_optimization_guaranteed] +struct NonZeroUsize(usize); + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn mutate_discriminant() -> u8 { + mir!( + let x: Option<NonZeroUsize>; + { + SetDiscriminant(x, 1); + // This assignment overwrites the niche in which the discriminant is stored. + place!(Field(Field(Variant(x, 1), 0), 0)) = 0_usize; + // So we cannot know the value of this discriminant. + let a = Discriminant(x); + match a { + 0 => bb1, + _ => bad, + } + } + bb1 = { + RET = 1; + Return() + } + bad = { + RET = 2; + Unreachable() + } + ) +} + +// Verify that we do not try to reason when there are mutable pointers involved. +fn mutable_ref() -> bool { + let mut x = 5; + let a = std::ptr::addr_of_mut!(x); + x = 7; + unsafe { *a = 8 }; + if x == 7 { + true + } else { + false + } +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn renumbered_bb(x: bool) -> u8 { + // This function has 2 TOs: 1-3-4 and 0-1-3-4-6. + // We verify that the second TO does not modify 3 once the first has been applied. + mir!( + let a: bool; + let b: bool; + { + b = false; + match x { true => bb1, _ => bb2 } + } + bb1 = { + a = false; + Goto(bb3) + } + bb2 = { + a = x; + b = x; + Goto(bb3) + } + bb3 = { + match a { false => bb4, _ => bb5 } + } + bb4 = { + match b { false => bb6, _ => bb7 } + } + bb5 = { + RET = 7; + Return() + } + bb6 = { + RET = 9; + Return() + } + bb7 = { + RET = 11; + Return() + } + ) +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn disappearing_bb(x: u8) -> u8 { + // This function has 3 TOs: 1-4-5, 0-1-4-7-5-8 and 3-4-7-5-6 + // After applying the first TO, we create bb9 to replace 4, and rename 1-4 edge by 1-9. The + // second TO may try to thread non-existing edge 9-4. + // This test verifies that we preserve semantics by bailing out of this second TO. + mir!( + let _11: i8; + let _12: bool; + let _13: bool; + { + _13 = false; + _12 = false; + _13 = true; + _12 = true; + match x { 0 => bb3, 1 => bb3, 2 => bb1, _ => bb2 } + } + bb1 = { + _12 = false; + Goto(bb4) + } + bb2 = { + Unreachable() + } + bb3 = { + _13 = false; + Goto(bb4) + } + bb4 = { + match _12 { false => bb5, _ => bb7 } + } + bb5 = { + match _13 { false => bb6, _ => bb8 } + } + bb6 = { + Return() + } + bb7 = { + Goto(bb5) + } + bb8 = { + Goto(bb6) + } + ) +} + +fn main() { + too_complex(Ok(0)); + identity(Ok(0)); + custom_discr(false); + dfa(); + multiple_match(5); + duplicate_chain(false); + mutate_discriminant(); + mutable_ref(); + renumbered_bb(true); + disappearing_bb(7); +} + +// EMIT_MIR jump_threading.too_complex.JumpThreading.diff +// EMIT_MIR jump_threading.identity.JumpThreading.diff +// EMIT_MIR jump_threading.custom_discr.JumpThreading.diff +// EMIT_MIR jump_threading.dfa.JumpThreading.diff +// EMIT_MIR jump_threading.multiple_match.JumpThreading.diff +// EMIT_MIR jump_threading.duplicate_chain.JumpThreading.diff +// EMIT_MIR jump_threading.mutate_discriminant.JumpThreading.diff +// EMIT_MIR jump_threading.mutable_ref.JumpThreading.diff +// EMIT_MIR jump_threading.renumbered_bb.JumpThreading.diff +// EMIT_MIR jump_threading.disappearing_bb.JumpThreading.diff diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff new file mode 100644 index 00000000000..f5eade4a914 --- /dev/null +++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-abort.diff @@ -0,0 +1,98 @@ +- // MIR for `too_complex` before JumpThreading ++ // MIR for `too_complex` after JumpThreading + + fn too_complex(_1: Result<i32, usize>) -> Option<i32> { + debug x => _1; + let mut _0: std::option::Option<i32>; + let mut _2: std::ops::ControlFlow<usize, i32>; + let mut _3: isize; + let _4: i32; + let mut _5: i32; + let _6: usize; + let mut _7: usize; + let mut _8: isize; + let _9: i32; + let mut _10: i32; + let _11: usize; + scope 1 { + debug v => _4; + } + scope 2 { + debug r => _6; + } + scope 3 { + debug v => _9; + } + scope 4 { + debug r => _11; + } + + bb0: { + StorageLive(_2); + _3 = discriminant(_1); + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = ((_1 as Err).0: usize); + StorageLive(_7); + _7 = _6; + _2 = ControlFlow::<usize, i32>::Break(move _7); + StorageDead(_7); + StorageDead(_6); +- goto -> bb4; ++ goto -> bb8; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_4); + _4 = ((_1 as Ok).0: i32); + StorageLive(_5); + _5 = _4; + _2 = ControlFlow::<usize, i32>::Continue(move _5); + StorageDead(_5); + StorageDead(_4); + goto -> bb4; + } + + bb4: { + _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2]; ++ goto -> bb6; + } + + bb5: { + StorageLive(_11); + _11 = ((_2 as Break).0: usize); + _0 = Option::<i32>::None; + StorageDead(_11); + goto -> bb7; + } + + bb6: { + StorageLive(_9); + _9 = ((_2 as Continue).0: i32); + StorageLive(_10); + _10 = _9; + _0 = Option::<i32>::Some(move _10); + StorageDead(_10); + StorageDead(_9); + goto -> bb7; + } + + bb7: { + StorageDead(_2); + return; ++ } ++ ++ bb8: { ++ _8 = discriminant(_2); ++ goto -> bb5; + } + } + diff --git a/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff new file mode 100644 index 00000000000..f5eade4a914 --- /dev/null +++ b/tests/mir-opt/jump_threading.too_complex.JumpThreading.panic-unwind.diff @@ -0,0 +1,98 @@ +- // MIR for `too_complex` before JumpThreading ++ // MIR for `too_complex` after JumpThreading + + fn too_complex(_1: Result<i32, usize>) -> Option<i32> { + debug x => _1; + let mut _0: std::option::Option<i32>; + let mut _2: std::ops::ControlFlow<usize, i32>; + let mut _3: isize; + let _4: i32; + let mut _5: i32; + let _6: usize; + let mut _7: usize; + let mut _8: isize; + let _9: i32; + let mut _10: i32; + let _11: usize; + scope 1 { + debug v => _4; + } + scope 2 { + debug r => _6; + } + scope 3 { + debug v => _9; + } + scope 4 { + debug r => _11; + } + + bb0: { + StorageLive(_2); + _3 = discriminant(_1); + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = ((_1 as Err).0: usize); + StorageLive(_7); + _7 = _6; + _2 = ControlFlow::<usize, i32>::Break(move _7); + StorageDead(_7); + StorageDead(_6); +- goto -> bb4; ++ goto -> bb8; + } + + bb2: { + unreachable; + } + + bb3: { + StorageLive(_4); + _4 = ((_1 as Ok).0: i32); + StorageLive(_5); + _5 = _4; + _2 = ControlFlow::<usize, i32>::Continue(move _5); + StorageDead(_5); + StorageDead(_4); + goto -> bb4; + } + + bb4: { + _8 = discriminant(_2); +- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2]; ++ goto -> bb6; + } + + bb5: { + StorageLive(_11); + _11 = ((_2 as Break).0: usize); + _0 = Option::<i32>::None; + StorageDead(_11); + goto -> bb7; + } + + bb6: { + StorageLive(_9); + _9 = ((_2 as Continue).0: i32); + StorageLive(_10); + _10 = _9; + _0 = Option::<i32>::Some(move _10); + StorageDead(_10); + StorageDead(_9); + goto -> bb7; + } + + bb7: { + StorageDead(_2); + return; ++ } ++ ++ bb8: { ++ _8 = discriminant(_2); ++ goto -> bb5; + } + } + |
