1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-linux-android -emit-llvm -O -o - %s \
2*67e74705SXin Li // RUN: | FileCheck %s --check-prefix=ANDROID --check-prefix=CHECK
3*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -O -o - %s \
4*67e74705SXin Li // RUN: | FileCheck %s --check-prefix=GNU --check-prefix=CHECK
5*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64 -emit-llvm -O -o - %s \
6*67e74705SXin Li // RUN: | FileCheck %s --check-prefix=GNU --check-prefix=CHECK
7*67e74705SXin Li // NaCl is an example of a target for which long double is the same as double.
8*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-nacl -emit-llvm -O -o - %s \
9*67e74705SXin Li // RUN: | FileCheck %s --check-prefix=NACL --check-prefix=CHECK
10*67e74705SXin Li
11*67e74705SXin Li // Android uses fp128 for long double but other x86_64 targets use x86_fp80.
12*67e74705SXin Li
13*67e74705SXin Li long double dataLD = 1.0L;
14*67e74705SXin Li // ANDROID: @dataLD = local_unnamed_addr global fp128 0xL00000000000000003FFF000000000000, align 16
15*67e74705SXin Li // GNU: @dataLD = local_unnamed_addr global x86_fp80 0xK3FFF8000000000000000, align 16
16*67e74705SXin Li
17*67e74705SXin Li long double _Complex dataLDC = {1.0L, 1.0L};
18*67e74705SXin Li // ANDROID: @dataLDC = local_unnamed_addr global { fp128, fp128 } { fp128 0xL00000000000000003FFF000000000000, fp128 0xL00000000000000003FFF000000000000 }, align 16
19*67e74705SXin Li // GNU: @dataLDC = local_unnamed_addr global { x86_fp80, x86_fp80 } { x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 16
20*67e74705SXin Li
TestLD(long double x)21*67e74705SXin Li long double TestLD(long double x) {
22*67e74705SXin Li return x * x;
23*67e74705SXin Li // ANDROID: define fp128 @TestLD(fp128 %x)
24*67e74705SXin Li // GNU: define x86_fp80 @TestLD(x86_fp80 %x)
25*67e74705SXin Li // NACL: define double @TestLD(double %x)
26*67e74705SXin Li }
27*67e74705SXin Li
TestLDC(long double _Complex x)28*67e74705SXin Li long double _Complex TestLDC(long double _Complex x) {
29*67e74705SXin Li return x * x;
30*67e74705SXin Li // ANDROID: define void @TestLDC({ fp128, fp128 }* {{.*}}, { fp128, fp128 }* {{.*}} %x)
31*67e74705SXin Li // GNU: define { x86_fp80, x86_fp80 } @TestLDC({ x86_fp80, x86_fp80 }* {{.*}} %x)
32*67e74705SXin Li // NACL: define { double, double } @TestLDC(double %x{{.*}}, double %x{{.*}})
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li typedef __builtin_va_list va_list;
36*67e74705SXin Li
TestGetVarInt(va_list ap)37*67e74705SXin Li int TestGetVarInt(va_list ap) {
38*67e74705SXin Li return __builtin_va_arg(ap, int);
39*67e74705SXin Li // Since int can be passed in memory or register there are two branches.
40*67e74705SXin Li // CHECK: define i32 @TestGetVarInt(
41*67e74705SXin Li // CHECK: br label
42*67e74705SXin Li // CHECK: br label
43*67e74705SXin Li // CHECK: = phi
44*67e74705SXin Li // CHECK: ret i32
45*67e74705SXin Li }
46*67e74705SXin Li
TestGetVarDouble(va_list ap)47*67e74705SXin Li double TestGetVarDouble(va_list ap) {
48*67e74705SXin Li return __builtin_va_arg(ap, double);
49*67e74705SXin Li // Since double can be passed in memory or register there are two branches.
50*67e74705SXin Li // CHECK: define double @TestGetVarDouble(
51*67e74705SXin Li // CHECK: br label
52*67e74705SXin Li // CHECK: br label
53*67e74705SXin Li // CHECK: = phi
54*67e74705SXin Li // CHECK: ret double
55*67e74705SXin Li }
56*67e74705SXin Li
TestGetVarLD(va_list ap)57*67e74705SXin Li long double TestGetVarLD(va_list ap) {
58*67e74705SXin Li return __builtin_va_arg(ap, long double);
59*67e74705SXin Li // fp128 and double can be passed in memory or in register, but x86_fp80 is in
60*67e74705SXin Li // memory.
61*67e74705SXin Li // ANDROID: define fp128 @TestGetVarLD(
62*67e74705SXin Li // GNU: define x86_fp80 @TestGetVarLD(
63*67e74705SXin Li // NACL: define double @TestGetVarLD(
64*67e74705SXin Li // ANDROID: br label
65*67e74705SXin Li // ANDROID: br label
66*67e74705SXin Li // NACL: br
67*67e74705SXin Li // ANDROID: = phi
68*67e74705SXin Li // GNU-NOT: br
69*67e74705SXin Li // GNU-NOT: = phi
70*67e74705SXin Li // NACL: = phi
71*67e74705SXin Li // ANDROID: ret fp128
72*67e74705SXin Li // GNU: ret x86_fp80
73*67e74705SXin Li }
74*67e74705SXin Li
TestGetVarLDC(va_list ap)75*67e74705SXin Li long double _Complex TestGetVarLDC(va_list ap) {
76*67e74705SXin Li return __builtin_va_arg(ap, long double _Complex);
77*67e74705SXin Li // Pair of fp128 or x86_fp80 are passed as struct in memory.
78*67e74705SXin Li // ANDROID: define void @TestGetVarLDC({ fp128, fp128 }* {{.*}}, %struct.__va_list_tag*
79*67e74705SXin Li // GNU: define { x86_fp80, x86_fp80 } @TestGetVarLDC(
80*67e74705SXin Li // Pair of double can go in SSE registers or memory
81*67e74705SXin Li // NACL: define { double, double } @TestGetVarLDC(
82*67e74705SXin Li // ANDROID-NOT: br
83*67e74705SXin Li // GNU-NOT: br
84*67e74705SXin Li // NACL: br
85*67e74705SXin Li // ANDROID-NOT: phi
86*67e74705SXin Li // GNU-NOT: phi
87*67e74705SXin Li // NACL: phi
88*67e74705SXin Li // ANDROID: ret void
89*67e74705SXin Li // GNU: ret { x86_fp80, x86_fp80 }
90*67e74705SXin Li // NACL: ret { double, double }
91*67e74705SXin Li }
92*67e74705SXin Li
93*67e74705SXin Li void TestVarArg(const char *s, ...);
94*67e74705SXin Li
TestPassVarInt(int x)95*67e74705SXin Li void TestPassVarInt(int x) {
96*67e74705SXin Li TestVarArg("A", x);
97*67e74705SXin Li // CHECK: define void @TestPassVarInt(i32 %x)
98*67e74705SXin Li // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, i32 %x)
99*67e74705SXin Li }
100*67e74705SXin Li
TestPassVarFloat(float x)101*67e74705SXin Li void TestPassVarFloat(float x) {
102*67e74705SXin Li TestVarArg("A", x);
103*67e74705SXin Li // CHECK: define void @TestPassVarFloat(float %x)
104*67e74705SXin Li // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, double %
105*67e74705SXin Li }
106*67e74705SXin Li
TestPassVarDouble(double x)107*67e74705SXin Li void TestPassVarDouble(double x) {
108*67e74705SXin Li TestVarArg("A", x);
109*67e74705SXin Li // CHECK: define void @TestPassVarDouble(double %x)
110*67e74705SXin Li // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, double %x
111*67e74705SXin Li }
112*67e74705SXin Li
TestPassVarLD(long double x)113*67e74705SXin Li void TestPassVarLD(long double x) {
114*67e74705SXin Li TestVarArg("A", x);
115*67e74705SXin Li // ANDROID: define void @TestPassVarLD(fp128 %x)
116*67e74705SXin Li // ANDROID: call {{.*}} @TestVarArg(i8* {{.*}}, fp128 %x
117*67e74705SXin Li // GNU: define void @TestPassVarLD(x86_fp80 %x)
118*67e74705SXin Li // GNU: call {{.*}} @TestVarArg(i8* {{.*}}, x86_fp80 %x
119*67e74705SXin Li // NACL: define void @TestPassVarLD(double %x)
120*67e74705SXin Li // NACL: call {{.*}} @TestVarArg(i8* {{.*}}, double %x
121*67e74705SXin Li }
122*67e74705SXin Li
TestPassVarLDC(long double _Complex x)123*67e74705SXin Li void TestPassVarLDC(long double _Complex x) {
124*67e74705SXin Li TestVarArg("A", x);
125*67e74705SXin Li // ANDROID: define void @TestPassVarLDC({ fp128, fp128 }* {{.*}} %x)
126*67e74705SXin Li // ANDROID: store fp128 %{{.*}}, fp128* %
127*67e74705SXin Li // ANDROID-NEXT: store fp128 %{{.*}}, fp128* %
128*67e74705SXin Li // ANDROID-NEXT: call {{.*}} @TestVarArg(i8* {{.*}}, { fp128, fp128 }* {{.*}} %
129*67e74705SXin Li // GNU: define void @TestPassVarLDC({ x86_fp80, x86_fp80 }* {{.*}} %x)
130*67e74705SXin Li // GNU: store x86_fp80 %{{.*}}, x86_fp80* %
131*67e74705SXin Li // GNU-NEXT: store x86_fp80 %{{.*}}, x86_fp80* %
132*67e74705SXin Li // GNU-NEXT: call {{.*}} @TestVarArg(i8* {{.*}}, { x86_fp80, x86_fp80 }* {{.*}} %
133*67e74705SXin Li // NACL: define void @TestPassVarLDC(double %x{{.*}}, double %x{{.*}})
134*67e74705SXin Li // NACL: call {{.*}} @TestVarArg(i8* {{.*}}, double %x{{.*}}, double %x{{.*}})
135*67e74705SXin Li }
136