From 5881b7c68b353c3723133c43f209802b3a0c9621 Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 21 Apr 2025 21:46:35 +0800 Subject: [PATCH] mir-opt: execute MatchBranchSimplification after GVN This can provide more opportunities for MatchBranchSimplification. --- compiler/rustc_mir_transform/src/lib.rs | 3 +-- ...l_unsigned_smaller.Inline.panic-abort.diff | 14 +++++------ ..._unsigned_smaller.Inline.panic-unwind.diff | 14 +++++------ ..._shr_signed_bigger.Inline.panic-abort.diff | 14 +++++------ ...shr_signed_bigger.Inline.panic-unwind.diff | 14 +++++------ ...d.unwrap_unchecked.Inline.panic-abort.diff | 16 ++++++------- ....unwrap_unchecked.Inline.panic-unwind.diff | 16 ++++++------- ...hecked.InstSimplify-after-simplifycfg.diff | 18 +++++++------- ...e_75439.foo.MatchBranchSimplification.diff | 24 ++++++------------- .../matchbr.match1.PreCodegen.after.mir | 13 ++++++++++ tests/mir-opt/pre-codegen/matchbr.rs | 10 ++++++++ ....foo.SimplifyLocals-final.panic-abort.diff | 5 ++-- ...foo.SimplifyLocals-final.panic-unwind.diff | 5 ++-- 13 files changed, 90 insertions(+), 76 deletions(-) create mode 100644 tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir create mode 100644 tests/mir-opt/pre-codegen/matchbr.rs diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 4d74ecddfb057..8b81f0e61797f 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -699,8 +699,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Now, we need to shrink the generated MIR. &ref_prop::ReferencePropagation, &sroa::ScalarReplacementOfAggregates, - &match_branches::MatchBranchSimplification, - // inst combine is after MatchBranchSimplification to clean up Ne(_1, false) &multiple_return_terminators::MultipleReturnTerminators, // After simplifycfg, it allows us to discover new opportunities for peephole // optimizations. @@ -709,6 +707,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &dead_store_elimination::DeadStoreElimination::Initial, &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, + &match_branches::MatchBranchSimplification, &dataflow_const_prop::DataflowConstProp, &single_use_consts::SingleUseConsts, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff index f36157a762c27..39ba480d20330 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff @@ -8,9 +8,9 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShlUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff index be1b066c6c1b4..5a758d3574060 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff @@ -8,9 +8,9 @@ let mut _3: u16; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shl) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShlUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff index 360687f3c4e7f..a0caf141f2d06 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff @@ -8,9 +8,9 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShrUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff index 986df55df0372..633089e7b2a28 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff @@ -8,9 +8,9 @@ let mut _3: i64; let mut _4: u32; + scope 1 (inlined core::num::::unchecked_shr) { -+ let mut _5: bool; -+ let _6: (); ++ let _5: (); + scope 2 (inlined core::ub_checks::check_language_ub) { ++ let mut _6: bool; + scope 3 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -22,20 +22,20 @@ StorageLive(_4); _4 = copy _2; - _0 = core::num::::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue]; -+ StorageLive(_6); + StorageLive(_5); -+ _5 = UbChecks(); -+ switchInt(move _5) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_6); ++ _6 = UbChecks(); ++ switchInt(copy _6) -> [0: bb2, otherwise: bb1]; } bb1: { -+ _6 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; ++ _5 = core::num::::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable]; + } + + bb2: { -+ StorageDead(_5); + _0 = ShrUnchecked(copy _3, copy _4); + StorageDead(_6); ++ StorageDead(_5); StorageDead(_4); StorageDead(_3); return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff index 28878736ed7cd..a5986a4315a2d 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff @@ -10,9 +10,9 @@ + scope 2 { + } + scope 3 (inlined unreachable_unchecked) { -+ let mut _4: bool; -+ let _5: (); ++ let _4: (); + scope 4 (inlined core::ub_checks::check_language_ub) { ++ let mut _5: bool; + scope 5 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -24,7 +24,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable]; + StorageLive(_3); -+ StorageLive(_5); ++ StorageLive(_4); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -34,15 +34,15 @@ + } + + bb2: { -+ StorageLive(_4); -+ _4 = UbChecks(); -+ assume(copy _4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = UbChecks(); ++ assume(copy _5); ++ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { + _0 = move ((_2 as Some).0: T); -+ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff index 27b6bb6a5bb23..12b03a6b6d921 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff @@ -10,9 +10,9 @@ + scope 2 { + } + scope 3 (inlined unreachable_unchecked) { -+ let mut _4: bool; -+ let _5: (); ++ let _4: (); + scope 4 (inlined core::ub_checks::check_language_ub) { ++ let mut _5: bool; + scope 5 (inlined core::ub_checks::check_language_ub::runtime) { + } + } @@ -24,7 +24,7 @@ _2 = move _1; - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; + StorageLive(_3); -+ StorageLive(_5); ++ StorageLive(_4); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -38,15 +38,15 @@ - bb2 (cleanup): { - resume; + bb2: { -+ StorageLive(_4); -+ _4 = UbChecks(); -+ assume(copy _4); -+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = UbChecks(); ++ assume(copy _5); ++ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { + _0 = move ((_2 as Some).0: T); -+ StorageDead(_5); ++ StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff index 5fee9a6733dd0..82353a2d5404a 100644 --- a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff +++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify-after-simplifycfg.diff @@ -10,9 +10,9 @@ scope 2 { } scope 3 (inlined unreachable_unchecked) { - let mut _4: bool; - let _5: (); + let _4: (); scope 4 (inlined core::ub_checks::check_language_ub) { + let mut _5: bool; scope 5 (inlined core::ub_checks::check_language_ub::runtime) { } } @@ -23,7 +23,7 @@ StorageLive(_2); _2 = copy _1; StorageLive(_3); - StorageLive(_5); + StorageLive(_4); _3 = discriminant(_2); switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; } @@ -33,16 +33,16 @@ } bb2: { - StorageLive(_4); -- _4 = UbChecks(); -+ _4 = const false; - assume(copy _4); - _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + StorageLive(_5); +- _5 = UbChecks(); ++ _5 = const false; + assume(copy _5); + _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; } bb3: { _0 = move ((_2 as Some).0: i32); - StorageDead(_5); + StorageDead(_4); StorageDead(_3); StorageDead(_2); return; diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff index 1ab9be9665221..d8eace98d556e 100644 --- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff +++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -5,23 +5,18 @@ debug bytes => _1; let mut _0: std::option::Option<[u8; 4]>; let _2: [u32; 4]; - let mut _3: [u8; 16]; - let mut _5: [u8; 4]; - let mut _6: u32; + let mut _4: [u8; 4]; scope 1 { debug dwords => _2; scope 2 { - debug ip => _4; - let _4: u32; + debug ip => _3; + let _3: u32; } } bb0: { StorageLive(_2); - StorageLive(_3); - _3 = copy _1; - _2 = move _3 as [u32; 4] (Transmute); - StorageDead(_3); + _2 = copy _1 as [u32; 4] (Transmute); switchInt(copy _2[0 of 4]) -> [0: bb1, otherwise: bb4]; } @@ -34,15 +29,10 @@ } bb3: { + _3 = copy _2[3 of 4]; StorageLive(_4); - _4 = copy _2[3 of 4]; - StorageLive(_5); - StorageLive(_6); - _6 = copy _4; - _5 = move _6 as [u8; 4] (Transmute); - StorageDead(_6); - _0 = Option::<[u8; 4]>::Some(move _5); - StorageDead(_5); + _4 = copy _3 as [u8; 4] (Transmute); + _0 = Option::<[u8; 4]>::Some(move _4); StorageDead(_4); goto -> bb5; } diff --git a/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir new file mode 100644 index 0000000000000..3a202728ea913 --- /dev/null +++ b/tests/mir-opt/pre-codegen/matchbr.match1.PreCodegen.after.mir @@ -0,0 +1,13 @@ +// MIR for `match1` after PreCodegen + +fn match1(_1: bool, _2: i32, _3: i32) -> i32 { + debug c => _1; + debug v1 => _2; + debug v2 => _3; + let mut _0: i32; + + bb0: { + _0 = Sub(copy _2, copy _3); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/matchbr.rs b/tests/mir-opt/pre-codegen/matchbr.rs new file mode 100644 index 0000000000000..1822739da2c7e --- /dev/null +++ b/tests/mir-opt/pre-codegen/matchbr.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +// EMIT_MIR matchbr.match1.PreCodegen.after.mir +pub fn match1(c: bool, v1: i32, v2: i32) -> i32 { + // CHECK-LABEL: fn match1( + // CHECK: bb0: + // CHECK-NEXT: _0 = Sub + // CHECK-NEXT: return; + if c { v1 - v2 } else { v1 - v2 } +} diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff index c363dfcbf70bb..ff1bc58524bc2 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-abort.diff @@ -8,6 +8,9 @@ let mut _3: std::option::Option; let mut _4: isize; let mut _5: isize; +- let mut _7: bool; +- let mut _8: u8; +- let mut _9: bool; scope 1 { debug a => _6; let _6: u8; @@ -32,9 +35,7 @@ } bb2: { - StorageLive(_6); _6 = copy (((_1.0: std::option::Option) as Some).0: u8); - StorageDead(_6); goto -> bb3; } diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff index 895b0067d2e63..2c289c664754a 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.panic-unwind.diff @@ -8,6 +8,9 @@ let mut _3: std::option::Option; let mut _4: isize; let mut _5: isize; +- let mut _7: bool; +- let mut _8: u8; +- let mut _9: bool; scope 1 { debug a => _6; let _6: u8; @@ -32,9 +35,7 @@ } bb2: { - StorageLive(_6); _6 = copy (((_1.0: std::option::Option) as Some).0: u8); - StorageDead(_6); goto -> bb3; }