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 13 long 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 17 long 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 21 long 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 28 long 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 35 typedef __builtin_va_list va_list; 36 37 int 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 47 double 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 57 long 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 75 long 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 93 void TestVarArg(const char *s, ...); 94 95 void TestPassVarInt(int x) { 96 TestVarArg("A", x); 97 // CHECK: define void @TestPassVarInt(i32 %x) 98 // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, i32 %x) 99 } 100 101 void TestPassVarFloat(float x) { 102 TestVarArg("A", x); 103 // CHECK: define void @TestPassVarFloat(float %x) 104 // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, double % 105 } 106 107 void TestPassVarDouble(double x) { 108 TestVarArg("A", x); 109 // CHECK: define void @TestPassVarDouble(double %x) 110 // CHECK: call {{.*}} @TestVarArg(i8* {{.*}}, double %x 111 } 112 113 void 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 123 void 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