blob: 1921b8a9ddda94a7e94c2b96fc839a5eaf1d01a9 [file] [edit]
//@ add-minicore
//@ compile-flags: -Cno-prepopulate-passes -Copt-level=0
//
//@ revisions: linux eabi watchos
//@[linux] compile-flags: --target armv7-unknown-linux-gnueabihf
//@[eabi] compile-flags: --target armv7r-none-eabi
//@[watchos] compile-flags: --target armv7k-apple-watchos
//
//@ needs-llvm-components: arm
// Test that structs are passed with the correct register alignment.
#![feature(no_core, lang_items)]
#![crate_type = "lib"]
#![no_core]
extern crate minicore;
use minicore::*;
#[repr(C)]
pub struct Natural {
pub a: u32,
pub b: u32,
}
// linux: define void @test_natural([2 x i32] %0)
// eabi: define dso_local void @test_natural([2 x i32] %0)
// watchos: define void @test_natural([2 x i32] %0)
#[unsafe(no_mangle)]
pub extern "C" fn test_natural(a: Natural) {
hint::black_box(a);
}
#[repr(C)]
pub struct HasU64 {
pub a: u64,
}
// linux: define void @test_has_u64(i64 %0)
// eabi: define dso_local void @test_has_u64(i64 %0)
// watchos: define void @test_has_u64(i64 %0)
#[unsafe(no_mangle)]
pub extern "C" fn test_has_u64(a: HasU64) {
hint::black_box(a);
}
#[repr(C)]
#[repr(align(8))]
pub struct Align8 {
pub a: u32,
pub b: u32,
}
#[repr(transparent)]
pub struct Transparent8 {
a: Align8,
}
// Here watchOS deviates from the others. On linux and eabi, the natural alignment of the struct
// contents is used, and the alignment modifier of the struct is not considered for ABI purposes.
// watchOS does respect the alignment annotation for register allocation.
//
// linux: define void @test_8([2 x i32] %0, [2 x i32] %1)
// eabi: define dso_local void @test_8([2 x i32] %0, [2 x i32] %1)
// watchos: define void @test_8(i64 %0, i64 %1)
#[unsafe(no_mangle)]
pub extern "C" fn test_8(a: Align8, b: Transparent8) {
hint::black_box(a);
hint::black_box(b);
}
#[repr(C)]
#[repr(align(16))]
pub struct Align16 {
pub a: u32,
pub b: u32,
}
#[repr(transparent)]
pub struct Transparent16 {
a: Align16,
}
#[repr(C)]
pub struct Wrapped16 {
pub a: Align16,
}
// Wrapping resets the unadjusted alignment.
//
// linux: define void @test_16([4 x i32] %0, [4 x i32] %1, [2 x i64] %2)
// eabi: define dso_local void @test_16([4 x i32] %0, [4 x i32] %1, [2 x i64] %2)
// watchos: define void @test_16([2 x i64] %0, [2 x i64] %1, [2 x i64] %2)
#[unsafe(no_mangle)]
pub extern "C" fn test_16(a: Align16, b: Transparent16, c: Wrapped16) {
hint::black_box(a);
hint::black_box(b);
hint::black_box(c);
}
// Packing is different, the alignment is 1 across targets.
#[repr(C)]
#[repr(packed)]
pub struct Packed {
pub a: u8,
pub b: u64,
}
// linux: define void @test_packed([3 x i32] %0)
// eabi: define dso_local void @test_packed([3 x i32] %0)
// watchos: define void @test_packed([3 x i32] %0)
#[unsafe(no_mangle)]
pub extern "C" fn test_packed(a: Packed) {
hint::black_box(a);
}