[llvm] 1c5b150 - CodeGen: Move libcall lowering configuration to subtarget (#168621)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 25 09:00:00 PST 2025


Author: Matt Arsenault
Date: 2025-11-25T11:59:56-05:00
New Revision: 1c5b1501ca50e039ae39075465972761449013e9

URL: https://github.com/llvm/llvm-project/commit/1c5b1501ca50e039ae39075465972761449013e9
DIFF: https://github.com/llvm/llvm-project/commit/1c5b1501ca50e039ae39075465972761449013e9.diff

LOG: CodeGen: Move libcall lowering configuration to subtarget (#168621)

Previously libcall lowering decisions were made directly
in the TargetLowering constructor. Pull these into the subtarget
to facilitate turning LibcallLoweringInfo into a separate analysis
in the future.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
    llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
    llvm/lib/CodeGen/LibcallLoweringInfo.cpp
    llvm/lib/CodeGen/TargetLoweringBase.cpp
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/lib/Target/ARM/ARMSubtarget.cpp
    llvm/lib/Target/ARM/ARMSubtarget.h
    llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
    llvm/lib/Target/MSP430/MSP430Subtarget.cpp
    llvm/lib/Target/MSP430/MSP430Subtarget.h
    llvm/lib/Target/Mips/Mips16ISelLowering.cpp
    llvm/lib/Target/Mips/Mips16ISelLowering.h
    llvm/lib/Target/Mips/MipsSubtarget.cpp
    llvm/lib/Target/Mips/MipsSubtarget.h
    llvm/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/lib/Target/Sparc/SparcSubtarget.cpp
    llvm/lib/Target/Sparc/SparcSubtarget.h

Removed: 
    


################################################################################
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/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/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 3a3b5298b1a2e..1d674b283db15 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -755,7 +755,7 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &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/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2ad8f877ff11b..32f3e5fa3c842 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -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/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index 89f38c847b1eb..e118169377fe2 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -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<RTLIB::LibcallImpl> 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/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<CallLowering> CallLoweringInfo;

diff  --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index dc1196127e3d4..a4a9eafd52ffe 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -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)                    \


        


More information about the llvm-commits mailing list