96 lines · c
1// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0 -target-abi aapcs16 -target-cpu cortex-a7 %s -o - -emit-llvm | FileCheck %s2 3// REQUIRES: aarch64-registered-target || arm-registered-target4 5#include <arm_neon.h>6 7// Make sure 64 and 128 bit types are naturally aligned by the v7k ABI:8 9// CHECK: target datalayout = "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"10 11typedef struct {12 float arr[4];13} HFA;14 15// CHECK: define{{.*}} void @simple_hfa([4 x float] %h.coerce)16void simple_hfa(HFA h) {}17 18// CHECK: define{{.*}} %struct.HFA @return_simple_hfa19HFA return_simple_hfa() { return (HFA){0}; }20 21typedef struct {22 double arr[4];23} BigHFA;24 25// We don't want any padding type to be included by Clang when using the26// APCS-VFP ABI, that needs to be handled by LLVM if needed.27 28// CHECK: void @no_padding(i32 noundef %r0, i32 noundef %r1, i32 noundef %r2, [4 x double] %d0_d3.coerce, [4 x double] %d4_d7.coerce, [4 x double] %sp.coerce, i64 noundef %split)29void no_padding(int r0, int r1, int r2, BigHFA d0_d3, BigHFA d4_d7, BigHFA sp,30 long long split) {}31 32// Structs larger than 16 bytes should be passed indirectly in space allocated33// by the caller (a pointer to this storage should be what occurs in the arg34// list).35 36typedef struct {37 float x;38 long long y;39 double z;40} BigStruct;41 42// CHECK: define{{.*}} void @big_struct_indirect(ptr dead_on_return noundef %b)43void big_struct_indirect(BigStruct b) {}44 45// CHECK: define{{.*}} void @return_big_struct_indirect(ptr dead_on_unwind noalias writable sret46BigStruct return_big_struct_indirect() { return (BigStruct){0}; }47 48// Structs smaller than 16 bytes should be passed directly, and coerced to49// either [N x i32] or [N x i64] depending on alignment requirements.50 51typedef struct {52 float x;53 int y;54 double z;55} SmallStruct;56 57// CHECK: define{{.*}} void @small_struct_direct([2 x i64] %s.coerce)58void small_struct_direct(SmallStruct s) {}59 60// CHECK: define{{.*}} [4 x i32] @return_small_struct_direct()61SmallStruct return_small_struct_direct() { return (SmallStruct){0}; }62 63typedef struct {64 float x;65 int y;66 int z;67} SmallStructSmallAlign;68 69// CHECK: define{{.*}} void @small_struct_align_direct([3 x i32] %s.coerce)70void small_struct_align_direct(SmallStructSmallAlign s) {}71 72typedef struct {73 char x;74 short y;75} PaddedSmallStruct;76 77// CHECK: define{{.*}} i32 @return_padded_small_struct()78PaddedSmallStruct return_padded_small_struct() { return (PaddedSmallStruct){0}; }79 80typedef struct {81 char arr[7];82} OddlySizedStruct;83 84// CHECK: define{{.*}} [2 x i32] @return_oddly_sized_struct()85OddlySizedStruct return_oddly_sized_struct() { return (OddlySizedStruct){0}; }86 87// CHECK: define{{.*}} <4 x float> @test_va_arg_vec(ptr noundef %l)88 89 90// CHECK: [[GEP_ALIGN:%.+]] = getelementptr inbounds i8, ptr {{%.*}}, i32 1591// CHECK: [[ALIGNED:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[GEP_ALIGN]], i32 -16)92// CHECK: load <4 x float>, ptr [[ALIGNED]], align 1693float32x4_t test_va_arg_vec(__builtin_va_list l) {94 return __builtin_va_arg(l, float32x4_t);95}96