From 61d3b2d0461f5b32696c1e01af44591a932ad19d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 14 Feb 2026 21:34:08 -0800 Subject: [PATCH 1/2] Add a mir-opt test showing the drop for a box of non-DST --- ...rop_bytes.PreCodegen.after.panic-abort.mir | 107 ++++++++++++++++++ ...op_bytes.PreCodegen.after.panic-unwind.mir | 107 ++++++++++++++++++ ...p_generic.PreCodegen.after.panic-abort.mir | 107 ++++++++++++++++++ ..._generic.PreCodegen.after.panic-unwind.mir | 107 ++++++++++++++++++ .../mir-opt/pre-codegen/drop_box_of_sized.rs | 22 ++++ 5 files changed, 450 insertions(+) create mode 100644 tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir create mode 100644 tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir create mode 100644 tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir create mode 100644 tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir create mode 100644 tests/mir-opt/pre-codegen/drop_box_of_sized.rs diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..32c1bd33bba75 --- /dev/null +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir @@ -0,0 +1,107 @@ +// MIR for `drop_bytes` after PreCodegen + +fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { + debug x => _1; + let mut _0: (); + scope 1 (inlined drop_in_place::> - shim(Some(Box<[u8; 1024]>))) { + scope 2 (inlined as Drop>::drop) { + let _2: std::ptr::NonNull<[u8; 1024]>; + let mut _3: *const [u8; 1024]; + let _8: (); + scope 3 { + scope 4 { + scope 17 (inlined Layout::size) { + } + scope 18 (inlined std::ptr::Unique::<[u8; 1024]>::cast::) { + scope 19 (inlined NonNull::<[u8; 1024]>::cast::) { + scope 20 (inlined NonNull::<[u8; 1024]>::as_ptr) { + } + } + } + scope 21 (inlined as From>>::from) { + scope 22 (inlined std::ptr::Unique::::as_non_null_ptr) { + } + } + scope 23 (inlined ::deallocate) { + scope 24 (inlined std::alloc::Global::deallocate_impl) { + scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _7: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::alignment) { + } + } + } + } + } + } + scope 5 (inlined std::ptr::Unique::<[u8; 1024]>::as_ptr) { + scope 6 (inlined NonNull::<[u8; 1024]>::as_ptr) { + } + } + scope 7 (inlined Layout::for_value_raw::<[u8; 1024]>) { + let mut _4: usize; + let mut _6: std::ptr::Alignment; + scope 8 { + scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { + } + } + scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { + } + scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { + let _5: usize; + scope 11 { + scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 14 (inlined core::ub_checks::check_language_ub) { + scope 15 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + scope 12 (inlined align_of_val_raw::<[u8; 1024]>) { + } + } + } + } + } + } + + bb0: { + _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); + StorageLive(_3); + _3 = copy _2 as *const [u8; 1024] (Transmute); + _4 = std::intrinsics::size_of_val::<[u8; 1024]>(copy _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_5); + _5 = std::intrinsics::align_of_val::<[u8; 1024]>(move _3) -> [return: bb2, unwind unreachable]; + } + + bb2: { + _6 = copy _5 as std::ptr::Alignment (Transmute); + StorageDead(_5); + StorageDead(_3); + switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + } + + bb3: { + StorageLive(_7); + _7 = copy _2 as *mut u8 (Transmute); + _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_7); + goto -> bb5; + } + + bb5: { + return; + } +} diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..32c1bd33bba75 --- /dev/null +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,107 @@ +// MIR for `drop_bytes` after PreCodegen + +fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { + debug x => _1; + let mut _0: (); + scope 1 (inlined drop_in_place::> - shim(Some(Box<[u8; 1024]>))) { + scope 2 (inlined as Drop>::drop) { + let _2: std::ptr::NonNull<[u8; 1024]>; + let mut _3: *const [u8; 1024]; + let _8: (); + scope 3 { + scope 4 { + scope 17 (inlined Layout::size) { + } + scope 18 (inlined std::ptr::Unique::<[u8; 1024]>::cast::) { + scope 19 (inlined NonNull::<[u8; 1024]>::cast::) { + scope 20 (inlined NonNull::<[u8; 1024]>::as_ptr) { + } + } + } + scope 21 (inlined as From>>::from) { + scope 22 (inlined std::ptr::Unique::::as_non_null_ptr) { + } + } + scope 23 (inlined ::deallocate) { + scope 24 (inlined std::alloc::Global::deallocate_impl) { + scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _7: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::alignment) { + } + } + } + } + } + } + scope 5 (inlined std::ptr::Unique::<[u8; 1024]>::as_ptr) { + scope 6 (inlined NonNull::<[u8; 1024]>::as_ptr) { + } + } + scope 7 (inlined Layout::for_value_raw::<[u8; 1024]>) { + let mut _4: usize; + let mut _6: std::ptr::Alignment; + scope 8 { + scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { + } + } + scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { + } + scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { + let _5: usize; + scope 11 { + scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 14 (inlined core::ub_checks::check_language_ub) { + scope 15 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + scope 12 (inlined align_of_val_raw::<[u8; 1024]>) { + } + } + } + } + } + } + + bb0: { + _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); + StorageLive(_3); + _3 = copy _2 as *const [u8; 1024] (Transmute); + _4 = std::intrinsics::size_of_val::<[u8; 1024]>(copy _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_5); + _5 = std::intrinsics::align_of_val::<[u8; 1024]>(move _3) -> [return: bb2, unwind unreachable]; + } + + bb2: { + _6 = copy _5 as std::ptr::Alignment (Transmute); + StorageDead(_5); + StorageDead(_3); + switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + } + + bb3: { + StorageLive(_7); + _7 = copy _2 as *mut u8 (Transmute); + _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_7); + goto -> bb5; + } + + bb5: { + return; + } +} diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir new file mode 100644 index 0000000000000..be994245fa307 --- /dev/null +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir @@ -0,0 +1,107 @@ +// MIR for `drop_generic` after PreCodegen + +fn drop_generic(_1: *mut Box) -> () { + debug x => _1; + let mut _0: (); + scope 1 (inlined drop_in_place::> - shim(Some(Box))) { + scope 2 (inlined as Drop>::drop) { + let _2: std::ptr::NonNull; + let mut _3: *const T; + let _8: (); + scope 3 { + scope 4 { + scope 17 (inlined Layout::size) { + } + scope 18 (inlined std::ptr::Unique::::cast::) { + scope 19 (inlined NonNull::::cast::) { + scope 20 (inlined NonNull::::as_ptr) { + } + } + } + scope 21 (inlined as From>>::from) { + scope 22 (inlined std::ptr::Unique::::as_non_null_ptr) { + } + } + scope 23 (inlined ::deallocate) { + scope 24 (inlined std::alloc::Global::deallocate_impl) { + scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _7: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::alignment) { + } + } + } + } + } + } + scope 5 (inlined std::ptr::Unique::::as_ptr) { + scope 6 (inlined NonNull::::as_ptr) { + } + } + scope 7 (inlined Layout::for_value_raw::) { + let mut _4: usize; + let mut _6: std::ptr::Alignment; + scope 8 { + scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { + } + } + scope 9 (inlined size_of_val_raw::) { + } + scope 10 (inlined std::ptr::Alignment::of_val_raw::) { + let _5: usize; + scope 11 { + scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 14 (inlined core::ub_checks::check_language_ub) { + scope 15 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + scope 12 (inlined align_of_val_raw::) { + } + } + } + } + } + } + + bb0: { + _2 = copy (((*_1).0: std::ptr::Unique).0: std::ptr::NonNull); + StorageLive(_3); + _3 = copy _2 as *const T (Transmute); + _4 = std::intrinsics::size_of_val::(copy _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_5); + _5 = std::intrinsics::align_of_val::(move _3) -> [return: bb2, unwind unreachable]; + } + + bb2: { + _6 = copy _5 as std::ptr::Alignment (Transmute); + StorageDead(_5); + StorageDead(_3); + switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + } + + bb3: { + StorageLive(_7); + _7 = copy _2 as *mut u8 (Transmute); + _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_7); + goto -> bb5; + } + + bb5: { + return; + } +} diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir new file mode 100644 index 0000000000000..be994245fa307 --- /dev/null +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,107 @@ +// MIR for `drop_generic` after PreCodegen + +fn drop_generic(_1: *mut Box) -> () { + debug x => _1; + let mut _0: (); + scope 1 (inlined drop_in_place::> - shim(Some(Box))) { + scope 2 (inlined as Drop>::drop) { + let _2: std::ptr::NonNull; + let mut _3: *const T; + let _8: (); + scope 3 { + scope 4 { + scope 17 (inlined Layout::size) { + } + scope 18 (inlined std::ptr::Unique::::cast::) { + scope 19 (inlined NonNull::::cast::) { + scope 20 (inlined NonNull::::as_ptr) { + } + } + } + scope 21 (inlined as From>>::from) { + scope 22 (inlined std::ptr::Unique::::as_non_null_ptr) { + } + } + scope 23 (inlined ::deallocate) { + scope 24 (inlined std::alloc::Global::deallocate_impl) { + scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { + let mut _7: *mut u8; + scope 26 (inlined Layout::size) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + scope 28 (inlined std::alloc::dealloc) { + scope 29 (inlined Layout::size) { + } + scope 30 (inlined Layout::alignment) { + } + } + } + } + } + } + scope 5 (inlined std::ptr::Unique::::as_ptr) { + scope 6 (inlined NonNull::::as_ptr) { + } + } + scope 7 (inlined Layout::for_value_raw::) { + let mut _4: usize; + let mut _6: std::ptr::Alignment; + scope 8 { + scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { + } + } + scope 9 (inlined size_of_val_raw::) { + } + scope 10 (inlined std::ptr::Alignment::of_val_raw::) { + let _5: usize; + scope 11 { + scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { + scope 14 (inlined core::ub_checks::check_language_ub) { + scope 15 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + scope 12 (inlined align_of_val_raw::) { + } + } + } + } + } + } + + bb0: { + _2 = copy (((*_1).0: std::ptr::Unique).0: std::ptr::NonNull); + StorageLive(_3); + _3 = copy _2 as *const T (Transmute); + _4 = std::intrinsics::size_of_val::(copy _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageLive(_5); + _5 = std::intrinsics::align_of_val::(move _3) -> [return: bb2, unwind unreachable]; + } + + bb2: { + _6 = copy _5 as std::ptr::Alignment (Transmute); + StorageDead(_5); + StorageDead(_3); + switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + } + + bb3: { + StorageLive(_7); + _7 = copy _2 as *mut u8 (Transmute); + _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; + } + + bb4: { + StorageDead(_7); + goto -> bb5; + } + + bb5: { + return; + } +} diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.rs b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs new file mode 100644 index 0000000000000..dca3ba3e320d3 --- /dev/null +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs @@ -0,0 +1,22 @@ +//@ compile-flags: -O -Zmir-opt-level=2 +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +#![crate_type = "lib"] + +// EMIT_MIR drop_box_of_sized.drop_generic.PreCodegen.after.mir +pub unsafe fn drop_generic(x: *mut Box) { + // CHECK-LABEL: fn drop_generic + // CHECK: = std::intrinsics::size_of_val:: + // CHECK: = std::intrinsics::align_of_val:: + // CHECK: alloc::alloc::__rust_dealloc + std::ptr::drop_in_place(x) +} + +// EMIT_MIR drop_box_of_sized.drop_bytes.PreCodegen.after.mir +pub unsafe fn drop_bytes(x: *mut Box<[u8; 1024]>) { + // CHECK-LABEL: fn drop_bytes + // CHECK: = std::intrinsics::size_of_val::<[u8; 1024]> + // CHECK: = std::intrinsics::align_of_val::<[u8; 1024]> + // CHECK: alloc::alloc::__rust_dealloc + std::ptr::drop_in_place(x) +} From 649e027b8827fe98c961ab73e323035179b75dbe Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 14 Feb 2026 22:26:25 -0800 Subject: [PATCH 2/2] mir-simplify `{size,align}_of_val::` --- .../rustc_mir_transform/src/instsimplify.rs | 51 +++++++++++++------ ..._sized.InstSimplify-after-simplifycfg.diff | 22 ++++++++ .../align_or_size_of_sized_val.rs | 19 +++++++ ..._sized.InstSimplify-after-simplifycfg.diff | 22 ++++++++ ...rop_bytes.PreCodegen.after.panic-abort.mir | 34 ++----------- ...op_bytes.PreCodegen.after.panic-unwind.mir | 34 ++----------- ...p_generic.PreCodegen.after.panic-abort.mir | 42 ++++++--------- ..._generic.PreCodegen.after.panic-unwind.mir | 42 ++++++--------- .../mir-opt/pre-codegen/drop_box_of_sized.rs | 11 ++-- 9 files changed, 144 insertions(+), 133 deletions(-) create mode 100644 tests/mir-opt/instsimplify/align_or_size_of_sized_val.align_of_val_sized.InstSimplify-after-simplifycfg.diff create mode 100644 tests/mir-opt/instsimplify/align_or_size_of_sized_val.rs create mode 100644 tests/mir-opt/instsimplify/align_or_size_of_sized_val.size_of_val_sized.InstSimplify-after-simplifycfg.diff diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 84d642ea4ebc0..b92938c7094eb 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -56,7 +56,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { let terminator = block.terminator.as_mut().unwrap(); ctx.simplify_primitive_clone(terminator, &mut block.statements); - ctx.simplify_align_of_slice_val(terminator, &mut block.statements); + ctx.simplify_size_or_align_of_val(terminator, &mut block.statements); ctx.simplify_intrinsic_assert(terminator); ctx.simplify_nounwind_call(terminator); simplify_duplicate_switch_targets(terminator); @@ -246,13 +246,18 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { terminator.kind = TerminatorKind::Goto { target: *destination_block }; } - // Convert `align_of_val::<[T]>(ptr)` to `align_of::()`, since the - // alignment of a slice doesn't actually depend on metadata at all - // and the element type is always `Sized`. - // - // This is here so it can run after inlining, where it's more useful. - // (LowerIntrinsics is done in cleanup, before the optimization passes.) - fn simplify_align_of_slice_val( + /// Simplify `size_of_val` and `align_of_val` if we don't actually need + /// to look at the value in order to calculate the result: + /// - For `Sized` types we can always do this for both, + /// - For `align_of_val::<[T]>` we can return `align_of::()`, since it + /// doesn't depend on the slice's length and the elements are sized. + /// + /// This is here so it can run after inlining, where it's more useful. + /// (LowerIntrinsics is done in cleanup, before the optimization passes.) + /// + /// Note that we intentionally just produce the lang item constants so this + /// works on generic types and avoids any risk of layout calculation cycles. + fn simplify_size_or_align_of_val( &self, terminator: &mut Terminator<'tcx>, statements: &mut Vec>, @@ -263,19 +268,35 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> { } = &terminator.kind && args.len() == 1 && let Some((fn_def_id, generics)) = func.const_fn_def() - && self.tcx.is_intrinsic(fn_def_id, sym::align_of_val) - && let ty::Slice(elem_ty) = *generics.type_at(0).kind() { - let align_def_id = self.tcx.require_lang_item(LangItem::AlignOf, source_info.span); - let align_const = Operand::unevaluated_constant( + let lang_item = if self.tcx.is_intrinsic(fn_def_id, sym::size_of_val) { + LangItem::SizeOf + } else if self.tcx.is_intrinsic(fn_def_id, sym::align_of_val) { + LangItem::AlignOf + } else { + return; + }; + let generic_ty = generics.type_at(0); + let ty = if generic_ty.is_sized(self.tcx, self.typing_env) { + generic_ty + } else if let LangItem::AlignOf = lang_item + && let ty::Slice(elem_ty) = *generic_ty.kind() + { + elem_ty + } else { + return; + }; + + let const_def_id = self.tcx.require_lang_item(lang_item, source_info.span); + let const_op = Operand::unevaluated_constant( self.tcx, - align_def_id, - &[elem_ty.into()], + const_def_id, + &[ty.into()], source_info.span, ); statements.push(Statement::new( source_info, - StatementKind::Assign(Box::new((*destination, Rvalue::Use(align_const)))), + StatementKind::Assign(Box::new((*destination, Rvalue::Use(const_op)))), )); terminator.kind = TerminatorKind::Goto { target: *destination_block }; } diff --git a/tests/mir-opt/instsimplify/align_or_size_of_sized_val.align_of_val_sized.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.align_of_val_sized.InstSimplify-after-simplifycfg.diff new file mode 100644 index 0000000000000..1fc160e9b07b2 --- /dev/null +++ b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.align_of_val_sized.InstSimplify-after-simplifycfg.diff @@ -0,0 +1,22 @@ +- // MIR for `align_of_val_sized` before InstSimplify-after-simplifycfg ++ // MIR for `align_of_val_sized` after InstSimplify-after-simplifycfg + + fn align_of_val_sized(_1: &T) -> usize { + debug val => _1; + let mut _0: usize; + let mut _2: *const T; + + bb0: { + StorageLive(_2); + _2 = &raw const (*_1); +- _0 = std::intrinsics::align_of_val::(move _2) -> [return: bb1, unwind unreachable]; ++ _0 = const ::ALIGN; ++ goto -> bb1; + } + + bb1: { + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/align_or_size_of_sized_val.rs b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.rs new file mode 100644 index 0000000000000..d186e1bc90141 --- /dev/null +++ b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.rs @@ -0,0 +1,19 @@ +//@ test-mir-pass: InstSimplify-after-simplifycfg +//@ needs-unwind + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +// EMIT_MIR align_or_size_of_sized_val.align_of_val_sized.InstSimplify-after-simplifycfg.diff +pub fn align_of_val_sized(val: &T) -> usize { + // CHECK-LABEL: fn align_of_val_sized + // CHECK: _0 = const ::ALIGN; + unsafe { core::intrinsics::align_of_val(val) } +} + +// EMIT_MIR align_or_size_of_sized_val.size_of_val_sized.InstSimplify-after-simplifycfg.diff +pub fn size_of_val_sized(val: &T) -> usize { + // CHECK-LABEL: fn size_of_val_sized + // CHECK: _0 = const ::SIZE; + unsafe { core::intrinsics::size_of_val(val) } +} diff --git a/tests/mir-opt/instsimplify/align_or_size_of_sized_val.size_of_val_sized.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.size_of_val_sized.InstSimplify-after-simplifycfg.diff new file mode 100644 index 0000000000000..e96c4d25b8358 --- /dev/null +++ b/tests/mir-opt/instsimplify/align_or_size_of_sized_val.size_of_val_sized.InstSimplify-after-simplifycfg.diff @@ -0,0 +1,22 @@ +- // MIR for `size_of_val_sized` before InstSimplify-after-simplifycfg ++ // MIR for `size_of_val_sized` after InstSimplify-after-simplifycfg + + fn size_of_val_sized(_1: &T) -> usize { + debug val => _1; + let mut _0: usize; + let mut _2: *const T; + + bb0: { + StorageLive(_2); + _2 = &raw const (*_1); +- _0 = std::intrinsics::size_of_val::(move _2) -> [return: bb1, unwind unreachable]; ++ _0 = const ::SIZE; ++ goto -> bb1; + } + + bb1: { + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir index 32c1bd33bba75..4b5ed1d223822 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-abort.mir @@ -6,8 +6,7 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 1 (inlined drop_in_place::> - shim(Some(Box<[u8; 1024]>))) { scope 2 (inlined as Drop>::drop) { let _2: std::ptr::NonNull<[u8; 1024]>; - let mut _3: *const [u8; 1024]; - let _8: (); + let _4: (); scope 3 { scope 4 { scope 17 (inlined Layout::size) { @@ -25,7 +24,7 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _7: *mut u8; + let mut _3: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { @@ -45,8 +44,6 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { } } scope 7 (inlined Layout::for_value_raw::<[u8; 1024]>) { - let mut _4: usize; - let mut _6: std::ptr::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } @@ -54,7 +51,6 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { } scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { - let _5: usize; scope 11 { scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { @@ -74,34 +70,12 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { bb0: { _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); StorageLive(_3); - _3 = copy _2 as *const [u8; 1024] (Transmute); - _4 = std::intrinsics::size_of_val::<[u8; 1024]>(copy _3) -> [return: bb1, unwind unreachable]; + _3 = copy _2 as *mut u8 (Transmute); + _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_5); - _5 = std::intrinsics::align_of_val::<[u8; 1024]>(move _3) -> [return: bb2, unwind unreachable]; - } - - bb2: { - _6 = copy _5 as std::ptr::Alignment (Transmute); - StorageDead(_5); StorageDead(_3); - switchInt(copy _4) -> [0: bb5, otherwise: bb3]; - } - - bb3: { - StorageLive(_7); - _7 = copy _2 as *mut u8 (Transmute); - _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_7); - goto -> bb5; - } - - bb5: { return; } } diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir index 32c1bd33bba75..4b5ed1d223822 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_bytes.PreCodegen.after.panic-unwind.mir @@ -6,8 +6,7 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 1 (inlined drop_in_place::> - shim(Some(Box<[u8; 1024]>))) { scope 2 (inlined as Drop>::drop) { let _2: std::ptr::NonNull<[u8; 1024]>; - let mut _3: *const [u8; 1024]; - let _8: (); + let _4: (); scope 3 { scope 4 { scope 17 (inlined Layout::size) { @@ -25,7 +24,7 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _7: *mut u8; + let mut _3: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { @@ -45,8 +44,6 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { } } scope 7 (inlined Layout::for_value_raw::<[u8; 1024]>) { - let mut _4: usize; - let mut _6: std::ptr::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } @@ -54,7 +51,6 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { scope 9 (inlined size_of_val_raw::<[u8; 1024]>) { } scope 10 (inlined std::ptr::Alignment::of_val_raw::<[u8; 1024]>) { - let _5: usize; scope 11 { scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { @@ -74,34 +70,12 @@ fn drop_bytes(_1: *mut Box<[u8; 1024]>) -> () { bb0: { _2 = copy (((*_1).0: std::ptr::Unique<[u8; 1024]>).0: std::ptr::NonNull<[u8; 1024]>); StorageLive(_3); - _3 = copy _2 as *const [u8; 1024] (Transmute); - _4 = std::intrinsics::size_of_val::<[u8; 1024]>(copy _3) -> [return: bb1, unwind unreachable]; + _3 = copy _2 as *mut u8 (Transmute); + _4 = alloc::alloc::__rust_dealloc(move _3, const 1024_usize, const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }}) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_5); - _5 = std::intrinsics::align_of_val::<[u8; 1024]>(move _3) -> [return: bb2, unwind unreachable]; - } - - bb2: { - _6 = copy _5 as std::ptr::Alignment (Transmute); - StorageDead(_5); StorageDead(_3); - switchInt(copy _4) -> [0: bb5, otherwise: bb3]; - } - - bb3: { - StorageLive(_7); - _7 = copy _2 as *mut u8 (Transmute); - _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_7); - goto -> bb5; - } - - bb5: { return; } } diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir index be994245fa307..c446ab395f3ec 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-abort.mir @@ -6,8 +6,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 1 (inlined drop_in_place::> - shim(Some(Box))) { scope 2 (inlined as Drop>::drop) { let _2: std::ptr::NonNull; - let mut _3: *const T; - let _8: (); + let _7: (); scope 3 { scope 4 { scope 17 (inlined Layout::size) { @@ -25,7 +24,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _7: *mut u8; + let mut _6: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { @@ -45,8 +44,8 @@ fn drop_generic(_1: *mut Box) -> () { } } scope 7 (inlined Layout::for_value_raw::) { - let mut _4: usize; - let mut _6: std::ptr::Alignment; + let mut _3: usize; + let mut _5: std::ptr::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } @@ -54,7 +53,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 9 (inlined size_of_val_raw::) { } scope 10 (inlined std::ptr::Alignment::of_val_raw::) { - let _5: usize; + let _4: usize; scope 11 { scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { @@ -73,35 +72,26 @@ fn drop_generic(_1: *mut Box) -> () { bb0: { _2 = copy (((*_1).0: std::ptr::Unique).0: std::ptr::NonNull); - StorageLive(_3); - _3 = copy _2 as *const T (Transmute); - _4 = std::intrinsics::size_of_val::(copy _3) -> [return: bb1, unwind unreachable]; + _3 = const ::SIZE; + StorageLive(_4); + _4 = const ::ALIGN; + _5 = copy _4 as std::ptr::Alignment (Transmute); + StorageDead(_4); + switchInt(copy _3) -> [0: bb3, otherwise: bb1]; } bb1: { - StorageLive(_5); - _5 = std::intrinsics::align_of_val::(move _3) -> [return: bb2, unwind unreachable]; + StorageLive(_6); + _6 = copy _2 as *mut u8 (Transmute); + _7 = alloc::alloc::__rust_dealloc(move _6, move _3, move _5) -> [return: bb2, unwind unreachable]; } bb2: { - _6 = copy _5 as std::ptr::Alignment (Transmute); - StorageDead(_5); - StorageDead(_3); - switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + StorageDead(_6); + goto -> bb3; } bb3: { - StorageLive(_7); - _7 = copy _2 as *mut u8 (Transmute); - _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_7); - goto -> bb5; - } - - bb5: { return; } } diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir index be994245fa307..c446ab395f3ec 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.drop_generic.PreCodegen.after.panic-unwind.mir @@ -6,8 +6,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 1 (inlined drop_in_place::> - shim(Some(Box))) { scope 2 (inlined as Drop>::drop) { let _2: std::ptr::NonNull; - let mut _3: *const T; - let _8: (); + let _7: (); scope 3 { scope 4 { scope 17 (inlined Layout::size) { @@ -25,7 +24,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 23 (inlined ::deallocate) { scope 24 (inlined std::alloc::Global::deallocate_impl) { scope 25 (inlined std::alloc::Global::deallocate_impl_runtime) { - let mut _7: *mut u8; + let mut _6: *mut u8; scope 26 (inlined Layout::size) { } scope 27 (inlined NonNull::::as_ptr) { @@ -45,8 +44,8 @@ fn drop_generic(_1: *mut Box) -> () { } } scope 7 (inlined Layout::for_value_raw::) { - let mut _4: usize; - let mut _6: std::ptr::Alignment; + let mut _3: usize; + let mut _5: std::ptr::Alignment; scope 8 { scope 16 (inlined #[track_caller] Layout::from_size_alignment_unchecked) { } @@ -54,7 +53,7 @@ fn drop_generic(_1: *mut Box) -> () { scope 9 (inlined size_of_val_raw::) { } scope 10 (inlined std::ptr::Alignment::of_val_raw::) { - let _5: usize; + let _4: usize; scope 11 { scope 13 (inlined #[track_caller] std::ptr::Alignment::new_unchecked) { scope 14 (inlined core::ub_checks::check_language_ub) { @@ -73,35 +72,26 @@ fn drop_generic(_1: *mut Box) -> () { bb0: { _2 = copy (((*_1).0: std::ptr::Unique).0: std::ptr::NonNull); - StorageLive(_3); - _3 = copy _2 as *const T (Transmute); - _4 = std::intrinsics::size_of_val::(copy _3) -> [return: bb1, unwind unreachable]; + _3 = const ::SIZE; + StorageLive(_4); + _4 = const ::ALIGN; + _5 = copy _4 as std::ptr::Alignment (Transmute); + StorageDead(_4); + switchInt(copy _3) -> [0: bb3, otherwise: bb1]; } bb1: { - StorageLive(_5); - _5 = std::intrinsics::align_of_val::(move _3) -> [return: bb2, unwind unreachable]; + StorageLive(_6); + _6 = copy _2 as *mut u8 (Transmute); + _7 = alloc::alloc::__rust_dealloc(move _6, move _3, move _5) -> [return: bb2, unwind unreachable]; } bb2: { - _6 = copy _5 as std::ptr::Alignment (Transmute); - StorageDead(_5); - StorageDead(_3); - switchInt(copy _4) -> [0: bb5, otherwise: bb3]; + StorageDead(_6); + goto -> bb3; } bb3: { - StorageLive(_7); - _7 = copy _2 as *mut u8 (Transmute); - _8 = alloc::alloc::__rust_dealloc(move _7, move _4, move _6) -> [return: bb4, unwind unreachable]; - } - - bb4: { - StorageDead(_7); - goto -> bb5; - } - - bb5: { return; } } diff --git a/tests/mir-opt/pre-codegen/drop_box_of_sized.rs b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs index dca3ba3e320d3..1e2953aa46b75 100644 --- a/tests/mir-opt/pre-codegen/drop_box_of_sized.rs +++ b/tests/mir-opt/pre-codegen/drop_box_of_sized.rs @@ -6,17 +6,16 @@ // EMIT_MIR drop_box_of_sized.drop_generic.PreCodegen.after.mir pub unsafe fn drop_generic(x: *mut Box) { // CHECK-LABEL: fn drop_generic - // CHECK: = std::intrinsics::size_of_val:: - // CHECK: = std::intrinsics::align_of_val:: - // CHECK: alloc::alloc::__rust_dealloc + // CHECK: [[SIZE:_.+]] = const ::SIZE; + // CHECK: [[ALIGN:_.+]] = const ::ALIGN; + // CHECK: [[ALIGNMENT:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute) + // CHECK: alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[ALIGNMENT]]) std::ptr::drop_in_place(x) } // EMIT_MIR drop_box_of_sized.drop_bytes.PreCodegen.after.mir pub unsafe fn drop_bytes(x: *mut Box<[u8; 1024]>) { // CHECK-LABEL: fn drop_bytes - // CHECK: = std::intrinsics::size_of_val::<[u8; 1024]> - // CHECK: = std::intrinsics::align_of_val::<[u8; 1024]> - // CHECK: alloc::alloc::__rust_dealloc + // CHECK: alloc::alloc::__rust_dealloc({{.+}}, const 1024_usize, {{.+}}Align1Shl0 {{.+}}) std::ptr::drop_in_place(x) }