120 lines · c
1// RUN: %clang_cc1 -triple x86_64-linux-android -emit-llvm -O -o - %s \2// RUN: | FileCheck %s --check-prefix=ANDROID --check-prefix=CHECK3// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -O -o - %s \4// RUN: | FileCheck %s --check-prefix=GNU --check-prefix=CHECK5// RUN: %clang_cc1 -triple x86_64 -emit-llvm -O -o - %s \6// RUN: | FileCheck %s --check-prefix=GNU --check-prefix=CHECK7 8// Android uses fp128 for long double but other x86_64 targets use x86_fp80.9 10long double dataLD = 1.0L;11// ANDROID: @dataLD ={{.*}} local_unnamed_addr global fp128 0xL00000000000000003FFF000000000000, align 1612// GNU: @dataLD ={{.*}} local_unnamed_addr global x86_fp80 0xK3FFF8000000000000000, align 1613 14long double _Complex dataLDC = {1.0L, 1.0L};15// ANDROID: @dataLDC ={{.*}} local_unnamed_addr global { fp128, fp128 } { fp128 0xL00000000000000003FFF000000000000, fp128 0xL00000000000000003FFF000000000000 }, align 1616// GNU: @dataLDC ={{.*}} local_unnamed_addr global { x86_fp80, x86_fp80 } { x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 1617 18long double TestLD(long double x) {19 return x * x;20// ANDROID: define{{.*}} fp128 @TestLD(fp128 noundef %x)21// GNU: define{{.*}} x86_fp80 @TestLD(x86_fp80 noundef %x)22}23 24long double _Complex TestLDC(long double _Complex x) {25 return x * x;26// ANDROID: define{{.*}} void @TestLDC(ptr {{.*}}, ptr {{.*}} %x)27// GNU: define{{.*}} { x86_fp80, x86_fp80 } @TestLDC(ptr {{.*}} %x)28}29 30typedef __builtin_va_list va_list;31 32int TestGetVarInt(va_list ap) {33 return __builtin_va_arg(ap, int);34// Since int can be passed in memory or register there are two branches.35// CHECK: define{{.*}} i32 @TestGetVarInt(36// CHECK: br label37// CHECK: br label38// CHECK: = phi39// CHECK: ret i3240}41 42double TestGetVarDouble(va_list ap) {43 return __builtin_va_arg(ap, double);44// Since double can be passed in memory or register there are two branches.45// CHECK: define{{.*}} double @TestGetVarDouble(46// CHECK: br label47// CHECK: br label48// CHECK: = phi49// CHECK: ret double50}51 52long double TestGetVarLD(va_list ap) {53 return __builtin_va_arg(ap, long double);54// fp128 and double can be passed in memory or in register, but x86_fp80 is in55// memory.56// ANDROID: define{{.*}} fp128 @TestGetVarLD(57// GNU: define{{.*}} x86_fp80 @TestGetVarLD(58// ANDROID: br label59// ANDROID: br label60// ANDROID: = phi61// GNU-NOT: br62// GNU-NOT: = phi63// ANDROID: ret fp12864// GNU: ret x86_fp8065}66 67long double _Complex TestGetVarLDC(va_list ap) {68 return __builtin_va_arg(ap, long double _Complex);69// Pair of fp128 or x86_fp80 are passed as struct in memory.70// ANDROID: define{{.*}} void @TestGetVarLDC(ptr {{.*}}, ptr71// GNU: define{{.*}} { x86_fp80, x86_fp80 } @TestGetVarLDC(72// Pair of double can go in SSE registers or memory73// ANDROID-NOT: br74// GNU-NOT: br75// ANDROID-NOT: phi76// GNU-NOT: phi77// ANDROID: ret void78// GNU: ret { x86_fp80, x86_fp80 }79}80 81void TestVarArg(const char *s, ...);82 83void TestPassVarInt(int x) {84 TestVarArg("A", x);85// CHECK: define{{.*}} void @TestPassVarInt(i32 noundef %x)86// CHECK: call {{.*}} @TestVarArg(ptr {{.*}}, i32 noundef %x)87}88 89void TestPassVarFloat(float x) {90 TestVarArg("A", x);91// CHECK: define{{.*}} void @TestPassVarFloat(float noundef %x)92// CHECK: call {{.*}} @TestVarArg(ptr {{.*}}, double noundef %93}94 95void TestPassVarDouble(double x) {96 TestVarArg("A", x);97// CHECK: define{{.*}} void @TestPassVarDouble(double noundef %x)98// CHECK: call {{.*}} @TestVarArg(ptr {{.*}}, double noundef %x99}100 101void TestPassVarLD(long double x) {102 TestVarArg("A", x);103// ANDROID: define{{.*}} void @TestPassVarLD(fp128 noundef %x)104// ANDROID: call {{.*}} @TestVarArg(ptr {{.*}}, fp128 noundef %x105// GNU: define{{.*}} void @TestPassVarLD(x86_fp80 noundef %x)106// GNU: call {{.*}} @TestVarArg(ptr {{.*}}, x86_fp80 noundef %x107}108 109void TestPassVarLDC(long double _Complex x) {110 TestVarArg("A", x);111// ANDROID: define{{.*}} void @TestPassVarLDC(ptr {{.*}} %x)112// ANDROID: store fp128 %{{.*}}, ptr %113// ANDROID-NEXT: store fp128 %{{.*}}, ptr %114// ANDROID-NEXT: call {{.*}} @TestVarArg(ptr {{.*}}, ptr {{.*}} %115// GNU: define{{.*}} void @TestPassVarLDC(ptr {{.*}} %x)116// GNU: store x86_fp80 %{{.*}}, ptr %117// GNU-NEXT: store x86_fp80 %{{.*}}, ptr %118// GNU-NEXT: call {{.*}} @TestVarArg(ptr {{.*}}, ptr {{.*}} %119}120