diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e2a9b540d3060..f6263656ed895 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn codegen_return_terminator(&mut self, bx: &mut Bx) { + pub(super) fn codegen_return_terminator(&mut self, bx: &mut Bx) { // Call `va_end` if this is the definition of a C-variadic function. if self.fn_abi.c_variadic { // The `VaList` "spoofed" argument is just after all the real arguments. @@ -1343,7 +1343,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::TerminatorKind::Return => { - self.codegen_return_terminator(bx); + match self.return_block { + CachedLlbb::Skip => self.codegen_return_terminator(bx), + CachedLlbb::Some(target) => bx.br(target), + CachedLlbb::None => { + let return_llbb = bx.append_sibling_block("return"); + self.return_block = CachedLlbb::Some(return_llbb); + bx.br(return_llbb); + } + } MergingSucc::False } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 0758e5d045673..b3dbd8fa99ebd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -92,6 +92,12 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// Cached terminate upon unwinding block and its reason terminate_block: Option<(Bx::BasicBlock, UnwindTerminateReason)>, + /// Shared return block, because LLVM would prefer only one `ret`. + /// + /// If this is `Skip`, there's only one return in the function (or none at all) + /// so there's no shared return, just the one in the normal BB. + return_block: CachedLlbb, + /// A bool flag for each basic block indicating whether it is a cold block. /// A cold block is a block that is unlikely to be executed at runtime. cold_blocks: IndexVec, @@ -204,6 +210,18 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( }) .collect(); + let return_block = if mir + .basic_blocks + .iter() + .filter(|bbd| matches!(bbd.terminator().kind, mir::TerminatorKind::Return)) + .count() + > 1 + { + CachedLlbb::None + } else { + CachedLlbb::Skip + }; + let mut fx = FunctionCx { instance, mir, @@ -214,6 +232,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cached_llbbs, unreachable_block: None, terminate_block: None, + return_block, cleanup_kinds, landing_pads: IndexVec::from_elem(None, &mir.basic_blocks), funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()), @@ -308,6 +327,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( for bb in unreached_blocks.iter() { fx.codegen_block_as_unreachable(bb); } + + if let CachedLlbb::Some(llbb) = fx.return_block { + let bx = &mut Bx::build(fx.cx, llbb); + fx.codegen_return_terminator(bx); + } } /// Produces, for each argument, a `Value` pointing at the diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 5df12ac4d8bc2..a29f438171b41 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -694,7 +694,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &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. &instsimplify::InstSimplify::AfterSimplifyCfg, @@ -711,6 +710,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &dest_prop::DestinationPropagation, &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), + // Can make blocks unused, so before the last simplify-cfg + &multiple_return_terminators::MultipleReturnTerminators, &o1(simplify::SimplifyCfg::Final), // After the last SimplifyCfg, because this wants one-block functions. &strip_debuginfo::StripDebugInfo, @@ -718,7 +719,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &dead_store_elimination::DeadStoreElimination::Final, &nrvo::RenameReturnPlace, &simplify::SimplifyLocals::Final, - &multiple_return_terminators::MultipleReturnTerminators, &large_enums::EnumSizeOpt { discrepancy: 128 }, // Some cleanup necessary at least for LLVM and potentially other codegen backends. &add_call_guards::CriticalCallEdges, diff --git a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs index c63bfdcee8559..0c672ef8a388d 100644 --- a/compiler/rustc_mir_transform/src/multiple_return_terminators.rs +++ b/compiler/rustc_mir_transform/src/multiple_return_terminators.rs @@ -1,40 +1,51 @@ //! This pass removes jumps to basic blocks containing only a return, and replaces them with a //! return instead. -use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; - -use crate::simplify; +use smallvec::SmallVec; pub(super) struct MultipleReturnTerminators; impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 4 + sess.mir_opt_level() >= 2 } fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // find basic blocks with no statement and a return terminator - let mut bbs_simple_returns = DenseBitSet::new_empty(body.basic_blocks.len()); - let bbs = body.basic_blocks_mut(); - for idx in bbs.indices() { - if bbs[idx].statements.is_empty() - && bbs[idx].terminator().kind == TerminatorKind::Return + let mut to_handle = )>>::new(); + for (bb, bbdata) in body.basic_blocks.iter_enumerated() { + // Look for returns where, if we lift them into the parents, we can save a block. + if let TerminatorKind::Return = bbdata.terminator().kind + && bbdata + .statements + .iter() + .all(|stmt| matches!(stmt.kind, StatementKind::StorageDead(_))) + && let predecessors = &body.basic_blocks.predecessors()[bb] + && predecessors.len() >= 2 + && predecessors.iter().all(|pred| { + matches!( + body.basic_blocks[*pred].terminator().kind, + TerminatorKind::Goto { .. }, + ) + }) { - bbs_simple_returns.insert(idx); + to_handle.push((bb, predecessors.clone())); } } - for bb in bbs { - if let TerminatorKind::Goto { target } = bb.terminator().kind { - if bbs_simple_returns.contains(target) { - bb.terminator_mut().kind = TerminatorKind::Return; - } - } + if to_handle.is_empty() { + return; } - simplify::remove_dead_blocks(body) + let bbs = body.basic_blocks_mut(); + for (succ, predecessors) in to_handle { + for pred in predecessors { + let (pred_block, succ_block) = bbs.pick2_mut(pred, succ); + pred_block.statements.extend(succ_block.statements.iter().cloned()); + *pred_block.terminator_mut() = succ_block.terminator().clone(); + } + } } fn is_required(&self) -> bool { diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs index 7a87bb7983bae..3983898b8ae09 100644 --- a/tests/codegen/asm/goto.rs +++ b/tests/codegen/asm/goto.rs @@ -19,7 +19,7 @@ pub unsafe fn asm_goto() { pub unsafe fn asm_goto_with_outputs() -> u64 { let out: u64; // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:return]]] asm!("{} /* {} */", out(reg) out, label { return 1; }); // CHECK: [[JUMPBB]]: // CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ] @@ -32,7 +32,7 @@ pub unsafe fn asm_goto_with_outputs() -> u64 { pub unsafe fn asm_goto_with_outputs_use_in_label() -> u64 { let out: u64; // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:return]]] asm!("{} /* {} */", out(reg) out, label { return out; }); // CHECK: [[JUMPBB]]: // CHECK-NEXT: [[RET:%.+]] = phi i64 [ 1, %[[FALLTHROUGHBB]] ], [ [[RES]], %start ] @@ -55,7 +55,7 @@ pub unsafe fn asm_goto_noreturn() -> u64 { pub unsafe fn asm_goto_noreturn_with_outputs() -> u64 { let out: u64; // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + // CHECK-NEXT: to label %[[FALLTHROUGHBB:return]] [label %[[JUMPBB:return]]] asm!("mov {}, 1", "jmp {}", out(reg) out, label { return out; }); // CHECK: [[JUMPBB]]: // CHECK-NEXT: ret i64 [[RES]] diff --git a/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs b/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs index 3909b203d0897..89f04cd7815ad 100644 --- a/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs +++ b/tests/codegen/issues/issue-112509-slice-get-andthen-get.rs @@ -3,8 +3,8 @@ // CHECK-LABEL: @write_u8_variant_a // CHECK-NEXT: {{.*}}: -// CHECK-NEXT: icmp ugt // CHECK-NEXT: getelementptr +// CHECK-NEXT: icmp ugt // CHECK-NEXT: select i1 {{.+}} null // CHECK-NEXT: insertvalue // CHECK-NEXT: insertvalue diff --git a/tests/codegen/multiple_returns.rs b/tests/codegen/multiple_returns.rs new file mode 100644 index 0000000000000..f0f9fc2e22210 --- /dev/null +++ b/tests/codegen/multiple_returns.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes + +#![crate_type = "lib"] + +// CHECK-LABEL: @simple_is_one_block +#[no_mangle] +pub unsafe fn simple_is_one_block(x: i32) -> i32 { + // CHECK: start: + // CHECK-NEXT: ret i32 %x + + // CHECK-NOT: return + + x +} + +// CHECK-LABEL: @branch_has_shared_block +#[no_mangle] +pub unsafe fn branch_has_shared_block(b: bool) -> i32 { + // CHECK: start: + // CHECK-NEXT: %[[A:.+]] = alloca [4 x i8] + // CHECK-NEXT: br i1 %b + + // CHECK: store i32 {{42|2015}}, ptr %[[A]] + // CHECK-NEXT: br label %return + + // CHECK: store i32 {{42|2015}}, ptr %[[A]] + // CHECK-NEXT: br label %return + + // CHECK: return: + // CHECK-NEXT: %[[R:.+]] = load i32, ptr %[[A]] + // CHECK-NEXT: ret i32 %[[R]] + + if b { 42 } else { 2015 } +} diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff index e87a565f0fc98..5f92f7fd29fc5 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff @@ -20,30 +20,35 @@ + StorageLive(_1); + StorageLive(_2); + _1 = const inner::promoted[0]; -+ _0 = index() -> [return: bb1, unwind unreachable]; ++ _0 = index() -> [return: bb2, unwind unreachable]; } bb1: { ++ StorageDead(_2); ++ StorageDead(_1); + return; ++ } ++ ++ bb2: { + StorageLive(_3); + _2 = Lt(copy _0, const 1_usize); -+ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _0) -> [success: bb2, unwind unreachable]; ++ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _0) -> [success: bb3, unwind unreachable]; + } + -+ bb2: { ++ bb3: { + _3 = copy (*_1)[_0]; -+ switchInt(move _3) -> [0: bb3, otherwise: bb4]; ++ switchInt(move _3) -> [0: bb4, otherwise: bb5]; + } + -+ bb3: { ++ bb4: { + _0 = const 0_usize; -+ goto -> bb4; ++ StorageDead(_3); ++ goto -> bb1; + } + -+ bb4: { ++ bb5: { + StorageDead(_3); -+ StorageDead(_2); -+ StorageDead(_1); - return; ++ goto -> bb1; } } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff index 834851b75adf1..fe68c300219b5 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff @@ -20,30 +20,35 @@ + StorageLive(_1); + StorageLive(_2); + _1 = const inner::promoted[0]; -+ _0 = index() -> [return: bb1, unwind continue]; ++ _0 = index() -> [return: bb2, unwind continue]; } bb1: { ++ StorageDead(_2); ++ StorageDead(_1); + return; ++ } ++ ++ bb2: { + StorageLive(_3); + _2 = Lt(copy _0, const 1_usize); -+ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _0) -> [success: bb2, unwind continue]; ++ assert(move _2, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _0) -> [success: bb3, unwind continue]; + } + -+ bb2: { ++ bb3: { + _3 = copy (*_1)[_0]; -+ switchInt(move _3) -> [0: bb3, otherwise: bb4]; ++ switchInt(move _3) -> [0: bb4, otherwise: bb5]; + } + -+ bb3: { ++ bb4: { + _0 = const 0_usize; -+ goto -> bb4; ++ StorageDead(_3); ++ goto -> bb1; + } + -+ bb4: { ++ bb5: { + StorageDead(_3); -+ StorageDead(_2); -+ StorageDead(_1); - return; ++ goto -> bb1; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir index 5876c55c52b94..9a18bd29369b1 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir @@ -49,7 +49,7 @@ fn num_to_digit(_1: char) -> u32 { _0 = move ((_4 as Some).0: u32); StorageDead(_5); StorageDead(_4); - goto -> bb8; + return; } bb6: { @@ -59,10 +59,6 @@ fn num_to_digit(_1: char) -> u32 { bb7: { StorageDead(_3); _0 = const 0_u32; - goto -> bb8; - } - - bb8: { return; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir index f1185353a43c8..dd0a550dc708d 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir @@ -49,7 +49,7 @@ fn num_to_digit(_1: char) -> u32 { _0 = move ((_4 as Some).0: u32); StorageDead(_5); StorageDead(_4); - goto -> bb8; + return; } bb6: { @@ -59,10 +59,6 @@ fn num_to_digit(_1: char) -> u32 { bb7: { StorageDead(_3); _0 = const 0_u32; - goto -> bb8; - } - - bb8: { return; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir index 5876c55c52b94..9a18bd29369b1 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir @@ -49,7 +49,7 @@ fn num_to_digit(_1: char) -> u32 { _0 = move ((_4 as Some).0: u32); StorageDead(_5); StorageDead(_4); - goto -> bb8; + return; } bb6: { @@ -59,10 +59,6 @@ fn num_to_digit(_1: char) -> u32 { bb7: { StorageDead(_3); _0 = const 0_u32; - goto -> bb8; - } - - bb8: { return; } } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir index f1185353a43c8..dd0a550dc708d 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir @@ -49,7 +49,7 @@ fn num_to_digit(_1: char) -> u32 { _0 = move ((_4 as Some).0: u32); StorageDead(_5); StorageDead(_4); - goto -> bb8; + return; } bb6: { @@ -59,10 +59,6 @@ fn num_to_digit(_1: char) -> u32 { bb7: { StorageDead(_3); _0 = const 0_u32; - goto -> bb8; - } - - bb8: { return; } } diff --git a/tests/mir-opt/multiple_return_terminators.rs b/tests/mir-opt/multiple_return_terminators.rs index 8d83082a829eb..252bdd0317d2e 100644 --- a/tests/mir-opt/multiple_return_terminators.rs +++ b/tests/mir-opt/multiple_return_terminators.rs @@ -1,15 +1,22 @@ -// skip-filecheck -//@ compile-flags: -Z mir-opt-level=4 +//@ test-mir-pass: MultipleReturnTerminators +//@ compile-flags: -Z mir-enable-passes=+SimplifyCfg-final + // EMIT_MIR multiple_return_terminators.test.MultipleReturnTerminators.diff +// EMIT_MIR multiple_return_terminators.test.SimplifyCfg-final.diff + +#[inline(never)] +fn test(x: bool) -> i32 { + // CHECK-LABEL: fn test + + // CHECK: _0 = const 42_i32; + // CHECK: return + + // CHECK: _0 = const 2015_i32; + // CHECK: return -fn test(x: bool) { - if x { - // test - } else { - // test - } + if x { 42 } else { 2015 } } fn main() { - test(true) + test(true); } diff --git a/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff b/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff index e28809f38afa6..c46aa4b1e4023 100644 --- a/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff +++ b/tests/mir-opt/multiple_return_terminators.test.MultipleReturnTerminators.diff @@ -1,11 +1,33 @@ - // MIR for `test` before MultipleReturnTerminators + // MIR for `test` after MultipleReturnTerminators - fn test(_1: bool) -> () { + fn test(_1: bool) -> i32 { debug x => _1; - let mut _0: (); + let mut _0: i32; + let mut _2: bool; bb0: { + StorageLive(_2); + _2 = copy _1; + switchInt(move _2) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 42_i32; +- goto -> bb3; ++ StorageDead(_2); ++ return; + } + + bb2: { + _0 = const 2015_i32; +- goto -> bb3; ++ StorageDead(_2); ++ return; + } + + bb3: { + StorageDead(_2); return; } } diff --git a/tests/mir-opt/multiple_return_terminators.test.SimplifyCfg-final.diff b/tests/mir-opt/multiple_return_terminators.test.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..cee9e4638abe0 --- /dev/null +++ b/tests/mir-opt/multiple_return_terminators.test.SimplifyCfg-final.diff @@ -0,0 +1,32 @@ +- // MIR for `test` before SimplifyCfg-final ++ // MIR for `test` after SimplifyCfg-final + + fn test(_1: bool) -> i32 { + debug x => _1; + let mut _0: i32; + let mut _2: bool; + + bb0: { + StorageLive(_2); + _2 = copy _1; + switchInt(move _2) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 42_i32; + StorageDead(_2); + return; + } + + bb2: { + _0 = const 2015_i32; +- StorageDead(_2); +- return; +- } +- +- bb3: { + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir index 9b3e28ab5b8ea..88fb73a6ee7aa 100644 --- a/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/chained_comparison.naive.PreCodegen.after.mir @@ -91,7 +91,11 @@ fn naive(_1: &Blueprint, _2: &Blueprint) -> bool { bb8: { _0 = const false; - goto -> bb10; + StorageDead(_14); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); + return; } bb9: { @@ -104,10 +108,6 @@ fn naive(_1: &Blueprint, _2: &Blueprint) -> bool { _0 = Eq(move _15, move _16); StorageDead(_16); StorageDead(_15); - goto -> bb10; - } - - bb10: { StorageDead(_14); StorageDead(_11); StorageDead(_8); diff --git a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir index 72d52701d112d..cfd50fec575cb 100644 --- a/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/chained_comparison.returning.PreCodegen.after.mir @@ -87,7 +87,7 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_15); StorageDead(_17); _0 = const true; - goto -> bb11; + return; } bb6: { @@ -95,7 +95,7 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_15); _0 = const false; StorageDead(_17); - goto -> bb11; + return; } bb7: { @@ -103,7 +103,7 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_12); _0 = const false; StorageDead(_14); - goto -> bb11; + return; } bb8: { @@ -111,7 +111,7 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_9); _0 = const false; StorageDead(_11); - goto -> bb11; + return; } bb9: { @@ -119,7 +119,7 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_6); _0 = const false; StorageDead(_8); - goto -> bb11; + return; } bb10: { @@ -127,10 +127,6 @@ fn returning(_1: &Blueprint, _2: &Blueprint) -> bool { StorageDead(_3); _0 = const false; StorageDead(_5); - goto -> bb11; - } - - bb11: { return; } } diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir index a9dd8886577dd..cde73f726d548 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-abort.mir @@ -23,7 +23,8 @@ fn checked_shl(_1: u32, _2: u32) -> Option { bb1: { _0 = const Option::::None; - goto -> bb3; + StorageDead(_3); + return; } bb2: { @@ -31,10 +32,6 @@ fn checked_shl(_1: u32, _2: u32) -> Option { _4 = ShlUnchecked(copy _1, copy _2); _0 = Option::::Some(move _4); StorageDead(_4); - goto -> bb3; - } - - bb3: { StorageDead(_3); return; } diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir index a9dd8886577dd..cde73f726d548 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.panic-unwind.mir @@ -23,7 +23,8 @@ fn checked_shl(_1: u32, _2: u32) -> Option { bb1: { _0 = const Option::::None; - goto -> bb3; + StorageDead(_3); + return; } bb2: { @@ -31,10 +32,6 @@ fn checked_shl(_1: u32, _2: u32) -> Option { _4 = ShlUnchecked(copy _1, copy _2); _0 = Option::::Some(move _4); StorageDead(_4); - goto -> bb3; - } - - bb3: { StorageDead(_3); return; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir index 9f88e1961ec88..a77d72f4b2700 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir @@ -31,13 +31,16 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 { StorageLive(_3); StorageLive(_4); _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { _3 = &(((*_1) as A).0: AllCopy); _0 = copy (*_1); - goto -> bb3; + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; } bb2: { @@ -46,17 +49,13 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 { _5 = &((((*_1) as B).0: NestCopy).1: AllCopy); StorageDead(_5); _0 = copy (*_1); - goto -> bb3; - } - - bb3: { StorageDead(_4); StorageDead(_3); StorageDead(_2); return; } - bb4: { + bb3: { unreachable; } } diff --git a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir index 5f4ec1de2701f..ef3304d8243ed 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir @@ -44,15 +44,11 @@ fn ::partial_cmp(_1: &MultiField, _2: &M StorageDead(_8); _0 = Option::::Some(move _10); StorageDead(_10); - goto -> bb3; + return; } bb2: { _0 = copy _6; - goto -> bb3; - } - - bb3: { return; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir index 2621ec6753187..b6d9703c8509a 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir @@ -32,7 +32,9 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { bb1: { _0 = const Option::::None; - goto -> bb4; + StorageDead(_4); + StorageDead(_5); + return; } bb2: { @@ -45,10 +47,6 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { ((*_1).0: u32) = move _6; StorageDead(_6); _0 = Option::::Some(copy _5); - goto -> bb4; - } - - bb4: { StorageDead(_4); StorageDead(_5); return; diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir index 338fb4b952329..2e0373687ce06 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir @@ -32,7 +32,9 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { bb1: { _0 = const Option::::None; - goto -> bb4; + StorageDead(_4); + StorageDead(_5); + return; } bb2: { @@ -45,10 +47,6 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { ((*_1).0: u32) = move _6; StorageDead(_6); _0 = Option::::Some(copy _5); - goto -> bb4; - } - - bb4: { StorageDead(_4); StorageDead(_5); return; diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir index cbfc58194cc1f..9786533ba5166 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -16,12 +16,13 @@ fn ezmap(_1: Option) -> Option { bb0: { StorageLive(_2); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { _0 = const Option::::None; - goto -> bb3; + StorageDead(_2); + return; } bb2: { @@ -30,15 +31,11 @@ fn ezmap(_1: Option) -> Option { _4 = Add(copy _3, const 1_i32); _0 = Option::::Some(move _4); StorageDead(_4); - goto -> bb3; - } - - bb3: { StorageDead(_2); return; } - bb4: { + bb3: { unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index 5a269717f8297..a4ea8b7479c86 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -184,7 +184,9 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 bb7: { StorageDead(_28); - goto -> bb9; + StorageDead(_22); + StorageDead(_16); + return; } bb8: { @@ -192,10 +194,6 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2 StorageDead(_19); StorageDead(_17); _0 = const true; - goto -> bb9; - } - - bb9: { StorageDead(_22); StorageDead(_16); return; diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir index f93f7264dec20..44d2aec2e3d49 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_b-{closure#0}.PreCodegen.after.mir @@ -58,15 +58,13 @@ fn variant_b::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:11:25: 11:41}, bb5: { StorageDead(_13); - goto -> bb7; + StorageDead(_12); + StorageDead(_11); + return; } bb6: { _0 = const true; - goto -> bb7; - } - - bb7: { StorageDead(_12); StorageDead(_11); return; diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir index ec67193bc7948..3878af9b3418e 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir @@ -31,7 +31,9 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { bb1: { StorageDead(_3); _0 = const Option::<&mut u32>::None; - goto -> bb3; + StorageDead(_4); + StorageDead(_8); + return; } bb2: { @@ -47,10 +49,6 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { _8 = &mut (*_7); _0 = Option::<&mut u32>::Some(copy _8); StorageDead(_7); - goto -> bb3; - } - - bb3: { StorageDead(_4); StorageDead(_8); return; diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir index ec67193bc7948..3878af9b3418e 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir @@ -31,7 +31,9 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { bb1: { StorageDead(_3); _0 = const Option::<&mut u32>::None; - goto -> bb3; + StorageDead(_4); + StorageDead(_8); + return; } bb2: { @@ -47,10 +49,6 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> { _8 = &mut (*_7); _0 = Option::<&mut u32>::Some(copy _8); StorageDead(_7); - goto -> bb3; - } - - bb3: { StorageDead(_4); StorageDead(_8); return; diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir index 38d00cfbabdda..be9b7017f9db4 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir @@ -51,17 +51,16 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { _0 = Eq(move _5, move _6); StorageDead(_6); StorageDead(_5); - goto -> bb3; + StorageDead(_3); + StorageDead(_7); + StorageDead(_8); + return; } bb2: { _7 = copy ((*_1).1: *const T); _8 = copy _7 as usize (Transmute); _0 = Eq(copy _8, const 0_usize); - goto -> bb3; - } - - bb3: { StorageDead(_3); StorageDead(_7); StorageDead(_8); diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir index 38d00cfbabdda..be9b7017f9db4 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir @@ -51,17 +51,16 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool { _0 = Eq(move _5, move _6); StorageDead(_6); StorageDead(_5); - goto -> bb3; + StorageDead(_3); + StorageDead(_7); + StorageDead(_8); + return; } bb2: { _7 = copy ((*_1).1: *const T); _8 = copy _7 as usize (Transmute); _0 = Eq(copy _8, const 0_usize); - goto -> bb3; - } - - bb3: { StorageDead(_3); StorageDead(_7); StorageDead(_8); diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir index b6df2300efb1f..a8054b01680c8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir @@ -96,7 +96,13 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb3: { _0 = const {transmute(0x0000000000000000): Option<&T>}; StorageDead(_7); - goto -> bb8; + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); + return; } bb4: { @@ -106,7 +112,13 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb5: { _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); + return; } bb6: { @@ -121,10 +133,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { _14 = &(*_13); StorageDead(_13); _0 = Option::<&T>::Some(copy _14); - goto -> bb8; - } - - bb8: { StorageDead(_14); StorageDead(_4); StorageDead(_12); diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir index b6df2300efb1f..a8054b01680c8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir @@ -96,7 +96,13 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb3: { _0 = const {transmute(0x0000000000000000): Option<&T>}; StorageDead(_7); - goto -> bb8; + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); + return; } bb4: { @@ -106,7 +112,13 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { bb5: { _0 = const {transmute(0x0000000000000000): Option<&T>}; - goto -> bb8; + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); + return; } bb6: { @@ -121,10 +133,6 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { _14 = &(*_13); StorageDead(_13); _0 = Option::<&T>::Some(copy _14); - goto -> bb8; - } - - bb8: { StorageDead(_14); StorageDead(_4); StorageDead(_12); diff --git a/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir index baa01e28a9410..c8efb5790c88a 100644 --- a/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir @@ -25,7 +25,7 @@ fn new(_1: Result) -> Result { bb0: { StorageLive(_4); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { @@ -34,7 +34,7 @@ fn new(_1: Result) -> Result { _5 = move ((_4 as Continue).0: T); _0 = Result::::Ok(copy _5); StorageDead(_4); - goto -> bb3; + return; } bb2: { @@ -43,14 +43,10 @@ fn new(_1: Result) -> Result { _7 = move ((_4 as Break).0: E); _0 = Result::::Err(copy _7); StorageDead(_4); - goto -> bb3; - } - - bb3: { return; } - bb4: { + bb3: { unreachable; } } diff --git a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir index ac485f485b1cc..b84bafe0fbc80 100644 --- a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir @@ -15,26 +15,22 @@ fn old(_1: Result) -> Result { bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { _3 = move ((_1 as Ok).0: T); _0 = Result::::Ok(copy _3); - goto -> bb3; + return; } bb2: { _4 = move ((_1 as Err).0: E); _0 = Result::::Err(copy _4); - goto -> bb3; - } - - bb3: { return; } - bb4: { + bb3: { unreachable; } } diff --git a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff index ce9d812701a8f..f9d21ec98b864 100644 --- a/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff +++ b/tests/mir-opt/separate_const_switch.identity.JumpThreading.diff @@ -42,7 +42,7 @@ StorageLive(_7); StorageLive(_8); _6 = discriminant(_1); - switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb1]; + switchInt(move _6) -> [0: bb7, 1: bb6, otherwise: bb1]; } bb1: { @@ -53,7 +53,7 @@ _5 = copy ((_2 as Continue).0: i32); _0 = Result::::Ok(copy _5); StorageDead(_2); - return; + goto -> bb4; } bb3: { @@ -61,10 +61,14 @@ _10 = copy ((_4 as Err).0: i32); _0 = Result::::Err(copy _10); StorageDead(_2); - return; + goto -> bb4; } bb4: { + return; + } + + bb5: { StorageDead(_8); StorageDead(_7); StorageDead(_6); @@ -73,23 +77,23 @@ + goto -> bb2; } - bb5: { + bb6: { _8 = copy ((_1 as Err).0: i32); StorageLive(_9); _9 = Result::::Err(copy _8); _2 = ControlFlow::, i32>::Break(move _9); StorageDead(_9); -- goto -> bb4; -+ goto -> bb7; +- goto -> bb5; ++ goto -> bb8; } - bb6: { + bb7: { _7 = copy ((_1 as Ok).0: i32); _2 = ControlFlow::, i32>::Continue(copy _7); - goto -> bb4; + goto -> bb5; + } + -+ bb7: { ++ bb8: { + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout index 76288c2aa49f2..c2e4df0cf609c 100644 --- a/tests/ui/stable-mir-print/basic_function.stdout +++ b/tests/ui/stable-mir-print/basic_function.stdout @@ -48,21 +48,18 @@ fn demux(_1: u8) -> u8 { } bb1: { _0 = 0_u8; - goto -> bb5; + return; } bb2: { _0 = 8_u8; - goto -> bb5; + return; } bb3: { _0 = 6_u8; - goto -> bb5; + return; } bb4: { _0 = 10_u8; - goto -> bb5; - } - bb5: { return; } }