294 lines · c
1// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi aapcs -emit-llvm -o - %s | FileCheck %s2// RUN: %clang_cc1 -triple armv7-apple-darwin -target-abi apcs-gnu -emit-llvm -o - %s | FileCheck -check-prefix=APCS-GNU %s3// RUN: %clang_cc1 -triple arm-linux-androideabi -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s4 5#include <stdarg.h>6 7typedef __attribute__(( ext_vector_type(2) )) int __int2;8typedef __attribute__(( ext_vector_type(3) )) char __char3;9typedef __attribute__(( ext_vector_type(5) )) char __char5;10typedef __attribute__(( ext_vector_type(9) )) char __char9;11typedef __attribute__(( ext_vector_type(19) )) char __char19;12typedef __attribute__(( ext_vector_type(3) )) short __short3;13typedef __attribute__(( ext_vector_type(5) )) short __short5;14 15// Passing legal vector types as varargs.16double varargs_vec_2i(int fixed, ...) {17// CHECK: varargs_vec_2i18// CHECK: [[VAR:%.*]] = alloca <2 x i32>, align 819// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)20// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 821// CHECK: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 822// CHECK: store <2 x i32> [[VEC]], ptr [[VAR]], align 823// APCS-GNU: varargs_vec_2i24// APCS-GNU: [[VAR:%.*]] = alloca <2 x i32>, align 825// APCS-GNU: [[AP:%.*]] = load ptr,26// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 827// APCS-GNU: [[VEC:%.*]] = load <2 x i32>, ptr [[AP]], align 428// APCS-GNU: store <2 x i32> [[VEC]], ptr [[VAR]], align 829// ANDROID: varargs_vec_2i30// ANDROID: [[VAR:%.*]] = alloca <2 x i32>, align 831// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)32// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 833// ANDROID: [[VEC:%.*]] = load <2 x i32>, ptr [[AP_ALIGN]], align 834// ANDROID: store <2 x i32> [[VEC]], ptr [[VAR]], align 835 va_list ap;36 double sum = fixed;37 va_start(ap, fixed);38 __int2 c3 = va_arg(ap, __int2);39 sum = sum + c3.x + c3.y;40 va_end(ap);41 return sum;42}43 44double test_2i(__int2 *in) {45// CHECK: test_2i46// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})47// APCS-GNU: test_2i48// APCS-GNU: call double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})49// ANDROID: test_2i50// ANDROID: call double (i32, ...) @varargs_vec_2i(i32 noundef 3, <2 x i32> noundef {{%.*}})51 return varargs_vec_2i(3, *in);52}53 54double varargs_vec_3c(int fixed, ...) {55// CHECK: varargs_vec_3c56// CHECK: alloca <3 x i8>, align 457// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 458// APCS-GNU: varargs_vec_3c59// APCS-GNU: alloca <3 x i8>, align 460// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 461// ANDROID: varargs_vec_3c62// ANDROID: alloca <3 x i8>, align 463// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 464 va_list ap;65 double sum = fixed;66 va_start(ap, fixed);67 __char3 c3 = va_arg(ap, __char3);68 sum = sum + c3.x + c3.y;69 va_end(ap);70 return sum;71}72 73double test_3c(__char3 *in) {74// CHECK: test_3c75// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3c(i32 noundef 3, i32 {{%.*}})76// APCS-GNU: test_3c77// APCS-GNU: call double (i32, ...) @varargs_vec_3c(i32 noundef 3, i32 {{%.*}})78// ANDROID: test_3c79// ANDROID: call double (i32, ...) @varargs_vec_3c(i32 noundef 3, <3 x i8> noundef {{%.*}})80 return varargs_vec_3c(3, *in);81}82 83double varargs_vec_5c(int fixed, ...) {84// CHECK: varargs_vec_5c85// CHECK: [[VAR:%.*]] = alloca <5 x i8>, align 886// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)87// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 888// CHECK: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 889// CHECK: store <5 x i8> [[VEC]], ptr [[VAR]], align 890// APCS-GNU: varargs_vec_5c91// APCS-GNU: [[VAR:%.*]] = alloca <5 x i8>, align 892// APCS-GNU: [[AP:%.*]] = load ptr,93// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 894// APCS-GNU: [[VEC:%.*]] = load <5 x i8>, ptr [[AP]], align 495// APCS-GNU: store <5 x i8> [[VEC]], ptr [[VAR]], align 896// ANDROID: varargs_vec_5c97// ANDROID: [[VAR:%.*]] = alloca <5 x i8>, align 898// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)99// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8100// ANDROID: [[VEC:%.*]] = load <5 x i8>, ptr [[AP_ALIGN]], align 8101// ANDROID: store <5 x i8> [[VEC]], ptr [[VAR]], align 8102 va_list ap;103 double sum = fixed;104 va_start(ap, fixed);105 __char5 c5 = va_arg(ap, __char5);106 sum = sum + c5.x + c5.y;107 va_end(ap);108 return sum;109}110 111double test_5c(__char5 *in) {112// CHECK: test_5c113// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})114// APCS-GNU: test_5c115// APCS-GNU: call double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})116// ANDROID: test_5c117// ANDROID: call double (i32, ...) @varargs_vec_5c(i32 noundef 5, <2 x i32> {{%.*}})118 return varargs_vec_5c(5, *in);119}120 121double varargs_vec_9c(int fixed, ...) {122// CHECK: varargs_vec_9c123// CHECK: [[VAR:%.*]] = alloca <9 x i8>, align 16124// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)125// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16126// CHECK: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8127// CHECK: store <9 x i8> [[T0]], ptr [[VAR]], align 16128// APCS-GNU: varargs_vec_9c129// APCS-GNU: [[VAR:%.*]] = alloca <9 x i8>, align 16130// APCS-GNU: [[AP:%.*]] = load ptr,131// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 16132// APCS-GNU: [[VEC:%.*]] = load <9 x i8>, ptr [[AP]], align 4133// APCS-GNU: store <9 x i8> [[VEC]], ptr [[VAR]], align 16134// ANDROID: varargs_vec_9c135// ANDROID: [[VAR:%.*]] = alloca <9 x i8>, align 16136// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)137// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16138// ANDROID: [[T0:%.*]] = load <9 x i8>, ptr [[AP_ALIGN]], align 8139// ANDROID: store <9 x i8> [[T0]], ptr [[VAR]], align 16140 va_list ap;141 double sum = fixed;142 va_start(ap, fixed);143 __char9 c9 = va_arg(ap, __char9);144 sum = sum + c9.x + c9.y;145 va_end(ap);146 return sum;147}148 149double test_9c(__char9 *in) {150// CHECK: test_9c151// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})152// APCS-GNU: test_9c153// APCS-GNU: call double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})154// ANDROID: test_9c155// ANDROID: call double (i32, ...) @varargs_vec_9c(i32 noundef 9, <4 x i32> {{%.*}})156 return varargs_vec_9c(9, *in);157}158 159double varargs_vec_19c(int fixed, ...) {160// CHECK: varargs_vec_19c161// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4162// CHECK: [[VAR2:%.*]] = load ptr, ptr [[AP]]163// APCS-GNU: varargs_vec_19c164// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4165// APCS-GNU: [[VAR2:%.*]] = load ptr, ptr [[AP]]166// ANDROID: varargs_vec_19c167// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP:%.*]], i32 4168// ANDROID: [[VAR2:%.*]] = load ptr, ptr [[AP]]169 va_list ap;170 double sum = fixed;171 va_start(ap, fixed);172 __char19 c19 = va_arg(ap, __char19);173 sum = sum + c19.x + c19.y;174 va_end(ap);175 return sum;176}177 178double test_19c(__char19 *in) {179// CHECK: test_19c180// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})181// APCS-GNU: test_19c182// APCS-GNU: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})183// ANDROID: test_19c184// ANDROID: call double (i32, ...) @varargs_vec_19c(i32 noundef 19, ptr dead_on_return noundef {{%.*}})185 return varargs_vec_19c(19, *in);186}187 188double varargs_vec_3s(int fixed, ...) {189// CHECK: varargs_vec_3s190// CHECK: alloca <3 x i16>, align 8191// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)192// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8193// APCS-GNU: varargs_vec_3s194// APCS-GNU: [[VAR:%.*]] = alloca <3 x i16>, align 8195// APCS-GNU: [[AP:%.*]] = load ptr,196// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 8197// APCS-GNU: [[VEC:%.*]] = load <4 x i16>, ptr [[AP]], align 4198// ANDROID: varargs_vec_3s199// ANDROID: alloca <3 x i16>, align 8200// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)201// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 8202 va_list ap;203 double sum = fixed;204 va_start(ap, fixed);205 __short3 c3 = va_arg(ap, __short3);206 sum = sum + c3.x + c3.y;207 va_end(ap);208 return sum;209}210 211double test_3s(__short3 *in) {212// CHECK: test_3s213// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_3s(i32 noundef 3, <2 x i32> {{%.*}})214// APCS-GNU: test_3s215// APCS-GNU: call double (i32, ...) @varargs_vec_3s(i32 noundef 3, <2 x i32> {{%.*}})216// ANDROID: test_3s217// ANDROID: call double (i32, ...) @varargs_vec_3s(i32 noundef 3, <3 x i16> noundef {{%.*}})218 return varargs_vec_3s(3, *in);219}220 221double varargs_vec_5s(int fixed, ...) {222// CHECK: varargs_vec_5s223// CHECK: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16224// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)225// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16226// CHECK: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8227// CHECK: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16228// APCS-GNU: varargs_vec_5s229// APCS-GNU: [[VAR:%.*]] = alloca <5 x i16>, align 16230// APCS-GNU: [[AP:%.*]] = load ptr,231// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP]], i32 16232// APCS-GNU: [[VEC:%.*]] = load <5 x i16>, ptr [[AP]], align 4233// ANDROID: varargs_vec_5s234// ANDROID: [[VAR_ALIGN:%.*]] = alloca <5 x i16>, align 16235// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)236// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16237// ANDROID: [[VEC:%.*]] = load <5 x i16>, ptr [[AP_ALIGN]], align 8238// ANDROID: store <5 x i16> [[VEC]], ptr [[VAR_ALIGN]], align 16239 va_list ap;240 double sum = fixed;241 va_start(ap, fixed);242 __short5 c5 = va_arg(ap, __short5);243 sum = sum + c5.x + c5.y;244 va_end(ap);245 return sum;246}247 248double test_5s(__short5 *in) {249// CHECK: test_5s250// CHECK: call arm_aapcscc double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})251// APCS-GNU: test_5s252// APCS-GNU: call double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})253// ANDROID: test_5s254// ANDROID: call double (i32, ...) @varargs_vec_5s(i32 noundef 5, <4 x i32> {{%.*}})255 return varargs_vec_5s(5, *in);256}257 258// Pass struct as varargs.259typedef struct260{261 __int2 i2;262 float f;263} StructWithVec;264 265double varargs_struct(int fixed, ...) {266// CHECK: varargs_struct267// CHECK: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)268// CHECK: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16269// APCS-GNU: varargs_struct270// APCS-GNU: [[VAR_ALIGN:%.*]] = alloca %struct.StructWithVec271// APCS-GNU: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i32 16272// APCS-GNU: call void @llvm.memcpy273// ANDROID: varargs_struct274// ANDROID: [[AP_ALIGN:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr {{%.*}}, i32 -8)275// ANDROID: [[AP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[AP_ALIGN]], i32 16276 va_list ap;277 double sum = fixed;278 va_start(ap, fixed);279 StructWithVec c3 = va_arg(ap, StructWithVec);280 sum = sum + c3.i2.x + c3.i2.y + c3.f;281 va_end(ap);282 return sum;283}284 285double test_struct(StructWithVec* d) {286// CHECK: test_struct287// CHECK: call arm_aapcscc double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})288// APCS-GNU: test_struct289// APCS-GNU: call double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})290// ANDROID: test_struct291// ANDROID: call double (i32, ...) @varargs_struct(i32 noundef 3, [2 x i64] {{%.*}})292 return varargs_struct(3, *d);293}294