diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 5d4560b7d5f..7b5697bc949 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -32,7 +32,6 @@ struct CallSite<'tcx> { callee: Instance<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, block: BasicBlock, - target: Option, source_info: SourceInfo, } @@ -367,7 +366,7 @@ impl<'tcx> Inliner<'tcx> { ) -> Option> { // Only consider direct calls to functions let terminator = bb_data.terminator(); - if let TerminatorKind::Call { ref func, target, fn_span, .. } = terminator.kind { + if let TerminatorKind::Call { ref func, fn_span, .. } = terminator.kind { let func_ty = func.ty(caller_body, self.tcx); if let ty::FnDef(def_id, args) = *func_ty.kind() { // To resolve an instance its args have to be fully normalized. @@ -386,7 +385,7 @@ impl<'tcx> Inliner<'tcx> { let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args); let source_info = SourceInfo { span: fn_span, ..terminator.source_info }; - return Some(CallSite { callee, fn_sig, block: bb, target, source_info }); + return Some(CallSite { callee, fn_sig, block: bb, source_info }); } } @@ -541,10 +540,23 @@ impl<'tcx> Inliner<'tcx> { mut callee_body: Body<'tcx>, ) { let terminator = caller_body[callsite.block].terminator.take().unwrap(); - let TerminatorKind::Call { args, destination, unwind, .. } = terminator.kind else { + let TerminatorKind::Call { args, destination, unwind, target, .. } = terminator.kind else { bug!("unexpected terminator kind {:?}", terminator.kind); }; + let return_block = if let Some(block) = target { + // Prepare a new block for code that should execute when call returns. We don't use + // target block directly since it might have other predecessors. + let mut data = BasicBlockData::new(Some(Terminator { + source_info: terminator.source_info, + kind: TerminatorKind::Goto { target: block }, + })); + data.is_cleanup = caller_body[block].is_cleanup; + Some(caller_body.basic_blocks_mut().push(data)) + } else { + None + }; + // If the call is something like `a[*i] = f(i)`, where // `i : &mut usize`, then just duplicating the `a[*i]` // Place could result in two different locations if `f` @@ -569,7 +581,8 @@ impl<'tcx> Inliner<'tcx> { destination, ); let dest_ty = dest.ty(caller_body, self.tcx); - let temp = Place::from(self.new_call_temp(caller_body, &callsite, dest_ty)); + let temp = + Place::from(self.new_call_temp(caller_body, &callsite, dest_ty, return_block)); caller_body[callsite.block].statements.push(Statement { source_info: callsite.source_info, kind: StatementKind::Assign(Box::new((temp, dest))), @@ -590,12 +603,14 @@ impl<'tcx> Inliner<'tcx> { caller_body, &callsite, destination.ty(caller_body, self.tcx).ty, + return_block, ), ) }; // Copy the arguments if needed. - let args: Vec<_> = self.make_call_args(args, &callsite, caller_body, &callee_body); + let args: Vec<_> = + self.make_call_args(args, &callsite, caller_body, &callee_body, return_block); let mut integrator = Integrator { args: &args, @@ -607,6 +622,7 @@ impl<'tcx> Inliner<'tcx> { callsite, cleanup_block: unwind, in_cleanup_block: false, + return_block, tcx: self.tcx, always_live_locals: BitSet::new_filled(callee_body.local_decls.len()), }; @@ -626,7 +642,7 @@ impl<'tcx> Inliner<'tcx> { }); } } - if let Some(block) = callsite.target { + if let Some(block) = return_block { // To avoid repeated O(n) insert, push any new statements to the end and rotate // the slice once. let mut n = 0; @@ -684,6 +700,7 @@ impl<'tcx> Inliner<'tcx> { callsite: &CallSite<'tcx>, caller_body: &mut Body<'tcx>, callee_body: &Body<'tcx>, + return_block: Option, ) -> Vec { let tcx = self.tcx; @@ -712,8 +729,18 @@ impl<'tcx> Inliner<'tcx> { // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() { let mut args = args.into_iter(); - let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); - let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); + let self_ = self.create_temp_if_necessary( + args.next().unwrap(), + callsite, + caller_body, + return_block, + ); + let tuple = self.create_temp_if_necessary( + args.next().unwrap(), + callsite, + caller_body, + return_block, + ); assert!(args.next().is_none()); let tuple = Place::from(tuple); @@ -730,13 +757,13 @@ impl<'tcx> Inliner<'tcx> { let tuple_field = Operand::Move(tcx.mk_place_field(tuple, FieldIdx::new(i), ty)); // Spill to a local to make e.g., `tmp0`. - self.create_temp_if_necessary(tuple_field, callsite, caller_body) + self.create_temp_if_necessary(tuple_field, callsite, caller_body, return_block) }); closure_ref_arg.chain(tuple_tmp_args).collect() } else { args.into_iter() - .map(|a| self.create_temp_if_necessary(a, callsite, caller_body)) + .map(|a| self.create_temp_if_necessary(a, callsite, caller_body, return_block)) .collect() } } @@ -748,6 +775,7 @@ impl<'tcx> Inliner<'tcx> { arg: Operand<'tcx>, callsite: &CallSite<'tcx>, caller_body: &mut Body<'tcx>, + return_block: Option, ) -> Local { // Reuse the operand if it is a moved temporary. if let Operand::Move(place) = &arg @@ -760,7 +788,7 @@ impl<'tcx> Inliner<'tcx> { // Otherwise, create a temporary for the argument. trace!("creating temp for argument {:?}", arg); let arg_ty = arg.ty(caller_body, self.tcx); - let local = self.new_call_temp(caller_body, callsite, arg_ty); + let local = self.new_call_temp(caller_body, callsite, arg_ty, return_block); caller_body[callsite.block].statements.push(Statement { source_info: callsite.source_info, kind: StatementKind::Assign(Box::new((Place::from(local), Rvalue::Use(arg)))), @@ -774,6 +802,7 @@ impl<'tcx> Inliner<'tcx> { caller_body: &mut Body<'tcx>, callsite: &CallSite<'tcx>, ty: Ty<'tcx>, + return_block: Option, ) -> Local { let local = caller_body.local_decls.push(LocalDecl::new(ty, callsite.source_info.span)); @@ -782,7 +811,7 @@ impl<'tcx> Inliner<'tcx> { kind: StatementKind::StorageLive(local), }); - if let Some(block) = callsite.target { + if let Some(block) = return_block { caller_body[block].statements.insert( 0, Statement { @@ -813,6 +842,7 @@ struct Integrator<'a, 'tcx> { callsite: &'a CallSite<'tcx>, cleanup_block: UnwindAction, in_cleanup_block: bool, + return_block: Option, tcx: TyCtxt<'tcx>, always_live_locals: BitSet, } @@ -956,7 +986,7 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { *unwind = self.map_unwind(*unwind); } TerminatorKind::Return => { - terminator.kind = if let Some(tgt) = self.callsite.target { + terminator.kind = if let Some(tgt) = self.return_block { TerminatorKind::Goto { target: tgt } } else { TerminatorKind::Unreachable diff --git a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff index 217c8b802ca..3ffe2ee0c0b 100644 --- a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-abort.diff @@ -69,58 +69,58 @@ + } + + bb2: { -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ _3 = <() as F>::call() -> [return: bb3, unwind unreachable]; -+ } -+ -+ bb3: { + _4 = <() as F>::call() -> [return: bb1, unwind unreachable]; + } + ++ bb3: { ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ _3 = <() as F>::call() -> [return: bb2, unwind unreachable]; ++ } ++ + bb4: { -+ StorageDead(_10); -+ StorageDead(_9); -+ StorageDead(_8); -+ _6 = <() as E>::call() -> [return: bb5, unwind unreachable]; ++ _7 = <() as E>::call() -> [return: bb3, unwind unreachable]; + } + + bb5: { -+ _7 = <() as E>::call() -> [return: bb2, unwind unreachable]; ++ StorageDead(_10); ++ StorageDead(_9); ++ StorageDead(_8); ++ _6 = <() as E>::call() -> [return: bb4, unwind unreachable]; + } + + bb6: { -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_11); -+ _9 = <() as D>::call() -> [return: bb7, unwind unreachable]; ++ _10 = <() as D>::call() -> [return: bb5, unwind unreachable]; + } + + bb7: { -+ _10 = <() as D>::call() -> [return: bb4, unwind unreachable]; ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_11); ++ _9 = <() as D>::call() -> [return: bb6, unwind unreachable]; + } + + bb8: { -+ StorageDead(_16); -+ StorageDead(_15); -+ StorageDead(_14); -+ _12 = <() as C>::call() -> [return: bb9, unwind unreachable]; ++ _13 = <() as C>::call() -> [return: bb7, unwind unreachable]; + } + + bb9: { -+ _13 = <() as C>::call() -> [return: bb6, unwind unreachable]; ++ StorageDead(_16); ++ StorageDead(_15); ++ StorageDead(_14); ++ _12 = <() as C>::call() -> [return: bb8, unwind unreachable]; + } + + bb10: { -+ StorageDead(_19); -+ StorageDead(_18); -+ StorageDead(_17); -+ _15 = <() as B>::call() -> [return: bb11, unwind unreachable]; ++ _16 = <() as B>::call() -> [return: bb9, unwind unreachable]; + } + + bb11: { -+ _16 = <() as B>::call() -> [return: bb8, unwind unreachable]; ++ StorageDead(_19); ++ StorageDead(_18); ++ StorageDead(_17); ++ _15 = <() as B>::call() -> [return: bb10, unwind unreachable]; + } + + bb12: { @@ -128,7 +128,7 @@ + } + + bb13: { -+ _19 = <() as A>::call() -> [return: bb10, unwind unreachable]; ++ _19 = <() as A>::call() -> [return: bb11, unwind unreachable]; } } diff --git a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff index 0a4ce40c529..3f334779e18 100644 --- a/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/exponential_runtime.main.Inline.panic-unwind.diff @@ -69,58 +69,58 @@ + } + + bb2: { -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ _3 = <() as F>::call() -> [return: bb3, unwind continue]; -+ } -+ -+ bb3: { + _4 = <() as F>::call() -> [return: bb1, unwind continue]; + } + ++ bb3: { ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ _3 = <() as F>::call() -> [return: bb2, unwind continue]; ++ } ++ + bb4: { -+ StorageDead(_10); -+ StorageDead(_9); -+ StorageDead(_8); -+ _6 = <() as E>::call() -> [return: bb5, unwind continue]; ++ _7 = <() as E>::call() -> [return: bb3, unwind continue]; + } + + bb5: { -+ _7 = <() as E>::call() -> [return: bb2, unwind continue]; ++ StorageDead(_10); ++ StorageDead(_9); ++ StorageDead(_8); ++ _6 = <() as E>::call() -> [return: bb4, unwind continue]; + } + + bb6: { -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_11); -+ _9 = <() as D>::call() -> [return: bb7, unwind continue]; ++ _10 = <() as D>::call() -> [return: bb5, unwind continue]; + } + + bb7: { -+ _10 = <() as D>::call() -> [return: bb4, unwind continue]; ++ StorageDead(_13); ++ StorageDead(_12); ++ StorageDead(_11); ++ _9 = <() as D>::call() -> [return: bb6, unwind continue]; + } + + bb8: { -+ StorageDead(_16); -+ StorageDead(_15); -+ StorageDead(_14); -+ _12 = <() as C>::call() -> [return: bb9, unwind continue]; ++ _13 = <() as C>::call() -> [return: bb7, unwind continue]; + } + + bb9: { -+ _13 = <() as C>::call() -> [return: bb6, unwind continue]; ++ StorageDead(_16); ++ StorageDead(_15); ++ StorageDead(_14); ++ _12 = <() as C>::call() -> [return: bb8, unwind continue]; + } + + bb10: { -+ StorageDead(_19); -+ StorageDead(_18); -+ StorageDead(_17); -+ _15 = <() as B>::call() -> [return: bb11, unwind continue]; ++ _16 = <() as B>::call() -> [return: bb9, unwind continue]; + } + + bb11: { -+ _16 = <() as B>::call() -> [return: bb8, unwind continue]; ++ StorageDead(_19); ++ StorageDead(_18); ++ StorageDead(_17); ++ _15 = <() as B>::call() -> [return: bb10, unwind continue]; + } + + bb12: { @@ -128,7 +128,7 @@ + } + + bb13: { -+ _19 = <() as A>::call() -> [return: bb10, unwind continue]; ++ _19 = <() as A>::call() -> [return: bb11, unwind continue]; } } diff --git a/tests/mir-opt/inline/indirect_destination.rs b/tests/mir-opt/inline/indirect_destination.rs new file mode 100644 index 00000000000..2842e23366e --- /dev/null +++ b/tests/mir-opt/inline/indirect_destination.rs @@ -0,0 +1,42 @@ +// Test for inlining with an indirect destination place. +// +// unit-test: Inline +// edition: 2021 +// needs-unwind +#![crate_type = "lib"] +#![feature(custom_mir, core_intrinsics)] +use core::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "initial")] +// CHECK-LABEL: fn f( +// CHECK: bb1: { +// CHECK-NEXT: StorageLive([[A:.*]]); +// CHECK-NEXT: [[A]] = &mut (*_1); +// CHECK-NEXT: StorageLive([[B:.*]]); +// CHECK-NEXT: [[B]] = const 42_u8; +// CHECK-NEXT: (*[[A]]) = move [[B]]; +// CHECK-NEXT: StorageDead([[B]]); +// CHECK-NEXT: StorageDead([[A]]); +// CHECK-NEXT: goto -> bb1; +// CHECK-NEXT: } +pub fn f(a: *mut u8) { + mir! { + { + Goto(bb1) + } + bb1 = { + Call(*a = g(), bb1, UnwindUnreachable()) + } + } +} + +#[custom_mir(dialect = "runtime", phase = "initial")] +#[inline(always)] +fn g() -> u8 { + mir! { + { + RET = 42; + Return() + } + } +} diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 40eeda53908..42dd7ba55cf 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -50,20 +50,20 @@ bb1: { - _3 = &mut _4; - _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind unreachable]; -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ StorageDead(_2); -+ drop(_4) -> [return: bb2, unwind unreachable]; ++ StorageDead(_4); ++ _0 = const (); ++ StorageDead(_1); ++ return; } bb2: { - StorageDead(_3); - _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; -+ StorageDead(_4); -+ _0 = const (); -+ StorageDead(_1); -+ return; ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ StorageDead(_2); ++ drop(_4) -> [return: bb1, unwind unreachable]; } bb3: { @@ -90,7 +90,7 @@ + bb6: { + _1 = CoroutineState::::Yielded(move _8); + discriminant((*_6)) = 3; -+ goto -> bb1; ++ goto -> bb2; + } + + bb7: { @@ -102,7 +102,7 @@ + StorageDead(_8); + _1 = CoroutineState::::Complete(_5); + discriminant((*_6)) = 1; -+ goto -> bb1; ++ goto -> bb2; + } + + bb9: { diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index fdb42bf3d8a..7b8958c13fc 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -34,18 +34,10 @@ StorageLive(_3); StorageLive(_4); - _4 = g() -> [return: bb1, unwind continue]; -- } -- -- bb1: { + _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; - _3 = &mut _4; -- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5]; -- } -- -- bb2: { ++ _3 = &mut _4; + _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { pointer: move _3 }; - StorageDead(_3); -- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; ++ StorageDead(_3); + StorageLive(_5); + _5 = const false; + StorageLive(_6); @@ -55,40 +47,50 @@ + switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; } + bb1: { +- _3 = &mut _4; +- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5]; ++ StorageDead(_4); ++ _0 = const (); ++ StorageDead(_1); ++ return; + } + +- bb2: { +- StorageDead(_3); +- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; ++ bb2 (cleanup): { ++ drop(_4) -> [return: bb3, unwind terminate(cleanup)]; + } + - bb3: { -+ bb1: { +- StorageDead(_2); +- drop(_4) -> [return: bb4, unwind: bb6]; ++ bb3 (cleanup): { ++ resume; + } + + bb4: { +- StorageDead(_4); +- _0 = const (); +- StorageDead(_1); +- return; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); - StorageDead(_2); -- drop(_4) -> [return: bb4, unwind: bb6]; -+ drop(_4) -> [return: bb2, unwind: bb4]; - } - -- bb4: { -+ bb2: { - StorageDead(_4); - _0 = const (); - StorageDead(_1); - return; ++ StorageDead(_2); ++ drop(_4) -> [return: bb1, unwind: bb3]; } - bb5 (cleanup): { - drop(_4) -> [return: bb6, unwind terminate(cleanup)]; -+ bb3 (cleanup): { -+ drop(_4) -> [return: bb4, unwind terminate(cleanup)]; - } - -- bb6 (cleanup): { -+ bb4 (cleanup): { - resume; -+ } -+ + bb5: { + StorageLive(_8); + switchInt(_5) -> [0: bb6, otherwise: bb7]; -+ } -+ + } + +- bb6 (cleanup): { +- resume; + bb6: { + _8 = const 13_i32; + goto -> bb8; @@ -102,11 +104,11 @@ + bb8: { + _1 = CoroutineState::::Yielded(move _8); + discriminant((*_6)) = 3; -+ goto -> bb1; ++ goto -> bb4; + } + + bb9: { -+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb3]; ++ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb2]; + } + + bb10: { @@ -114,7 +116,7 @@ + StorageDead(_8); + _1 = CoroutineState::::Complete(_5); + discriminant((*_6)) = 1; -+ goto -> bb1; ++ goto -> bb4; + } + + bb11: { diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff deleted file mode 100644 index b90e0505c54..00000000000 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-abort.diff +++ /dev/null @@ -1,209 +0,0 @@ -- // MIR for `main` before Inline -+ // MIR for `main` after Inline - - fn main() -> () { - let mut _0: (); - let _1: std::boxed::Box>; - let mut _2: std::vec::Vec; - scope 1 { - debug _x => _1; - } -+ scope 2 (inlined Vec::::new) { -+ let mut _3: alloc::raw_vec::RawVec; -+ } -+ scope 3 (inlined Box::>::new) { -+ debug x => _2; -+ let mut _4: usize; -+ let mut _5: usize; -+ let mut _6: *mut u8; -+ let mut _7: *const std::vec::Vec; -+ scope 4 { -+ scope 5 (inlined alloc::alloc::exchange_malloc) { -+ debug size => _4; -+ debug align => _5; -+ let _8: std::alloc::Layout; -+ let mut _9: std::result::Result, std::alloc::AllocError>; -+ let mut _10: isize; -+ let mut _12: !; -+ scope 6 { -+ debug layout => _8; -+ let _11: std::ptr::NonNull<[u8]>; -+ let mut _13: &std::alloc::Global; -+ scope 8 { -+ debug ptr => _11; -+ scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) { -+ debug self => _11; -+ let mut _15: std::ptr::NonNull; -+ scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) { -+ debug self => _11; -+ let mut _16: *mut u8; -+ let mut _17: *mut [u8]; -+ scope 20 { -+ scope 21 (inlined NonNull::<[u8]>::as_ptr) { -+ debug self => _11; -+ let mut _18: *const [u8]; -+ } -+ scope 22 (inlined ptr::mut_ptr::::as_mut_ptr) { -+ debug self => _17; -+ } -+ scope 23 (inlined NonNull::::new_unchecked) { -+ debug ptr => _16; -+ let mut _19: *const u8; -+ scope 24 { -+ scope 25 (inlined NonNull::::new_unchecked::runtime::) { -+ debug ptr => _16; -+ scope 26 (inlined ptr::mut_ptr::::is_null) { -+ debug self => _16; -+ let mut _20: *mut u8; -+ scope 27 { -+ scope 28 (inlined ptr::mut_ptr::::is_null::runtime_impl) { -+ debug ptr => _20; -+ scope 29 (inlined ptr::mut_ptr::::addr) { -+ debug self => _20; -+ scope 30 { -+ scope 31 (inlined ptr::mut_ptr::::cast::<()>) { -+ debug self => _20; -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ scope 32 (inlined NonNull::::as_ptr) { -+ debug self => _15; -+ let mut _21: *const u8; -+ } -+ } -+ } -+ scope 17 (inlined ::allocate) { -+ debug self => const _; -+ debug layout => _8; -+ } -+ } -+ scope 7 { -+ scope 9 (inlined Layout::from_size_align_unchecked) { -+ debug size => _4; -+ debug align => _5; -+ let mut _14: std::ptr::Alignment; -+ scope 10 { -+ scope 11 (inlined std::ptr::Alignment::new_unchecked) { -+ debug align => _5; -+ scope 12 { -+ scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) { -+ debug align => _5; -+ scope 15 (inlined core::num::::is_power_of_two) { -+ debug self => _5; -+ scope 16 (inlined core::num::::count_ones) { -+ debug self => _5; -+ } -+ } -+ } -+ } -+ scope 13 { -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } - - bb0: { - StorageLive(_1); - StorageLive(_2); -- _2 = Vec::::new() -> [return: bb1, unwind unreachable]; -+ StorageLive(_3); -+ _3 = const _; -+ _2 = Vec:: { buf: move _3, len: const 0_usize }; -+ StorageDead(_3); -+ StorageLive(_4); -+ StorageLive(_5); -+ StorageLive(_6); -+ StorageLive(_7); -+ _4 = SizeOf(std::vec::Vec); -+ _5 = AlignOf(std::vec::Vec); -+ StorageLive(_8); -+ StorageLive(_10); -+ StorageLive(_11); -+ StorageLive(_12); -+ StorageLive(_13); -+ StorageLive(_14); -+ _14 = _5 as std::ptr::Alignment (Transmute); -+ _8 = Layout { size: _4, align: move _14 }; -+ StorageDead(_14); -+ StorageLive(_9); -+ _13 = const _; -+ _9 = std::alloc::Global::alloc_impl(move _13, _8, const false) -> [return: bb5, unwind unreachable]; - } - - bb1: { -- _1 = Box::>::new(move _2) -> [return: bb2, unwind unreachable]; -+ StorageDead(_1); -+ return; - } - - bb2: { -+ _12 = handle_alloc_error(move _8) -> unwind unreachable; -+ } -+ -+ bb3: { -+ unreachable; -+ } -+ -+ bb4: { -+ _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>); -+ StorageLive(_15); -+ StorageLive(_16); -+ StorageLive(_17); -+ StorageLive(_18); -+ _18 = (_11.0: *const [u8]); -+ _17 = move _18 as *mut [u8] (PtrToPtr); -+ StorageDead(_18); -+ _16 = _17 as *mut u8 (PtrToPtr); -+ StorageDead(_17); -+ StorageLive(_19); -+ StorageLive(_20); -+ _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer)); -+ _15 = NonNull:: { pointer: _19 }; -+ StorageDead(_20); -+ StorageDead(_19); -+ StorageDead(_16); -+ StorageLive(_21); -+ _21 = (_15.0: *const u8); -+ _6 = move _21 as *mut u8 (PtrToPtr); -+ StorageDead(_21); -+ StorageDead(_15); -+ StorageDead(_9); -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_11); -+ StorageDead(_10); -+ StorageDead(_8); -+ _1 = ShallowInitBox(move _6, std::vec::Vec); -+ _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); -+ (*_7) = move _2; -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ StorageDead(_4); - StorageDead(_2); - _0 = const (); -- drop(_1) -> [return: bb3, unwind unreachable]; -+ drop(_1) -> [return: bb1, unwind unreachable]; - } - -- bb3: { -- StorageDead(_1); -- return; -+ bb5: { -+ _10 = discriminant(_9); -+ switchInt(move _10) -> [0: bb4, 1: bb2, otherwise: bb3]; - } - } - diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff deleted file mode 100644 index f9c637caa18..00000000000 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.panic-unwind.diff +++ /dev/null @@ -1,222 +0,0 @@ -- // MIR for `main` before Inline -+ // MIR for `main` after Inline - - fn main() -> () { - let mut _0: (); - let _1: std::boxed::Box>; - let mut _2: std::vec::Vec; - scope 1 { - debug _x => _1; - } -+ scope 2 (inlined Vec::::new) { -+ let mut _3: alloc::raw_vec::RawVec; -+ } -+ scope 3 (inlined Box::>::new) { -+ debug x => _2; -+ let mut _4: usize; -+ let mut _5: usize; -+ let mut _6: *mut u8; -+ let mut _7: *const std::vec::Vec; -+ scope 4 { -+ scope 5 (inlined alloc::alloc::exchange_malloc) { -+ debug size => _4; -+ debug align => _5; -+ let _8: std::alloc::Layout; -+ let mut _9: std::result::Result, std::alloc::AllocError>; -+ let mut _10: isize; -+ let mut _12: !; -+ scope 6 { -+ debug layout => _8; -+ let _11: std::ptr::NonNull<[u8]>; -+ let mut _13: &std::alloc::Global; -+ scope 8 { -+ debug ptr => _11; -+ scope 18 (inlined NonNull::<[u8]>::as_mut_ptr) { -+ debug self => _11; -+ let mut _15: std::ptr::NonNull; -+ scope 19 (inlined NonNull::<[u8]>::as_non_null_ptr) { -+ debug self => _11; -+ let mut _16: *mut u8; -+ let mut _17: *mut [u8]; -+ scope 20 { -+ scope 21 (inlined NonNull::<[u8]>::as_ptr) { -+ debug self => _11; -+ let mut _18: *const [u8]; -+ } -+ scope 22 (inlined ptr::mut_ptr::::as_mut_ptr) { -+ debug self => _17; -+ } -+ scope 23 (inlined NonNull::::new_unchecked) { -+ debug ptr => _16; -+ let mut _19: *const u8; -+ scope 24 { -+ scope 25 (inlined NonNull::::new_unchecked::runtime::) { -+ debug ptr => _16; -+ scope 26 (inlined ptr::mut_ptr::::is_null) { -+ debug self => _16; -+ let mut _20: *mut u8; -+ scope 27 { -+ scope 28 (inlined ptr::mut_ptr::::is_null::runtime_impl) { -+ debug ptr => _20; -+ scope 29 (inlined ptr::mut_ptr::::addr) { -+ debug self => _20; -+ scope 30 { -+ scope 31 (inlined ptr::mut_ptr::::cast::<()>) { -+ debug self => _20; -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ scope 32 (inlined NonNull::::as_ptr) { -+ debug self => _15; -+ let mut _21: *const u8; -+ } -+ } -+ } -+ scope 17 (inlined ::allocate) { -+ debug self => const _; -+ debug layout => _8; -+ } -+ } -+ scope 7 { -+ scope 9 (inlined Layout::from_size_align_unchecked) { -+ debug size => _4; -+ debug align => _5; -+ let mut _14: std::ptr::Alignment; -+ scope 10 { -+ scope 11 (inlined std::ptr::Alignment::new_unchecked) { -+ debug align => _5; -+ scope 12 { -+ scope 14 (inlined std::ptr::Alignment::new_unchecked::runtime) { -+ debug align => _5; -+ scope 15 (inlined core::num::::is_power_of_two) { -+ debug self => _5; -+ scope 16 (inlined core::num::::count_ones) { -+ debug self => _5; -+ } -+ } -+ } -+ } -+ scope 13 { -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ } - - bb0: { - StorageLive(_1); - StorageLive(_2); -- _2 = Vec::::new() -> [return: bb1, unwind continue]; -+ StorageLive(_3); -+ _3 = const _; -+ _2 = Vec:: { buf: move _3, len: const 0_usize }; -+ StorageDead(_3); -+ StorageLive(_4); -+ StorageLive(_5); -+ StorageLive(_6); -+ StorageLive(_7); -+ _4 = SizeOf(std::vec::Vec); -+ _5 = AlignOf(std::vec::Vec); -+ StorageLive(_8); -+ StorageLive(_10); -+ StorageLive(_11); -+ StorageLive(_12); -+ StorageLive(_13); -+ StorageLive(_14); -+ _14 = _5 as std::ptr::Alignment (Transmute); -+ _8 = Layout { size: _4, align: move _14 }; -+ StorageDead(_14); -+ StorageLive(_9); -+ _13 = const _; -+ _9 = std::alloc::Global::alloc_impl(move _13, _8, const false) -> [return: bb7, unwind: bb3]; - } - - bb1: { -- _1 = Box::>::new(move _2) -> [return: bb2, unwind: bb4]; -+ StorageDead(_1); -+ return; - } - -- bb2: { -- StorageDead(_2); -- _0 = const (); -- drop(_1) -> [return: bb3, unwind: bb4]; -+ bb2 (cleanup): { -+ resume; - } - -- bb3: { -- StorageDead(_1); -- return; -+ bb3 (cleanup): { -+ drop(_2) -> [return: bb2, unwind terminate(cleanup)]; - } - -- bb4 (cleanup): { -- resume; -+ bb4: { -+ _12 = handle_alloc_error(move _8) -> bb3; -+ } -+ -+ bb5: { -+ unreachable; -+ } -+ -+ bb6: { -+ _11 = ((_9 as Ok).0: std::ptr::NonNull<[u8]>); -+ StorageLive(_15); -+ StorageLive(_16); -+ StorageLive(_17); -+ StorageLive(_18); -+ _18 = (_11.0: *const [u8]); -+ _17 = move _18 as *mut [u8] (PtrToPtr); -+ StorageDead(_18); -+ _16 = _17 as *mut u8 (PtrToPtr); -+ StorageDead(_17); -+ StorageLive(_19); -+ StorageLive(_20); -+ _19 = _16 as *const u8 (PointerCoercion(MutToConstPointer)); -+ _15 = NonNull:: { pointer: _19 }; -+ StorageDead(_20); -+ StorageDead(_19); -+ StorageDead(_16); -+ StorageLive(_21); -+ _21 = (_15.0: *const u8); -+ _6 = move _21 as *mut u8 (PtrToPtr); -+ StorageDead(_21); -+ StorageDead(_15); -+ StorageDead(_9); -+ StorageDead(_13); -+ StorageDead(_12); -+ StorageDead(_11); -+ StorageDead(_10); -+ StorageDead(_8); -+ _1 = ShallowInitBox(move _6, std::vec::Vec); -+ _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); -+ (*_7) = move _2; -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ StorageDead(_4); -+ StorageDead(_2); -+ _0 = const (); -+ drop(_1) -> [return: bb1, unwind: bb2]; -+ } -+ -+ bb7: { -+ _10 = discriminant(_9); -+ switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5]; - } - } - diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs deleted file mode 100644 index 65f8e2916b6..00000000000 --- a/tests/mir-opt/inline/inline_into_box_place.rs +++ /dev/null @@ -1,11 +0,0 @@ -// ignore-endian-big -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -// ignore-debug MIR alignment checks in std alter the diff, breaking the test -// compile-flags: -Zmir-opt-level=4 -Zinline-mir-hint-threshold=200 - -// EMIT_MIR inline_into_box_place.main.Inline.diff -fn main() { - // CHECK-LABEL: fn main( - // CHECK: (inlined Box::>::new) - let _x: Box> = Box::new(Vec::new()); -} diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff index f17c9ba3f9f..f50603a66a5 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-abort.diff @@ -60,16 +60,6 @@ } 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; @@ -77,14 +67,14 @@ _0 = Result::::Ok(move _2); StorageDead(_2); StorageDead(_3); - goto -> bb5; + goto -> bb4; } - bb3: { + bb2: { unreachable; } - bb4: { + bb3: { StorageLive(_6); _6 = ((_3 as Break).0: std::result::Result); StorageLive(_8); @@ -100,11 +90,21 @@ StorageDead(_6); StorageDead(_2); StorageDead(_3); - goto -> bb5; + goto -> bb4; + } + + bb4: { + return; } bb5: { - return; + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); +- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ goto -> bb1; } bb6: { @@ -113,7 +113,7 @@ _13 = Result::::Err(move _12); _3 = ControlFlow::, i32>::Break(move _13); StorageDead(_13); -- goto -> bb1; +- goto -> bb5; + goto -> bb9; } @@ -124,7 +124,7 @@ bb8: { _11 = move ((_4 as Ok).0: i32); _3 = ControlFlow::, i32>::Continue(move _11); - goto -> bb1; + goto -> bb5; + } + + bb9: { @@ -133,7 +133,7 @@ + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); -+ goto -> bb4; ++ goto -> bb3; } } diff --git a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff index f17c9ba3f9f..f50603a66a5 100644 --- a/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff +++ b/tests/mir-opt/jump_threading.identity.JumpThreading.panic-unwind.diff @@ -60,16 +60,6 @@ } 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; @@ -77,14 +67,14 @@ _0 = Result::::Ok(move _2); StorageDead(_2); StorageDead(_3); - goto -> bb5; + goto -> bb4; } - bb3: { + bb2: { unreachable; } - bb4: { + bb3: { StorageLive(_6); _6 = ((_3 as Break).0: std::result::Result); StorageLive(_8); @@ -100,11 +90,21 @@ StorageDead(_6); StorageDead(_2); StorageDead(_3); - goto -> bb5; + goto -> bb4; + } + + bb4: { + return; } bb5: { - return; + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); +- switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; ++ goto -> bb1; } bb6: { @@ -113,7 +113,7 @@ _13 = Result::::Err(move _12); _3 = ControlFlow::, i32>::Break(move _13); StorageDead(_13); -- goto -> bb1; +- goto -> bb5; + goto -> bb9; } @@ -124,7 +124,7 @@ bb8: { _11 = move ((_4 as Ok).0: i32); _3 = ControlFlow::, i32>::Continue(move _11); - goto -> bb1; + goto -> bb5; + } + + bb9: { @@ -133,7 +133,7 @@ + StorageDead(_10); + StorageDead(_4); + _5 = discriminant(_3); -+ goto -> bb4; ++ goto -> bb3; } } diff --git a/tests/mir-opt/jump_threading.rs b/tests/mir-opt/jump_threading.rs index 852dcd0db01..66e5c5d3c11 100644 --- a/tests/mir-opt/jump_threading.rs +++ b/tests/mir-opt/jump_threading.rs @@ -52,19 +52,19 @@ fn identity(x: Result) -> Result { // CHECK: [[x:_.*]] = _1; // CHECK: switchInt(move {{_.*}}) -> [0: bb8, 1: bb6, otherwise: bb7]; // CHECK: bb1: { - // CHECK: goto -> bb2; - // CHECK: bb2: { // CHECK: {{_.*}} = (([[controlflow:_.*]] as Continue).0: i32); // CHECK: _0 = Result::::Ok( - // CHECK: goto -> bb5; - // CHECK: bb3: { + // CHECK: goto -> bb4; + // CHECK: bb2: { // CHECK: unreachable; - // CHECK: bb4: { + // CHECK: bb3: { // CHECK: {{_.*}} = (([[controlflow]] as Break).0: std::result::Result); // CHECK: _0 = Result::::Err( - // CHECK: goto -> bb5; - // CHECK: bb5: { + // CHECK: goto -> bb4; + // CHECK: bb4: { // CHECK: return; + // CHECK: bb5: { + // CHECK: goto -> bb1; // CHECK: bb6: { // CHECK: {{_.*}} = move (([[x]] as Err).0: i32); // CHECK: [[controlflow]] = ControlFlow::, i32>::Break( @@ -74,9 +74,9 @@ fn identity(x: Result) -> Result { // CHECK: bb8: { // CHECK: {{_.*}} = move (([[x]] as Ok).0: i32); // CHECK: [[controlflow]] = ControlFlow::, i32>::Continue( - // CHECK: goto -> bb1; + // CHECK: goto -> bb5; // CHECK: bb9: { - // CHECK: goto -> bb4; + // CHECK: goto -> bb3; Ok(x?) } diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index fe4b33001fc..d287b20c4ea 100644 --- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -52,29 +52,21 @@ StorageLive(_10); StorageLive(_11); _9 = discriminant(_1); - switchInt(move _9) -> [0: bb6, 1: bb5, otherwise: bb3]; + switchInt(move _9) -> [0: bb6, 1: bb5, otherwise: bb2]; } bb1: { - StorageDead(_11); - StorageDead(_10); - StorageDead(_9); - _5 = discriminant(_3); - switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; - } - - bb2: { _8 = ((_3 as Continue).0: i32); _0 = Result::::Ok(_8); StorageDead(_3); return; } - bb3: { + bb2: { unreachable; } - bb4: { + bb3: { _6 = ((_3 as Break).0: std::result::Result); _13 = ((_6 as Err).0: i32); _0 = Result::::Err(move _13); @@ -82,19 +74,27 @@ return; } + bb4: { + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); + _5 = discriminant(_3); + switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; + } + bb5: { _11 = ((_1 as Err).0: i32); StorageLive(_12); _12 = Result::::Err(move _11); _3 = ControlFlow::, i32>::Break(move _12); StorageDead(_12); - goto -> bb1; + goto -> bb4; } bb6: { _10 = ((_1 as Ok).0: i32); _3 = ControlFlow::, i32>::Continue(move _10); - goto -> bb1; + goto -> bb4; } }