diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index 0f9b2ff5ab81e..06690dcbf6eb7 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -38,19 +38,16 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // FIXME: This optimization can result in unsoundness, because it introduces - // additional uses of a place holding the discriminant value without ensuring that - // it is valid to do so. - if !tcx.sess.opts.debugging_opts.unsound_mir_opts { + if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } let param_env = tcx.param_env(body.source.def_id()); - let bbs = body.basic_blocks_mut(); + let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut(); 'outer: for bb_idx in bbs.indices() { let (discr, val, switch_ty, first, second) = match bbs[bb_idx].terminator().kind { TerminatorKind::SwitchInt { - discr: Operand::Copy(ref place) | Operand::Move(ref place), + discr: ref discr @ (Operand::Copy(_) | Operand::Move(_)), switch_ty, ref targets, .. @@ -59,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { if target == targets.otherwise() { continue; } - (place, value, switch_ty, target, targets.otherwise()) + (discr, value, switch_ty, target, targets.otherwise()) } // Only optimize switch int statements _ => continue, @@ -99,6 +96,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { // Take ownership of items now that we know we can optimize. let discr = discr.clone(); + // Introduce a temporary for the discriminant value. + let source_info = bbs[bb_idx].terminator().source_info; + let discr_local = local_decls.push(LocalDecl::new(switch_ty, source_info.span)); + // We already checked that first and second are different blocks, // and bb_idx has a different terminator from both of them. let (from, first, second) = bbs.pick3_mut(bb_idx, first, second); @@ -127,7 +128,11 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { rustc_span::DUMMY_SP, ); let op = if f_b { BinOp::Eq } else { BinOp::Ne }; - let rhs = Rvalue::BinaryOp(op, Operand::Copy(discr.clone()), const_cmp); + let rhs = Rvalue::BinaryOp( + op, + Operand::Copy(Place::from(discr_local)), + const_cmp, + ); Statement { source_info: f.source_info, kind: StatementKind::Assign(box (*lhs, rhs)), @@ -138,7 +143,16 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { _ => unreachable!(), } }); + + from.statements + .push(Statement { source_info, kind: StatementKind::StorageLive(discr_local) }); + from.statements.push(Statement { + source_info, + kind: StatementKind::Assign(box (Place::from(discr_local), Rvalue::Use(discr))), + }); from.statements.extend(new_stmts); + from.statements + .push(Statement { source_info, kind: StatementKind::StorageDead(discr_local) }); from.terminator_mut().kind = first.terminator().kind.clone(); } } diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff index 648cf241cbaba..d3a29aa5d51c1 100644 --- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff @@ -10,6 +10,7 @@ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:9: 35:10 let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:12: 35:13 let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:15: 35:16 ++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:19:9: 19:10 scope 1 { debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 @@ -33,10 +34,13 @@ StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 - switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 -+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 -+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 ++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 ++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 ++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 } diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff index 648cf241cbaba..d3a29aa5d51c1 100644 --- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff @@ -10,6 +10,7 @@ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:9: 35:10 let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:12: 35:13 let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:15: 35:16 ++ let mut _11: i32; // in scope 0 at $DIR/matches_reduce_branches.rs:19:9: 19:10 scope 1 { debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 @@ -33,10 +34,13 @@ StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 - switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 -+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 -+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 ++ StorageLive(_11); // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _11 = _1; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _2 = Ne(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 ++ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 ++ StorageDead(_11); // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 } diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff index a52abfb1a727d..ba963e3fe920b 100644 --- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff @@ -6,12 +6,16 @@ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:6:25: 6:25 let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ let mut _4: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 - switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 -+ _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ _4 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 } diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff index a52abfb1a727d..ba963e3fe920b 100644 --- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff @@ -6,12 +6,16 @@ let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:6:25: 6:25 let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ let mut _4: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 - switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 -+ _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ _4 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 ++ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL ++ StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 } diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff new file mode 100644 index 0000000000000..1f46d3777bed8 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff @@ -0,0 +1,116 @@ +- // MIR for `match_nested_if` before MatchBranchSimplification ++ // MIR for `match_nested_if` after MatchBranchSimplification + + fn match_nested_if() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:38:25: 38:29 + let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:39:21: 39:23 + let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 ++ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + scope 1 { + debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:39:21: 39:23 + StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 + _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 +- switchInt(_6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ _7 = _6; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:42: 40:47 ++ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb1: { + _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:30: 40:34 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb2: { + _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:42: 40:47 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb3: { + StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:40:47: 40:48 +- switchInt(_5) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ _8 = _5; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:62: 40:67 ++ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb4: { + _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:62: 40:67 + goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb5: { + _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:50: 40:54 + goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb6: { + StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:40:67: 40:68 +- switchInt(_4) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _9 = _4; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:82: 40:87 ++ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb7: { + _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:82: 40:87 + goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb8: { + _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:70: 40:74 + goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb9: { + StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:40:87: 40:88 +- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 ++ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:14: 41:19 ++ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb10: { + StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 + _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:92: 40:96 + goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:39:15: 42:6 + } + + bb11: { + StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 + _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:14: 41:19 + goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:39:15: 42:6 + } + + bb12: { + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:42:6: 42:7 + _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:43:5: 43:8 + StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:44:1: 44:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:44:2: 44:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff new file mode 100644 index 0000000000000..1f46d3777bed8 --- /dev/null +++ b/src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.64bit.diff @@ -0,0 +1,116 @@ +- // MIR for `match_nested_if` before MatchBranchSimplification ++ // MIR for `match_nested_if` after MatchBranchSimplification + + fn match_nested_if() -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:38:25: 38:29 + let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:39:21: 39:23 + let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 ++ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + scope 1 { + debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:39:9: 39:12 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:39:21: 39:23 + StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 + _6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:24: 40:28 +- switchInt(_6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ _7 = _6; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:42: 40:47 ++ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb1: { + _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:30: 40:34 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb2: { + _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:42: 40:47 + goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:48 + } + + bb3: { + StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:40:47: 40:48 +- switchInt(_5) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ _8 = _5; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:62: 40:67 ++ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 ++ goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb4: { + _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:62: 40:67 + goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb5: { + _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:50: 40:54 + goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:40:18: 40:68 + } + + bb6: { + StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:40:67: 40:68 +- switchInt(_4) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _9 = _4; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:40:82: 40:87 ++ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb7: { + _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:40:82: 40:87 + goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb8: { + _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:70: 40:74 + goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb9: { + StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:40:87: 40:88 +- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 ++ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:14: 41:19 ++ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 ++ goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:40:15: 40:88 + } + + bb10: { + StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 + _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:40:92: 40:96 + goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:39:15: 42:6 + } + + bb11: { + StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:95: 40:96 + _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:14: 41:19 + goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:39:15: 42:6 + } + + bb12: { + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:42:6: 42:7 + _0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:43:5: 43:8 + StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:44:1: 44:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:44:2: 44:2 + } + } + diff --git a/src/test/mir-opt/matches_reduce_branches.rs b/src/test/mir-opt/matches_reduce_branches.rs index 54b79a84263fe..e95a62aeeb0b9 100644 --- a/src/test/mir-opt/matches_reduce_branches.rs +++ b/src/test/mir-opt/matches_reduce_branches.rs @@ -1,7 +1,7 @@ -// compile-flags: -Zunsound-mir-opts // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff // EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff +// EMIT_MIR matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff fn foo(bar: Option<()>) { if matches!(bar, None) { @@ -35,9 +35,17 @@ fn bar(i: i32) -> (bool, bool, bool, bool) { (a, b, c, d) } +fn match_nested_if() -> bool { + let val = match () { + () if if if if true {true} else {false} {true} else {false} {true} else {false} => true, + _ => false, + }; + val +} fn main() { let _ = foo(None); let _ = foo(Some(())); let _ = bar(0); + let _ = match_nested_if(); } diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff index 39830946aebd6..dc3a6a36d9eef 100644 --- a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff +++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff @@ -8,61 +8,52 @@ let mut _3: isize; // in scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 let mut _4: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _5: isize; // in scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + let mut _6: isize; // in scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + let mut _7: isize; // in scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + let mut _8: bool; // in scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _3 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 - switchInt(move _3) -> [0_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + StorageLive(_6); // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + _6 = move _3; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + _2 = Eq(_6, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 } bb1: { _0 = const true; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 } bb2: { - _0 = const false; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - } - - bb3: { StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _5 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 - switchInt(move _5) -> [1_isize: bb9, otherwise: bb8]; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + StorageLive(_7); // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + _7 = move _5; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + _4 = Eq(_7, const 1_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + goto -> bb5; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 } - bb4: { + bb3: { StorageDead(_4); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46 StorageDead(_2); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46 return; // scope 0 at $DIR/not_equal_false.rs:5:2: 5:2 } - bb5: { - _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - } - - bb6: { - _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - } - - bb7: { - switchInt(move _2) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - } - - bb8: { - _4 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - } - - bb9: { - _4 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + bb4: { + switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 } - bb10: { - switchInt(move _4) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + bb5: { + StorageLive(_8); // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + _8 = move _4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 +- _0 = Ne(_8, const false); // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 ++ _0 = _8; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + StorageDead(_8); // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 } }