From af6045817fdb1fcc37b7d2f3bc14e11aedf3738b Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 16 Sep 2024 21:27:29 -0700 Subject: [PATCH] compiler: Fix handling of `repr(align(N), simd)` The attributes may not be sensible to combine in user code, but they should still work. --- compiler/rustc_ty_utils/src/layout.rs | 12 ++++++++++-- tests/ui/simd/repr-align-and-simd.rs | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/ui/simd/repr-align-and-simd.rs diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index c153fb64c333b..16fb3154dcd14 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -506,6 +506,8 @@ fn layout_of_uncached<'tcx>( .checked_mul(e_len, dl) .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; + let requested_align = def.repr().align.clone(); + let (abi, align) = if def.repr().packed() && !e_len.is_power_of_two() { // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close @@ -518,7 +520,13 @@ fn layout_of_uncached<'tcx>( }, ) } else { - (Abi::Vector { element: e_abi, count: e_len }, dl.vector_align(size)) + let natural_align = dl.vector_align(size); + let align = if let Some(align) = requested_align { + natural_align.max(AbiAndPrefAlign::new(align)) + } else { + natural_align + }; + (Abi::Vector { element: e_abi, count: e_len }, align) }; let size = size.align_to(align.abi); @@ -536,7 +544,7 @@ fn layout_of_uncached<'tcx>( largest_niche: e_ly.largest_niche, size, align, - max_repr_align: None, + max_repr_align: requested_align, unadjusted_abi_align: align.abi, }) } diff --git a/tests/ui/simd/repr-align-and-simd.rs b/tests/ui/simd/repr-align-and-simd.rs new file mode 100644 index 0000000000000..a7d28a2aa534b --- /dev/null +++ b/tests/ui/simd/repr-align-and-simd.rs @@ -0,0 +1,19 @@ +//@ run-pass +// A regression test for https://github.com/rust-lang/rust/issues/130402 +// Our SIMD representation did not combine correctly with the repr(align) attribute, +// and this will remain a concern regardless of what we do with SIMD types. +#![feature(repr_simd)] +use std::mem::{size_of, align_of}; + +#[repr(simd, align(64))] +struct IntelsIdeaOfWhatAvx512Means([u8; 32]); + +#[repr(transparent)] +struct DesignValidation(IntelsIdeaOfWhatAvx512Means); + +fn main() { + assert_eq!(64, size_of::()); + assert_eq!(64, align_of::()); + assert_eq!(64, size_of::()); + assert_eq!(64, align_of::()); +}