diff --git a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h index e88079e796e7d..8624fd2403a12 100644 --- a/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h +++ b/llvm/include/llvm/CodeGen/LibcallLoweringInfo.h @@ -13,6 +13,8 @@ namespace llvm { +class TargetSubtargetInfo; + class LibcallLoweringInfo { private: const RTLIB::RuntimeLibcallsInfo &RTLCI; @@ -21,7 +23,12 @@ class LibcallLoweringInfo { RTLIB::Unsupported}; public: - LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI); + LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI, + const TargetSubtargetInfo &Subtarget); + + const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const { + return RTLCI; + } /// Get the libcall routine name for the specified libcall. // FIXME: This should be removed. Only LibcallImpl should have a name. diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 4c932c523e423..7df5d8a09f0f6 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -355,7 +355,8 @@ class LLVM_ABI TargetLoweringBase { llvm_unreachable("Invalid content kind"); } - explicit TargetLoweringBase(const TargetMachine &TM); + explicit TargetLoweringBase(const TargetMachine &TM, + const TargetSubtargetInfo &STI); TargetLoweringBase(const TargetLoweringBase &) = delete; TargetLoweringBase &operator=(const TargetLoweringBase &) = delete; virtual ~TargetLoweringBase(); @@ -3977,7 +3978,8 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase { TargetLowering(const TargetLowering &) = delete; TargetLowering &operator=(const TargetLowering &) = delete; - explicit TargetLowering(const TargetMachine &TM); + explicit TargetLowering(const TargetMachine &TM, + const TargetSubtargetInfo &STI); ~TargetLowering() override; bool isPositionIndependent() const; diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index a1a130aa27798..6f95f0fea6441 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -38,6 +38,7 @@ class InstrItineraryData; struct InstrStage; class InstructionSelector; class LegalizerInfo; +class LibcallLoweringInfo; class MachineInstr; struct MachineSchedPolicy; struct MCReadAdvanceEntry; @@ -139,6 +140,12 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo { return nullptr; } + /// Configure the LibcallLoweringInfo for this subtarget. The libcalls will be + /// pre-configured with defaults based on RuntimeLibcallsInfo. This may be + /// used to override those decisions, such as disambiguating alternative + /// implementations. + virtual void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {} + /// Resolve a SchedClass at runtime, where SchedClass identifies an /// MCSchedClassDesc with the isVariant property. This may return the ID of /// another variant SchedClass, but repeated invocation must quickly terminate diff --git a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp index 5c1698cb6060e..6f3607e8db824 100644 --- a/llvm/lib/CodeGen/LibcallLoweringInfo.cpp +++ b/llvm/lib/CodeGen/LibcallLoweringInfo.cpp @@ -7,11 +7,13 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LibcallLoweringInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" using namespace llvm; LibcallLoweringInfo::LibcallLoweringInfo( - const RTLIB::RuntimeLibcallsInfo &RTLCI) + const RTLIB::RuntimeLibcallsInfo &RTLCI, + const TargetSubtargetInfo &Subtarget) : RTLCI(RTLCI) { // TODO: This should be generated with lowering predicates, and assert the // call is available. @@ -23,4 +25,6 @@ LibcallLoweringInfo::LibcallLoweringInfo( LibcallImpls[LC] = Impl; } } + + Subtarget.initLibcallLoweringInfo(*this); } diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index bb64f4ee70280..a2c6a22043001 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -41,8 +41,9 @@ using namespace llvm; using namespace llvm::SDPatternMatch; /// NOTE: The TargetMachine owns TLOF. -TargetLowering::TargetLowering(const TargetMachine &tm) - : TargetLoweringBase(tm) {} +TargetLowering::TargetLowering(const TargetMachine &tm, + const TargetSubtargetInfo &sti) + : TargetLoweringBase(tm, sti) {} // Define the virtual destructor out-of-line for build efficiency. TargetLowering::~TargetLowering() = default; diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 0562fd8c08ba8..0a3a7b5b3083e 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -749,12 +749,13 @@ ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate( } /// NOTE: The TargetMachine owns TLOF. -TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) +TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm, + const TargetSubtargetInfo &STI) : TM(tm), RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel, TM.Options.FloatABIType, TM.Options.EABIVersion, TM.Options.MCOptions.getABIName(), TM.Options.VecLib), - Libcalls(RuntimeLibcallInfo) { + Libcalls(RuntimeLibcallInfo, STI) { initActions(); // Perform these initializations only once. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 8f41f230b5521..2fc8b0c9a22cd 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -387,7 +387,7 @@ extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG) { AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, const AArch64Subtarget &STI) - : TargetLowering(TM), Subtarget(&STI) { + : TargetLowering(TM, STI), Subtarget(&STI) { // AArch64 doesn't have comparisons which set GPRs or setcc instructions, so // we have to make something up. Arbitrarily, choose ZeroOrOne. setBooleanContents(ZeroOrOneBooleanContent); diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index db890df7c50f9..19b3ae5e695c7 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -60,8 +60,9 @@ unsigned AMDGPUTargetLowering::numBitsSigned(SDValue Op, SelectionDAG &DAG) { } AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM, - const AMDGPUSubtarget &STI) - : TargetLowering(TM), Subtarget(&STI) { + const TargetSubtargetInfo &STI, + const AMDGPUSubtarget &AMDGPUSTI) + : TargetLowering(TM, STI), Subtarget(&AMDGPUSTI) { // Always lower memset, memcpy, and memmove intrinsics to load/store // instructions, rather then generating calls to memset, mempcy or memmove. MaxStoresPerMemset = MaxStoresPerMemsetOptSize = ~0U; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h index 473975133f5b3..9c0eff99981cd 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h @@ -180,7 +180,8 @@ class AMDGPUTargetLowering : public TargetLowering { const SmallVectorImpl &Ins) const; public: - AMDGPUTargetLowering(const TargetMachine &TM, const AMDGPUSubtarget &STI); + AMDGPUTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI, + const AMDGPUSubtarget &AMDGPUSTI); bool mayIgnoreSignedZero(SDValue Op) const; diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp index c799c7f63e105..950a9d8649c93 100644 --- a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp @@ -30,7 +30,8 @@ using namespace llvm; R600TargetLowering::R600TargetLowering(const TargetMachine &TM, const R600Subtarget &STI) - : AMDGPUTargetLowering(TM, STI), Subtarget(&STI), Gen(STI.getGeneration()) { + : AMDGPUTargetLowering(TM, STI, STI), Subtarget(&STI), + Gen(STI.getGeneration()) { addRegisterClass(MVT::f32, &R600::R600_Reg32RegClass); addRegisterClass(MVT::i32, &R600::R600_Reg32RegClass); addRegisterClass(MVT::v2f32, &R600::R600_Reg64RegClass); diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index e37d739fc25df..1e0f0e5173690 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -87,7 +87,7 @@ static unsigned findFirstFreeSGPR(CCState &CCInfo) { SITargetLowering::SITargetLowering(const TargetMachine &TM, const GCNSubtarget &STI) - : AMDGPUTargetLowering(TM, STI), Subtarget(&STI) { + : AMDGPUTargetLowering(TM, STI, STI), Subtarget(&STI) { addRegisterClass(MVT::i1, &AMDGPU::VReg_1RegClass); addRegisterClass(MVT::i64, &AMDGPU::SReg_64RegClass); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index cd8d7a0bee5e3..32f3e5fa3c842 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -508,7 +508,7 @@ const ARMBaseTargetMachine &ARMTargetLowering::getTM() const { ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, const ARMSubtarget &STI) - : TargetLowering(TM_), Subtarget(&STI), + : TargetLowering(TM_, STI), Subtarget(&STI), RegInfo(Subtarget->getRegisterInfo()), Itins(Subtarget->getInstrItineraryData()) { const auto &TM = static_cast(TM_); @@ -518,74 +518,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, const Triple &TT = TM.getTargetTriple(); - if (TT.isOSBinFormatMachO()) { - // Uses VFP for Thumb libfuncs if available. - if (Subtarget->isThumb() && Subtarget->hasVFP2Base() && - Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) { - // clang-format off - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Single-precision floating-point arithmetic. - { RTLIB::ADD_F32, RTLIB::impl___addsf3vfp }, - { RTLIB::SUB_F32, RTLIB::impl___subsf3vfp }, - { RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp }, - { RTLIB::DIV_F32, RTLIB::impl___divsf3vfp }, - - // Double-precision floating-point arithmetic. - { RTLIB::ADD_F64, RTLIB::impl___adddf3vfp }, - { RTLIB::SUB_F64, RTLIB::impl___subdf3vfp }, - { RTLIB::MUL_F64, RTLIB::impl___muldf3vfp }, - { RTLIB::DIV_F64, RTLIB::impl___divdf3vfp }, - - // Single-precision comparisons. - { RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp }, - { RTLIB::UNE_F32, RTLIB::impl___nesf2vfp }, - { RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp }, - { RTLIB::OLE_F32, RTLIB::impl___lesf2vfp }, - { RTLIB::OGE_F32, RTLIB::impl___gesf2vfp }, - { RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp }, - { RTLIB::UO_F32, RTLIB::impl___unordsf2vfp }, - - // Double-precision comparisons. - { RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp }, - { RTLIB::UNE_F64, RTLIB::impl___nedf2vfp }, - { RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp }, - { RTLIB::OLE_F64, RTLIB::impl___ledf2vfp }, - { RTLIB::OGE_F64, RTLIB::impl___gedf2vfp }, - { RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp }, - { RTLIB::UO_F64, RTLIB::impl___unorddf2vfp }, - - // Floating-point to integer conversions. - // i64 conversions are done via library routines even when generating VFP - // instructions, so use the same ones. - { RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp }, - { RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp }, - { RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp }, - { RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp }, - - // Conversions between floating types. - { RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp }, - { RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp }, - - // Integer to floating-point conversions. - // i64 conversions are done via library routines even when generating VFP - // instructions, so use the same ones. - // FIXME: There appears to be some naming inconsistency in ARM libgcc: - // e.g., __floatunsidf vs. __floatunssidfvfp. - { RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp }, - { RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp }, - { RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp }, - { RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp }, - }; - // clang-format on - - for (const auto &LC : LibraryCalls) - setLibcallImpl(LC.Op, LC.Impl); - } - } - if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, &ARM::tGPRRegClass); else diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index 7ec232ae9bac5..cad0cb6a441a0 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -129,6 +129,76 @@ const RegisterBankInfo *ARMSubtarget::getRegBankInfo() const { return RegBankInfo.get(); } +void ARMSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + const Triple &TT = getTargetTriple(); + if (TT.isOSBinFormatMachO()) { + // Uses VFP for Thumb libfuncs if available. + if (isThumb() && hasVFP2Base() && hasARMOps() && !useSoftFloat()) { + // clang-format off + static const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Single-precision floating-point arithmetic. + { RTLIB::ADD_F32, RTLIB::impl___addsf3vfp }, + { RTLIB::SUB_F32, RTLIB::impl___subsf3vfp }, + { RTLIB::MUL_F32, RTLIB::impl___mulsf3vfp }, + { RTLIB::DIV_F32, RTLIB::impl___divsf3vfp }, + + // Double-precision floating-point arithmetic. + { RTLIB::ADD_F64, RTLIB::impl___adddf3vfp }, + { RTLIB::SUB_F64, RTLIB::impl___subdf3vfp }, + { RTLIB::MUL_F64, RTLIB::impl___muldf3vfp }, + { RTLIB::DIV_F64, RTLIB::impl___divdf3vfp }, + + // Single-precision comparisons. + { RTLIB::OEQ_F32, RTLIB::impl___eqsf2vfp }, + { RTLIB::UNE_F32, RTLIB::impl___nesf2vfp }, + { RTLIB::OLT_F32, RTLIB::impl___ltsf2vfp }, + { RTLIB::OLE_F32, RTLIB::impl___lesf2vfp }, + { RTLIB::OGE_F32, RTLIB::impl___gesf2vfp }, + { RTLIB::OGT_F32, RTLIB::impl___gtsf2vfp }, + { RTLIB::UO_F32, RTLIB::impl___unordsf2vfp }, + + // Double-precision comparisons. + { RTLIB::OEQ_F64, RTLIB::impl___eqdf2vfp }, + { RTLIB::UNE_F64, RTLIB::impl___nedf2vfp }, + { RTLIB::OLT_F64, RTLIB::impl___ltdf2vfp }, + { RTLIB::OLE_F64, RTLIB::impl___ledf2vfp }, + { RTLIB::OGE_F64, RTLIB::impl___gedf2vfp }, + { RTLIB::OGT_F64, RTLIB::impl___gtdf2vfp }, + { RTLIB::UO_F64, RTLIB::impl___unorddf2vfp }, + + // Floating-point to integer conversions. + // i64 conversions are done via library routines even when generating VFP + // instructions, so use the same ones. + { RTLIB::FPTOSINT_F64_I32, RTLIB::impl___fixdfsivfp }, + { RTLIB::FPTOUINT_F64_I32, RTLIB::impl___fixunsdfsivfp }, + { RTLIB::FPTOSINT_F32_I32, RTLIB::impl___fixsfsivfp }, + { RTLIB::FPTOUINT_F32_I32, RTLIB::impl___fixunssfsivfp }, + + // Conversions between floating types. + { RTLIB::FPROUND_F64_F32, RTLIB::impl___truncdfsf2vfp }, + { RTLIB::FPEXT_F32_F64, RTLIB::impl___extendsfdf2vfp }, + + // Integer to floating-point conversions. + // i64 conversions are done via library routines even when generating VFP + // instructions, so use the same ones. + // FIXME: There appears to be some naming inconsistency in ARM libgcc: + // e.g., __floatunsidf vs. __floatunssidfvfp. + { RTLIB::SINTTOFP_I32_F64, RTLIB::impl___floatsidfvfp }, + { RTLIB::UINTTOFP_I32_F64, RTLIB::impl___floatunssidfvfp }, + { RTLIB::SINTTOFP_I32_F32, RTLIB::impl___floatsisfvfp }, + { RTLIB::UINTTOFP_I32_F32, RTLIB::impl___floatunssisfvfp }, + }; + // clang-format on + + for (const auto &LC : LibraryCalls) + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } +} + bool ARMSubtarget::isXRaySupported() const { // We don't currently suppport Thumb, but Windows requires Thumb. return hasV6Ops() && hasARMOps() && !isTargetWindows(); diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 4a0883cc662e7..2a90f4223cbce 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -258,6 +258,7 @@ class ARMSubtarget : public ARMGenSubtargetInfo { InstructionSelector *getInstructionSelector() const override; const LegalizerInfo *getLegalizerInfo() const override; const RegisterBankInfo *getRegBankInfo() const override; + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; private: ARMSelectionDAGInfo TSInfo; diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 545bc3af05383..054ff989d54b8 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -34,7 +34,7 @@ namespace llvm { AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM, const AVRSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { // Set up the register classes. addRegisterClass(MVT::i8, &AVR::GPR8RegClass); addRegisterClass(MVT::i16, &AVR::DREGSRegClass); diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp index ecefd2379356a..a8d1faa85116b 100644 --- a/llvm/lib/Target/BPF/BPFISelLowering.cpp +++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp @@ -58,7 +58,7 @@ static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg, BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI) - : TargetLowering(TM) { + : TargetLowering(TM, STI) { // Set up the register classes. addRegisterClass(MVT::i64, &BPF::GPRRegClass); diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index f0c5f523a003c..fae9cbf9832fe 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -206,7 +206,7 @@ DirectXTargetMachine::getTargetTransformInfo(const Function &F) const { DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM, const DirectXSubtarget &STI) - : TargetLowering(TM) { + : TargetLowering(TM, STI) { addRegisterClass(MVT::i32, &dxil::DXILClassRegClass); computeRegisterProperties(STI.getRegisterInfo()); } diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 894a07e6b68c2..5f953bf53bc7d 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1504,8 +1504,8 @@ HexagonTargetLowering::LowerGlobalTLSAddress(SDValue Op, HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, const HexagonSubtarget &ST) - : TargetLowering(TM), HTM(static_cast(TM)), - Subtarget(ST) { + : TargetLowering(TM, ST), + HTM(static_cast(TM)), Subtarget(ST) { auto &HRI = *Subtarget.getRegisterInfo(); setPrefLoopAlignment(Align(16)); diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp index f412f66d9d192..631a8de035ac2 100644 --- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp @@ -70,7 +70,7 @@ static cl::opt LanaiLowerConstantMulThreshold( LanaiTargetLowering::LanaiTargetLowering(const TargetMachine &TM, const LanaiSubtarget &STI) - : TargetLowering(TM) { + : TargetLowering(TM, STI) { // Set up the register classes. addRegisterClass(MVT::i32, &Lanai::GPRRegClass); diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index cf4ffc82f6009..83d841dba33e3 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -76,7 +76,7 @@ static cl::opt ZeroDivCheck("loongarch-check-zero-division", cl::Hidden, LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, const LoongArchSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { MVT GRLenVT = Subtarget.getGRLenVT(); diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index 5653099431b18..e118169377fe2 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -42,7 +42,7 @@ static cl::optMSP430NoLegalImmediate( MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, const MSP430Subtarget &STI) - : TargetLowering(TM) { + : TargetLowering(TM, STI) { // Set up the register classes. addRegisterClass(MVT::i8, &MSP430::GR8RegClass); @@ -148,68 +148,6 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::JumpTable, MVT::i16, Custom); - if (STI.hasHWMult16()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw}, - // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else if (STI.hasHWMult32()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32}, - // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else if (STI.hasHWMultF5()) { - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw}, - // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc - // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } else { // NoHWMult - const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - } LibraryCalls[] = { - // Integer Multiply - EABI Table 9 - {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi}, - {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl}, - {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll}, - // The __mspabi_mpysl* functions are NOT implemented in libgcc - // The __mspabi_mpyul* functions are NOT implemented in libgcc - }; - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - } - } - setMinFunctionAlignment(Align(2)); setPrefFunctionAlignment(Align(2)); setMaxAtomicSizeInBitsSupported(0); diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp index 89fc4b21cfb88..386f2a0fa8f47 100644 --- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp @@ -68,3 +68,67 @@ MSP430Subtarget::~MSP430Subtarget() = default; const SelectionDAGTargetInfo *MSP430Subtarget::getSelectionDAGInfo() const { return TSInfo.get(); } + +void MSP430Subtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (hasHWMult16()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw}, + // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else if (hasHWMult32()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_hw32}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_hw32}, + // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else if (hasHWMultF5()) { + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi_f5hw}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl_f5hw}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll_f5hw}, + // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc + // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } else { // NoHWMult + const struct { + const RTLIB::Libcall Op; + const RTLIB::LibcallImpl Impl; + } LibraryCalls[] = { + // Integer Multiply - EABI Table 9 + {RTLIB::MUL_I16, RTLIB::impl___mspabi_mpyi}, + {RTLIB::MUL_I32, RTLIB::impl___mspabi_mpyl}, + {RTLIB::MUL_I64, RTLIB::impl___mspabi_mpyll}, + // The __mspabi_mpysl* functions are NOT implemented in libgcc + // The __mspabi_mpyul* functions are NOT implemented in libgcc + }; + for (const auto &LC : LibraryCalls) { + Info.setLibcallImpl(LC.Op, LC.Impl); + } + } +} diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h index f7a9896ac8edc..4cb5c9b7467e5 100644 --- a/llvm/lib/Target/MSP430/MSP430Subtarget.h +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h @@ -74,6 +74,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo { } const SelectionDAGTargetInfo *getSelectionDAGInfo() const override; + + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; }; } // End llvm namespace diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp index 51049c83dec52..ac32426288e08 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp @@ -44,26 +44,6 @@ struct Mips16IntrinsicHelperType{ }; } // namespace -// Libcalls for which no helper is generated. Sorted by name for binary search. -static const RTLIB::LibcallImpl HardFloatLibCalls[] = { - RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3, - RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3, - RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2, - RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi, - RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf, - RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf, - RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2, - RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2, - RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2, - RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2, - RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3, - RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2, - RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc, - RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc, - RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3, - RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2, - RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2}; - static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = { {"__fixunsdfsi", "__mips16_call_stub_2" }, {"ceil", "__mips16_call_stub_df_2"}, @@ -97,9 +77,6 @@ Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM, // Set up the register classes addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass); - if (!Subtarget.useSoftFloat()) - setMips16HardFloatLibCalls(); - setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall); setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall); setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall); @@ -218,16 +195,6 @@ bool Mips16TargetLowering::isEligibleForTailCallOptimization( return false; } -void Mips16TargetLowering::setMips16HardFloatLibCalls() { - for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) { - assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && - "Array not sorted!"); - RTLIB::Libcall LC = - RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(HardFloatLibCalls[I]); - setLibcallImpl(LC, HardFloatLibCalls[I]); - } -} - // // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much // cleaner way to do all of this but it will have to wait until the traditional @@ -384,7 +351,8 @@ static bool isMips16HardFloatLibcall(StringRef Name) { iota_range ParsedLibcalls = RTLIB::RuntimeLibcallsInfo::lookupLibcallImplName(Name); return !ParsedLibcalls.empty() && - binary_search(HardFloatLibCalls, *ParsedLibcalls.begin()); + binary_search(MipsSubtarget::HardFloatLibCalls, + *ParsedLibcalls.begin()); } void Mips16TargetLowering:: diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.h b/llvm/lib/Target/Mips/Mips16ISelLowering.h index f120cbbd24f91..8f9f01b46b5a8 100644 --- a/llvm/lib/Target/Mips/Mips16ISelLowering.h +++ b/llvm/lib/Target/Mips/Mips16ISelLowering.h @@ -35,8 +35,6 @@ namespace llvm { const CCState &CCInfo, unsigned NextStackOffset, const MipsFunctionInfo &FI) const override; - void setMips16HardFloatLibCalls(); - unsigned int getMips16HelperFunctionStubNumber(ArgListTy &Args) const; diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 2fd73275721b1..b52aa3ce67950 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -295,7 +295,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI) - : TargetLowering(TM), Subtarget(STI), ABI(TM.getABI()) { + : TargetLowering(TM, STI), Subtarget(STI), ABI(TM.getABI()) { // Mips does not have i1 type, so use i32 for // setcc operations results (slt, sgt, ...). setBooleanContents(ZeroOrOneBooleanContent); diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index 8c4bb15a7e617..b22647a851c2b 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -305,3 +305,35 @@ const RegisterBankInfo *MipsSubtarget::getRegBankInfo() const { InstructionSelector *MipsSubtarget::getInstructionSelector() const { return InstSelector.get(); } + +// Libcalls for which no helper is generated. Sorted by name for binary search. +const RTLIB::LibcallImpl MipsSubtarget::HardFloatLibCalls[34] = { + RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3, + RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3, + RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2, + RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi, + RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf, + RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf, + RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2, + RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2, + RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2, + RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2, + RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3, + RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2, + RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc, + RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc, + RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3, + RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2, + RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2}; + +void MipsSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (inMips16Mode() && !useSoftFloat()) { + for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) { + assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) && + "Array not sorted!"); + RTLIB::Libcall LC = + RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(HardFloatLibCalls[I]); + Info.setLibcallImpl(LC, HardFloatLibCalls[I]); + } + } +} diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 52f892a160c38..0fbd425df1695 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -247,6 +247,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo { /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + static const RTLIB::LibcallImpl HardFloatLibCalls[34]; + bool hasMips1() const { return MipsArchVersion >= Mips1; } bool hasMips2() const { return MipsArchVersion >= Mips2; } bool hasMips3() const { return MipsArchVersion >= Mips3; } @@ -400,6 +402,8 @@ class MipsSubtarget : public MipsGenSubtargetInfo { return &InstrItins; } + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; + protected: // GlobalISel related APIs. std::unique_ptr CallLoweringInfo; diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp index 8fc3a68de6c79..a77eb0240e677 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -514,7 +514,7 @@ VectorizePTXValueVTs(const SmallVectorImpl &ValueVTs, // NVPTXTargetLowering Constructor. NVPTXTargetLowering::NVPTXTargetLowering(const NVPTXTargetMachine &TM, const NVPTXSubtarget &STI) - : TargetLowering(TM), nvTM(&TM), STI(STI), GlobalUniqueCallSite(0) { + : TargetLowering(TM, STI), nvTM(&TM), STI(STI), GlobalUniqueCallSite(0) { // always lower memset, memcpy, and memmove intrinsics to load/store // instructions, rather // then generating calls to memset, mempcy or memmove. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 220010c4d3d34..9ead9e58f8931 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -174,7 +174,7 @@ extern cl::opt ANDIGlueBug; PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { // Initialize map that relates the PPC addressing modes to the computed flags // of a load/store instruction. The map is used to determine the optimal // addressing mode when selecting load and stores. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 2d6bb06d689c3..3d6d4f6654d17 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -95,7 +95,7 @@ static const unsigned ZvfbfaOps[] = {ISD::FNEG, ISD::FABS, ISD::FCOPYSIGN, RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, const RISCVSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { RISCVABI::ABI ABI = Subtarget.getTargetABI(); assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp index e742a9811984b..8547ccfa7eaaa 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp @@ -24,6 +24,10 @@ using namespace llvm; +SPIRVTargetLowering::SPIRVTargetLowering(const TargetMachine &TM, + const SPIRVSubtarget &ST) + : TargetLowering(TM, ST), STI(ST) {} + // Returns true of the types logically match, as defined in // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpCopyLogical. static bool typesLogicallyMatch(const SPIRVType *Ty1, const SPIRVType *Ty2, diff --git a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h index 9025e6eb0842e..3d31a116bad4a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVISelLowering.h +++ b/llvm/lib/Target/SPIRV/SPIRVISelLowering.h @@ -29,8 +29,7 @@ class SPIRVTargetLowering : public TargetLowering { public: explicit SPIRVTargetLowering(const TargetMachine &TM, - const SPIRVSubtarget &ST) - : TargetLowering(TM), STI(ST) {} + const SPIRVSubtarget &ST); // Stop IRTranslator breaking up FMA instrs to preserve types information. bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index ae3c32687c207..a4a9eafd52ffe 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1573,7 +1573,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI) - : TargetLowering(TM), Subtarget(&STI) { + : TargetLowering(TM, STI), Subtarget(&STI) { MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); // Instructions which use registers as conditionals examine all the @@ -1905,42 +1905,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FP_EXTEND, MVT::f128, Custom); setOperationAction(ISD::FP_ROUND, MVT::f64, Custom); - setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); - - // Setup Runtime library names. - if (Subtarget->is64Bit() && !Subtarget->useSoftFloat()) { - setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Qp_add); - setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Qp_sub); - setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Qp_mul); - setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Qp_div); - setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Qp_sqrt); - setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Qp_qtoi); - setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Qp_qtoui); - setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Qp_itoq); - setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Qp_uitoq); - setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::impl__Qp_qtox); - setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::impl__Qp_qtoux); - setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::impl__Qp_xtoq); - setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::impl__Qp_uxtoq); - setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Qp_stoq); - setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Qp_dtoq); - setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Qp_qtos); - setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Qp_qtod); - } else if (!Subtarget->useSoftFloat()) { - setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Q_add); - setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Q_sub); - setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Q_mul); - setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Q_div); - setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Q_sqrt); - setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Q_qtoi); - setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Q_qtou); - setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Q_itoq); - setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Q_utoq); - setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Q_stoq); - setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Q_dtoq); - setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Q_qtos); - setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Q_qtod); - } + setOperationAction(ISD::FP_ROUND, MVT::f32, Custom); } if (Subtarget->fixAllFDIVSQRT()) { diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp index 005930834a0c3..1d72d0bdada03 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -68,6 +68,46 @@ const SelectionDAGTargetInfo *SparcSubtarget::getSelectionDAGInfo() const { return TSInfo.get(); } +void SparcSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const { + if (hasHardQuad()) + return; + + // Setup Runtime library names. + if (is64Bit() && !useSoftFloat()) { + Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Qp_add); + Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Qp_sub); + Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Qp_mul); + Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Qp_div); + Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Qp_sqrt); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Qp_qtoi); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Qp_qtoui); + Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Qp_itoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Qp_uitoq); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::impl__Qp_qtox); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::impl__Qp_qtoux); + Info.setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::impl__Qp_xtoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::impl__Qp_uxtoq); + Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Qp_stoq); + Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Qp_dtoq); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Qp_qtos); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Qp_qtod); + } else if (!useSoftFloat()) { + Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Q_add); + Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Q_sub); + Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Q_mul); + Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Q_div); + Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Q_sqrt); + Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Q_qtoi); + Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Q_qtou); + Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Q_itoq); + Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Q_utoq); + Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Q_stoq); + Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Q_dtoq); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Q_qtos); + Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Q_qtod); + } +} + int SparcSubtarget::getAdjustedFrameSize(int frameSize) const { if (is64Bit()) { diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.h b/llvm/lib/Target/Sparc/SparcSubtarget.h index f575f6d7da37f..02d56eb8f3000 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.h +++ b/llvm/lib/Target/Sparc/SparcSubtarget.h @@ -63,6 +63,8 @@ class SparcSubtarget : public SparcGenSubtargetInfo { const SelectionDAGTargetInfo *getSelectionDAGInfo() const override; + void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override; + bool enableMachineScheduler() const override; #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index dfd76f9b0427f..06501b745b3f7 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -92,7 +92,7 @@ static MachineOperand earlyUseOperand(MachineOperand Op) { SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); auto *Regs = STI.getSpecialRegisters(); diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index e1735424a776b..a64193236f2ad 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -886,7 +886,7 @@ bool VETargetLowering::allowsMisalignedMemoryAccesses(EVT VT, VETargetLowering::VETargetLowering(const TargetMachine &TM, const VESubtarget &STI) - : TargetLowering(TM), Subtarget(&STI) { + : TargetLowering(TM, STI), Subtarget(&STI) { // Instructions which use registers as conditionals examine all the // bits (as does the pseudo SELECT_CC expansion). I don't think it // matters much whether it's ZeroOrOneBooleanContent, or diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index ad70d1b7e0a1e..abd8b2e095ae1 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -43,7 +43,7 @@ using namespace llvm; WebAssemblyTargetLowering::WebAssemblyTargetLowering( const TargetMachine &TM, const WebAssemblySubtarget &STI) - : TargetLowering(TM), Subtarget(&STI) { + : TargetLowering(TM, STI), Subtarget(&STI) { auto MVTPtr = Subtarget->hasAddr64() ? MVT::i64 : MVT::i32; // Set the load count for memcmp expand optimization diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 1251a3ca8dbaa..35e1649325932 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -130,7 +130,7 @@ static cl::opt MulConstantOptimization( X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, const X86Subtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { bool UseX87 = !Subtarget.useSoftFloat() && Subtarget.hasX87(); MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 0a96ab236c6ad..7c49e5b620bdf 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -42,7 +42,7 @@ using namespace llvm; XCoreTargetLowering::XCoreTargetLowering(const TargetMachine &TM, const XCoreSubtarget &Subtarget) - : TargetLowering(TM), TM(TM), Subtarget(Subtarget) { + : TargetLowering(TM, Subtarget), TM(TM), Subtarget(Subtarget) { // Set up the register classes. addRegisterClass(MVT::i32, &XCore::GRRegsRegClass); diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 71c98621c81ee..a9cf67128cdef 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -54,7 +54,7 @@ static unsigned toCallerWindow(unsigned Reg) { XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM, STI), Subtarget(STI) { MVT PtrVT = MVT::i32; // Set up the register classes. addRegisterClass(MVT::i32, &Xtensa::ARRegClass); diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc index 3ea51de751fad..c5e1c747bce32 100644 --- a/llvm/unittests/CodeGen/MFCommon.inc +++ b/llvm/unittests/CodeGen/MFCommon.inc @@ -2,7 +2,8 @@ // depending on a real target. class BogusTargetLowering : public TargetLowering { public: - BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {} + BogusTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI) + : TargetLowering(TM, STI) {} }; class BogusFrameLowering : public TargetFrameLowering { @@ -87,7 +88,7 @@ public: BogusSubtarget(TargetMachine &TM) : TargetSubtargetInfo(Triple(""), "", "", "", {}, {}, {}, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr), - FL(), TL(TM) {} + FL(), TL(TM, *this) {} ~BogusSubtarget() override = default; const TargetFrameLowering *getFrameLowering() const override { return &FL; } diff --git a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp index 809960d368e4e..14e1efaf65c8f 100644 --- a/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp +++ b/llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp @@ -25,6 +25,8 @@ namespace llvm { class AArch64SelectionDAGTest : public testing::Test { protected: + const TargetSubtargetInfo *STI; + static void SetUpTestCase() { LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64Target(); @@ -55,8 +57,8 @@ class AArch64SelectionDAGTest : public testing::Test { MachineModuleInfo MMI(TM.get()); - MF = std::make_unique(*F, *TM, *TM->getSubtargetImpl(*F), - MMI.getContext(), 0); + STI = TM->getSubtargetImpl(*F); + MF = std::make_unique(*F, *TM, *STI, MMI.getContext(), 0); DAG = std::make_unique(*TM, CodeGenOptLevel::None); if (!DAG) @@ -337,7 +339,7 @@ TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_ADDC) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -356,7 +358,7 @@ TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto Int8VT = EVT::getIntegerVT(Context, 8); @@ -382,7 +384,7 @@ TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) { } TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto Int8VT = EVT::getIntegerVT(Context, 8); @@ -784,7 +786,7 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_VSHL) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -804,7 +806,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -828,7 +830,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -844,7 +846,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) { } TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -864,7 +866,7 @@ TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) { } TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -880,7 +882,7 @@ TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) { TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -898,7 +900,7 @@ TEST_F(AArch64SelectionDAGTest, } TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -914,7 +916,7 @@ TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) { TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; auto IntVT = EVT::getIntegerVT(Context, 8); @@ -932,7 +934,7 @@ TEST_F(AArch64SelectionDAGTest, } TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) { - TargetLowering TL(*TM); + TargetLowering TL(*TM, *STI); SDLoc Loc; unsigned NumElts = 16;