https://github.com/tgross35 updated https://github.com/llvm/llvm-project/pull/76558
>From 31405591b5661156348ec7a45e66eb43e0ace15b Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Fri, 11 Aug 2023 22:16:01 -0400 Subject: [PATCH 1/6] [IR] Add a test for `f128` libcall lowering (nfc) `f128` intrinsic functions sometimes lower to `long double` library calls when they instead need to be `f128` versions. Add a test demonstrating current behavior. --- .../CodeGen/Generic/f128-math-lowering.ll | 328 ++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 llvm/test/CodeGen/Generic/f128-math-lowering.ll diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll b/llvm/test/CodeGen/Generic/f128-math-lowering.ll new file mode 100644 index 0000000000000..dfbd1eaeda109 --- /dev/null +++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll @@ -0,0 +1,328 @@ +; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-S390X +; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD +; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; +; REQUIRES: aarch64-registered-target +; REQUIRES: riscv-registered-target +; REQUIRES: systemz-registered-target +; REQUIRES: x86-registered-target +; +; Verify that fp128 intrinsics only lower to `long double` calls (e.g. `sinl`) +; on platforms where `f128` and `long double` have the same layout, and +; otherwise lower to `f128` versions (e.g. `sinf128`). +; +; Targets include: +; * x86, x64 (80-bit long double) +; * aarch64 (long double == f128) +; * riscv32 (long double == f64) +; * s390x (long double == f128, hardware support) +; * A couple assorted environments for x86 +; +; FIXME: only targets where long double is `f128` should be using `USELD`, all +; others need to be NOTLD. PowerPC should be added but it currently emits an +; interesting blend of both (e.g. `acosl` but `ceilf128`). + +define fp128 @test_acosf128(fp128 %a) { +; CHECK-LABEL: test_acosf128: +; CHECK-NOTLD: acosf128 +; CHECK-USELD: acosl +; CHECK-S390X: acosl +start: + %0 = tail call fp128 @llvm.acos.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_asinf128(fp128 %a) { +; CHECK-LABEL: test_asinf128: +; CHECK-NOTLD: asinf128 +; CHECK-USELD: asinl +; CHECK-S390X: asinl +start: + %0 = tail call fp128 @llvm.asin.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_atanf128(fp128 %a) { +; CHECK-LABEL: test_atanf128: +; CHECK-NOTLD: atanf128 +; CHECK-USELD: atanl +; CHECK-S390X: atanl +start: + %0 = tail call fp128 @llvm.atan.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_ceilf128(fp128 %a) { +; CHECK-LABEL: test_ceilf128: +; CHECK-NOTLD: ceilf128 +; CHECK-USELD: ceill +; CHECK-S390X: ceill +start: + %0 = tail call fp128 @llvm.ceil.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_copysignf128(fp128 %a, fp128 %b) { +; copysign should always get lowered to assembly +; CHECK-LABEL: test_copysignf128: +; CHECK-NOT: copysignl +; CHECK-NOT: copysignf128 +start: + %0 = tail call fp128 @llvm.copysign.f128(fp128 %a, fp128 %b) + ret fp128 %0 +} + +define fp128 @test_cosf128(fp128 %a) { +; CHECK-LABEL: test_cosf128: +; CHECK-NOTLD: cosf128 +; CHECK-USELD: cosl +; CHECK-S390X: cosl +start: + %0 = tail call fp128 @llvm.cos.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_exp10f128(fp128 %a) { +; CHECK-LABEL: test_exp2f128: +; CHECK-NOTLD: exp10f128 +; CHECK-USELD: exp10l +; CHECK-S390X: exp10l +start: + %0 = tail call fp128 @llvm.exp10.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_exp2f128(fp128 %a) { +; CHECK-LABEL: test_exp2f128: +; CHECK-NOTLD: exp2f128 +; CHECK-USELD: exp2l +; CHECK-S390X: exp2l +start: + %0 = tail call fp128 @llvm.exp2.f128(fp128 %a) + ret fp128 %0 +} + + +define fp128 @test_expf128(fp128 %a) { +; CHECK-LABEL: test_expf128: +; CHECK-NOTLD: expf128 +; CHECK-USELD: expl +; CHECK-S390X: expl +start: + %0 = tail call fp128 @llvm.exp.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_fabsf128(fp128 %a) { +; fabs should always get lowered to assembly +; CHECK-LABEL: test_fabsf128: +; CHECK-NOT: fabsl +; CHECK-NOT: fabsf128 +start: + %0 = tail call fp128 @llvm.fabs.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_floorf128(fp128 %a) { +; CHECK-LABEL: test_floorf128: +; CHECK-NOTLD: floorf128 +; CHECK-USELD: floorl +; CHECK-S390X: floorl +start: + %0 = tail call fp128 @llvm.floor.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_fmaf128(fp128 %a, fp128 %b, fp128 %c) { +; CHECK-LABEL: test_fmaf128: +; CHECK-NOTLD: fmaf128 +; CHECK-USELD: fmal +; CHECK-S390X: fmal +start: + %0 = tail call fp128 @llvm.fma.f128(fp128 %a, fp128 %b, fp128 %c) + ret fp128 %0 +} + +define { fp128, i32 } @test_frexpf128(fp128 %a) { +; CHECK-LABEL: test_frexpf128: +; CHECK-NOTLD: frexpf128 +; CHECK-USELD: frexpl +; CHECK-S390X: frexpl +start: + %0 = tail call { fp128, i32 } @llvm.frexp.f128(fp128 %a) + ret { fp128, i32 } %0 +} + +define fp128 @test_ldexpf128(fp128 %a, i32 %b) { +; CHECK-LABEL: test_ldexpf128: +; CHECK-NOTLD: ldexpf128 +; CHECK-USELD: ldexpl +; CHECK-S390X: ldexpl +start: + %0 = tail call fp128 @llvm.ldexp.f128(fp128 %a, i32 %b) + ret fp128 %0 +} + +define i64 @test_llrintf128(fp128 %a) { +; CHECK-LABEL: test_llrintf128: +; CHECK-NOTLD: llrintf128 +; CHECK-USELD: llrintl +; CHECK-S390X: llrintl +start: + %0 = tail call i64 @llvm.llrint.f128(fp128 %a) + ret i64 %0 +} + +define i64 @test_llroundf128(fp128 %a) { +; CHECK-LABEL: test_llroundf128: +; CHECK-NOTLD: llroundf128 +; CHECK-USELD: llroundl +; CHECK-S390X: llroundl +start: + %0 = tail call i64 @llvm.llround.i64.f128(fp128 %a) + ret i64 %0 +} + +define fp128 @test_log10f128(fp128 %a) { +; CHECK-LABEL: test_log10f128: +; CHECK-NOTLD: log10f128 +; CHECK-USELD: log10l +; CHECK-S390X: log10l +start: + %0 = tail call fp128 @llvm.log10.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_log2f128(fp128 %a) { +; CHECK-LABEL: test_log2f128: +; CHECK-NOTLD: log2f128 +; CHECK-USELD: log2l +; CHECK-S390X: log2l +start: + %0 = tail call fp128 @llvm.log2.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_logf128(fp128 %a) { +; CHECK-LABEL: test_logf128: +; CHECK-NOTLD: logf128 +; CHECK-USELD: logl +; CHECK-S390X: logl +start: + %0 = tail call fp128 @llvm.log.f128(fp128 %a) + ret fp128 %0 +} + +define i64 @test_lrintf128(fp128 %a) { +; CHECK-LABEL: test_exp2f128: +; CHECK-NOTLD: lrintf128 +; CHECK-USELD: lrintl +; CHECK-S390X: lrintl +start: + %0 = tail call i64 @llvm.lrint.f128(fp128 %a) + ret i64 %0 +} + +define i64 @test_lroundf128(fp128 %a) { +; CHECK-LABEL: test_lroundf128: +; CHECK-NOTLD: lroundf128 +; CHECK-USELD: lroundl +; CHECK-S390X: lroundl +start: + %0 = tail call i64 @llvm.lround.i64.f128(fp128 %a) + ret i64 %0 +} + +define fp128 @test_nearbyintf128(fp128 %a) { +; CHECK-LABEL: test_nearbyintf128: +; CHECK-NOTLD: nearbyintf128 +; CHECK-USELD: nearbyintl +; CHECK-S390X: nearbyintl +start: + %0 = tail call fp128 @llvm.nearbyint.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_powf128(fp128 %a, fp128 %b) { +; CHECK-LABEL: test_powf128: +; CHECK-NOTLD: powf128 +; CHECK-USELD: powl +; CHECK-S390X: powl +start: + %0 = tail call fp128 @llvm.pow.f128(fp128 %a, fp128 %b) + ret fp128 %0 +} + +define fp128 @test_rintf128(fp128 %a) { +; CHECK-LABEL: test_rintf128: +; CHECK-NOTLD: rintf128 +; CHECK-USELD: rintl +; CHECK-S390X: fixbr {{%.*}}, 0, {{%.*}} +start: + %0 = tail call fp128 @llvm.rint.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_roundevenf128(fp128 %a) { +; CHECK-LABEL: test_roundevenf128: +; CHECK-NOTLD: roundevenf128 +; CHECK-USELD: roundevenl +; CHECK-S390X: roundevenl +start: + %0 = tail call fp128 @llvm.roundeven.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_roundf128(fp128 %a) { +; CHECK-LABEL: test_roundf128: +; CHECK-NOTLD: roundf128 +; CHECK-USELD: roundl +; CHECK-S390X: roundl +start: + %0 = tail call fp128 @llvm.round.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_sinf128(fp128 %a) { +; CHECK-LABEL: test_sinf128: +; CHECK-NOTLD: sinf128 +; CHECK-USELD: sinl +; CHECK-S390X: sinl +start: + %0 = tail call fp128 @llvm.sin.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_sqrtf128(fp128 %a) { +; CHECK-LABEL: test_sqrtf128: +; CHECK-NOTLD: sqrtf128 +; CHECK-USELD: sqrtl +; CHECK-S390X: sqxbr {{%.*}}, {{%.*}} +start: + %0 = tail call fp128 @llvm.sqrt.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_tanf128(fp128 %a) { +; CHECK-LABEL: test_tanf128: +; CHECK-NOTLD: tanf128 +; CHECK-USELD: tanl +; CHECK-S390X: tanl +start: + %0 = tail call fp128 @llvm.tan.f128(fp128 %a) + ret fp128 %0 +} + +define fp128 @test_truncf128(fp128 %a) { +; CHECK-LABEL: test_truncf128: +; CHECK-NOTLD: truncf128 +; CHECK-USELD: truncl +; CHECK-S390X: truncl +start: + %0 = tail call fp128 @llvm.trunc.f128(fp128 %a) + ret fp128 %0 +} >From 6843a6f55901b65b3994f7a26596eb9e00bf0331 Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Thu, 27 Feb 2025 07:34:36 +0000 Subject: [PATCH 2/6] [llvm][clang] duplicate `long double` layout logic from clang to LLVM Information about the size and alignment of `long double` is currently part of clang. Copy this logic to LLVM so it can be used to control lowering of intrinsics. Additionally, add an assertion to make sure Clang and LLVM agree. --- clang/include/clang/Basic/TargetInfo.h | 4 + clang/lib/Basic/TargetInfo.cpp | 18 +++ clang/lib/Basic/Targets.cpp | 15 +- llvm/include/llvm/TargetParser/Triple.h | 17 ++ llvm/lib/TargetParser/Triple.cpp | 198 ++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index db23afa6d6f0b..84eecbcb19e0c 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1274,6 +1274,10 @@ class TargetInfo : public TransferrableTargetInfo, return Triple; } + /// Assert that layouts for C types computed by Clang are the same as layouts + /// stored in the LLVM target. + void validateCLayouts() const; + /// Returns the target ID if supported. virtual std::optional<std::string> getTargetID() const { return std::nullopt; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 0699ec686e4e6..5f3d0b73b67c5 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -959,6 +959,24 @@ bool TargetInfo::validatePointerAuthKey(const llvm::APSInt &value) const { return false; } +void TargetInfo::validateCLayouts() const { + llvm::Triple::CLayouts TripleLayouts = Triple.getCLayouts(getABI()); + if (__builtin_expect(LongDoubleWidth != TripleLayouts.LongDoubleWidth || + LongDoubleAlign != TripleLayouts.LongDoubleAlign || + LongDoubleFormat != TripleLayouts.LongDoubleFormat, + 0)) { + fprintf(stderr, "Clang's 'long double' width is %d, LLVM expected %d\n", + LongDoubleWidth, TripleLayouts.LongDoubleWidth); + fprintf(stderr, "Clang's long double' alignment is %d, LLVM expected %d\n", + LongDoubleAlign, TripleLayouts.LongDoubleAlign); + fprintf( + stderr, "Clang's long double' format is %d, LLVM expected %d\n", + llvm::APFloatBase::SemanticsToEnum(*LongDoubleFormat), + llvm::APFloatBase::SemanticsToEnum(*TripleLayouts.LongDoubleFormat)); + llvm_unreachable("Clang & LLVM layout mismatch"); + } +} + void TargetInfo::CheckFixedPointBits() const { // Check that the number of fractional and integral bits (and maybe sign) can // fit into the bits given for a fixed point type. diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 281aebdb1c35d..b3d455bd9e9c1 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -109,14 +109,15 @@ void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) { // Driver code //===----------------------------------------------------------------------===// -std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, - const TargetOptions &Opts) { +static std::unique_ptr<TargetInfo> AllocateTargetImpl(const llvm::Triple &Triple, + const TargetOptions &Opts) { llvm::Triple::OSType os = Triple.getOS(); switch (Triple.getArch()) { default: return nullptr; + // Keep this in sync with llvm Triple.cpp getCLayouts case llvm::Triple::arc: return std::make_unique<ARCTargetInfo>(Triple, Opts); @@ -762,6 +763,16 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, return std::make_unique<XtensaTargetInfo>(Triple, Opts); } } + +std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, + const TargetOptions &Opts) { + // Configure Clang's target and check the result against LLVM's target. + std::unique_ptr<TargetInfo> target = AllocateTargetImpl(Triple, Opts); + if (target != nullptr) { + target->validateCLayouts(); + } + return target; +} } // namespace targets } // namespace clang diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index 09c0d223d9b4d..fdf77d0004376 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -9,6 +9,7 @@ #ifndef LLVM_TARGETPARSER_TRIPLE_H #define LLVM_TARGETPARSER_TRIPLE_H +#include "llvm/ADT/APFloat.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/VersionTuple.h" @@ -1268,6 +1269,22 @@ class Triple { /// Returns a canonicalized OS version number for the specified OS. static VersionTuple getCanonicalVersionForOS(OSType OSKind, const VersionTuple &Version); + + /// Layouts for C types that are relevant to libc calls generated by LLVM + struct CLayouts { + unsigned LongDoubleWidth; + unsigned LongDoubleAlign; + const fltSemantics *LongDoubleFormat; + }; + + /// Provide default layouts relevant to C. Frontends may override these + /// values. + CLayouts getCLayouts(const StringRef &ABIName) const; + + /// Return true if `long double` and `_Float128` have the same layout. + bool isLongDoubleF128(const StringRef &ABIName) const { + return getCLayouts(ABIName).LongDoubleWidth == 128; + } }; } // End llvm namespace diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index e9e6f130f757c..c83384c8d2bcf 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -2164,6 +2164,204 @@ VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind, } } +Triple::CLayouts Triple::getCLayouts(const StringRef &ABIName) const { + Triple::CLayouts Layouts; + + // Default to a 32-bit RISC platform + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + + enum ArchType Arch = getArch(); + + // Keep this in sync with clang Targets.cpp AllocateTargetImpl + if (Arch == arc) { + Layouts.LongDoubleAlign = 32; + } else if (Arch == xcore) { + Layouts.LongDoubleAlign = 32; + } else if (Arch == hexagon) { + // default configuration + } else if (Arch == lanai) { + // default configuration + } else if (Arch == aarch64_32 || Arch == aarch64) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + + if (isOSWindows()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOSDarwin()) { + Layouts.LongDoubleWidth = Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } else if (Arch == arm || Arch == thumb || Arch == armeb || Arch == thumbeb) { + if (isOSNaCl()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOSWindows()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } else if (Arch == avr) { + Layouts.LongDoubleWidth = 32; + Layouts.LongDoubleAlign = 8; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + } else if (Arch == bpfeb || Arch == bpfel) { + // default configuration + } else if (Arch == msp430) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 16; + } else if (Arch == mips || Arch == mipsel || Arch == mips64 || + Arch == mips64el) { + if (isMIPS32()) { + // o32 + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else { + // n32 & n64 + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + if (isOSFreeBSD()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } + } else if (Arch == m68k) { + // default configuration + } else if (Arch == ppc || Arch == ppcle || Arch == ppc64 || Arch == ppc64le) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); + + if (Arch == ppc || Arch == ppcle) { + if (isOSAIX()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 32; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOSFreeBSD() || isOSNetBSD() || isOSOpenBSD() || isMusl()) { + Layouts.LongDoubleWidth = Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } + } else if (Arch == nvptx || Arch == nvptx64) { + // nvcc does not copy set long double layouts + } else if (Arch == amdgcn || Arch == r600) { + // default configuration + } else if (Arch == riscv32 || Arch == riscv64) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Arch == sparc || Arch == sparcel) { + // default configuration + } else if (Arch == sparcv9) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Arch == systemz) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Arch == tce || Arch == tcele) { + Layouts.LongDoubleWidth = 32; + Layouts.LongDoubleAlign = 32; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + } else if (Arch == x86) { + Layouts.LongDoubleWidth = 96; + Layouts.LongDoubleAlign = 32; + Layouts.LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); + + if (isOSDarwin()) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + } else if (isAndroid()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOHOSFamily()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOSWindows()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + + if (isWindowsCygwinEnvironment()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + } + } else if (isOSNaCl()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } else if (isOSIAMCU()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } else if (Arch == x86_64) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); + + if (isOSDarwin()) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + } else if (isOSLinux() && isAndroid()) { + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (isOSLinux() && isOHOSFamily()) { + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (isOSWindows()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + + if (isWindowsGNUEnvironment()) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + } + } else if (isOSNaCl()) { + Layouts.LongDoubleWidth = 64; + Layouts.LongDoubleAlign = 64; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } + } else if (Arch == spir || Arch == spir64 || Arch == spirv || + Arch == spirv32 || Arch == spirv64) { + // default configuration + } else if (Arch == wasm32 || Arch == wasm64) { + Layouts.LongDoubleWidth = Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + + if (isOSEmscripten()) { + Layouts.LongDoubleAlign = 64; + } + } else if (Arch == dxil) { + // default configuration + } else if (Arch == renderscript32) { + // default configuration + } else if (Arch == renderscript64) { + // same as aarch64 on linux + Layouts.LongDoubleWidth = Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Arch == ve) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } else if (Arch == csky) { + Layouts.LongDoubleAlign = 32; + } else if (Arch == loongarch32 || Arch == loongarch64) { + Layouts.LongDoubleWidth = 128; + Layouts.LongDoubleAlign = 128; + Layouts.LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } + + return Layouts; +} + // HLSL triple environment orders are relied on in the front end static_assert(Triple::Vertex - Triple::Pixel == 1, "incorrect HLSL stage order"); >From 8a53d7707d056f926842c30cb547c73893101859 Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Thu, 28 Dec 2023 04:01:22 -0500 Subject: [PATCH 3/6] [IR] Change `fp128` lowering to use `f128` functions by default Switch from emitting long double functions to using `f128`-specific functions. Fixes https://github.com/llvm/llvm-project/issues/44744. --- llvm/include/llvm/IR/RuntimeLibcalls.def | 68 ++++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index c6ac341d71a20..fb9642eaae11c 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -110,12 +110,12 @@ HANDLE_LIBCALL(DIV_PPCF128, "__gcc_qdiv") HANDLE_LIBCALL(REM_F32, "fmodf") HANDLE_LIBCALL(REM_F64, "fmod") HANDLE_LIBCALL(REM_F80, "fmodl") -HANDLE_LIBCALL(REM_F128, "fmodl") +HANDLE_LIBCALL(REM_F128, "fmodf128") HANDLE_LIBCALL(REM_PPCF128, "fmodl") HANDLE_LIBCALL(FMA_F32, "fmaf") HANDLE_LIBCALL(FMA_F64, "fma") HANDLE_LIBCALL(FMA_F80, "fmal") -HANDLE_LIBCALL(FMA_F128, "fmal") +HANDLE_LIBCALL(FMA_F128, "fmaf128") HANDLE_LIBCALL(FMA_PPCF128, "fmal") HANDLE_LIBCALL(POWI_F32, "__powisf2") HANDLE_LIBCALL(POWI_F64, "__powidf2") @@ -125,62 +125,62 @@ HANDLE_LIBCALL(POWI_PPCF128, "__powitf2") HANDLE_LIBCALL(SQRT_F32, "sqrtf") HANDLE_LIBCALL(SQRT_F64, "sqrt") HANDLE_LIBCALL(SQRT_F80, "sqrtl") -HANDLE_LIBCALL(SQRT_F128, "sqrtl") +HANDLE_LIBCALL(SQRT_F128, "sqrtf128") HANDLE_LIBCALL(SQRT_PPCF128, "sqrtl") HANDLE_LIBCALL(CBRT_F32, "cbrtf") HANDLE_LIBCALL(CBRT_F64, "cbrt") HANDLE_LIBCALL(CBRT_F80, "cbrtl") -HANDLE_LIBCALL(CBRT_F128, "cbrtl") +HANDLE_LIBCALL(CBRT_F128, "cbrtf128") HANDLE_LIBCALL(CBRT_PPCF128, "cbrtl") HANDLE_LIBCALL(LOG_F32, "logf") HANDLE_LIBCALL(LOG_F64, "log") HANDLE_LIBCALL(LOG_F80, "logl") -HANDLE_LIBCALL(LOG_F128, "logl") +HANDLE_LIBCALL(LOG_F128, "logf128") HANDLE_LIBCALL(LOG_PPCF128, "logl") HANDLE_LIBCALL(LOG_FINITE_F32, "__logf_finite") HANDLE_LIBCALL(LOG_FINITE_F64, "__log_finite") HANDLE_LIBCALL(LOG_FINITE_F80, "__logl_finite") -HANDLE_LIBCALL(LOG_FINITE_F128, "__logl_finite") +HANDLE_LIBCALL(LOG_FINITE_F128, "__logf128_finite") HANDLE_LIBCALL(LOG_FINITE_PPCF128, "__logl_finite") HANDLE_LIBCALL(LOG2_F32, "log2f") HANDLE_LIBCALL(LOG2_F64, "log2") HANDLE_LIBCALL(LOG2_F80, "log2l") -HANDLE_LIBCALL(LOG2_F128, "log2l") +HANDLE_LIBCALL(LOG2_F128, "log2f128") HANDLE_LIBCALL(LOG2_PPCF128, "log2l") HANDLE_LIBCALL(LOG2_FINITE_F32, "__log2f_finite") HANDLE_LIBCALL(LOG2_FINITE_F64, "__log2_finite") HANDLE_LIBCALL(LOG2_FINITE_F80, "__log2l_finite") -HANDLE_LIBCALL(LOG2_FINITE_F128, "__log2l_finite") +HANDLE_LIBCALL(LOG2_FINITE_F128, "__log2f128_finite") HANDLE_LIBCALL(LOG2_FINITE_PPCF128, "__log2l_finite") HANDLE_LIBCALL(LOG10_F32, "log10f") HANDLE_LIBCALL(LOG10_F64, "log10") HANDLE_LIBCALL(LOG10_F80, "log10l") -HANDLE_LIBCALL(LOG10_F128, "log10l") +HANDLE_LIBCALL(LOG10_F128, "log10f128") HANDLE_LIBCALL(LOG10_PPCF128, "log10l") HANDLE_LIBCALL(LOG10_FINITE_F32, "__log10f_finite") HANDLE_LIBCALL(LOG10_FINITE_F64, "__log10_finite") HANDLE_LIBCALL(LOG10_FINITE_F80, "__log10l_finite") -HANDLE_LIBCALL(LOG10_FINITE_F128, "__log10l_finite") +HANDLE_LIBCALL(LOG10_FINITE_F128, "__log10f128_finite") HANDLE_LIBCALL(LOG10_FINITE_PPCF128, "__log10l_finite") HANDLE_LIBCALL(EXP_F32, "expf") HANDLE_LIBCALL(EXP_F64, "exp") HANDLE_LIBCALL(EXP_F80, "expl") -HANDLE_LIBCALL(EXP_F128, "expl") +HANDLE_LIBCALL(EXP_F128, "expf128") HANDLE_LIBCALL(EXP_PPCF128, "expl") HANDLE_LIBCALL(EXP_FINITE_F32, "__expf_finite") HANDLE_LIBCALL(EXP_FINITE_F64, "__exp_finite") HANDLE_LIBCALL(EXP_FINITE_F80, "__expl_finite") -HANDLE_LIBCALL(EXP_FINITE_F128, "__expl_finite") +HANDLE_LIBCALL(EXP_FINITE_F128, "__expf128_finite") HANDLE_LIBCALL(EXP_FINITE_PPCF128, "__expl_finite") HANDLE_LIBCALL(EXP2_F32, "exp2f") HANDLE_LIBCALL(EXP2_F64, "exp2") HANDLE_LIBCALL(EXP2_F80, "exp2l") -HANDLE_LIBCALL(EXP2_F128, "exp2l") +HANDLE_LIBCALL(EXP2_F128, "exp2f128") HANDLE_LIBCALL(EXP2_PPCF128, "exp2l") HANDLE_LIBCALL(EXP2_FINITE_F32, "__exp2f_finite") HANDLE_LIBCALL(EXP2_FINITE_F64, "__exp2_finite") HANDLE_LIBCALL(EXP2_FINITE_F80, "__exp2l_finite") -HANDLE_LIBCALL(EXP2_FINITE_F128, "__exp2l_finite") +HANDLE_LIBCALL(EXP2_FINITE_F128, "__exp2f128_finite") HANDLE_LIBCALL(EXP2_FINITE_PPCF128, "__exp2l_finite") HANDLE_LIBCALL(EXP10_F32, "exp10f") HANDLE_LIBCALL(EXP10_F64, "exp10") @@ -190,12 +190,12 @@ HANDLE_LIBCALL(EXP10_PPCF128, "exp10l") HANDLE_LIBCALL(SIN_F32, "sinf") HANDLE_LIBCALL(SIN_F64, "sin") HANDLE_LIBCALL(SIN_F80, "sinl") -HANDLE_LIBCALL(SIN_F128, "sinl") +HANDLE_LIBCALL(SIN_F128, "sinf128") HANDLE_LIBCALL(SIN_PPCF128, "sinl") HANDLE_LIBCALL(COS_F32, "cosf") HANDLE_LIBCALL(COS_F64, "cos") HANDLE_LIBCALL(COS_F80, "cosl") -HANDLE_LIBCALL(COS_F128, "cosl") +HANDLE_LIBCALL(COS_F128, "cosf128") HANDLE_LIBCALL(COS_PPCF128, "cosl") HANDLE_LIBCALL(TAN_F32, "tanf") HANDLE_LIBCALL(TAN_F64, "tan") @@ -247,62 +247,62 @@ HANDLE_LIBCALL(SINCOS_STRET_F64, nullptr) HANDLE_LIBCALL(POW_F32, "powf") HANDLE_LIBCALL(POW_F64, "pow") HANDLE_LIBCALL(POW_F80, "powl") -HANDLE_LIBCALL(POW_F128, "powl") +HANDLE_LIBCALL(POW_F128, "powf128") HANDLE_LIBCALL(POW_PPCF128, "powl") HANDLE_LIBCALL(POW_FINITE_F32, "__powf_finite") HANDLE_LIBCALL(POW_FINITE_F64, "__pow_finite") HANDLE_LIBCALL(POW_FINITE_F80, "__powl_finite") -HANDLE_LIBCALL(POW_FINITE_F128, "__powl_finite") +HANDLE_LIBCALL(POW_FINITE_F128, "__powf128_finite") HANDLE_LIBCALL(POW_FINITE_PPCF128, "__powl_finite") HANDLE_LIBCALL(CEIL_F32, "ceilf") HANDLE_LIBCALL(CEIL_F64, "ceil") HANDLE_LIBCALL(CEIL_F80, "ceill") -HANDLE_LIBCALL(CEIL_F128, "ceill") +HANDLE_LIBCALL(CEIL_F128, "ceilf128") HANDLE_LIBCALL(CEIL_PPCF128, "ceill") HANDLE_LIBCALL(TRUNC_F32, "truncf") HANDLE_LIBCALL(TRUNC_F64, "trunc") HANDLE_LIBCALL(TRUNC_F80, "truncl") -HANDLE_LIBCALL(TRUNC_F128, "truncl") +HANDLE_LIBCALL(TRUNC_F128, "truncf128") HANDLE_LIBCALL(TRUNC_PPCF128, "truncl") HANDLE_LIBCALL(RINT_F32, "rintf") HANDLE_LIBCALL(RINT_F64, "rint") HANDLE_LIBCALL(RINT_F80, "rintl") -HANDLE_LIBCALL(RINT_F128, "rintl") +HANDLE_LIBCALL(RINT_F128, "rintf128") HANDLE_LIBCALL(RINT_PPCF128, "rintl") HANDLE_LIBCALL(NEARBYINT_F32, "nearbyintf") HANDLE_LIBCALL(NEARBYINT_F64, "nearbyint") HANDLE_LIBCALL(NEARBYINT_F80, "nearbyintl") -HANDLE_LIBCALL(NEARBYINT_F128, "nearbyintl") +HANDLE_LIBCALL(NEARBYINT_F128, "nearbyintf128") HANDLE_LIBCALL(NEARBYINT_PPCF128, "nearbyintl") HANDLE_LIBCALL(ROUND_F32, "roundf") HANDLE_LIBCALL(ROUND_F64, "round") HANDLE_LIBCALL(ROUND_F80, "roundl") -HANDLE_LIBCALL(ROUND_F128, "roundl") +HANDLE_LIBCALL(ROUND_F128, "roundf128") HANDLE_LIBCALL(ROUND_PPCF128, "roundl") HANDLE_LIBCALL(ROUNDEVEN_F32, "roundevenf") HANDLE_LIBCALL(ROUNDEVEN_F64, "roundeven") HANDLE_LIBCALL(ROUNDEVEN_F80, "roundevenl") -HANDLE_LIBCALL(ROUNDEVEN_F128, "roundevenl") +HANDLE_LIBCALL(ROUNDEVEN_F128, "roundevenf128") HANDLE_LIBCALL(ROUNDEVEN_PPCF128, "roundevenl") HANDLE_LIBCALL(FLOOR_F32, "floorf") HANDLE_LIBCALL(FLOOR_F64, "floor") HANDLE_LIBCALL(FLOOR_F80, "floorl") -HANDLE_LIBCALL(FLOOR_F128, "floorl") +HANDLE_LIBCALL(FLOOR_F128, "floorf128") HANDLE_LIBCALL(FLOOR_PPCF128, "floorl") HANDLE_LIBCALL(COPYSIGN_F32, "copysignf") HANDLE_LIBCALL(COPYSIGN_F64, "copysign") HANDLE_LIBCALL(COPYSIGN_F80, "copysignl") -HANDLE_LIBCALL(COPYSIGN_F128, "copysignl") +HANDLE_LIBCALL(COPYSIGN_F128, "copysignf128") HANDLE_LIBCALL(COPYSIGN_PPCF128, "copysignl") HANDLE_LIBCALL(FMIN_F32, "fminf") HANDLE_LIBCALL(FMIN_F64, "fmin") HANDLE_LIBCALL(FMIN_F80, "fminl") -HANDLE_LIBCALL(FMIN_F128, "fminl") +HANDLE_LIBCALL(FMIN_F128, "fminf128") HANDLE_LIBCALL(FMIN_PPCF128, "fminl") HANDLE_LIBCALL(FMAX_F32, "fmaxf") HANDLE_LIBCALL(FMAX_F64, "fmax") HANDLE_LIBCALL(FMAX_F80, "fmaxl") -HANDLE_LIBCALL(FMAX_F128, "fmaxl") +HANDLE_LIBCALL(FMAX_F128, "fmaxf128") HANDLE_LIBCALL(FMAX_PPCF128, "fmaxl") HANDLE_LIBCALL(FMINIMUM_F32, "fminimumf") HANDLE_LIBCALL(FMINIMUM_F64, "fminimum") @@ -327,32 +327,32 @@ HANDLE_LIBCALL(FMAXIMUMNUM_PPCF128, "fmaximum_numl") HANDLE_LIBCALL(LROUND_F32, "lroundf") HANDLE_LIBCALL(LROUND_F64, "lround") HANDLE_LIBCALL(LROUND_F80, "lroundl") -HANDLE_LIBCALL(LROUND_F128, "lroundl") +HANDLE_LIBCALL(LROUND_F128, "lroundf128") HANDLE_LIBCALL(LROUND_PPCF128, "lroundl") HANDLE_LIBCALL(LLROUND_F32, "llroundf") HANDLE_LIBCALL(LLROUND_F64, "llround") HANDLE_LIBCALL(LLROUND_F80, "llroundl") -HANDLE_LIBCALL(LLROUND_F128, "llroundl") +HANDLE_LIBCALL(LLROUND_F128, "llroundf128") HANDLE_LIBCALL(LLROUND_PPCF128, "llroundl") HANDLE_LIBCALL(LRINT_F32, "lrintf") HANDLE_LIBCALL(LRINT_F64, "lrint") HANDLE_LIBCALL(LRINT_F80, "lrintl") -HANDLE_LIBCALL(LRINT_F128, "lrintl") +HANDLE_LIBCALL(LRINT_F128, "lrintf128") HANDLE_LIBCALL(LRINT_PPCF128, "lrintl") HANDLE_LIBCALL(LLRINT_F32, "llrintf") HANDLE_LIBCALL(LLRINT_F64, "llrint") HANDLE_LIBCALL(LLRINT_F80, "llrintl") -HANDLE_LIBCALL(LLRINT_F128, "llrintl") +HANDLE_LIBCALL(LLRINT_F128, "llrintf128") HANDLE_LIBCALL(LLRINT_PPCF128, "llrintl") HANDLE_LIBCALL(LDEXP_F32, "ldexpf") HANDLE_LIBCALL(LDEXP_F64, "ldexp") HANDLE_LIBCALL(LDEXP_F80, "ldexpl") -HANDLE_LIBCALL(LDEXP_F128, "ldexpl") +HANDLE_LIBCALL(LDEXP_F128, "ldexpf128") HANDLE_LIBCALL(LDEXP_PPCF128, "ldexpl") HANDLE_LIBCALL(FREXP_F32, "frexpf") HANDLE_LIBCALL(FREXP_F64, "frexp") HANDLE_LIBCALL(FREXP_F80, "frexpl") -HANDLE_LIBCALL(FREXP_F128, "frexpl") +HANDLE_LIBCALL(FREXP_F128, "frexpf128") HANDLE_LIBCALL(FREXP_PPCF128, "frexpl") HANDLE_LIBCALL(SINCOSPI_F32, "sincospif") HANDLE_LIBCALL(SINCOSPI_F64, "sincospi") >From bb0c2348bc7623fd8753919647e1412fd72e5bee Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Thu, 27 Feb 2025 07:11:54 +0000 Subject: [PATCH 4/6] debugging --- clang/lib/Basic/Targets/ARM.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index ca2c1ffbb0eb7..2f2c49090fafd 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -25,6 +25,7 @@ using namespace clang::targets; void ARMTargetInfo::setABIAAPCS() { IsAAPCS = true; + fprintf(stderr, "setabiaapcs"); DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; BFloat16Width = BFloat16Align = 16; BFloat16Format = &llvm::APFloat::BFloat(); @@ -75,6 +76,7 @@ void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { IsAAPCS = false; + fprintf(stderr, "is aapcs16 %d\n", IsAAPCS); if (IsAAPCS16) DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; else >From 895ee6ec02663ebb822a1e8154863bc7a44fd3bb Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Thu, 27 Feb 2025 08:23:17 +0000 Subject: [PATCH 5/6] fixup! [llvm][clang] duplicate `long double` layout logic from clang to LLVM --- llvm/include/llvm/TargetParser/Triple.h | 2 +- llvm/lib/TargetParser/Triple.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index fdf77d0004376..ededea48ecaff 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -1283,7 +1283,7 @@ class Triple { /// Return true if `long double` and `_Float128` have the same layout. bool isLongDoubleF128(const StringRef &ABIName) const { - return getCLayouts(ABIName).LongDoubleWidth == 128; + return getCLayouts(ABIName).LongDoubleFormat == &APFloatBase::IEEEquad(); } }; diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index c83384c8d2bcf..2a5e129e93d5d 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -2165,12 +2165,12 @@ VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind, } Triple::CLayouts Triple::getCLayouts(const StringRef &ABIName) const { - Triple::CLayouts Layouts; - // Default to a 32-bit RISC platform - Layouts.LongDoubleWidth = 64; - Layouts.LongDoubleAlign = 64; - Layouts.LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + Triple::CLayouts Layouts { + .LongDoubleWidth = 64, + .LongDoubleAlign = 64, + .LongDoubleFormat = &llvm::APFloat::IEEEdouble(), + }; enum ArchType Arch = getArch(); >From 04e87bde35734da45288292eacb9b0e31b529024 Mon Sep 17 00:00:00 2001 From: Trevor Gross <tmgr...@umich.edu> Date: Thu, 27 Feb 2025 09:05:28 +0000 Subject: [PATCH 6/6] fixup! [IR] Change `fp128` lowering to use `f128` functions by default --- llvm/include/llvm/IR/RuntimeLibcalls.def | 30 +++--- llvm/lib/IR/RuntimeLibcalls.cpp | 94 +++++++++---------- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 26 ----- .../CodeGen/Generic/f128-math-lowering.ll | 11 ++- 4 files changed, 69 insertions(+), 92 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def index fb9642eaae11c..515b484cab343 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -185,7 +185,7 @@ HANDLE_LIBCALL(EXP2_FINITE_PPCF128, "__exp2l_finite") HANDLE_LIBCALL(EXP10_F32, "exp10f") HANDLE_LIBCALL(EXP10_F64, "exp10") HANDLE_LIBCALL(EXP10_F80, "exp10l") -HANDLE_LIBCALL(EXP10_F128, "exp10l") +HANDLE_LIBCALL(EXP10_F128, "exp10f128") HANDLE_LIBCALL(EXP10_PPCF128, "exp10l") HANDLE_LIBCALL(SIN_F32, "sinf") HANDLE_LIBCALL(SIN_F64, "sin") @@ -200,42 +200,42 @@ HANDLE_LIBCALL(COS_PPCF128, "cosl") HANDLE_LIBCALL(TAN_F32, "tanf") HANDLE_LIBCALL(TAN_F64, "tan") HANDLE_LIBCALL(TAN_F80, "tanl") -HANDLE_LIBCALL(TAN_F128,"tanl") +HANDLE_LIBCALL(TAN_F128,"tanf128") HANDLE_LIBCALL(TAN_PPCF128, "tanl") HANDLE_LIBCALL(SINH_F32, "sinhf") HANDLE_LIBCALL(SINH_F64, "sinh") HANDLE_LIBCALL(SINH_F80, "sinhl") -HANDLE_LIBCALL(SINH_F128, "sinhl") +HANDLE_LIBCALL(SINH_F128, "sinhf128") HANDLE_LIBCALL(SINH_PPCF128, "sinhl") HANDLE_LIBCALL(COSH_F32, "coshf") HANDLE_LIBCALL(COSH_F64, "cosh") HANDLE_LIBCALL(COSH_F80, "coshl") -HANDLE_LIBCALL(COSH_F128, "coshl") +HANDLE_LIBCALL(COSH_F128, "coshf128") HANDLE_LIBCALL(COSH_PPCF128, "coshl") HANDLE_LIBCALL(TANH_F32, "tanhf") HANDLE_LIBCALL(TANH_F64, "tanh") HANDLE_LIBCALL(TANH_F80, "tanhl") -HANDLE_LIBCALL(TANH_F128,"tanhl") +HANDLE_LIBCALL(TANH_F128,"tanhf128") HANDLE_LIBCALL(TANH_PPCF128, "tanhl") HANDLE_LIBCALL(ASIN_F32, "asinf") HANDLE_LIBCALL(ASIN_F64, "asin") HANDLE_LIBCALL(ASIN_F80, "asinl") -HANDLE_LIBCALL(ASIN_F128, "asinl") +HANDLE_LIBCALL(ASIN_F128, "asinf128") HANDLE_LIBCALL(ASIN_PPCF128, "asinl") HANDLE_LIBCALL(ACOS_F32, "acosf") HANDLE_LIBCALL(ACOS_F64, "acos") HANDLE_LIBCALL(ACOS_F80, "acosl") -HANDLE_LIBCALL(ACOS_F128, "acosl") +HANDLE_LIBCALL(ACOS_F128, "acosf128") HANDLE_LIBCALL(ACOS_PPCF128, "acosl") HANDLE_LIBCALL(ATAN_F32, "atanf") HANDLE_LIBCALL(ATAN_F64, "atan") HANDLE_LIBCALL(ATAN_F80, "atanl") -HANDLE_LIBCALL(ATAN_F128,"atanl") +HANDLE_LIBCALL(ATAN_F128,"atanf128") HANDLE_LIBCALL(ATAN_PPCF128, "atanl") HANDLE_LIBCALL(ATAN2_F32, "atan2f") HANDLE_LIBCALL(ATAN2_F64, "atan2") HANDLE_LIBCALL(ATAN2_F80, "atan2l") -HANDLE_LIBCALL(ATAN2_F128,"atan2l") +HANDLE_LIBCALL(ATAN2_F128,"atan2f128") HANDLE_LIBCALL(ATAN2_PPCF128, "atan2l") HANDLE_LIBCALL(SINCOS_F32, nullptr) HANDLE_LIBCALL(SINCOS_F64, nullptr) @@ -307,22 +307,22 @@ HANDLE_LIBCALL(FMAX_PPCF128, "fmaxl") HANDLE_LIBCALL(FMINIMUM_F32, "fminimumf") HANDLE_LIBCALL(FMINIMUM_F64, "fminimum") HANDLE_LIBCALL(FMINIMUM_F80, "fminimuml") -HANDLE_LIBCALL(FMINIMUM_F128, "fminimuml") +HANDLE_LIBCALL(FMINIMUM_F128, "fminimumf128") HANDLE_LIBCALL(FMINIMUM_PPCF128, "fminimuml") HANDLE_LIBCALL(FMAXIMUM_F32, "fmaximumf") HANDLE_LIBCALL(FMAXIMUM_F64, "fmaximum") HANDLE_LIBCALL(FMAXIMUM_F80, "fmaximuml") -HANDLE_LIBCALL(FMAXIMUM_F128, "fmaximuml") +HANDLE_LIBCALL(FMAXIMUM_F128, "fmaximumf128") HANDLE_LIBCALL(FMAXIMUM_PPCF128, "fmaximum_numl") HANDLE_LIBCALL(FMINIMUMNUM_F32, "fminimum_numf") HANDLE_LIBCALL(FMINIMUMNUM_F64, "fminimum_num") HANDLE_LIBCALL(FMINIMUMNUM_F80, "fminimum_numl") -HANDLE_LIBCALL(FMINIMUMNUM_F128, "fminimum_numl") +HANDLE_LIBCALL(FMINIMUMNUM_F128, "fminimum_numf128") HANDLE_LIBCALL(FMINIMUMNUM_PPCF128, "fminimum_numl") HANDLE_LIBCALL(FMAXIMUMNUM_F32, "fmaximum_numf") HANDLE_LIBCALL(FMAXIMUMNUM_F64, "fmaximum_num") HANDLE_LIBCALL(FMAXIMUMNUM_F80, "fmaximum_numl") -HANDLE_LIBCALL(FMAXIMUMNUM_F128, "fmaximum_numl") +HANDLE_LIBCALL(FMAXIMUMNUM_F128, "fmaximum_numf128") HANDLE_LIBCALL(FMAXIMUMNUM_PPCF128, "fmaximum_numl") HANDLE_LIBCALL(LROUND_F32, "lroundf") HANDLE_LIBCALL(LROUND_F64, "lround") @@ -357,12 +357,12 @@ HANDLE_LIBCALL(FREXP_PPCF128, "frexpl") HANDLE_LIBCALL(SINCOSPI_F32, "sincospif") HANDLE_LIBCALL(SINCOSPI_F64, "sincospi") HANDLE_LIBCALL(SINCOSPI_F80, "sincospil") -HANDLE_LIBCALL(SINCOSPI_F128, "sincospil") +HANDLE_LIBCALL(SINCOSPI_F128, "sincospif128") HANDLE_LIBCALL(SINCOSPI_PPCF128, "sincospil") HANDLE_LIBCALL(MODF_F32, "modff") HANDLE_LIBCALL(MODF_F64, "modf") HANDLE_LIBCALL(MODF_F80, "modfl") -HANDLE_LIBCALL(MODF_F128, "modfl") +HANDLE_LIBCALL(MODF_F128, "modff128") HANDLE_LIBCALL(MODF_PPCF128, "modfl") // Floating point environment diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 1f94400f7c088..2e3b071c8f4bf 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -25,52 +25,53 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) { for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC) setLibcallCallingConv((RTLIB::Libcall)LC, CallingConv::C); - // Use the f128 variants of math functions on x86_64 - if (TT.getArch() == Triple::ArchType::x86_64 && TT.isGNUEnvironment()) { - setLibcallName(RTLIB::REM_F128, "fmodf128"); - setLibcallName(RTLIB::FMA_F128, "fmaf128"); - setLibcallName(RTLIB::SQRT_F128, "sqrtf128"); - setLibcallName(RTLIB::CBRT_F128, "cbrtf128"); - setLibcallName(RTLIB::LOG_F128, "logf128"); - setLibcallName(RTLIB::LOG_FINITE_F128, "__logf128_finite"); - setLibcallName(RTLIB::LOG2_F128, "log2f128"); - setLibcallName(RTLIB::LOG2_FINITE_F128, "__log2f128_finite"); - setLibcallName(RTLIB::LOG10_F128, "log10f128"); - setLibcallName(RTLIB::LOG10_FINITE_F128, "__log10f128_finite"); - setLibcallName(RTLIB::EXP_F128, "expf128"); - setLibcallName(RTLIB::EXP_FINITE_F128, "__expf128_finite"); - setLibcallName(RTLIB::EXP2_F128, "exp2f128"); - setLibcallName(RTLIB::EXP2_FINITE_F128, "__exp2f128_finite"); - setLibcallName(RTLIB::EXP10_F128, "exp10f128"); - setLibcallName(RTLIB::SIN_F128, "sinf128"); - setLibcallName(RTLIB::COS_F128, "cosf128"); - setLibcallName(RTLIB::TAN_F128, "tanf128"); - setLibcallName(RTLIB::SINCOS_F128, "sincosf128"); - setLibcallName(RTLIB::ASIN_F128, "asinf128"); - setLibcallName(RTLIB::ACOS_F128, "acosf128"); - setLibcallName(RTLIB::ATAN_F128, "atanf128"); - setLibcallName(RTLIB::ATAN2_F128, "atan2f128"); - setLibcallName(RTLIB::SINH_F128, "sinhf128"); - setLibcallName(RTLIB::COSH_F128, "coshf128"); - setLibcallName(RTLIB::TANH_F128, "tanhf128"); - setLibcallName(RTLIB::POW_F128, "powf128"); - setLibcallName(RTLIB::POW_FINITE_F128, "__powf128_finite"); - setLibcallName(RTLIB::CEIL_F128, "ceilf128"); - setLibcallName(RTLIB::TRUNC_F128, "truncf128"); - setLibcallName(RTLIB::RINT_F128, "rintf128"); - setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128"); - setLibcallName(RTLIB::ROUND_F128, "roundf128"); - setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenf128"); - setLibcallName(RTLIB::FLOOR_F128, "floorf128"); - setLibcallName(RTLIB::COPYSIGN_F128, "copysignf128"); - setLibcallName(RTLIB::FMIN_F128, "fminf128"); - setLibcallName(RTLIB::FMAX_F128, "fmaxf128"); - setLibcallName(RTLIB::LROUND_F128, "lroundf128"); - setLibcallName(RTLIB::LLROUND_F128, "llroundf128"); - setLibcallName(RTLIB::LRINT_F128, "lrintf128"); - setLibcallName(RTLIB::LLRINT_F128, "llrintf128"); - setLibcallName(RTLIB::LDEXP_F128, "ldexpf128"); - setLibcallName(RTLIB::FREXP_F128, "frexpf128"); + // The long double version of library functions is more common than the + // f128-specific version. Use these if that is the long double type on the + // platform, or if the frontend specifies. + if (TT.isLongDoubleF128("")) { + setLibcallName(RTLIB::ACOS_F128, "acosl"); + setLibcallName(RTLIB::ASIN_F128, "asinl"); + setLibcallName(RTLIB::ATAN2_F128,"atan2l"); + setLibcallName(RTLIB::ATAN_F128,"atanl"); + setLibcallName(RTLIB::CBRT_F128, "cbrtl"); + setLibcallName(RTLIB::CEIL_F128, "ceill"); + setLibcallName(RTLIB::COPYSIGN_F128, "copysignl"); + setLibcallName(RTLIB::COSH_F128, "coshl"); + setLibcallName(RTLIB::COS_F128, "cosl"); + setLibcallName(RTLIB::EXP10_F128, "exp10l"); + setLibcallName(RTLIB::EXP2_F128, "exp2l"); + setLibcallName(RTLIB::EXP_F128, "expl"); + setLibcallName(RTLIB::FLOOR_F128, "floorl"); + setLibcallName(RTLIB::FMAXIMUMNUM_F128, "fmaximum_numl"); + setLibcallName(RTLIB::FMAXIMUM_F128, "fmaximuml"); + setLibcallName(RTLIB::FMAX_F128, "fmaxl"); + setLibcallName(RTLIB::FMA_F128, "fmal"); + setLibcallName(RTLIB::FMINIMUMNUM_F128, "fminimum_numl"); + setLibcallName(RTLIB::FMINIMUM_F128, "fminimuml"); + setLibcallName(RTLIB::FMIN_F128, "fminl"); + setLibcallName(RTLIB::FREXP_F128, "frexpl"); + setLibcallName(RTLIB::LDEXP_F128, "ldexpl"); + setLibcallName(RTLIB::LLRINT_F128, "llrintl"); + setLibcallName(RTLIB::LLROUND_F128, "llroundl"); + setLibcallName(RTLIB::LOG10_F128, "log10l"); + setLibcallName(RTLIB::LOG2_F128, "log2l"); + setLibcallName(RTLIB::LOG_F128, "logl"); + setLibcallName(RTLIB::LRINT_F128, "lrintl"); + setLibcallName(RTLIB::LROUND_F128, "lroundl"); + setLibcallName(RTLIB::MODF_F128, "modfl"); + setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintl"); + setLibcallName(RTLIB::POW_F128, "powl"); + setLibcallName(RTLIB::REM_F128, "fmodl"); + setLibcallName(RTLIB::RINT_F128, "rintl"); + setLibcallName(RTLIB::ROUNDEVEN_F128, "roundevenl"); + setLibcallName(RTLIB::ROUND_F128, "roundl"); + setLibcallName(RTLIB::SINCOSPI_F128, "sincospil"); + setLibcallName(RTLIB::SINH_F128, "sinhl"); + setLibcallName(RTLIB::SIN_F128, "sinl"); + setLibcallName(RTLIB::SQRT_F128, "sqrtl"); + setLibcallName(RTLIB::TANH_F128,"tanhl"); + setLibcallName(RTLIB::TAN_F128,"tanl"); + setLibcallName(RTLIB::TRUNC_F128, "truncl"); } // For IEEE quad-precision libcall names, PPC uses "kf" instead of "tf". @@ -177,7 +178,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) { setLibcallName(RTLIB::SINCOS_F32, "sincosf"); setLibcallName(RTLIB::SINCOS_F64, "sincos"); setLibcallName(RTLIB::SINCOS_F80, "sincosl"); - setLibcallName(RTLIB::SINCOS_F128, "sincosl"); setLibcallName(RTLIB::SINCOS_PPCF128, "sincosl"); } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index d6c8e8d506799..55dd608184e17 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1418,32 +1418,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, setTargetDAGCombine({ISD::TRUNCATE, ISD::SETCC, ISD::SELECT_CC}); } - setLibcallName(RTLIB::LOG_F128, "logf128"); - setLibcallName(RTLIB::LOG2_F128, "log2f128"); - setLibcallName(RTLIB::LOG10_F128, "log10f128"); - setLibcallName(RTLIB::EXP_F128, "expf128"); - setLibcallName(RTLIB::EXP2_F128, "exp2f128"); - setLibcallName(RTLIB::SIN_F128, "sinf128"); - setLibcallName(RTLIB::COS_F128, "cosf128"); - setLibcallName(RTLIB::SINCOS_F128, "sincosf128"); - setLibcallName(RTLIB::POW_F128, "powf128"); - setLibcallName(RTLIB::FMIN_F128, "fminf128"); - setLibcallName(RTLIB::FMAX_F128, "fmaxf128"); - setLibcallName(RTLIB::REM_F128, "fmodf128"); - setLibcallName(RTLIB::SQRT_F128, "sqrtf128"); - setLibcallName(RTLIB::CEIL_F128, "ceilf128"); - setLibcallName(RTLIB::FLOOR_F128, "floorf128"); - setLibcallName(RTLIB::TRUNC_F128, "truncf128"); - setLibcallName(RTLIB::ROUND_F128, "roundf128"); - setLibcallName(RTLIB::LROUND_F128, "lroundf128"); - setLibcallName(RTLIB::LLROUND_F128, "llroundf128"); - setLibcallName(RTLIB::RINT_F128, "rintf128"); - setLibcallName(RTLIB::LRINT_F128, "lrintf128"); - setLibcallName(RTLIB::LLRINT_F128, "llrintf128"); - setLibcallName(RTLIB::NEARBYINT_F128, "nearbyintf128"); - setLibcallName(RTLIB::FMA_F128, "fmaf128"); - setLibcallName(RTLIB::FREXP_F128, "frexpf128"); - if (Subtarget.isAIXABI()) { setLibcallName(RTLIB::MEMCPY, isPPC64 ? "___memmove64" : "___memmove"); setLibcallName(RTLIB::MEMMOVE, isPPC64 ? "___memmove64" : "___memmove"); diff --git a/llvm/test/CodeGen/Generic/f128-math-lowering.ll b/llvm/test/CodeGen/Generic/f128-math-lowering.ll index dfbd1eaeda109..a68cd1c39698e 100644 --- a/llvm/test/CodeGen/Generic/f128-math-lowering.ll +++ b/llvm/test/CodeGen/Generic/f128-math-lowering.ll @@ -1,12 +1,15 @@ ; RUN: llc < %s -mtriple=aarch64-unknown-none -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD -; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD -; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=i686-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD +; RUN: llc < %s -mtriple=powerpc-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD +; RUN: llc < %s -mtriple=powerpc64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD +; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD ; RUN: llc < %s -mtriple=s390x-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-S390X -; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=x86_64-unknown -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD -; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-USELD +; RUN: llc < %s -mtriple=x86_64-unknown-linux-musl -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-NOTLD ; ; REQUIRES: aarch64-registered-target +; REQUIRES: powerpc-registered-target ; REQUIRES: riscv-registered-target ; REQUIRES: systemz-registered-target ; REQUIRES: x86-registered-target _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits