summaryrefslogtreecommitdiffstats
path: root/tests/codegen/aarch64-struct-align-128.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
commit023939b627b7dc93b01471f7d41fb8553ddb4ffa (patch)
tree60fc59477c605c72b0a1051409062ddecc43f877 /tests/codegen/aarch64-struct-align-128.rs
parentAdding debian version 1.72.1+dfsg1-1. (diff)
downloadrustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.tar.xz
rustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/codegen/aarch64-struct-align-128.rs')
-rw-r--r--tests/codegen/aarch64-struct-align-128.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/tests/codegen/aarch64-struct-align-128.rs b/tests/codegen/aarch64-struct-align-128.rs
new file mode 100644
index 000000000..bf3471778
--- /dev/null
+++ b/tests/codegen/aarch64-struct-align-128.rs
@@ -0,0 +1,150 @@
+// Test that structs aligned to 128 bits are passed with the correct ABI on aarch64.
+
+// revisions:linux darwin windows
+//[linux] compile-flags: --target aarch64-unknown-linux-gnu
+//[darwin] compile-flags: --target aarch64-apple-darwin
+//[windows] compile-flags: --target aarch64-pc-windows-msvc
+//[linux] needs-llvm-components: aarch64
+//[darwin] needs-llvm-components: aarch64
+//[windows] needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+
+
+// Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits.
+#[repr(C)]
+pub struct Align8 {
+ pub a: u64,
+ pub b: u64,
+}
+
+// repr(transparent), so same as above.
+#[repr(transparent)]
+pub struct Transparent8 {
+ a: Align8
+}
+
+// Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits.
+#[repr(C)]
+pub struct Wrapped8 {
+ a: Align8,
+}
+
+extern "C" {
+ // linux: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
+ // darwin: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
+ // windows: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
+ fn test_8(a: Align8, b: Transparent8, c: Wrapped8);
+}
+
+
+
+// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
+// EXCEPT on Linux, where there's a special case to use its unadjusted alignment,
+// making it the same as `Align8`, so it's be passed as `[i64 x 2]`.
+#[repr(C)]
+#[repr(align(16))]
+pub struct Align16 {
+ pub a: u64,
+ pub b: u64,
+}
+
+// repr(transparent), so same as above.
+#[repr(transparent)]
+pub struct Transparent16 {
+ a: Align16
+}
+
+// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
+// On Linux, the "unadjustedness" doesn't recurse into fields, so this is passed as `i128`.
+#[repr(C)]
+pub struct Wrapped16 {
+ pub a: Align16,
+}
+
+extern "C" {
+ // linux: declare void @test_16([2 x i64], [2 x i64], i128)
+ // darwin: declare void @test_16(i128, i128, i128)
+ // windows: declare void @test_16(i128, i128, i128)
+ fn test_16(a: Align16, b: Transparent16, c: Wrapped16);
+}
+
+
+
+// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
+#[repr(C)]
+pub struct I128 {
+ pub a: i128,
+}
+
+// repr(transparent), so same as above.
+#[repr(transparent)]
+pub struct TransparentI128 {
+ a: I128
+}
+
+// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits.
+#[repr(C)]
+pub struct WrappedI128 {
+ pub a: I128
+}
+
+extern "C" {
+ // linux: declare void @test_i128(i128, i128, i128)
+ // darwin: declare void @test_i128(i128, i128, i128)
+ // windows: declare void @test_i128(i128, i128, i128)
+ fn test_i128(a: I128, b: TransparentI128, c: WrappedI128);
+}
+
+
+
+// Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits.
+// Note that the Linux special case does not apply, because packing is not considered "adjustment".
+#[repr(C)]
+#[repr(packed)]
+pub struct Packed {
+ pub a: i128,
+}
+
+// repr(transparent), so same as above.
+#[repr(transparent)]
+pub struct TransparentPacked {
+ a: Packed
+}
+
+// Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits.
+#[repr(C)]
+pub struct WrappedPacked {
+ pub a: Packed
+}
+
+extern "C" {
+ // linux: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
+ // darwin: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
+ // windows: declare void @test_packed([2 x i64], [2 x i64], [2 x i64])
+ fn test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked);
+}
+
+
+
+pub unsafe fn main(
+ a1: Align8, a2: Transparent8, a3: Wrapped8,
+ b1: Align16, b2: Transparent16, b3: Wrapped16,
+ c1: I128, c2: TransparentI128, c3: WrappedI128,
+ d1: Packed, d2: TransparentPacked, d3: WrappedPacked,
+) {
+ test_8(a1, a2, a3);
+ test_16(b1, b2, b3);
+ test_i128(c1, c2, c3);
+ test_packed(d1, d2, d3);
+}