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