diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -101,8 +101,42 @@ // that prefix labels. if (FD->hasAttr()) Name = getMangledName(D); - else - Name = Context.BuiltinInfo.getName(BuiltinID) + 10; + else { + // TODO: This mutation should also be applied to other targets other than + // PPC, after backend supports IEEE 128-bit style libcalls. + bool UseF128Name = + getTriple().isPPC64() && + &getTarget().getLongDoubleFormat() == &llvm::APFloat::IEEEquad(); + switch (BuiltinID) { + case Builtin::BIprintf: + case Builtin::BI__builtin_printf: + Name = UseF128Name ? "__printfieee128" : "printf"; + break; + case Builtin::BIvsnprintf: + case Builtin::BI__builtin_vsnprintf: + Name = UseF128Name ? "__vsnprintfieee128" : "vsnprintf"; + break; + case Builtin::BIvsprintf: + case Builtin::BI__builtin_vsprintf: + Name = UseF128Name ? "__vsprintfieee128" : "vsprintf"; + break; + case Builtin::BIsprintf: + case Builtin::BI__builtin_sprintf: + Name = UseF128Name ? "__sprintfieee128" : "sprintf"; + break; + case Builtin::BIsnprintf: + case Builtin::BI__builtin_snprintf: + Name = UseF128Name ? "__snprintfieee128" : "snprintf"; + break; + case Builtin::BIfprintf: + case Builtin::BI__builtin_fprintf: + Name = UseF128Name ? "__fprintfieee128" : "fprintf"; + break; + default: + Name = Context.BuiltinInfo.getName(BuiltinID) + 10; + break; + } + } llvm::FunctionType *Ty = cast(getTypes().ConvertType(FD->getType())); diff --git a/clang/test/CodeGen/ppc64-f128-builtins.c b/clang/test/CodeGen/ppc64-f128-builtins.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/ppc64-f128-builtins.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple powerpc64le-linux-gnu -emit-llvm -o - %s \ +// RUN: -mabi=ieeelongdouble | FileCheck --check-prefix=IEEE128 %s +// RUN: %clang_cc1 -triple powerpc64le-linux-gnu -emit-llvm -o - %s \ +// RUN: -mabi=ibmlongdouble | FileCheck --check-prefix=PPC128 %s + +long double x; + +void test_printf() { + __builtin_printf("%.Lf", x); +} + +void test_vsnprintf() { + char buf[20]; + __builtin_va_list va; + __builtin_vsnprintf(buf, 20, "%.Lf", va); +} + +void test_vsprintf() { + char buf[20]; + __builtin_va_list va; + __builtin_vsprintf(buf, "%.Lf", va); +} + +void test_sprintf() { + char buf[20]; + __builtin_sprintf(buf, "%.Lf", x); +} + +void test_snprintf() { + char buf[20]; + __builtin_snprintf(buf, 20, "%.Lf", x); +} + +void test_fprintf() { + FILE *fp; + __builtin_fprintf(fp, "%.Lf", x): +}