Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,19 +1498,21 @@ where
// Compute the size and alignment of the vector
let size =
elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?;
let (repr, align) = match kind {
let (repr, size, align) = match kind {
SimdVectorKind::Scalable(number_of_vectors) => (
BackendRepr::SimdScalableVector { element, count, number_of_vectors },
size.checked_mul(number_of_vectors.0 as u64, dl)
.ok_or_else(|| LayoutCalculatorError::SizeOverflow)?,
dl.llvmlike_vector_align(size),
),
// 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
// to a vector as possible.
SimdVectorKind::PackedFixed if !count.is_power_of_two() => {
(BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size))
(BackendRepr::Memory { sized: true }, size, Align::max_aligned_factor(size))
}
SimdVectorKind::PackedFixed | SimdVectorKind::Fixed => {
(BackendRepr::SimdVector { element, count }, dl.llvmlike_vector_align(size))
(BackendRepr::SimdVector { element, count }, size, dl.llvmlike_vector_align(size))
}
};
let size = size.align_to(align);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {

if arg_idx.is_none()
&& arg.layout.size > Primitive::Pointer(AddressSpace::ZERO).size(cx) * 2
&& !matches!(arg.layout.backend_repr, BackendRepr::SimdVector { .. })
&& !matches!(
arg.layout.backend_repr,
BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. }
)
{
// Return values larger than 2 registers using a return area
// pointer. LLVM and Cranelift disagree about how to return
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/scalable-vectors/layout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//@ only-aarch64
#![feature(rustc_attrs)]
#![crate_type = "lib"]

// Tests that the computed layout size of scalable vectors is equal to
// `element size * element count * number of vectors`. Scalable vectors are of course scalable and
// so do not have a fixed size, but using this size with things like `llvm.memcpy` produces the
// correct and expected results.

#[rustc_dump_layout(size)]
#[rustc_scalable_vector(4)]
struct ScalableFloat(f32); //~ ERROR: size: Size(16 bytes)

#[rustc_dump_layout(size)]
#[rustc_scalable_vector(8)]
struct ScalableU8WithFewerCount(u8); //~ ERROR: size: Size(8 bytes)

#[rustc_dump_layout(size)]
#[rustc_scalable_vector(16)]
struct ScalableU8(u8); //~ ERROR: size: Size(16 bytes)

#[rustc_dump_layout(size)]
#[rustc_scalable_vector(16)]
struct ScalableBool(bool); //~ ERROR: size: Size(16 bytes)

#[rustc_dump_layout(size)]
#[rustc_scalable_vector]
struct ScalableTuple(ScalableU8, ScalableU8, ScalableU8); //~ ERROR: size: Size(48 bytes)
32 changes: 32 additions & 0 deletions tests/ui/scalable-vectors/layout.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error: size: Size(16 bytes)
--> $DIR/layout.rs:12:1
|
LL | struct ScalableFloat(f32);
| ^^^^^^^^^^^^^^^^^^^^

error: size: Size(8 bytes)
--> $DIR/layout.rs:16:1
|
LL | struct ScalableU8WithFewerCount(u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: size: Size(16 bytes)
--> $DIR/layout.rs:20:1
|
LL | struct ScalableU8(u8);
| ^^^^^^^^^^^^^^^^^

error: size: Size(16 bytes)
--> $DIR/layout.rs:24:1
|
LL | struct ScalableBool(bool);
| ^^^^^^^^^^^^^^^^^^^

error: size: Size(48 bytes)
--> $DIR/layout.rs:28:1
|
LL | struct ScalableTuple(ScalableU8, ScalableU8, ScalableU8);
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

Loading