From 6e86e11148474e4ecd49dbf0ca5dd9caddcdbd11 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Wed, 10 Jul 2024 13:41:08 -0500 Subject: [PATCH 1/2] [libc] Use `rint` builtin for rounding on the GPU (#98345) Summary: Previously this went through the generic bit-twiddling implementation instead of using the dedicated GPU instruction. This patch adds this in to the utility, mirroring the special-casing of the x64 and aarch targets. This results in much nicer code. The following example shows the opencl device libs implementation on the left and the LLVM libc on the right, https://godbolt.org/z/3ch48ccf5. The libc version is "branchier", but the results seem similar. --- libc/src/__support/FPUtil/nearest_integer.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libc/src/__support/FPUtil/nearest_integer.h b/libc/src/__support/FPUtil/nearest_integer.h index bc98667c8a3b3a..f9d952cfa163b9 100644 --- a/libc/src/__support/FPUtil/nearest_integer.h +++ b/libc/src/__support/FPUtil/nearest_integer.h @@ -17,6 +17,18 @@ #include "x86_64/nearest_integer.h" #elif defined(LIBC_TARGET_ARCH_IS_AARCH64) #include "aarch64/nearest_integer.h" +#elif defined(LIBC_TARGET_ARCH_IS_GPU) + +namespace LIBC_NAMESPACE { +namespace fputil { + +LIBC_INLINE float nearest_integer(float x) { return __builtin_rintf(x); } + +LIBC_INLINE double nearest_integer(double x) { return __builtin_rint(x); } + +} // namespace fputil +} // namespace LIBC_NAMESPACE + #else namespace LIBC_NAMESPACE { From 24619f6aaf1df4ef07c9b495681fb73f58a767c4 Mon Sep 17 00:00:00 2001 From: Michael Maitland Date: Wed, 10 Jul 2024 15:12:58 -0400 Subject: [PATCH 2/2] [RISCV][GISEL] Do not initialize GlobalISel objects unless needed (#98233) Prior to this commit, we created the GlobalISel objects in the RISCVSubtarget constructor, even if we are not running GlobalISel. This patch moves creation of the GlobalISel objects into their getters, which ensures that we only create these objects if they are actually needed. This helps since some of the constructors of the GlobalISel objects have a significant amount of code. We make the `unique_ptr`s `mutable` since GlobalISel passes only have access to `const TargetSubtargetInfo` through `MF.getSubtarget()`. This patch is tested by the fact that all existing RISC-V GlobalISel tests remain passing. --- llvm/lib/Target/RISCV/RISCVSubtarget.cpp | 21 ++++++++++++--------- llvm/lib/Target/RISCV/RISCVSubtarget.h | 8 ++++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index e84ddc65e2b703..d8414623d302b1 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -97,29 +97,32 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax), FrameLowering( initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)), - InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) { - CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering())); - Legalizer.reset(new RISCVLegalizerInfo(*this)); - - auto *RBI = new RISCVRegisterBankInfo(getHwMode()); - RegBankInfo.reset(RBI); - InstSelector.reset(createRISCVInstructionSelector( - *static_cast(&TM), *this, *RBI)); -} + InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {} const CallLowering *RISCVSubtarget::getCallLowering() const { + if (!CallLoweringInfo) + CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering())); return CallLoweringInfo.get(); } InstructionSelector *RISCVSubtarget::getInstructionSelector() const { + if (!InstSelector) { + InstSelector.reset(createRISCVInstructionSelector( + *static_cast(&TLInfo.getTargetMachine()), + *this, *static_cast(getRegBankInfo()))); + } return InstSelector.get(); } const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const { + if (!Legalizer) + Legalizer.reset(new RISCVLegalizerInfo(*this)); return Legalizer.get(); } const RegisterBankInfo *RISCVSubtarget::getRegBankInfo() const { + if (!RegBankInfo) + RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode())); return RegBankInfo.get(); } diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 347c1bc3c278fd..b146f48f81b724 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -245,10 +245,10 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { protected: // GlobalISel related APIs. - std::unique_ptr CallLoweringInfo; - std::unique_ptr InstSelector; - std::unique_ptr Legalizer; - std::unique_ptr RegBankInfo; + mutable std::unique_ptr CallLoweringInfo; + mutable std::unique_ptr InstSelector; + mutable std::unique_ptr Legalizer; + mutable std::unique_ptr RegBankInfo; // Return the known range for the bit length of RVV data registers as set // at the command line. A value of 0 means nothing is known about that particular