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