Pass alignments through the shim as Alignment (not usize)

We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.

The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
This commit is contained in:
Scott McMurray 2026-02-13 21:04:59 -08:00
parent f403dee04e
commit 774268afc1
11 changed files with 41 additions and 70 deletions

View file

@ -128,11 +128,15 @@ impl AllocFnFactory<'_, '_> {
let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
let ty_usize = self.cx.ty_path(usize);
args.push(self.cx.param(self.span, size, ty_usize.clone()));
args.push(self.cx.param(self.span, align, ty_usize));
args.push(self.cx.param(self.span, size, ty_usize));
let ty_align = self.ptr_alignment();
args.push(self.cx.param(self.span, align, ty_align));
let layout_new =
self.cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
let layout_new = self.cx.std_path(&[
sym::alloc,
sym::Layout,
sym::from_size_alignment_unchecked,
]);
let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new));
let size = self.cx.expr_ident(self.span, size);
let align = self.cx.expr_ident(self.span, align);
@ -175,6 +179,12 @@ impl AllocFnFactory<'_, '_> {
self.cx.ty_path(usize)
}
fn ptr_alignment(&self) -> Box<Ty> {
let path = self.cx.std_path(&[sym::ptr, sym::Alignment]);
let path = self.cx.path(self.span, path);
self.cx.ty_path(path)
}
fn ptr_u8(&self) -> Box<Ty> {
let u8 = self.cx.path_ident(self.span, Ident::new(sym::u8, self.span));
let ty_u8 = self.cx.ty_path(u8);

View file

@ -157,6 +157,7 @@ symbols! {
Abi,
AcqRel,
Acquire,
Alignment,
Any,
Arc,
ArcWeak,
@ -1147,6 +1148,7 @@ symbols! {
from_output,
from_residual,
from_size_align_unchecked,
from_size_alignment_unchecked,
from_str,
from_str_method,
from_str_nonconst,

View file

@ -5,7 +5,7 @@
#[stable(feature = "alloc_module", since = "1.28.0")]
#[doc(inline)]
pub use core::alloc::*;
use core::ptr::{self, NonNull};
use core::ptr::{self, Alignment, NonNull};
use core::{cmp, hint};
unsafe extern "Rust" {
@ -18,19 +18,19 @@ unsafe extern "Rust" {
#[rustc_nounwind]
#[rustc_std_internal_symbol]
#[rustc_allocator_zeroed_variant = "__rust_alloc_zeroed"]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
fn __rust_alloc(size: usize, align: Alignment) -> *mut u8;
#[rustc_deallocator]
#[rustc_nounwind]
#[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
fn __rust_dealloc(ptr: *mut u8, size: usize, align: Alignment);
#[rustc_reallocator]
#[rustc_nounwind]
#[rustc_std_internal_symbol]
fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8;
fn __rust_realloc(ptr: *mut u8, old_size: usize, align: Alignment, new_size: usize) -> *mut u8;
#[rustc_allocator_zeroed]
#[rustc_nounwind]
#[rustc_std_internal_symbol]
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
fn __rust_alloc_zeroed(size: usize, align: Alignment) -> *mut u8;
#[rustc_nounwind]
#[rustc_std_internal_symbol]
@ -92,7 +92,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
// stable code until it is actually stabilized.
__rust_no_alloc_shim_is_unstable_v2();
__rust_alloc(layout.size(), layout.align())
__rust_alloc(layout.size(), layout.alignment())
}
}
@ -112,7 +112,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
unsafe { __rust_dealloc(ptr, layout.size(), layout.alignment()) }
}
/// Reallocates memory with the global allocator.
@ -132,7 +132,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) }
unsafe { __rust_realloc(ptr, layout.size(), layout.alignment(), new_size) }
}
/// Allocates zero-initialized memory with the global allocator.
@ -175,7 +175,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
// stable code until it is actually stabilized.
__rust_no_alloc_shim_is_unstable_v2();
__rust_alloc_zeroed(layout.size(), layout.align())
__rust_alloc_zeroed(layout.size(), layout.alignment())
}
}

View file

@ -1777,7 +1777,7 @@ pub(crate) mod builtin {
///
/// See also [`std::alloc::GlobalAlloc`](../../../std/alloc/trait.GlobalAlloc.html).
#[stable(feature = "global_allocator", since = "1.28.0")]
#[allow_internal_unstable(rustc_attrs)]
#[allow_internal_unstable(rustc_attrs, ptr_alignment_type)]
#[rustc_builtin_macro]
pub macro global_allocator($item:item) {
/* compiler built-in */

View file

@ -41,6 +41,6 @@ pub fn box_lotsa_padding() -> Box<LotsaPadding> {
// Hide the `allocalign` attribute in the declaration of __rust_alloc
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
// CHECK: declare {{(dso_local )?}}noalias noundef ptr @{{.*}}__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
// CHECK: declare {{(dso_local )?}}noalias noundef ptr @{{.*}}__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef range(i{{[0-9]+}} 1, {{-2147483647|-9223372036854775807}})) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) {{(uwtable )?}}"alloc-family"="__rust_alloc" {{.*}} }

View file

@ -197,6 +197,6 @@ pub fn vec_array(n: usize) -> Vec<[u32; 1_000_000]> {
}
// Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away.
// CHECK: declare noalias noundef ptr @{{.*}}__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]]
// CHECK: declare noalias noundef ptr @{{.*}}__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef range(i64 1, -9223372036854775807)) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]]
// CHECK-DAG: attributes [[RUST_ALLOC_ZEROED_ATTRS]] = { {{.*}} allockind("alloc,zeroed,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} }

View file

@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _10: ();
let _9: ();
scope 3 {
scope 4 {
scope 17 (inlined Layout::size) {
@ -32,16 +32,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
scope 27 (inlined NonNull::<u8>::as_ptr) {
}
scope 28 (inlined std::alloc::dealloc) {
let mut _9: usize;
scope 29 (inlined Layout::size) {
}
scope 30 (inlined Layout::align) {
scope 31 (inlined std::ptr::Alignment::as_usize) {
scope 32 (inlined std::ptr::Alignment::as_nonzero) {
}
scope 33 (inlined NonZero::<usize>::get) {
}
}
scope 30 (inlined Layout::alignment) {
}
}
}
@ -100,13 +93,10 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb2: {
StorageLive(_8);
_8 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_9);
_9 = copy _7 as usize (Transmute);
_10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable];
_9 = alloc::alloc::__rust_dealloc(move _8, move _5, move _7) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_9);
StorageDead(_8);
goto -> bb4;
}

View file

@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _10: ();
let _9: ();
scope 3 {
scope 4 {
scope 17 (inlined Layout::size) {
@ -32,16 +32,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
scope 27 (inlined NonNull::<u8>::as_ptr) {
}
scope 28 (inlined std::alloc::dealloc) {
let mut _9: usize;
scope 29 (inlined Layout::size) {
}
scope 30 (inlined Layout::align) {
scope 31 (inlined std::ptr::Alignment::as_usize) {
scope 32 (inlined std::ptr::Alignment::as_nonzero) {
}
scope 33 (inlined NonZero::<usize>::get) {
}
}
scope 30 (inlined Layout::alignment) {
}
}
}
@ -100,13 +93,10 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb2: {
StorageLive(_8);
_8 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_9);
_9 = copy _7 as usize (Transmute);
_10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable];
_9 = alloc::alloc::__rust_dealloc(move _8, move _5, move _7) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_9);
StorageDead(_8);
goto -> bb4;
}

View file

@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _10: ();
let _9: ();
scope 3 {
scope 4 {
scope 17 (inlined Layout::size) {
@ -32,16 +32,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
scope 27 (inlined NonNull::<u8>::as_ptr) {
}
scope 28 (inlined std::alloc::dealloc) {
let mut _9: usize;
scope 29 (inlined Layout::size) {
}
scope 30 (inlined Layout::align) {
scope 31 (inlined std::ptr::Alignment::as_usize) {
scope 32 (inlined std::ptr::Alignment::as_nonzero) {
}
scope 33 (inlined NonZero::<usize>::get) {
}
}
scope 30 (inlined Layout::alignment) {
}
}
}
@ -100,13 +93,10 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb2: {
StorageLive(_8);
_8 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_9);
_9 = copy _7 as usize (Transmute);
_10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable];
_9 = alloc::alloc::__rust_dealloc(move _8, move _5, move _7) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_9);
StorageDead(_8);
goto -> bb4;
}

View file

@ -8,7 +8,7 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
let _2: std::ptr::NonNull<[T]>;
let mut _3: *mut [T];
let mut _4: *const [T];
let _10: ();
let _9: ();
scope 3 {
scope 4 {
scope 17 (inlined Layout::size) {
@ -32,16 +32,9 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
scope 27 (inlined NonNull::<u8>::as_ptr) {
}
scope 28 (inlined std::alloc::dealloc) {
let mut _9: usize;
scope 29 (inlined Layout::size) {
}
scope 30 (inlined Layout::align) {
scope 31 (inlined std::ptr::Alignment::as_usize) {
scope 32 (inlined std::ptr::Alignment::as_nonzero) {
}
scope 33 (inlined NonZero::<usize>::get) {
}
}
scope 30 (inlined Layout::alignment) {
}
}
}
@ -100,13 +93,10 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
bb2: {
StorageLive(_8);
_8 = copy _3 as *mut u8 (PtrToPtr);
StorageLive(_9);
_9 = copy _7 as usize (Transmute);
_10 = alloc::alloc::__rust_dealloc(move _8, move _5, move _9) -> [return: bb3, unwind unreachable];
_9 = alloc::alloc::__rust_dealloc(move _8, move _5, move _7) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_9);
StorageDead(_8);
goto -> bb4;
}

View file

@ -11,7 +11,6 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) {
// CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]>
// CHECK: [[ALIGN:_.+]] = const <T as std::mem::SizedTypeProperties>::ALIGN;
// CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute);
// CHECK: [[C:_.+]] = copy [[B]] as usize (Transmute);
// CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[C]]) ->
// CHECK: = alloc::alloc::__rust_dealloc({{.+}}, move [[SIZE]], move [[B]]) ->
std::ptr::drop_in_place(ptr)
}