diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index f48dba9663a52..2a0ea321ac6c4 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -6,6 +6,7 @@ use std::ops::{Range, RangeFrom}; use rustc_abi::{ExternAbi, FieldIdx}; use rustc_attr_data_structures::{InlineAttr, OptimizeAttr}; +use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_index::Idx; @@ -553,46 +554,53 @@ fn resolve_callsite<'tcx, I: Inliner<'tcx>>( let terminator = bb_data.terminator(); // FIXME(explicit_tail_calls): figure out if we can inline tail calls - if let TerminatorKind::Call { ref func, fn_span, .. } = terminator.kind { - let func_ty = func.ty(caller_body, tcx); - if let ty::FnDef(def_id, args) = *func_ty.kind() { - if !inliner.should_inline_for_callee(def_id) { - debug!("not enabled"); - return None; - } - - // To resolve an instance its args have to be fully normalized. - let args = tcx.try_normalize_erasing_regions(inliner.typing_env(), args).ok()?; - let callee = - Instance::try_resolve(tcx, inliner.typing_env(), def_id, args).ok().flatten()?; + let (def_id, args, fn_span) = match terminator.kind { + TerminatorKind::Call { ref func, fn_span, .. } => { + let func_ty = func.ty(caller_body, tcx); + let ty::FnDef(def_id, args) = *func_ty.kind() else { return None }; + (def_id, args, fn_span) + } + TerminatorKind::Drop { place, .. } => { + let ty = place.ty(caller_body, tcx).ty; + let def_id = tcx.require_lang_item(LangItem::DropInPlace, terminator.source_info.span); + let args = tcx.mk_args(&[ty.into()]); + (def_id, args, terminator.source_info.span) + } + _ => return None, + }; - if let InstanceKind::Virtual(..) | InstanceKind::Intrinsic(_) = callee.def { - return None; - } + if !inliner.should_inline_for_callee(def_id) { + debug!("not enabled"); + return None; + } - if inliner.history().contains(&callee.def_id()) { - return None; - } + // To resolve an instance its args have to be fully normalized. + let args = tcx.try_normalize_erasing_regions(inliner.typing_env(), args).ok()?; + let callee = Instance::try_resolve(tcx, inliner.typing_env(), def_id, args).ok().flatten()?; - let fn_sig = tcx.fn_sig(def_id).instantiate(tcx, args); + if let InstanceKind::Virtual(..) | InstanceKind::Intrinsic(_) = callee.def { + return None; + } - // Additionally, check that the body that we're inlining actually agrees - // with the ABI of the trait that the item comes from. - if let InstanceKind::Item(instance_def_id) = callee.def - && tcx.def_kind(instance_def_id) == DefKind::AssocFn - && let instance_fn_sig = tcx.fn_sig(instance_def_id).skip_binder() - && instance_fn_sig.abi() != fn_sig.abi() - { - return None; - } + if inliner.history().contains(&callee.def_id()) { + return None; + } - let source_info = SourceInfo { span: fn_span, ..terminator.source_info }; + let fn_sig = tcx.fn_sig(def_id).instantiate(tcx, args); - return Some(CallSite { callee, fn_sig, block: bb, source_info }); - } + // Additionally, check that the body that we're inlining actually agrees + // with the ABI of the trait that the item comes from. + if let InstanceKind::Item(instance_def_id) = callee.def + && tcx.def_kind(instance_def_id) == DefKind::AssocFn + && let instance_fn_sig = tcx.fn_sig(instance_def_id).skip_binder() + && instance_fn_sig.abi() != fn_sig.abi() + { + return None; } - None + let source_info = SourceInfo { span: fn_span, ..terminator.source_info }; + + Some(CallSite { callee, fn_sig, block: bb, source_info }) } /// Attempts to inline a callsite into the caller body. When successful returns basic blocks @@ -603,6 +611,23 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( caller_body: &mut Body<'tcx>, callsite: &CallSite<'tcx>, ) -> Result, &'static str> { + // Fast path to inline trivial drops. + if let InstanceKind::DropGlue(_, None) = callsite.callee.def { + let terminator = caller_body[callsite.block].terminator_mut(); + let target = match terminator.kind { + TerminatorKind::Call { target, .. } => target, + TerminatorKind::Drop { target, .. } => Some(target), + _ => bug!("unexpected terminator kind {:?}", terminator.kind), + }; + if let Some(target) = target { + terminator.kind = TerminatorKind::Goto { target }; + } else { + terminator.kind = TerminatorKind::Unreachable; + } + let next_block = caller_body.basic_blocks.next_index(); + return Ok(next_block..next_block); + } + let tcx = inliner.tcx(); check_mir_is_available(inliner, caller_body, callsite.callee)?; @@ -611,17 +636,6 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( check_codegen_attributes(inliner, callsite, callee_attrs)?; inliner.check_codegen_attributes_extra(callee_attrs)?; - let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); - let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; - let destination_ty = destination.ty(&caller_body.local_decls, tcx).ty; - for arg in args { - if !arg.node.ty(&caller_body.local_decls, tcx).is_sized(tcx, inliner.typing_env()) { - // We do not allow inlining functions with unsized params. Inlining these functions - // could create unsized locals, which are unsound and being phased out. - return Err("call has unsized argument"); - } - } - let callee_body = try_instance_mir(tcx, callsite.callee.def)?; check_inline::is_inline_valid_on_body(tcx, callee_body)?; inliner.check_callee_mir_body(callsite, callee_body, callee_attrs)?; @@ -642,54 +656,73 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>( return Err("implementation limitation -- callee body failed validation"); } - // Check call signature compatibility. - // Normally, this shouldn't be required, but trait normalization failure can create a - // validation ICE. - let output_type = callee_body.return_ty(); - if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) { - trace!(?output_type, ?destination_ty); - return Err("implementation limitation -- return type mismatch"); - } - if callsite.fn_sig.abi() == ExternAbi::RustCall { - let (self_arg, arg_tuple) = match &args[..] { - [arg_tuple] => (None, arg_tuple), - [self_arg, arg_tuple] => (Some(self_arg), arg_tuple), - _ => bug!("Expected `rust-call` to have 1 or 2 args"), - }; + let terminator = caller_body[callsite.block].terminator.as_ref().unwrap(); + match &terminator.kind { + TerminatorKind::Call { args, destination, .. } => { + let destination_ty = destination.ty(&caller_body.local_decls, tcx).ty; + for arg in args { + if !arg.node.ty(&caller_body.local_decls, tcx).is_sized(tcx, inliner.typing_env()) { + // We do not allow inlining functions with unsized params. Inlining these functions + // could create unsized locals, which are unsound and being phased out. + return Err("call has unsized argument"); + } + } - let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx)); + // Check call signature compatibility. + // Normally, this shouldn't be required, but trait normalization failure can create a + // validation ICE. + let output_type = callee_body.return_ty(); + if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) { + trace!(?output_type, ?destination_ty); + return Err("implementation limitation -- return type mismatch"); + } + if callsite.fn_sig.abi() == ExternAbi::RustCall { + let (self_arg, arg_tuple) = match &args[..] { + [arg_tuple] => (None, arg_tuple), + [self_arg, arg_tuple] => (Some(self_arg), arg_tuple), + _ => bug!("Expected `rust-call` to have 1 or 2 args"), + }; - let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx); - let arg_tys = if callee_body.spread_arg.is_some() { - std::slice::from_ref(&arg_tuple_ty) - } else { - let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else { - bug!("Closure arguments are not passed as a tuple"); - }; - arg_tuple_tys.as_slice() - }; + let self_arg_ty = + self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx)); - for (arg_ty, input) in - self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter()) - { - let input_type = callee_body.local_decls[input].ty; - if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { - trace!(?arg_ty, ?input_type); - debug!("failed to normalize tuple argument type"); - return Err("implementation limitation"); - } - } - } else { - for (arg, input) in args.iter().zip(callee_body.args_iter()) { - let input_type = callee_body.local_decls[input].ty; - let arg_ty = arg.node.ty(&caller_body.local_decls, tcx); - if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { - trace!(?arg_ty, ?input_type); - debug!("failed to normalize argument type"); - return Err("implementation limitation -- arg mismatch"); + let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx); + let arg_tys = if callee_body.spread_arg.is_some() { + std::slice::from_ref(&arg_tuple_ty) + } else { + let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else { + bug!("Closure arguments are not passed as a tuple"); + }; + arg_tuple_tys.as_slice() + }; + + for (arg_ty, input) in self_arg_ty + .into_iter() + .chain(arg_tys.iter().copied()) + .zip(callee_body.args_iter()) + { + let input_type = callee_body.local_decls[input].ty; + if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { + trace!(?arg_ty, ?input_type); + debug!("failed to normalize tuple argument type"); + return Err("implementation limitation"); + } + } + } else { + for (arg, input) in args.iter().zip(callee_body.args_iter()) { + let input_type = callee_body.local_decls[input].ty; + let arg_ty = arg.node.ty(&caller_body.local_decls, tcx); + if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) { + trace!(?arg_ty, ?input_type); + debug!("failed to normalize argument type"); + return Err("implementation limitation -- arg mismatch"); + } + } } } - } + TerminatorKind::Drop { .. } => {} + _ => bug!(), + }; let old_blocks = caller_body.basic_blocks.next_index(); inline_call(inliner, caller_body, callsite, callee_body); @@ -854,9 +887,31 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( ) { let tcx = inliner.tcx(); let terminator = caller_body[callsite.block].terminator.take().unwrap(); - let TerminatorKind::Call { func, args, destination, unwind, target, .. } = terminator.kind - else { - bug!("unexpected terminator kind {:?}", terminator.kind); + let (args, destination, unwind, target) = match terminator.kind { + TerminatorKind::Call { args, destination, unwind, target, .. } => { + (args, destination, unwind, target) + } + TerminatorKind::Drop { place, unwind, target, .. } => { + // `drop_in_place` takes a `*mut`, so we need to take the address to pass it. + let place_ty = place.ty(caller_body, tcx).ty; + let place_addr_ty = Ty::new_mut_ptr(tcx, place_ty); + let arg_place: Place<'tcx> = + new_call_temp(caller_body, callsite, place_addr_ty, Some(target)).into(); + caller_body[callsite.block].statements.push(Statement { + source_info: callsite.source_info, + kind: StatementKind::Assign(Box::new(( + arg_place, + Rvalue::RawPtr(RawPtrKind::Mut, place), + ))), + }); + let arg = Spanned { span: terminator.source_info.span, node: Operand::Move(arg_place) }; + + // Create a dummy destination place as calls have one. + let destination: Place<'tcx> = + new_call_temp(caller_body, callsite, tcx.types.unit, Some(target)).into(); + (vec![arg].into_boxed_slice(), destination, unwind, Some(target)) + } + _ => bug!("unexpected terminator kind {:?}", terminator.kind), }; let return_block = if let Some(block) = target { @@ -1014,7 +1069,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( // the actually used items. By doing this we can entirely avoid visiting the callee! // We need to reconstruct the `required_item` for the callee so that we can find and // remove it. - let callee_item = MentionedItem::Fn(func.ty(caller_body, tcx)); + let callee_item = MentionedItem::Fn(callsite.callee.ty(tcx, inliner.typing_env())); let caller_mentioned_items = caller_body.mentioned_items.as_mut().unwrap(); if let Some(idx) = caller_mentioned_items.iter().position(|item| item.node == callee_item) { // We found the callee, so remove it and add its items instead. diff --git a/tests/mir-opt/c_unwind_terminate.rs b/tests/mir-opt/c_unwind_terminate.rs index 64524e74d28e5..c54cf2764939a 100644 --- a/tests/mir-opt/c_unwind_terminate.rs +++ b/tests/mir-opt/c_unwind_terminate.rs @@ -14,9 +14,14 @@ fn panic() { // EMIT_MIR c_unwind_terminate.test.AbortUnwindingCalls.after.mir extern "C" fn test() { // CHECK-LABEL: fn test( + // CHECK: panic + // CHECK-SAME: unwind: [[panic_unwind:bb.*]]] // CHECK: drop - // CHECK-SAME: unwind: [[unwind:bb.*]]] - // CHECK: [[unwind]] (cleanup) + // CHECK-SAME: unwind: [[drop_unwind:bb.*]]] + // CHECK: [[panic_unwind]] (cleanup) + // CHECK-NEXT: drop + // CHECK-SAME: terminate(cleanup) + // CHECK: [[drop_unwind]] (cleanup) // CHECK-NEXT: terminate(abi) let _val = Noise; panic(); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff index 2c89670dcf7d7..9dc14bec19335 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -60,10 +64,15 @@ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind unreachable]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb1, unwind unreachable]; } bb1: { + StorageDead(_9); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff index 8fecfe224cc69..2f81a39b10e24 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -60,16 +64,21 @@ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb2, unwind: bb1]; } - bb1: { - StorageDead(_1); - return; + bb1 (cleanup): { + resume; } - bb2 (cleanup): { - resume; + bb2: { + StorageDead(_9); + StorageDead(_8); + StorageDead(_1); + return; } } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff index 976ea252c2f89..e52edb907fdc5 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -60,10 +64,15 @@ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind unreachable]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb1, unwind unreachable]; } bb1: { + StorageDead(_9); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff index 6c59f5e3e2e86..aaae58b4664e0 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -60,16 +64,21 @@ _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb2, unwind: bb1]; } - bb1: { - StorageDead(_1); - return; + bb1 (cleanup): { + resume; } - bb2 (cleanup): { - resume; + bb2: { + StorageDead(_9); + StorageDead(_8); + StorageDead(_1); + return; } } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index 1f9cf6d6aca83..65b44e7861d6e 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -67,10 +71,15 @@ + _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind unreachable]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb1, unwind unreachable]; } bb1: { + StorageDead(_9); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index a8760285fac11..dfdeca9946e5f 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -67,16 +71,21 @@ + _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb2, unwind: bb1]; } - bb1: { - StorageDead(_1); - return; + bb1 (cleanup): { + resume; } - bb2 (cleanup): { - resume; + bb2: { + StorageDead(_9); + StorageDead(_8); + StorageDead(_1); + return; } } + diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index c398ae70a1a3e..fe2c3883843ca 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -67,10 +71,15 @@ + _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind unreachable]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb1, unwind unreachable]; } bb1: { + StorageDead(_9); + StorageDead(_8); StorageDead(_1); return; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 02934c02587d2..47b2f26c5db67 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -5,6 +5,8 @@ let mut _0: (); let _1: A; let mut _2: std::boxed::Box<[bool]>; + let mut _8: *mut A; + let mut _9: (); scope 1 { debug a => _1; } @@ -37,6 +39,8 @@ } } } + scope 14 (inlined drop_in_place:: - shim(Some(A))) { + } bb0: { StorageLive(_1); @@ -67,16 +71,21 @@ + _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }}; StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb1, unwind: bb2]; + StorageLive(_8); + _8 = &raw mut _1; + StorageLive(_9); + drop(((*_8).0: std::boxed::Box<[bool]>)) -> [return: bb2, unwind: bb1]; } - bb1: { - StorageDead(_1); - return; + bb1 (cleanup): { + resume; } - bb2 (cleanup): { - resume; + bb2: { + StorageDead(_9); + StorageDead(_8); + StorageDead(_1); + return; } } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index 25ffff619e60b..8b3faa149ee65 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -11,6 +11,8 @@ let mut _9: std::boxed::Box<()>; let mut _10: *const (); let mut _23: usize; + let mut _44: usize; + let mut _45: std::ptr::Alignment; scope 1 { debug vp_ctx => _1; let _4: *const (); @@ -66,11 +68,82 @@ } } } + scope 19 (inlined drop_in_place::> - shim(Some(Box<()>))) { + scope 20 (inlined as Drop>::drop) { + let mut _24: *const (); + let mut _25: *mut (); + let _26: (); + let _34: std::ptr::NonNull<()>; + scope 21 { + let _46: usize; + let _47: std::ptr::Alignment; + scope 22 { + scope 30 (inlined Layout::size) { + } + scope 31 (inlined Unique::<()>::cast::) { + let mut _32: std::ptr::NonNull; + scope 32 (inlined NonNull::<()>::cast::) { + let mut _33: *const u8; + scope 33 (inlined NonNull::<()>::as_ptr) { + } + } + } + scope 34 (inlined as From>>::from) { + scope 35 (inlined Unique::::as_non_null_ptr) { + } + } + scope 36 (inlined ::deallocate) { + let mut _35: usize; + let mut _36: *mut u8; + scope 37 (inlined Layout::size) { + } + scope 38 (inlined NonNull::::as_ptr) { + } + scope 39 (inlined std::alloc::dealloc) { + let mut _37: usize; + scope 40 (inlined Layout::size) { + } + scope 41 (inlined Layout::align) { + let mut _38: std::ptr::Alignment; + scope 42 (inlined std::ptr::Alignment::as_usize) { + let _39: std::ptr::alignment::AlignmentEnum; + let mut _40: u32; + let mut _41: bool; + let mut _42: bool; + let mut _43: bool; + } + } + } + } + } + scope 23 (inlined Unique::<()>::as_ptr) { + scope 24 (inlined NonNull::<()>::as_ptr) { + } + } + scope 25 (inlined Layout::for_value_raw::<()>) { + let mut _27: usize; + let mut _28: usize; + scope 26 { + scope 29 (inlined #[track_caller] Layout::from_size_align_unchecked) { + let mut _29: bool; + let _30: (); + let mut _31: std::ptr::Alignment; + } + } + scope 27 (inlined size_of_val_raw::<()>) { + } + scope 28 (inlined align_of_val_raw::<()>) { + } + } + } + } + } bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -81,28 +154,23 @@ StorageLive(_14); StorageLive(_16); StorageLive(_17); - StorageLive(_19); +- StorageLive(_19); ++ nop; _19 = const false; -- switchInt(move _19) -> [0: bb6, otherwise: bb5]; -+ switchInt(const false) -> [0: bb6, otherwise: bb5]; +- switchInt(move _19) -> [0: bb5, otherwise: bb4]; ++ switchInt(const false) -> [0: bb5, otherwise: bb4]; } bb1: { - StorageDead(_3); - StorageDead(_1); - return; - } - - bb2: { unreachable; } - bb3: { + bb2: { - _18 = handle_alloc_error(move _14) -> unwind unreachable; + _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; } - bb4: { + bb3: { _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); StorageLive(_22); _22 = copy _17 as *mut [u8] (Transmute); @@ -121,8 +189,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -135,26 +204,45 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_23); StorageDead(_6); - StorageLive(_7); +- StorageLive(_7); ++ nop; StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); +- StorageDead(_7); - StorageDead(_5); ++ nop; + nop; StorageDead(_4); - drop(_3) -> [return: bb1, unwind unreachable]; + StorageLive(_46); + StorageLive(_47); + StorageLive(_25); +- StorageLive(_27); ++ nop; + StorageLive(_32); +- StorageLive(_34); ++ nop; + _34 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + StorageLive(_24); +- _25 = copy _34 as *mut () (Transmute); +- _24 = copy _34 as *const () (Transmute); ++ _25 = copy _7; ++ _24 = copy _10; + StorageLive(_28); +- _27 = std::intrinsics::size_of_val::<()>(copy _24) -> [return: bb9, unwind unreachable]; ++ _27 = std::intrinsics::size_of_val::<()>(copy _10) -> [return: bb9, unwind unreachable]; } - bb5: { -- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb6, unwind unreachable]; -+ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; + bb4: { +- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb5, unwind unreachable]; ++ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb5, unwind unreachable]; } - bb6: { - StorageDead(_19); + bb5: { +- StorageDead(_19); ++ nop; StorageLive(_21); - _21 = copy _12 as std::ptr::Alignment (Transmute); - _14 = Layout { size: copy _11, align: move _21 }; @@ -162,13 +250,123 @@ + _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_21); StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb7, unwind unreachable]; -+ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; +- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb6, unwind unreachable]; ++ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb6, unwind unreachable]; } - bb7: { + bb6: { _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; + switchInt(move _16) -> [0: bb3, 1: bb2, otherwise: bb1]; + } + + bb7: { +- StorageDead(_34); ++ nop; + StorageDead(_32); +- StorageDead(_27); ++ nop; + StorageDead(_25); + StorageDead(_46); + StorageDead(_47); +- StorageDead(_3); ++ nop; + StorageDead(_1); + return; + } + + bb8: { + StorageLive(_33); +- _33 = copy _25 as *const u8 (PtrToPtr); ++ _33 = copy _34 as *const u8 (Transmute); + _32 = NonNull:: { pointer: move _33 }; + StorageDead(_33); + StorageLive(_44); + StorageLive(_45); +- _44 = copy _46; +- _45 = copy _47; ++ _44 = copy _27; ++ _45 = copy _31; + StorageLive(_35); +- _35 = copy _44; +- switchInt(move _35) -> [0: bb14, otherwise: bb13]; ++ _35 = copy _27; ++ switchInt(copy _27) -> [0: bb14, otherwise: bb13]; + } + + bb9: { +- _28 = std::intrinsics::align_of_val::<()>(move _24) -> [return: bb10, unwind unreachable]; ++ _28 = std::intrinsics::align_of_val::<()>(copy _10) -> [return: bb10, unwind unreachable]; + } + + bb10: { + StorageLive(_29); + _29 = const false; +- switchInt(move _29) -> [0: bb12, otherwise: bb11]; ++ switchInt(const false) -> [0: bb12, otherwise: bb11]; + } + + bb11: { + _30 = Layout::from_size_align_unchecked::precondition_check(copy _27, copy _28) -> [return: bb12, unwind unreachable]; + } + + bb12: { + StorageDead(_29); +- StorageLive(_31); ++ nop; + _31 = copy _28 as std::ptr::Alignment (Transmute); + _46 = copy _27; +- _47 = move _31; +- StorageDead(_31); ++ _47 = copy _31; ++ nop; + StorageDead(_28); + StorageDead(_24); +- switchInt(move _27) -> [0: bb7, otherwise: bb8]; ++ switchInt(copy _27) -> [0: bb7, otherwise: bb8]; + } + + bb13: { + StorageLive(_36); +- _36 = copy _32 as *mut u8 (Transmute); ++ _36 = copy _34 as *mut u8 (Transmute); + StorageLive(_37); + StorageLive(_38); +- _38 = copy _45; ++ _38 = copy _31; + StorageLive(_40); + StorageLive(_41); + StorageLive(_42); + StorageLive(_43); + StorageLive(_39); +- _39 = copy (_38.0: std::ptr::alignment::AlignmentEnum); ++ _39 = copy (_31.0: std::ptr::alignment::AlignmentEnum); + _40 = discriminant(_39); + _41 = Ge(copy _40, const 1_u32); + _42 = Le(copy _40, const 2147483648_u32); + _43 = BitAnd(move _41, move _42); + assume(move _43); + _37 = copy _40 as usize (IntToInt); + StorageDead(_39); + StorageDead(_43); + StorageDead(_42); + StorageDead(_41); + StorageDead(_40); + StorageDead(_38); +- _26 = alloc::alloc::__rust_dealloc(move _36, move _35, move _37) -> [return: bb15, unwind unreachable]; ++ _26 = alloc::alloc::__rust_dealloc(move _36, copy _27, move _37) -> [return: bb15, unwind unreachable]; + } + + bb14: { + StorageDead(_35); + StorageDead(_44); + StorageDead(_45); + goto -> bb7; + } + + bb15: { + StorageDead(_37); + StorageDead(_36); + goto -> bb14; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index b2085afb71379..57a173d426b2c 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -11,6 +11,8 @@ let mut _9: std::boxed::Box<()>; let mut _10: *const (); let mut _11: usize; + let mut _32: usize; + let mut _33: std::ptr::Alignment; scope 1 { debug vp_ctx => _1; let _4: *const (); @@ -32,11 +34,82 @@ } } } + scope 8 (inlined drop_in_place::> - shim(Some(Box<()>))) { + scope 9 (inlined as Drop>::drop) { + let mut _12: *const (); + let mut _13: *mut (); + let _14: (); + let _22: std::ptr::NonNull<()>; + scope 10 { + let _34: usize; + let _35: std::ptr::Alignment; + scope 11 { + scope 19 (inlined Layout::size) { + } + scope 20 (inlined Unique::<()>::cast::) { + let mut _20: std::ptr::NonNull; + scope 21 (inlined NonNull::<()>::cast::) { + let mut _21: *const u8; + scope 22 (inlined NonNull::<()>::as_ptr) { + } + } + } + scope 23 (inlined as From>>::from) { + scope 24 (inlined Unique::::as_non_null_ptr) { + } + } + scope 25 (inlined ::deallocate) { + let mut _23: usize; + let mut _24: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + let mut _25: usize; + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::align) { + let mut _26: std::ptr::Alignment; + scope 31 (inlined std::ptr::Alignment::as_usize) { + let _27: std::ptr::alignment::AlignmentEnum; + let mut _28: u32; + let mut _29: bool; + let mut _30: bool; + let mut _31: bool; + } + } + } + } + } + scope 12 (inlined Unique::<()>::as_ptr) { + scope 13 (inlined NonNull::<()>::as_ptr) { + } + } + scope 14 (inlined Layout::for_value_raw::<()>) { + let mut _15: usize; + let mut _16: usize; + scope 15 { + scope 18 (inlined #[track_caller] Layout::from_size_align_unchecked) { + let mut _17: bool; + let _18: (); + let mut _19: std::ptr::Alignment; + } + } + scope 16 (inlined size_of_val_raw::<()>) { + } + scope 17 (inlined align_of_val_raw::<()>) { + } + } + } + } + } bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +119,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -60,27 +134,145 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_11); StorageDead(_6); - StorageLive(_7); +- StorageLive(_7); ++ nop; StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); +- StorageDead(_7); - StorageDead(_5); ++ nop; + nop; StorageDead(_4); - drop(_3) -> [return: bb2, unwind: bb3]; + StorageLive(_34); + StorageLive(_35); + StorageLive(_13); +- StorageLive(_15); ++ nop; + StorageLive(_20); +- StorageLive(_22); ++ nop; + _22 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + StorageLive(_12); +- _13 = copy _22 as *mut () (Transmute); +- _12 = copy _22 as *const () (Transmute); ++ _13 = copy _7; ++ _12 = copy _10; + StorageLive(_16); +- _15 = std::intrinsics::size_of_val::<()>(copy _12) -> [return: bb4, unwind unreachable]; ++ _15 = std::intrinsics::size_of_val::<()>(copy _10) -> [return: bb4, unwind unreachable]; } bb2: { - StorageDead(_3); +- StorageDead(_22); ++ nop; + StorageDead(_20); +- StorageDead(_15); ++ nop; + StorageDead(_13); + StorageDead(_34); + StorageDead(_35); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } - bb3 (cleanup): { - resume; + bb3: { + StorageLive(_21); +- _21 = copy _13 as *const u8 (PtrToPtr); ++ _21 = copy _22 as *const u8 (Transmute); + _20 = NonNull:: { pointer: move _21 }; + StorageDead(_21); + StorageLive(_32); + StorageLive(_33); +- _32 = copy _34; +- _33 = copy _35; ++ _32 = copy _15; ++ _33 = copy _19; + StorageLive(_23); +- _23 = copy _32; +- switchInt(move _23) -> [0: bb9, otherwise: bb8]; ++ _23 = copy _15; ++ switchInt(copy _15) -> [0: bb9, otherwise: bb8]; + } + + bb4: { +- _16 = std::intrinsics::align_of_val::<()>(move _12) -> [return: bb5, unwind unreachable]; ++ _16 = std::intrinsics::align_of_val::<()>(copy _10) -> [return: bb5, unwind unreachable]; + } + + bb5: { + StorageLive(_17); + _17 = const false; +- switchInt(move _17) -> [0: bb7, otherwise: bb6]; ++ switchInt(const false) -> [0: bb7, otherwise: bb6]; + } + + bb6: { + _18 = Layout::from_size_align_unchecked::precondition_check(copy _15, copy _16) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_17); +- StorageLive(_19); ++ nop; + _19 = copy _16 as std::ptr::Alignment (Transmute); + _34 = copy _15; +- _35 = move _19; +- StorageDead(_19); ++ _35 = copy _19; ++ nop; + StorageDead(_16); + StorageDead(_12); +- switchInt(move _15) -> [0: bb2, otherwise: bb3]; ++ switchInt(copy _15) -> [0: bb2, otherwise: bb3]; + } + + bb8: { + StorageLive(_24); +- _24 = copy _20 as *mut u8 (Transmute); ++ _24 = copy _22 as *mut u8 (Transmute); + StorageLive(_25); + StorageLive(_26); +- _26 = copy _33; ++ _26 = copy _19; + StorageLive(_28); + StorageLive(_29); + StorageLive(_30); + StorageLive(_31); + StorageLive(_27); +- _27 = copy (_26.0: std::ptr::alignment::AlignmentEnum); ++ _27 = copy (_19.0: std::ptr::alignment::AlignmentEnum); + _28 = discriminant(_27); + _29 = Ge(copy _28, const 1_u32); + _30 = Le(copy _28, const 2147483648_u32); + _31 = BitAnd(move _29, move _30); + assume(move _31); + _25 = copy _28 as usize (IntToInt); + StorageDead(_27); + StorageDead(_31); + StorageDead(_30); + StorageDead(_29); + StorageDead(_28); + StorageDead(_26); +- _14 = alloc::alloc::__rust_dealloc(move _24, move _23, move _25) -> [return: bb10, unwind unreachable]; ++ _14 = alloc::alloc::__rust_dealloc(move _24, copy _15, move _25) -> [return: bb10, unwind unreachable]; + } + + bb9: { + StorageDead(_23); + StorageDead(_32); + StorageDead(_33); + goto -> bb2; + } + + bb10: { + StorageDead(_25); + StorageDead(_24); + goto -> bb9; } } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index 839b53e3b0b3b..adcb4fb2c44f3 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -11,6 +11,8 @@ let mut _9: std::boxed::Box<()>; let mut _10: *const (); let mut _23: usize; + let mut _44: usize; + let mut _45: std::ptr::Alignment; scope 1 { debug vp_ctx => _1; let _4: *const (); @@ -66,11 +68,82 @@ } } } + scope 19 (inlined drop_in_place::> - shim(Some(Box<()>))) { + scope 20 (inlined as Drop>::drop) { + let mut _24: *const (); + let mut _25: *mut (); + let _26: (); + let _34: std::ptr::NonNull<()>; + scope 21 { + let _46: usize; + let _47: std::ptr::Alignment; + scope 22 { + scope 30 (inlined Layout::size) { + } + scope 31 (inlined Unique::<()>::cast::) { + let mut _32: std::ptr::NonNull; + scope 32 (inlined NonNull::<()>::cast::) { + let mut _33: *const u8; + scope 33 (inlined NonNull::<()>::as_ptr) { + } + } + } + scope 34 (inlined as From>>::from) { + scope 35 (inlined Unique::::as_non_null_ptr) { + } + } + scope 36 (inlined ::deallocate) { + let mut _35: usize; + let mut _36: *mut u8; + scope 37 (inlined Layout::size) { + } + scope 38 (inlined NonNull::::as_ptr) { + } + scope 39 (inlined std::alloc::dealloc) { + let mut _37: usize; + scope 40 (inlined Layout::size) { + } + scope 41 (inlined Layout::align) { + let mut _38: std::ptr::Alignment; + scope 42 (inlined std::ptr::Alignment::as_usize) { + let _39: std::ptr::alignment::AlignmentEnum; + let mut _40: u64; + let mut _41: bool; + let mut _42: bool; + let mut _43: bool; + } + } + } + } + } + scope 23 (inlined Unique::<()>::as_ptr) { + scope 24 (inlined NonNull::<()>::as_ptr) { + } + } + scope 25 (inlined Layout::for_value_raw::<()>) { + let mut _27: usize; + let mut _28: usize; + scope 26 { + scope 29 (inlined #[track_caller] Layout::from_size_align_unchecked) { + let mut _29: bool; + let _30: (); + let mut _31: std::ptr::Alignment; + } + } + scope 27 (inlined size_of_val_raw::<()>) { + } + scope 28 (inlined align_of_val_raw::<()>) { + } + } + } + } + } bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; StorageLive(_11); StorageLive(_12); StorageLive(_13); @@ -81,28 +154,23 @@ StorageLive(_14); StorageLive(_16); StorageLive(_17); - StorageLive(_19); +- StorageLive(_19); ++ nop; _19 = const false; -- switchInt(move _19) -> [0: bb6, otherwise: bb5]; -+ switchInt(const false) -> [0: bb6, otherwise: bb5]; +- switchInt(move _19) -> [0: bb5, otherwise: bb4]; ++ switchInt(const false) -> [0: bb5, otherwise: bb4]; } bb1: { - StorageDead(_3); - StorageDead(_1); - return; - } - - bb2: { unreachable; } - bb3: { + bb2: { - _18 = handle_alloc_error(move _14) -> unwind unreachable; + _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; } - bb4: { + bb3: { _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); StorageLive(_22); _22 = copy _17 as *mut [u8] (Transmute); @@ -121,8 +189,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -135,26 +204,45 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_23); StorageDead(_6); - StorageLive(_7); +- StorageLive(_7); ++ nop; StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); +- StorageDead(_7); - StorageDead(_5); ++ nop; + nop; StorageDead(_4); - drop(_3) -> [return: bb1, unwind unreachable]; + StorageLive(_46); + StorageLive(_47); + StorageLive(_25); +- StorageLive(_27); ++ nop; + StorageLive(_32); +- StorageLive(_34); ++ nop; + _34 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + StorageLive(_24); +- _25 = copy _34 as *mut () (Transmute); +- _24 = copy _34 as *const () (Transmute); ++ _25 = copy _7; ++ _24 = copy _10; + StorageLive(_28); +- _27 = std::intrinsics::size_of_val::<()>(copy _24) -> [return: bb9, unwind unreachable]; ++ _27 = std::intrinsics::size_of_val::<()>(copy _10) -> [return: bb9, unwind unreachable]; } - bb5: { -- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb6, unwind unreachable]; -+ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; + bb4: { +- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb5, unwind unreachable]; ++ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb5, unwind unreachable]; } - bb6: { - StorageDead(_19); + bb5: { +- StorageDead(_19); ++ nop; StorageLive(_21); - _21 = copy _12 as std::ptr::Alignment (Transmute); - _14 = Layout { size: copy _11, align: move _21 }; @@ -162,13 +250,123 @@ + _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; StorageDead(_21); StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb7, unwind unreachable]; -+ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; +- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb6, unwind unreachable]; ++ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb6, unwind unreachable]; } - bb7: { + bb6: { _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; + switchInt(move _16) -> [0: bb3, 1: bb2, otherwise: bb1]; + } + + bb7: { +- StorageDead(_34); ++ nop; + StorageDead(_32); +- StorageDead(_27); ++ nop; + StorageDead(_25); + StorageDead(_46); + StorageDead(_47); +- StorageDead(_3); ++ nop; + StorageDead(_1); + return; + } + + bb8: { + StorageLive(_33); +- _33 = copy _25 as *const u8 (PtrToPtr); ++ _33 = copy _34 as *const u8 (Transmute); + _32 = NonNull:: { pointer: move _33 }; + StorageDead(_33); + StorageLive(_44); + StorageLive(_45); +- _44 = copy _46; +- _45 = copy _47; ++ _44 = copy _27; ++ _45 = copy _31; + StorageLive(_35); +- _35 = copy _44; +- switchInt(move _35) -> [0: bb14, otherwise: bb13]; ++ _35 = copy _27; ++ switchInt(copy _27) -> [0: bb14, otherwise: bb13]; + } + + bb9: { +- _28 = std::intrinsics::align_of_val::<()>(move _24) -> [return: bb10, unwind unreachable]; ++ _28 = std::intrinsics::align_of_val::<()>(copy _10) -> [return: bb10, unwind unreachable]; + } + + bb10: { + StorageLive(_29); + _29 = const false; +- switchInt(move _29) -> [0: bb12, otherwise: bb11]; ++ switchInt(const false) -> [0: bb12, otherwise: bb11]; + } + + bb11: { + _30 = Layout::from_size_align_unchecked::precondition_check(copy _27, copy _28) -> [return: bb12, unwind unreachable]; + } + + bb12: { + StorageDead(_29); +- StorageLive(_31); ++ nop; + _31 = copy _28 as std::ptr::Alignment (Transmute); + _46 = copy _27; +- _47 = move _31; +- StorageDead(_31); ++ _47 = copy _31; ++ nop; + StorageDead(_28); + StorageDead(_24); +- switchInt(move _27) -> [0: bb7, otherwise: bb8]; ++ switchInt(copy _27) -> [0: bb7, otherwise: bb8]; + } + + bb13: { + StorageLive(_36); +- _36 = copy _32 as *mut u8 (Transmute); ++ _36 = copy _34 as *mut u8 (Transmute); + StorageLive(_37); + StorageLive(_38); +- _38 = copy _45; ++ _38 = copy _31; + StorageLive(_40); + StorageLive(_41); + StorageLive(_42); + StorageLive(_43); + StorageLive(_39); +- _39 = copy (_38.0: std::ptr::alignment::AlignmentEnum); ++ _39 = copy (_31.0: std::ptr::alignment::AlignmentEnum); + _40 = discriminant(_39); + _41 = Ge(copy _40, const 1_u64); + _42 = Le(copy _40, const 9223372036854775808_u64); + _43 = BitAnd(move _41, move _42); + assume(move _43); + _37 = copy _40 as usize (IntToInt); + StorageDead(_39); + StorageDead(_43); + StorageDead(_42); + StorageDead(_41); + StorageDead(_40); + StorageDead(_38); +- _26 = alloc::alloc::__rust_dealloc(move _36, move _35, move _37) -> [return: bb15, unwind unreachable]; ++ _26 = alloc::alloc::__rust_dealloc(move _36, copy _27, move _37) -> [return: bb15, unwind unreachable]; + } + + bb14: { + StorageDead(_35); + StorageDead(_44); + StorageDead(_45); + goto -> bb7; + } + + bb15: { + StorageDead(_37); + StorageDead(_36); + goto -> bb14; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index b2085afb71379..123544c5e4464 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -11,6 +11,8 @@ let mut _9: std::boxed::Box<()>; let mut _10: *const (); let mut _11: usize; + let mut _32: usize; + let mut _33: std::ptr::Alignment; scope 1 { debug vp_ctx => _1; let _4: *const (); @@ -32,11 +34,82 @@ } } } + scope 8 (inlined drop_in_place::> - shim(Some(Box<()>))) { + scope 9 (inlined as Drop>::drop) { + let mut _12: *const (); + let mut _13: *mut (); + let _14: (); + let _22: std::ptr::NonNull<()>; + scope 10 { + let _34: usize; + let _35: std::ptr::Alignment; + scope 11 { + scope 19 (inlined Layout::size) { + } + scope 20 (inlined Unique::<()>::cast::) { + let mut _20: std::ptr::NonNull; + scope 21 (inlined NonNull::<()>::cast::) { + let mut _21: *const u8; + scope 22 (inlined NonNull::<()>::as_ptr) { + } + } + } + scope 23 (inlined as From>>::from) { + scope 24 (inlined Unique::::as_non_null_ptr) { + } + } + scope 25 (inlined ::deallocate) { + let mut _23: usize; + let mut _24: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + let mut _25: usize; + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::align) { + let mut _26: std::ptr::Alignment; + scope 31 (inlined std::ptr::Alignment::as_usize) { + let _27: std::ptr::alignment::AlignmentEnum; + let mut _28: u64; + let mut _29: bool; + let mut _30: bool; + let mut _31: bool; + } + } + } + } + } + scope 12 (inlined Unique::<()>::as_ptr) { + scope 13 (inlined NonNull::<()>::as_ptr) { + } + } + scope 14 (inlined Layout::for_value_raw::<()>) { + let mut _15: usize; + let mut _16: usize; + scope 15 { + scope 18 (inlined #[track_caller] Layout::from_size_align_unchecked) { + let mut _17: bool; + let _18: (); + let mut _19: std::ptr::Alignment; + } + } + scope 16 (inlined size_of_val_raw::<()>) { + } + scope 17 (inlined align_of_val_raw::<()>) { + } + } + } + } + } bb0: { StorageLive(_1); StorageLive(_2); - StorageLive(_3); +- StorageLive(_3); ++ nop; _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } @@ -46,8 +119,9 @@ StorageDead(_2); StorageLive(_4); - _9 = deref_copy _3; +- _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); ++ _10 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); _4 = copy _10; - StorageLive(_5); + nop; @@ -60,27 +134,145 @@ + _5 = *const [()] from (copy _10, const 1_usize); StorageDead(_11); StorageDead(_6); - StorageLive(_7); +- StorageLive(_7); ++ nop; StorageLive(_8); _8 = copy _5; - _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); ++ _7 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); StorageDead(_8); - StorageDead(_7); +- StorageDead(_7); - StorageDead(_5); ++ nop; + nop; StorageDead(_4); - drop(_3) -> [return: bb2, unwind: bb3]; + StorageLive(_34); + StorageLive(_35); + StorageLive(_13); +- StorageLive(_15); ++ nop; + StorageLive(_20); +- StorageLive(_22); ++ nop; + _22 = copy ((_3.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>); + StorageLive(_12); +- _13 = copy _22 as *mut () (Transmute); +- _12 = copy _22 as *const () (Transmute); ++ _13 = copy _7; ++ _12 = copy _10; + StorageLive(_16); +- _15 = std::intrinsics::size_of_val::<()>(copy _12) -> [return: bb4, unwind unreachable]; ++ _15 = std::intrinsics::size_of_val::<()>(copy _10) -> [return: bb4, unwind unreachable]; } bb2: { - StorageDead(_3); +- StorageDead(_22); ++ nop; + StorageDead(_20); +- StorageDead(_15); ++ nop; + StorageDead(_13); + StorageDead(_34); + StorageDead(_35); +- StorageDead(_3); ++ nop; StorageDead(_1); return; } - bb3 (cleanup): { - resume; + bb3: { + StorageLive(_21); +- _21 = copy _13 as *const u8 (PtrToPtr); ++ _21 = copy _22 as *const u8 (Transmute); + _20 = NonNull:: { pointer: move _21 }; + StorageDead(_21); + StorageLive(_32); + StorageLive(_33); +- _32 = copy _34; +- _33 = copy _35; ++ _32 = copy _15; ++ _33 = copy _19; + StorageLive(_23); +- _23 = copy _32; +- switchInt(move _23) -> [0: bb9, otherwise: bb8]; ++ _23 = copy _15; ++ switchInt(copy _15) -> [0: bb9, otherwise: bb8]; + } + + bb4: { +- _16 = std::intrinsics::align_of_val::<()>(move _12) -> [return: bb5, unwind unreachable]; ++ _16 = std::intrinsics::align_of_val::<()>(copy _10) -> [return: bb5, unwind unreachable]; + } + + bb5: { + StorageLive(_17); + _17 = const false; +- switchInt(move _17) -> [0: bb7, otherwise: bb6]; ++ switchInt(const false) -> [0: bb7, otherwise: bb6]; + } + + bb6: { + _18 = Layout::from_size_align_unchecked::precondition_check(copy _15, copy _16) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_17); +- StorageLive(_19); ++ nop; + _19 = copy _16 as std::ptr::Alignment (Transmute); + _34 = copy _15; +- _35 = move _19; +- StorageDead(_19); ++ _35 = copy _19; ++ nop; + StorageDead(_16); + StorageDead(_12); +- switchInt(move _15) -> [0: bb2, otherwise: bb3]; ++ switchInt(copy _15) -> [0: bb2, otherwise: bb3]; + } + + bb8: { + StorageLive(_24); +- _24 = copy _20 as *mut u8 (Transmute); ++ _24 = copy _22 as *mut u8 (Transmute); + StorageLive(_25); + StorageLive(_26); +- _26 = copy _33; ++ _26 = copy _19; + StorageLive(_28); + StorageLive(_29); + StorageLive(_30); + StorageLive(_31); + StorageLive(_27); +- _27 = copy (_26.0: std::ptr::alignment::AlignmentEnum); ++ _27 = copy (_19.0: std::ptr::alignment::AlignmentEnum); + _28 = discriminant(_27); + _29 = Ge(copy _28, const 1_u64); + _30 = Le(copy _28, const 9223372036854775808_u64); + _31 = BitAnd(move _29, move _30); + assume(move _31); + _25 = copy _28 as usize (IntToInt); + StorageDead(_27); + StorageDead(_31); + StorageDead(_30); + StorageDead(_29); + StorageDead(_28); + StorageDead(_26); +- _14 = alloc::alloc::__rust_dealloc(move _24, move _23, move _25) -> [return: bb10, unwind unreachable]; ++ _14 = alloc::alloc::__rust_dealloc(move _24, copy _15, move _25) -> [return: bb10, unwind unreachable]; + } + + bb9: { + StorageDead(_23); + StorageDead(_32); + StorageDead(_33); + goto -> bb2; + } + + bb10: { + StorageDead(_25); + StorageDead(_24); + goto -> bb9; } } diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff index dc0004105a7b7..76f1b1801de28 100644 --- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff @@ -5,35 +5,40 @@ let mut _0: (); let _1: (); + scope 1 (inlined foo) { -+ let _2: D; ++ let mut _2: *mut D; ++ let _3: D; + scope 2 { + debug _d => const D; + } ++ scope 3 (inlined drop_in_place:: - shim(Some(D))) { ++ scope 4 (inlined ::drop) { ++ debug self => _2; ++ } ++ } + } bb0: { StorageLive(_1); - _1 = foo() -> [return: bb1, unwind continue]; -+ StorageLive(_2); -+ asm!("", options(MAY_UNWIND)) -> [return: bb2, unwind: bb3]; ++ StorageLive(_3); ++ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb2]; } bb1: { ++ StorageLive(_2); ++ _2 = &raw mut _3; + StorageDead(_2); ++ StorageDead(_3); StorageDead(_1); _0 = const (); return; + } + -+ bb2: { -+ drop(_2) -> [return: bb1, unwind continue]; ++ bb2 (cleanup): { ++ drop(_3) -> [return: bb3, unwind terminate(cleanup)]; + } + + bb3 (cleanup): { -+ drop(_2) -> [return: bb4, unwind terminate(cleanup)]; -+ } -+ -+ bb4 (cleanup): { + resume; } } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff rename to tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.32bit.panic-unwind.diff diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.64bit.panic-unwind.diff similarity index 74% rename from tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff rename to tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.64bit.panic-unwind.diff index 0615f8132af00..21b20329d4fa9 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.64bit.panic-unwind.diff @@ -18,31 +18,43 @@ _3 = &mut _1; StorageLive(_4); _4 = move _2; -- _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _0 = > as FnMut>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3]; + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); + _6 = copy (*_3); + _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); + _5 = &mut (*_7); -+ _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable]; ++ _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2]; } bb1: { - StorageDead(_4); - StorageDead(_3); -- drop(_1) -> [return: bb2, unwind unreachable]; +- drop(_1) -> [return: bb2, unwind: bb4]; + return; } - bb2: { +- bb2: { - return; ++ bb2 (cleanup): { ++ drop(_1) -> [return: bb3, unwind terminate(cleanup)]; + } + + bb3 (cleanup): { +- drop(_1) -> [return: bb4, unwind terminate(cleanup)]; ++ resume; + } + +- bb4 (cleanup): { +- resume; ++ bb4: { + StorageDead(_5); + StorageDead(_7); + StorageDead(_6); + StorageDead(_4); + StorageDead(_3); -+ drop(_1) -> [return: bb1, unwind unreachable]; ++ drop(_1) -> [return: bb1, unwind: bb3]; } } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs index ac0c3ddac764c..f5d00af2874a7 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs @@ -1,4 +1,5 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// EMIT_MIR_FOR_EACH_BIT_WIDTH //@ compile-flags: -Zmir-enable-passes=+Inline --crate-type=lib #![feature(fn_traits, tuple_trait, unboxed_closures)] diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.32bit.panic-unwind.diff similarity index 100% rename from tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff rename to tests/mir-opt/inline/inline_box_fn.call.Inline.32bit.panic-unwind.diff diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.64bit.panic-unwind.diff similarity index 64% rename from tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff rename to tests/mir-opt/inline/inline_box_fn.call.Inline.64bit.panic-unwind.diff index ecea7a97513d5..3a4a528e879fb 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.64bit.panic-unwind.diff @@ -19,34 +19,47 @@ _3 = &_1; StorageLive(_4); _4 = (const 1_i32,); -- _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable]; +- _2 = as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3]; + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); + _6 = copy (*_3); + _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); + _5 = &(*_7); -+ _2 = >::call(move _5, move _4) -> [return: bb2, unwind unreachable]; ++ _2 = >::call(move _5, move _4) -> [return: bb4, unwind: bb2]; } bb1: { +- StorageDead(_4); +- StorageDead(_3); +- StorageDead(_2); +- _0 = const (); +- drop(_1) -> [return: bb2, unwind: bb4]; + return; -+ } -+ -+ bb2: { + } + +- bb2: { +- return; ++ bb2 (cleanup): { ++ drop(_1) -> [return: bb3, unwind terminate(cleanup)]; + } + + bb3 (cleanup): { +- drop(_1) -> [return: bb4, unwind terminate(cleanup)]; ++ resume; + } + +- bb4 (cleanup): { +- resume; ++ bb4: { + StorageDead(_5); + StorageDead(_7); + StorageDead(_6); - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); - _0 = const (); -- drop(_1) -> [return: bb2, unwind unreachable]; -- } -- -- bb2: { -- return; -+ drop(_1) -> [return: bb1, unwind unreachable]; ++ StorageDead(_4); ++ StorageDead(_3); ++ StorageDead(_2); ++ _0 = const (); ++ drop(_1) -> [return: bb1, unwind: bb3]; } } diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs index e9ab3bef01fbe..58095b2df8d13 100644 --- a/tests/mir-opt/inline/inline_box_fn.rs +++ b/tests/mir-opt/inline/inline_box_fn.rs @@ -1,4 +1,5 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// EMIT_MIR_FOR_EACH_BIT_WIDTH //@ test-mir-pass: Inline //@ compile-flags: --crate-type=lib 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 151580da19e09..20d1062d2281e 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 @@ -8,6 +8,8 @@ let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; let mut _4: {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _5: bool; ++ let mut _9: *mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; ++ let mut _10: (); scope 1 { debug _r => _1; } @@ -23,6 +25,15 @@ + let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; + let mut _8: i32; ++ } ++ scope 6 (inlined drop_in_place::<{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> - shim(Some({coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}))) { ++ debug a => _15; ++ let mut _11: bool; ++ let mut _12: i32; ++ let mut _13: bool; ++ let mut _14: bool; ++ let _15: bool; ++ let mut _16: u32; + } bb0: { @@ -41,70 +52,88 @@ + StorageLive(_7); + _6 = copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); -+ switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9]; ++ switchInt(move _7) -> [0: bb2, 1: bb6, 3: bb7, otherwise: bb8]; } bb1: { - _3 = &mut _4; - _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new(move _3) -> [return: bb2, unwind unreachable]; -+ StorageDead(_4); -+ _0 = const (); -+ StorageDead(_1); -+ return; ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); ++ StorageDead(_2); ++ StorageLive(_9); ++ _9 = &raw mut _4; ++ StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_13); ++ StorageLive(_14); ++ StorageLive(_15); ++ StorageLive(_16); ++ _16 = discriminant((*_9)); ++ switchInt(move _16) -> [0: bb9, 3: bb10, otherwise: bb9]; } bb2: { - StorageDead(_3); - _1 = <{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; -+ StorageDead(_7); -+ StorageDead(_6); -+ StorageDead(_5); -+ StorageDead(_2); -+ drop(_4) -> [return: bb1, unwind unreachable]; ++ StorageLive(_8); ++ switchInt(copy _5) -> [0: bb3, otherwise: bb4]; } bb3: { - StorageDead(_2); - drop(_4) -> [return: bb4, unwind unreachable]; -+ StorageLive(_8); -+ switchInt(copy _5) -> [0: bb4, otherwise: bb5]; ++ _8 = const 13_i32; ++ goto -> bb5; } bb4: { -- StorageDead(_4); -- _0 = const (); -- StorageDead(_1); -- return; -+ _8 = const 13_i32; -+ goto -> bb6; -+ } -+ -+ bb5: { + _8 = const 7_i32; -+ goto -> bb6; ++ goto -> bb5; + } + -+ bb6: { ++ bb5: { + _1 = CoroutineState::::Yielded(move _8); + StorageDead(_8); + discriminant((*_6)) = 3; -+ goto -> bb2; ++ goto -> bb1; + } + -+ bb7: { -+ assert(const false, "coroutine resumed after completion") -> [success: bb7, unwind unreachable]; ++ bb6: { ++ assert(const false, "coroutine resumed after completion") -> [success: bb6, unwind unreachable]; + } + -+ bb8: { ++ bb7: { + StorageLive(_8); + StorageDead(_8); + _1 = CoroutineState::::Complete(copy _5); + discriminant((*_6)) = 1; -+ goto -> bb2; ++ goto -> bb1; + } + -+ bb9: { ++ bb8: { + unreachable; ++ } ++ ++ bb9: { ++ StorageDead(_16); ++ StorageDead(_15); ++ StorageDead(_14); ++ StorageDead(_13); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_9); + StorageDead(_4); + _0 = const (); + StorageDead(_1); + return; ++ } ++ ++ bb10: { ++ StorageLive(_12); ++ StorageDead(_12); ++ goto -> 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 6196fc0d0c6bf..fc9f8b932270f 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 @@ -8,6 +8,8 @@ let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; let mut _4: {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _5: bool; ++ let mut _9: *mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; ++ let mut _10: (); scope 1 { debug _r => _1; } @@ -23,6 +25,15 @@ + let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; + let mut _8: i32; ++ } ++ scope 6 (inlined drop_in_place::<{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> - shim(Some({coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}))) { ++ debug a => _15; ++ let mut _11: bool; ++ let mut _12: i32; ++ let mut _13: bool; ++ let mut _14: bool; ++ let _15: bool; ++ let mut _16: u32; + } bb0: { @@ -41,84 +52,103 @@ + StorageLive(_7); + _6 = copy (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); -+ switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; ++ switchInt(move _7) -> [0: bb4, 1: bb8, 3: bb9, otherwise: bb10]; } - bb1: { +- bb1: { - _3 = &mut _4; - _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new(move _3) -> [return: bb2, unwind: bb5]; -+ StorageDead(_4); -+ _0 = const (); -+ StorageDead(_1); -+ return; ++ bb1 (cleanup): { ++ drop(_4) -> [return: bb2, unwind terminate(cleanup)]; } - bb2: { - StorageDead(_3); - _1 = <{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; + bb2 (cleanup): { -+ drop(_4) -> [return: bb3, unwind terminate(cleanup)]; - } - -- bb3: { -- StorageDead(_2); -- drop(_4) -> [return: bb4, unwind: bb6]; -+ bb3 (cleanup): { + resume; } - bb4: { -- StorageDead(_4); -- _0 = const (); -- StorageDead(_1); -- return; + bb3: { + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); -+ StorageDead(_2); -+ drop(_4) -> [return: bb1, unwind: bb3]; + StorageDead(_2); +- drop(_4) -> [return: bb4, unwind: bb6]; ++ StorageLive(_9); ++ _9 = &raw mut _4; ++ StorageLive(_10); ++ StorageLive(_11); ++ StorageLive(_13); ++ StorageLive(_14); ++ StorageLive(_15); ++ StorageLive(_16); ++ _16 = discriminant((*_9)); ++ switchInt(move _16) -> [0: bb11, 3: bb12, otherwise: bb11]; } -- bb5 (cleanup): { -- drop(_4) -> [return: bb6, unwind terminate(cleanup)]; -+ bb5: { + bb4: { + StorageLive(_8); -+ switchInt(copy _5) -> [0: bb6, otherwise: bb7]; - } - -- bb6 (cleanup): { -- resume; -+ bb6: { ++ switchInt(copy _5) -> [0: bb5, otherwise: bb6]; ++ } ++ ++ bb5: { + _8 = const 13_i32; -+ goto -> bb8; ++ goto -> bb7; + } + -+ bb7: { ++ bb6: { + _8 = const 7_i32; -+ goto -> bb8; ++ goto -> bb7; + } + -+ bb8: { ++ bb7: { + _1 = CoroutineState::::Yielded(move _8); + StorageDead(_8); + discriminant((*_6)) = 3; -+ goto -> bb4; ++ goto -> bb3; + } + -+ bb9: { -+ assert(const false, "coroutine resumed after completion") -> [success: bb9, unwind: bb2]; ++ bb8: { ++ assert(const false, "coroutine resumed after completion") -> [success: bb8, unwind: bb1]; + } + -+ bb10: { ++ bb9: { + StorageLive(_8); + StorageDead(_8); + _1 = CoroutineState::::Complete(copy _5); + discriminant((*_6)) = 1; -+ goto -> bb4; ++ goto -> bb3; + } + -+ bb11: { ++ bb10: { + unreachable; ++ } ++ ++ bb11: { ++ StorageDead(_16); ++ StorageDead(_15); ++ StorageDead(_14); ++ StorageDead(_13); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_9); + StorageDead(_4); + _0 = const (); + StorageDead(_1); + return; + } + +- bb5 (cleanup): { +- drop(_4) -> [return: bb6, unwind terminate(cleanup)]; +- } +- +- bb6 (cleanup): { +- resume; ++ bb12: { ++ StorageLive(_12); ++ StorageDead(_12); ++ goto -> bb11; } } diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.32bit.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.32bit.diff new file mode 100644 index 0000000000000..bf1b08dcb87b2 --- /dev/null +++ b/tests/mir-opt/inline/unsized_argument.caller.Inline.32bit.diff @@ -0,0 +1,271 @@ +- // MIR for `caller` before Inline ++ // MIR for `caller` after Inline + + fn caller(_1: Box<[i32]>) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: std::boxed::Box<[i32]>; + let mut _4: *const [i32]; ++ let mut _5: *mut std::boxed::Box<[i32]>; ++ let mut _6: (); ++ let mut _27: std::alloc::Layout; ++ scope 1 (inlined drop_in_place::> - shim(Some(Box<[i32]>))) { ++ let mut _7: &mut std::boxed::Box<[i32]>; ++ let mut _8: (); ++ let mut _9: &mut std::boxed::Box<[i32]>; ++ let mut _10: (); ++ let mut _11: *const [i32]; ++ scope 2 (inlined as Drop>::drop) { ++ let mut _13: *const [i32]; ++ let mut _14: *mut [i32]; ++ let mut _15: &std::alloc::Layout; ++ let _16: (); ++ let mut _17: &std::alloc::Global; ++ let _25: std::ptr::NonNull<[i32]>; ++ let _26: std::marker::PhantomData<[i32]>; ++ scope 3 { ++ let _12: std::alloc::Layout; ++ scope 4 { ++ scope 12 (inlined Layout::size) { ++ } ++ scope 13 (inlined Unique::<[i32]>::cast::) { ++ let mut _23: std::ptr::NonNull; ++ scope 14 (inlined NonNull::<[i32]>::cast::) { ++ let mut _24: *const u8; ++ scope 15 (inlined NonNull::<[i32]>::as_ptr) { ++ } ++ } ++ } ++ scope 16 (inlined as From>>::from) { ++ scope 17 (inlined Unique::::as_non_null_ptr) { ++ } ++ } ++ scope 18 (inlined ::deallocate) { ++ let mut _28: usize; ++ let mut _29: &std::alloc::Layout; ++ let mut _30: *mut u8; ++ let mut _31: std::alloc::Layout; ++ scope 19 (inlined Layout::size) { ++ } ++ scope 20 (inlined NonNull::::as_ptr) { ++ } ++ scope 21 (inlined std::alloc::dealloc) { ++ let mut _32: &std::alloc::Layout; ++ let mut _33: usize; ++ let mut _34: &std::alloc::Layout; ++ scope 22 (inlined Layout::size) { ++ } ++ scope 23 (inlined Layout::align) { ++ let mut _35: std::ptr::Alignment; ++ scope 24 (inlined std::ptr::Alignment::as_usize) { ++ let _36: std::ptr::alignment::AlignmentEnum; ++ let mut _37: u32; ++ let mut _38: bool; ++ let mut _39: bool; ++ let mut _40: bool; ++ } ++ } ++ } ++ } ++ } ++ scope 5 (inlined Unique::<[i32]>::as_ptr) { ++ scope 6 (inlined NonNull::<[i32]>::as_ptr) { ++ } ++ } ++ scope 7 (inlined Layout::for_value_raw::<[i32]>) { ++ let mut _18: usize; ++ let mut _19: usize; ++ scope 8 { ++ scope 11 (inlined #[track_caller] Layout::from_size_align_unchecked) { ++ let mut _20: bool; ++ let _21: (); ++ let mut _22: std::ptr::Alignment; ++ } ++ } ++ scope 9 (inlined size_of_val_raw::<[i32]>) { ++ } ++ scope 10 (inlined align_of_val_raw::<[i32]>) { ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = move _1; + _4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); +- _2 = callee(move (*_4)) -> [return: bb1, unwind: bb3]; ++ _2 = callee(move (*_4)) -> [return: bb1, unwind: bb2]; + } + + bb1: { +- drop(_3) -> [return: bb2, unwind: bb4]; ++ StorageLive(_5); ++ _5 = &raw mut _3; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_10); ++ StorageLive(_11); ++ _11 = copy (((*_5).0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); ++ drop((*_11)) -> [return: bb4, unwind: bb5]; + } + +- bb2: { ++ bb2 (cleanup): { ++ drop(_3) -> [return: bb3, unwind terminate(cleanup)]; ++ } ++ ++ bb3 (cleanup): { ++ resume; ++ } ++ ++ bb4: { ++ _7 = &mut (*_5); ++ StorageLive(_12); ++ StorageLive(_14); ++ StorageLive(_16); ++ StorageLive(_18); ++ StorageLive(_21); ++ StorageLive(_23); ++ StorageLive(_25); ++ StorageLive(_26); ++ _25 = copy (((*_7).0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>); ++ _26 = copy (((*_7).0: std::ptr::Unique<[i32]>).1: std::marker::PhantomData<[i32]>); ++ StorageLive(_13); ++ _14 = copy _25 as *mut [i32] (Transmute); ++ _13 = copy _25 as *const [i32] (Transmute); ++ StorageLive(_19); ++ _18 = std::intrinsics::size_of_val::<[i32]>(copy _13) -> [return: bb8, unwind unreachable]; ++ } ++ ++ bb5 (cleanup): { ++ _9 = &mut (*_5); ++ _10 = as Drop>::drop(move _9) -> [return: bb3, unwind terminate(cleanup)]; ++ } ++ ++ bb6: { ++ StorageDead(_26); ++ StorageDead(_25); ++ StorageDead(_23); ++ StorageDead(_21); ++ StorageDead(_18); ++ StorageDead(_16); ++ StorageDead(_14); ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_9); ++ StorageDead(_8); ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + +- bb3 (cleanup): { +- drop(_3) -> [return: bb4, unwind terminate(cleanup)]; ++ bb7: { ++ StorageLive(_17); ++ _17 = &((*_7).1: std::alloc::Global); ++ StorageLive(_24); ++ _24 = copy _14 as *const u8 (PtrToPtr); ++ _23 = NonNull:: { pointer: move _24 }; ++ StorageDead(_24); ++ StorageLive(_27); ++ _27 = copy _12; ++ StorageLive(_28); ++ StorageLive(_29); ++ _29 = &_27; ++ _28 = copy (_27.0: usize); ++ StorageDead(_29); ++ switchInt(move _28) -> [0: bb13, otherwise: bb12]; + } + +- bb4 (cleanup): { +- resume; ++ bb8: { ++ _19 = std::intrinsics::align_of_val::<[i32]>(move _13) -> [return: bb9, unwind unreachable]; ++ } ++ ++ bb9: { ++ StorageLive(_20); ++ _20 = UbChecks(); ++ switchInt(move _20) -> [0: bb11, otherwise: bb10]; ++ } ++ ++ bb10: { ++ _21 = Layout::from_size_align_unchecked::precondition_check(copy _18, copy _19) -> [return: bb11, unwind unreachable]; ++ } ++ ++ bb11: { ++ StorageDead(_20); ++ StorageLive(_22); ++ _22 = copy _19 as std::ptr::Alignment (Transmute); ++ _12 = Layout { size: copy _18, align: move _22 }; ++ StorageDead(_22); ++ StorageDead(_19); ++ StorageDead(_13); ++ StorageLive(_15); ++ _15 = &_12; ++ StorageDead(_15); ++ switchInt(move _18) -> [0: bb6, otherwise: bb7]; ++ } ++ ++ bb12: { ++ StorageLive(_30); ++ _30 = copy _23 as *mut u8 (Transmute); ++ StorageLive(_31); ++ _31 = copy _27; ++ StorageLive(_32); ++ _32 = &_31; ++ StorageDead(_32); ++ StorageLive(_33); ++ StorageLive(_34); ++ _34 = &_31; ++ StorageLive(_35); ++ _35 = copy (_27.1: std::ptr::Alignment); ++ StorageLive(_37); ++ StorageLive(_38); ++ StorageLive(_39); ++ StorageLive(_40); ++ StorageLive(_36); ++ _36 = copy (_35.0: std::ptr::alignment::AlignmentEnum); ++ _37 = discriminant(_36); ++ _38 = Ge(copy _37, const 1_u32); ++ _39 = Le(copy _37, const 2147483648_u32); ++ _40 = BitAnd(move _38, move _39); ++ assume(move _40); ++ _33 = copy _37 as usize (IntToInt); ++ StorageDead(_36); ++ StorageDead(_40); ++ StorageDead(_39); ++ StorageDead(_38); ++ StorageDead(_37); ++ StorageDead(_35); ++ StorageDead(_34); ++ _16 = alloc::alloc::__rust_dealloc(move _30, move _28, move _33) -> [return: bb14, unwind unreachable]; ++ } ++ ++ bb13: { ++ StorageDead(_28); ++ StorageDead(_27); ++ StorageDead(_17); ++ goto -> bb6; ++ } ++ ++ bb14: { ++ StorageDead(_33); ++ StorageDead(_31); ++ StorageDead(_30); ++ goto -> bb13; + } + } + diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.64bit.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.64bit.diff new file mode 100644 index 0000000000000..430f38f9b01f3 --- /dev/null +++ b/tests/mir-opt/inline/unsized_argument.caller.Inline.64bit.diff @@ -0,0 +1,271 @@ +- // MIR for `caller` before Inline ++ // MIR for `caller` after Inline + + fn caller(_1: Box<[i32]>) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: std::boxed::Box<[i32]>; + let mut _4: *const [i32]; ++ let mut _5: *mut std::boxed::Box<[i32]>; ++ let mut _6: (); ++ let mut _27: std::alloc::Layout; ++ scope 1 (inlined drop_in_place::> - shim(Some(Box<[i32]>))) { ++ let mut _7: &mut std::boxed::Box<[i32]>; ++ let mut _8: (); ++ let mut _9: &mut std::boxed::Box<[i32]>; ++ let mut _10: (); ++ let mut _11: *const [i32]; ++ scope 2 (inlined as Drop>::drop) { ++ let mut _13: *const [i32]; ++ let mut _14: *mut [i32]; ++ let mut _15: &std::alloc::Layout; ++ let _16: (); ++ let mut _17: &std::alloc::Global; ++ let _25: std::ptr::NonNull<[i32]>; ++ let _26: std::marker::PhantomData<[i32]>; ++ scope 3 { ++ let _12: std::alloc::Layout; ++ scope 4 { ++ scope 12 (inlined Layout::size) { ++ } ++ scope 13 (inlined Unique::<[i32]>::cast::) { ++ let mut _23: std::ptr::NonNull; ++ scope 14 (inlined NonNull::<[i32]>::cast::) { ++ let mut _24: *const u8; ++ scope 15 (inlined NonNull::<[i32]>::as_ptr) { ++ } ++ } ++ } ++ scope 16 (inlined as From>>::from) { ++ scope 17 (inlined Unique::::as_non_null_ptr) { ++ } ++ } ++ scope 18 (inlined ::deallocate) { ++ let mut _28: usize; ++ let mut _29: &std::alloc::Layout; ++ let mut _30: *mut u8; ++ let mut _31: std::alloc::Layout; ++ scope 19 (inlined Layout::size) { ++ } ++ scope 20 (inlined NonNull::::as_ptr) { ++ } ++ scope 21 (inlined std::alloc::dealloc) { ++ let mut _32: &std::alloc::Layout; ++ let mut _33: usize; ++ let mut _34: &std::alloc::Layout; ++ scope 22 (inlined Layout::size) { ++ } ++ scope 23 (inlined Layout::align) { ++ let mut _35: std::ptr::Alignment; ++ scope 24 (inlined std::ptr::Alignment::as_usize) { ++ let _36: std::ptr::alignment::AlignmentEnum; ++ let mut _37: u64; ++ let mut _38: bool; ++ let mut _39: bool; ++ let mut _40: bool; ++ } ++ } ++ } ++ } ++ } ++ scope 5 (inlined Unique::<[i32]>::as_ptr) { ++ scope 6 (inlined NonNull::<[i32]>::as_ptr) { ++ } ++ } ++ scope 7 (inlined Layout::for_value_raw::<[i32]>) { ++ let mut _18: usize; ++ let mut _19: usize; ++ scope 8 { ++ scope 11 (inlined #[track_caller] Layout::from_size_align_unchecked) { ++ let mut _20: bool; ++ let _21: (); ++ let mut _22: std::ptr::Alignment; ++ } ++ } ++ scope 9 (inlined size_of_val_raw::<[i32]>) { ++ } ++ scope 10 (inlined align_of_val_raw::<[i32]>) { ++ } ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = move _1; + _4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); +- _2 = callee(move (*_4)) -> [return: bb1, unwind: bb3]; ++ _2 = callee(move (*_4)) -> [return: bb1, unwind: bb2]; + } + + bb1: { +- drop(_3) -> [return: bb2, unwind: bb4]; ++ StorageLive(_5); ++ _5 = &raw mut _3; ++ StorageLive(_6); ++ StorageLive(_7); ++ StorageLive(_8); ++ StorageLive(_9); ++ StorageLive(_10); ++ StorageLive(_11); ++ _11 = copy (((*_5).0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); ++ drop((*_11)) -> [return: bb4, unwind: bb5]; + } + +- bb2: { ++ bb2 (cleanup): { ++ drop(_3) -> [return: bb3, unwind terminate(cleanup)]; ++ } ++ ++ bb3 (cleanup): { ++ resume; ++ } ++ ++ bb4: { ++ _7 = &mut (*_5); ++ StorageLive(_12); ++ StorageLive(_14); ++ StorageLive(_16); ++ StorageLive(_18); ++ StorageLive(_21); ++ StorageLive(_23); ++ StorageLive(_25); ++ StorageLive(_26); ++ _25 = copy (((*_7).0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>); ++ _26 = copy (((*_7).0: std::ptr::Unique<[i32]>).1: std::marker::PhantomData<[i32]>); ++ StorageLive(_13); ++ _14 = copy _25 as *mut [i32] (Transmute); ++ _13 = copy _25 as *const [i32] (Transmute); ++ StorageLive(_19); ++ _18 = std::intrinsics::size_of_val::<[i32]>(copy _13) -> [return: bb8, unwind unreachable]; ++ } ++ ++ bb5 (cleanup): { ++ _9 = &mut (*_5); ++ _10 = as Drop>::drop(move _9) -> [return: bb3, unwind terminate(cleanup)]; ++ } ++ ++ bb6: { ++ StorageDead(_26); ++ StorageDead(_25); ++ StorageDead(_23); ++ StorageDead(_21); ++ StorageDead(_18); ++ StorageDead(_16); ++ StorageDead(_14); ++ StorageDead(_12); ++ StorageDead(_11); ++ StorageDead(_10); ++ StorageDead(_9); ++ StorageDead(_8); ++ StorageDead(_7); ++ StorageDead(_6); ++ StorageDead(_5); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + +- bb3 (cleanup): { +- drop(_3) -> [return: bb4, unwind terminate(cleanup)]; ++ bb7: { ++ StorageLive(_17); ++ _17 = &((*_7).1: std::alloc::Global); ++ StorageLive(_24); ++ _24 = copy _14 as *const u8 (PtrToPtr); ++ _23 = NonNull:: { pointer: move _24 }; ++ StorageDead(_24); ++ StorageLive(_27); ++ _27 = copy _12; ++ StorageLive(_28); ++ StorageLive(_29); ++ _29 = &_27; ++ _28 = copy (_27.0: usize); ++ StorageDead(_29); ++ switchInt(move _28) -> [0: bb13, otherwise: bb12]; + } + +- bb4 (cleanup): { +- resume; ++ bb8: { ++ _19 = std::intrinsics::align_of_val::<[i32]>(move _13) -> [return: bb9, unwind unreachable]; ++ } ++ ++ bb9: { ++ StorageLive(_20); ++ _20 = UbChecks(); ++ switchInt(move _20) -> [0: bb11, otherwise: bb10]; ++ } ++ ++ bb10: { ++ _21 = Layout::from_size_align_unchecked::precondition_check(copy _18, copy _19) -> [return: bb11, unwind unreachable]; ++ } ++ ++ bb11: { ++ StorageDead(_20); ++ StorageLive(_22); ++ _22 = copy _19 as std::ptr::Alignment (Transmute); ++ _12 = Layout { size: copy _18, align: move _22 }; ++ StorageDead(_22); ++ StorageDead(_19); ++ StorageDead(_13); ++ StorageLive(_15); ++ _15 = &_12; ++ StorageDead(_15); ++ switchInt(move _18) -> [0: bb6, otherwise: bb7]; ++ } ++ ++ bb12: { ++ StorageLive(_30); ++ _30 = copy _23 as *mut u8 (Transmute); ++ StorageLive(_31); ++ _31 = copy _27; ++ StorageLive(_32); ++ _32 = &_31; ++ StorageDead(_32); ++ StorageLive(_33); ++ StorageLive(_34); ++ _34 = &_31; ++ StorageLive(_35); ++ _35 = copy (_27.1: std::ptr::Alignment); ++ StorageLive(_37); ++ StorageLive(_38); ++ StorageLive(_39); ++ StorageLive(_40); ++ StorageLive(_36); ++ _36 = copy (_35.0: std::ptr::alignment::AlignmentEnum); ++ _37 = discriminant(_36); ++ _38 = Ge(copy _37, const 1_u64); ++ _39 = Le(copy _37, const 9223372036854775808_u64); ++ _40 = BitAnd(move _38, move _39); ++ assume(move _40); ++ _33 = copy _37 as usize (IntToInt); ++ StorageDead(_36); ++ StorageDead(_40); ++ StorageDead(_39); ++ StorageDead(_38); ++ StorageDead(_37); ++ StorageDead(_35); ++ StorageDead(_34); ++ _16 = alloc::alloc::__rust_dealloc(move _30, move _28, move _33) -> [return: bb14, unwind unreachable]; ++ } ++ ++ bb13: { ++ StorageDead(_28); ++ StorageDead(_27); ++ StorageDead(_17); ++ goto -> bb6; ++ } ++ ++ bb14: { ++ StorageDead(_33); ++ StorageDead(_31); ++ StorageDead(_30); ++ goto -> bb13; + } + } + diff --git a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff b/tests/mir-opt/inline/unsized_argument.caller.Inline.diff deleted file mode 100644 index 644d6d320de04..0000000000000 --- a/tests/mir-opt/inline/unsized_argument.caller.Inline.diff +++ /dev/null @@ -1,38 +0,0 @@ -- // MIR for `caller` before Inline -+ // MIR for `caller` after Inline - - fn caller(_1: Box<[i32]>) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: std::boxed::Box<[i32]>; - let mut _4: *const [i32]; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = move _1; - _4 = copy ((_3.0: std::ptr::Unique<[i32]>).0: std::ptr::NonNull<[i32]>) as *const [i32] (Transmute); - _2 = callee(move (*_4)) -> [return: bb1, unwind: bb3]; - } - - bb1: { - drop(_3) -> [return: bb2, unwind: bb4]; - } - - bb2: { - StorageDead(_3); - StorageDead(_2); - _0 = const (); - return; - } - - bb3 (cleanup): { - drop(_3) -> [return: bb4, unwind terminate(cleanup)]; - } - - bb4 (cleanup): { - resume; - } - } - diff --git a/tests/mir-opt/inline/unsized_argument.rs b/tests/mir-opt/inline/unsized_argument.rs index 281f7fe775382..7ffa6de1be7e6 100644 --- a/tests/mir-opt/inline/unsized_argument.rs +++ b/tests/mir-opt/inline/unsized_argument.rs @@ -1,3 +1,4 @@ +// EMIT_MIR_FOR_EACH_BIT_WIDTH //@ needs-unwind #![feature(unsized_fn_params)] diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index 1e9a6dd4f5c8f..50e298a18ac24 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -13,6 +13,10 @@ let mut _8: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; let mut _9: &mut std::task::Context<'_>; let mut _10: &mut std::task::Context<'_>; ++ let mut _52: *mut ActionPermit<'_, T>; ++ let mut _53: (); ++ let mut _54: *mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _55: (); scope 1 { debug fut => _2; let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; @@ -96,12 +100,45 @@ + scope 11 (inlined as IntoFuture>::into_future) { + } + } ++ scope 24 (inlined drop_in_place::> - shim(Some(ActionPermit<'_, T>))) { ++ } + } } + scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) { + } } + scope 4 (inlined ActionPermit::<'_, T>::perform) { ++ } ++ scope 25 (inlined drop_in_place::<{async fn body of ActionPermit<'_, T>::perform()}> - shim(Some({async fn body of ActionPermit<'_, T>::perform()}))) { ++ let mut _56: &mut std::task::Context<'_>; ++ let _57: ActionPermit<'_, T>; ++ let mut _58: std::future::Ready<()>; ++ let mut _59: std::future::Ready<()>; ++ let mut _60: (); ++ let mut _62: (); ++ let _63: (); ++ let mut _64: std::task::Poll<()>; ++ let mut _65: std::pin::Pin<&mut std::future::Ready<()>>; ++ let mut _66: &mut std::future::Ready<()>; ++ let mut _67: &mut std::future::Ready<()>; ++ let mut _68: &mut std::task::Context<'_>; ++ let mut _69: &mut std::task::Context<'_>; ++ let mut _70: &mut std::task::Context<'_>; ++ let mut _71: isize; ++ let mut _73: !; ++ let mut _74: &mut std::task::Context<'_>; ++ let mut _75: (); ++ let mut _76: (); ++ let mut _77: &mut std::task::Context<'_>; ++ let mut _78: u32; ++ scope 26 { ++ let mut _61: std::future::Ready<()>; ++ scope 27 { ++ let _72: (); ++ scope 28 { ++ } ++ } ++ } + } bb0: { @@ -149,16 +186,11 @@ + StorageLive(_40); + _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _32 = discriminant((*_33)); -+ switchInt(move _32) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5]; ++ switchInt(move _32) -> [0: bb2, 1: bb8, 3: bb7, otherwise: bb4]; } - bb3: { + bb1: { -+ StorageDead(_2); -+ return; -+ } -+ -+ bb2: { + StorageDead(_40); + StorageDead(_39); + StorageDead(_38); @@ -183,10 +215,34 @@ _0 = const (); StorageDead(_4); - drop(_2) -> [return: bb4, unwind unreachable]; -+ drop(_2) -> [return: bb1, unwind unreachable]; ++ StorageLive(_54); ++ _54 = &raw mut _2; ++ StorageLive(_55); ++ StorageLive(_56); ++ StorageLive(_57); ++ StorageLive(_59); ++ StorageLive(_60); ++ StorageLive(_61); ++ StorageLive(_62); ++ StorageLive(_63); ++ StorageLive(_64); ++ StorageLive(_65); ++ StorageLive(_66); ++ StorageLive(_67); ++ StorageLive(_68); ++ StorageLive(_69); ++ StorageLive(_70); ++ StorageLive(_71); ++ StorageLive(_72); ++ StorageLive(_73); ++ StorageLive(_76); ++ StorageLive(_77); ++ StorageLive(_78); ++ _78 = discriminant((*_54)); ++ switchInt(move _78) -> [0: bb13, 3: bb14, otherwise: bb12]; } -+ bb3: { ++ bb2: { + _31 = move _9; + _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); @@ -204,12 +260,10 @@ + StorageDead(_13); + _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; -+ goto -> bb4; ++ goto -> bb3; + } + - bb4: { -- StorageDead(_2); -- return; ++ bb3: { + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); @@ -250,14 +304,14 @@ + StorageDead(_44); + StorageLive(_50); + _50 = discriminant(_43); -+ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5]; ++ switchInt(move _50) -> [0: bb9, 1: bb10, otherwise: bb4]; + } + -+ bb5: { + bb4: { + unreachable; + } + -+ bb6: { ++ bb5: { + _17 = const (); + StorageDead(_23); + StorageDead(_21); @@ -272,10 +326,10 @@ + StorageDead(_29); + _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_38)) = 3; -+ goto -> bb2; ++ goto -> bb1; + } + -+ bb7: { ++ bb6: { + StorageLive(_26); + _26 = copy ((_18 as Ready).0: ()); + _30 = copy _26; @@ -286,17 +340,13 @@ + StorageDead(_17); + StorageDead(_12); + _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable]; ++ StorageLive(_52); ++ _52 = &raw mut (((*_39) as variant#3).0: ActionPermit<'_, T>); ++ StorageLive(_53); ++ drop(((*_52).0: std::cell::Ref<'_, T>)) -> [return: bb11, unwind unreachable]; + } + -+ bb8: { -+ _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_40)) = 1; -+ goto -> bb2; -+ } -+ -+ bb9: { ++ bb7: { + StorageLive(_12); + StorageLive(_28); + StorageLive(_29); @@ -305,18 +355,18 @@ + _31 = move _28; + StorageDead(_28); + _16 = const (); -+ goto -> bb4; ++ goto -> bb3; + } + -+ bb10: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb10, unwind unreachable]; ++ bb8: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb8, unwind unreachable]; + } + -+ bb11: { ++ bb9: { + _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; + } + -+ bb12: { ++ bb10: { + _42 = move ((_43 as Some).0: ()); + StorageDead(_50); + StorageDead(_43); @@ -328,7 +378,57 @@ + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); -+ switchInt(move _25) -> [0: bb7, 1: bb6, otherwise: bb5]; ++ switchInt(move _25) -> [0: bb6, 1: bb5, otherwise: bb4]; ++ } ++ ++ bb11: { ++ StorageDead(_53); ++ StorageDead(_52); ++ _7 = Poll::<()>::Ready(move _30); ++ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_40)) = 1; ++ goto -> bb1; ++ } ++ ++ bb12: { ++ StorageDead(_78); ++ StorageDead(_77); ++ StorageDead(_76); ++ StorageDead(_73); ++ StorageDead(_72); ++ StorageDead(_71); ++ StorageDead(_70); ++ StorageDead(_69); ++ StorageDead(_68); ++ StorageDead(_67); ++ StorageDead(_66); ++ StorageDead(_65); ++ StorageDead(_64); ++ StorageDead(_63); ++ StorageDead(_62); ++ StorageDead(_61); ++ StorageDead(_60); ++ StorageDead(_59); ++ StorageDead(_57); ++ StorageDead(_56); ++ StorageDead(_55); ++ StorageDead(_54); + StorageDead(_2); + return; ++ } ++ ++ bb13: { ++ drop(((*_54).0: ActionPermit<'_, T>)) -> [return: bb12, unwind unreachable]; ++ } ++ ++ bb14: { ++ StorageLive(_58); ++ StorageLive(_74); ++ StorageLive(_75); ++ StorageDead(_75); ++ StorageDead(_74); ++ StorageDead(_58); ++ drop((((*_54) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind unreachable]; } } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 94b89a310baa8..98950fdc7d198 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -13,6 +13,10 @@ let mut _8: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; let mut _9: &mut std::task::Context<'_>; let mut _10: &mut std::task::Context<'_>; ++ let mut _54: *mut ActionPermit<'_, T>; ++ let mut _55: (); ++ let mut _56: *mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _57: (); scope 1 { debug fut => _2; let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; @@ -98,12 +102,45 @@ + scope 11 (inlined as IntoFuture>::into_future) { + } + } ++ scope 24 (inlined drop_in_place::> - shim(Some(ActionPermit<'_, T>))) { ++ } + } } + scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) { + } } + scope 4 (inlined ActionPermit::<'_, T>::perform) { ++ } ++ scope 25 (inlined drop_in_place::<{async fn body of ActionPermit<'_, T>::perform()}> - shim(Some({async fn body of ActionPermit<'_, T>::perform()}))) { ++ let mut _58: &mut std::task::Context<'_>; ++ let _59: ActionPermit<'_, T>; ++ let mut _60: std::future::Ready<()>; ++ let mut _61: std::future::Ready<()>; ++ let mut _62: (); ++ let mut _64: (); ++ let _65: (); ++ let mut _66: std::task::Poll<()>; ++ let mut _67: std::pin::Pin<&mut std::future::Ready<()>>; ++ let mut _68: &mut std::future::Ready<()>; ++ let mut _69: &mut std::future::Ready<()>; ++ let mut _70: &mut std::task::Context<'_>; ++ let mut _71: &mut std::task::Context<'_>; ++ let mut _72: &mut std::task::Context<'_>; ++ let mut _73: isize; ++ let mut _75: !; ++ let mut _76: &mut std::task::Context<'_>; ++ let mut _77: (); ++ let mut _78: (); ++ let mut _79: &mut std::task::Context<'_>; ++ let mut _80: u32; ++ scope 26 { ++ let mut _63: std::future::Ready<()>; ++ scope 27 { ++ let _74: (); ++ scope 28 { ++ } ++ } ++ } + } bb0: { @@ -153,24 +190,18 @@ + StorageLive(_42); + _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _32 = discriminant((*_33)); -+ switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7]; ++ switchInt(move _32) -> [0: bb4, 1: bb13, 2: bb12, 3: bb11, otherwise: bb6]; } -- bb3: { -+ bb1: { -+ StorageDead(_2); -+ return; ++ bb1 (cleanup): { ++ drop(_2) -> [return: bb2, unwind terminate(cleanup)]; + } + + bb2 (cleanup): { -+ drop(_2) -> [return: bb3, unwind terminate(cleanup)]; -+ } -+ -+ bb3 (cleanup): { + resume; + } + -+ bb4: { + bb3: { + StorageDead(_42); + StorageDead(_41); + StorageDead(_40); @@ -197,13 +228,34 @@ _0 = const (); StorageDead(_4); - drop(_2) -> [return: bb4, unwind: bb6]; -+ drop(_2) -> [return: bb1, unwind: bb3]; ++ StorageLive(_56); ++ _56 = &raw mut _2; ++ StorageLive(_57); ++ StorageLive(_58); ++ StorageLive(_59); ++ StorageLive(_61); ++ StorageLive(_62); ++ StorageLive(_63); ++ StorageLive(_64); ++ StorageLive(_65); ++ StorageLive(_66); ++ StorageLive(_67); ++ StorageLive(_68); ++ StorageLive(_69); ++ StorageLive(_70); ++ StorageLive(_71); ++ StorageLive(_72); ++ StorageLive(_73); ++ StorageLive(_74); ++ StorageLive(_75); ++ StorageLive(_78); ++ StorageLive(_79); ++ StorageLive(_80); ++ _80 = discriminant((*_56)); ++ switchInt(move _80) -> [0: bb18, 3: bb19, otherwise: bb17]; } -- bb4: { -- StorageDead(_2); -- return; -+ bb5: { + bb4: { + _31 = move _9; + _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); @@ -221,12 +273,10 @@ + StorageDead(_13); + _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; -+ goto -> bb6; - } - -- bb5 (cleanup): { -- drop(_2) -> [return: bb6, unwind terminate(cleanup)]; -+ bb6: { ++ goto -> bb5; ++ } ++ ++ bb5: { + StorageLive(_17); + StorageLive(_18); + StorageLive(_19); @@ -267,16 +317,14 @@ + StorageDead(_46); + StorageLive(_52); + _52 = discriminant(_45); -+ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7]; - } - -- bb6 (cleanup): { -- resume; -+ bb7: { ++ switchInt(move _52) -> [0: bb14, 1: bb15, otherwise: bb6]; ++ } ++ ++ bb6: { + unreachable; + } + -+ bb8: { ++ bb7: { + _17 = const (); + StorageDead(_23); + StorageDead(_21); @@ -291,10 +339,10 @@ + StorageDead(_29); + _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_38)) = 3; -+ goto -> bb4; ++ goto -> bb3; + } + -+ bb9: { ++ bb8: { + StorageLive(_26); + _26 = copy ((_18 as Ready).0: ()); + _30 = copy _26; @@ -305,17 +353,13 @@ + StorageDead(_17); + StorageDead(_12); + _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12]; ++ StorageLive(_54); ++ _54 = &raw mut (((*_39) as variant#3).0: ActionPermit<'_, T>); ++ StorageLive(_55); ++ drop(((*_54).0: std::cell::Ref<'_, T>)) -> [return: bb16, unwind: bb10]; + } + -+ bb10: { -+ _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_40)) = 1; -+ goto -> bb4; -+ } -+ -+ bb11 (cleanup): { ++ bb9 (cleanup): { + StorageDead(_22); + StorageDead(_19); + StorageDead(_23); @@ -324,16 +368,16 @@ + StorageDead(_17); + StorageDead(_12); + _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; ++ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind terminate(cleanup)]; + } + -+ bb12 (cleanup): { ++ bb10 (cleanup): { + _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_42)) = 2; -+ goto -> bb2; ++ goto -> bb1; + } + -+ bb13: { ++ bb11: { + StorageLive(_12); + StorageLive(_28); + StorageLive(_29); @@ -342,22 +386,22 @@ + _31 = move _28; + StorageDead(_28); + _16 = const (); -+ goto -> bb6; ++ goto -> bb5; + } + -+ bb14: { -+ assert(const false, "`async fn` resumed after panicking") -> [success: bb14, unwind: bb2]; ++ bb12: { ++ assert(const false, "`async fn` resumed after panicking") -> [success: bb12, unwind: bb1]; + } + -+ bb15: { -+ assert(const false, "`async fn` resumed after completion") -> [success: bb15, unwind: bb2]; ++ bb13: { ++ assert(const false, "`async fn` resumed after completion") -> [success: bb13, unwind: bb1]; + } + -+ bb16: { -+ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11; ++ bb14: { ++ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb9; + } + -+ bb17: { ++ bb15: { + _44 = move ((_45 as Some).0: ()); + StorageDead(_52); + StorageDead(_45); @@ -369,7 +413,61 @@ + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); -+ switchInt(move _25) -> [0: bb9, 1: bb8, otherwise: bb7]; ++ switchInt(move _25) -> [0: bb8, 1: bb7, otherwise: bb6]; ++ } ++ ++ bb16: { ++ StorageDead(_55); ++ StorageDead(_54); ++ _7 = Poll::<()>::Ready(move _30); ++ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_40)) = 1; ++ goto -> bb3; ++ } ++ ++ bb17: { ++ StorageDead(_80); ++ StorageDead(_79); ++ StorageDead(_78); ++ StorageDead(_75); ++ StorageDead(_74); ++ StorageDead(_73); ++ StorageDead(_72); ++ StorageDead(_71); ++ StorageDead(_70); ++ StorageDead(_69); ++ StorageDead(_68); ++ StorageDead(_67); ++ StorageDead(_66); ++ StorageDead(_65); ++ StorageDead(_64); ++ StorageDead(_63); ++ StorageDead(_62); ++ StorageDead(_61); ++ StorageDead(_59); ++ StorageDead(_58); ++ StorageDead(_57); ++ StorageDead(_56); + StorageDead(_2); + return; + } + +- bb5 (cleanup): { +- drop(_2) -> [return: bb6, unwind terminate(cleanup)]; ++ bb18: { ++ drop(((*_56).0: ActionPermit<'_, T>)) -> [return: bb17, unwind: bb2]; + } + +- bb6 (cleanup): { +- resume; ++ bb19: { ++ StorageLive(_60); ++ StorageLive(_76); ++ StorageLive(_77); ++ StorageDead(_77); ++ StorageDead(_76); ++ StorageDead(_60); ++ drop((((*_56) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb17, unwind: bb2]; } } diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index e537dd6a28ef8..aecb471971e07 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -8,14 +8,18 @@ fn vec_move(_1: Vec) -> () { let mut _4: &mut std::vec::IntoIter; let mut _5: std::option::Option; let mut _6: isize; - let _8: (); + let _10: (); scope 1 { debug iter => _3; - let _7: impl Sized; + let _9: impl Sized; scope 2 { - debug x => _7; + debug x => _9; } } + scope 3 (inlined drop_in_place::> - shim(Some(std::vec::IntoIter))) { + let mut _7: &mut std::vec::IntoIter; + let mut _8: (); + } bb0: { StorageLive(_2); @@ -41,18 +45,21 @@ fn vec_move(_1: Vec) -> () { bb4: { StorageDead(_5); - drop(_3) -> [return: bb5, unwind continue]; + StorageLive(_7); + _7 = &mut _3; + _8 = as Drop>::drop(move _7) -> [return: bb5, unwind continue]; } bb5: { + StorageDead(_7); StorageDead(_3); StorageDead(_2); return; } bb6: { - _7 = move ((_5 as Some).0: impl Sized); - _8 = opaque::(move _7) -> [return: bb7, unwind: bb9]; + _9 = move ((_5 as Some).0: impl Sized); + _10 = opaque::(move _9) -> [return: bb7, unwind: bb9]; } bb7: { diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff new file mode 100644 index 0000000000000..52832e739051d --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff @@ -0,0 +1,15 @@ +- // MIR for `cannot_opt_generic` before RemoveUnneededDrops ++ // MIR for `cannot_opt_generic` after RemoveUnneededDrops + + fn cannot_opt_generic(_1: T) -> () { + let mut _0: (); + + bb0: { + drop(_1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + return; + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff deleted file mode 100644 index 0c73602bec84b..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-abort.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `cannot_opt_generic` before RemoveUnneededDrops -+ // MIR for `cannot_opt_generic` after RemoveUnneededDrops - - fn cannot_opt_generic(_1: T) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: T; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { - nop; - StorageLive(_3); - _3 = move _1; - drop(_3) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_3); - nop; - nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff deleted file mode 100644 index 59cce9fbcdd0a..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.panic-unwind.diff +++ /dev/null @@ -1,30 +0,0 @@ -- // MIR for `cannot_opt_generic` before RemoveUnneededDrops -+ // MIR for `cannot_opt_generic` after RemoveUnneededDrops - - fn cannot_opt_generic(_1: T) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: T; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { - nop; - StorageLive(_3); - _3 = move _1; - drop(_3) -> [return: bb2, unwind: bb1]; - } - - bb1 (cleanup): { - resume; - } - - bb2: { - StorageDead(_3); - nop; - nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff new file mode 100644 index 0000000000000..3d67cada5ddfd --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff @@ -0,0 +1,15 @@ +- // MIR for `dont_opt` before RemoveUnneededDrops ++ // MIR for `dont_opt` after RemoveUnneededDrops + + fn dont_opt(_1: Vec) -> () { + let mut _0: (); + + bb0: { + drop(_1) -> [return: bb1, unwind unreachable]; + } + + bb1: { + return; + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff deleted file mode 100644 index 428b366b5a684..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-abort.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `dont_opt` before RemoveUnneededDrops -+ // MIR for `dont_opt` after RemoveUnneededDrops - - fn dont_opt(_1: Vec) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: std::vec::Vec; - scope 1 (inlined std::mem::drop::>) { - } - - bb0: { - nop; - StorageLive(_3); - _3 = move _1; - drop(_3) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_3); - nop; - nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff deleted file mode 100644 index 445c1f82a96f8..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.dont_opt.RemoveUnneededDrops.panic-unwind.diff +++ /dev/null @@ -1,30 +0,0 @@ -- // MIR for `dont_opt` before RemoveUnneededDrops -+ // MIR for `dont_opt` after RemoveUnneededDrops - - fn dont_opt(_1: Vec) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: std::vec::Vec; - scope 1 (inlined std::mem::drop::>) { - } - - bb0: { - nop; - StorageLive(_3); - _3 = move _1; - drop(_3) -> [return: bb2, unwind: bb1]; - } - - bb1 (cleanup): { - resume; - } - - bb2: { - StorageDead(_3); - nop; - nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff new file mode 100644 index 0000000000000..cb7e58ca1a1f9 --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff @@ -0,0 +1,15 @@ +- // MIR for `opt` before RemoveUnneededDrops ++ // MIR for `opt` after RemoveUnneededDrops + + fn opt(_1: bool) -> () { + let mut _0: (); + + bb0: { +- drop(_1) -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + return; + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff deleted file mode 100644 index 01eb6d4901f76..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-abort.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `opt` before RemoveUnneededDrops -+ // MIR for `opt` after RemoveUnneededDrops - - fn opt(_1: bool) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: bool; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { -- nop; - StorageLive(_3); - _3 = copy _1; -- drop(_3) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { - StorageDead(_3); -- nop; -- nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff deleted file mode 100644 index c2c3cb76e8328..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.panic-unwind.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `opt` before RemoveUnneededDrops -+ // MIR for `opt` after RemoveUnneededDrops - - fn opt(_1: bool) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: bool; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { -- nop; - StorageLive(_3); - _3 = copy _1; -- drop(_3) -> [return: bb1, unwind continue]; -- } -- -- bb1: { - StorageDead(_3); -- nop; -- nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff new file mode 100644 index 0000000000000..1e166eee9fb07 --- /dev/null +++ b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff @@ -0,0 +1,15 @@ +- // MIR for `opt_generic_copy` before RemoveUnneededDrops ++ // MIR for `opt_generic_copy` after RemoveUnneededDrops + + fn opt_generic_copy(_1: T) -> () { + let mut _0: (); + + bb0: { +- drop(_1) -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + return; + } + } + diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff deleted file mode 100644 index a82ede6196ed3..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-abort.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `opt_generic_copy` before RemoveUnneededDrops -+ // MIR for `opt_generic_copy` after RemoveUnneededDrops - - fn opt_generic_copy(_1: T) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: T; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { -- nop; - StorageLive(_3); - _3 = copy _1; -- drop(_3) -> [return: bb1, unwind unreachable]; -- } -- -- bb1: { - StorageDead(_3); -- nop; -- nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff b/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff deleted file mode 100644 index 6e7c9ead740f0..0000000000000 --- a/tests/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.panic-unwind.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `opt_generic_copy` before RemoveUnneededDrops -+ // MIR for `opt_generic_copy` after RemoveUnneededDrops - - fn opt_generic_copy(_1: T) -> () { - debug x => _1; - let mut _0: (); - let _2: (); - let mut _3: T; - scope 1 (inlined std::mem::drop::) { - } - - bb0: { -- nop; - StorageLive(_3); - _3 = copy _1; -- drop(_3) -> [return: bb1, unwind continue]; -- } -- -- bb1: { - StorageDead(_3); -- nop; -- nop; - return; - } - } - diff --git a/tests/mir-opt/remove_unneeded_drops.rs b/tests/mir-opt/remove_unneeded_drops.rs index cad79e0aa0cbc..49dc611838e38 100644 --- a/tests/mir-opt/remove_unneeded_drops.rs +++ b/tests/mir-opt/remove_unneeded_drops.rs @@ -1,28 +1,56 @@ -// skip-filecheck -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: RemoveUnneededDrops + +#![feature(custom_mir, core_intrinsics)] +use std::intrinsics::mir::*; + // EMIT_MIR remove_unneeded_drops.opt.RemoveUnneededDrops.diff +#[custom_mir(dialect = "runtime")] fn opt(x: bool) { - drop(x); + // CHECK-LABEL: fn opt( + // CHECK-NOT: drop( + mir! { + { Drop(x, ReturnTo(bb1), UnwindUnreachable()) } + bb1 = { Return() } + } } // EMIT_MIR remove_unneeded_drops.dont_opt.RemoveUnneededDrops.diff +#[custom_mir(dialect = "runtime")] fn dont_opt(x: Vec) { - drop(x); + // CHECK-LABEL: fn dont_opt( + // CHECK: drop( + mir! { + { Drop(x, ReturnTo(bb1), UnwindUnreachable()) } + bb1 = { Return() } + } } // EMIT_MIR remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff +#[custom_mir(dialect = "runtime")] fn opt_generic_copy(x: T) { - drop(x); + // CHECK-LABEL: fn opt_generic_copy( + // CHECK-NOT: drop( + mir! { + { Drop(x, ReturnTo(bb1), UnwindUnreachable()) } + bb1 = { Return() } + } } // EMIT_MIR remove_unneeded_drops.cannot_opt_generic.RemoveUnneededDrops.diff // since the pass is not running on monomorphisized code, // we can't (but probably should) optimize this +#[custom_mir(dialect = "runtime")] fn cannot_opt_generic(x: T) { - drop(x); + // CHECK-LABEL: fn cannot_opt_generic( + // CHECK: drop( + mir! { + { Drop(x, ReturnTo(bb1), UnwindUnreachable()) } + bb1 = { Return() } + } } fn main() { + // CHECK-LABEL: fn main( opt(true); opt_generic_copy(42); cannot_opt_generic(42);