Skip to content

RuntimeLibcalls: Associate calling convention with libcall impls #144979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: users/arsenm/tablegen/define-runtime-libcall-sets-tablegen
Choose a base branch
from

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Jun 20, 2025

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.
@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

@llvm/pr-subscribers-backend-arm
@llvm/pr-subscribers-backend-msp430

@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)

Changes

Instead of associating the libcall with the RTLIB::Libcall, put it
into a table indexed by the RTLIB::LibcallImpl. The LibcallImpls
should contain all ABI details for a particular implementation, not
the abstract Libcall. In the future the wrappers in terms of the
RTLIB::Libcall should be removed.


Full diff: https://github.com/llvm/llvm-project/pull/144979.diff

6 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/TargetLowering.h (+14-2)
  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.h (+23-9)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+42-28)
  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+15-9)
  • (modified) llvm/lib/Target/Lanai/LanaiISelLowering.cpp (+2-2)
  • (modified) llvm/lib/Target/MSP430/MSP430ISelLowering.cpp (+2-1)
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 69ae4f80297d5..fa08eb64642de 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3562,6 +3562,11 @@ class LLVM_ABI TargetLoweringBase {
     Libcalls.setLibcallImpl(Call, Impl);
   }
 
+  /// Get the libcall impl routine name for the specified libcall.
+  RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
+    return Libcalls.getLibcallImpl(Call);
+  }
+
   /// Get the libcall routine name for the specified libcall.
   const char *getLibcallName(RTLIB::Libcall Call) const {
     return Libcalls.getLibcallName(Call);
@@ -3584,11 +3589,18 @@ class LLVM_ABI TargetLoweringBase {
   }
 
   /// Set the CallingConv that should be used for the specified libcall.
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-    Libcalls.setLibcallCallingConv(Call, CC);
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+    Libcalls.setLibcallImplCallingConv(Call, CC);
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall
+  /// implementation.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+    return Libcalls.getLibcallImplCallingConv(Call);
   }
 
   /// Get the CallingConv that should be used for the specified libcall.
+  // FIXME: Remove this wrapper and directly use the used LibcallImpl
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
     return Libcalls.getLibcallCallingConv(Call);
   }
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index d69c23753da7a..dce16ab99171f 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -37,6 +37,10 @@ template <> struct enum_iteration_traits<RTLIB::Libcall> {
   static constexpr bool is_iterable = true;
 };
 
+template <> struct enum_iteration_traits<RTLIB::LibcallImpl> {
+  static constexpr bool is_iterable = true;
+};
+
 namespace RTLIB {
 
 // Return an iterator over all Libcall values.
@@ -44,6 +48,10 @@ static inline auto libcalls() {
   return enum_seq(static_cast<RTLIB::Libcall>(0), RTLIB::UNKNOWN_LIBCALL);
 }
 
+static inline auto libcall_impls() {
+  return enum_seq(static_cast<RTLIB::LibcallImpl>(1), RTLIB::NumLibcallImpls);
+}
+
 /// A simple container for information about the supported runtime calls.
 struct RuntimeLibcallsInfo {
   explicit RuntimeLibcallsInfo(
@@ -76,16 +84,21 @@ struct RuntimeLibcallsInfo {
     return LibcallImpls[Call];
   }
 
-  /// Set the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
-  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
-    LibcallCallingConvs[Call] = CC;
+  /// Set the CallingConv that should be used for the specified libcall
+  /// implementation
+  void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
+    LibcallImplCallingConvs[Call] = CC;
   }
 
-  /// Get the CallingConv that should be used for the specified libcall.
-  // FIXME: This should be a function of RTLIB::LibcallImpl
+  // FIXME: Remove this wrapper in favor of directly using
+  // getLibcallImplCallingConv
   CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
-    return LibcallCallingConvs[Call];
+    return LibcallImplCallingConvs[LibcallImpls[Call]];
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall.
+  CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
+    return LibcallImplCallingConvs[Call];
   }
 
   ArrayRef<RTLIB::LibcallImpl> getLibcallImpls() const {
@@ -130,8 +143,9 @@ struct RuntimeLibcallsInfo {
   static_assert(static_cast<int>(CallingConv::C) == 0,
                 "default calling conv should be encoded as 0");
 
-  /// Stores the CallingConv that should be used for each libcall.
-  CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL] = {};
+  /// Stores the CallingConv that should be used for each libcall
+  /// implementation.;
+  CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] = {};
 
   /// The condition type that should be used to test the result of each of the
   /// soft floating-point comparison libcall against integer zero.
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index eaa2cf5100c77..9492aef16e638 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -29,8 +29,8 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
     CallingConv::ID DefaultCC = FloatABIType == FloatABI::Hard
                                     ? CallingConv::ARM_AAPCS_VFP
                                     : CallingConv::ARM_AAPCS;
-    for (RTLIB::Libcall LC : RTLIB::libcalls())
-      Info.setLibcallCallingConv(LC, DefaultCC);
+    for (RTLIB::LibcallImpl LC : RTLIB::libcall_impls())
+      Info.setLibcallImplCallingConv(LC, DefaultCC);
   }
 
   // Register based DivRem for AEABI (RTABI 4.2)
@@ -50,7 +50,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
 
       for (const auto &LC : LibraryCalls) {
         Info.setLibcallImpl(LC.Op, LC.Impl);
-        Info.setLibcallCallingConv(LC.Op, LC.CC);
+        Info.setLibcallImplCallingConv(LC.Impl, LC.CC);
       }
     } else {
       const struct {
@@ -66,7 +66,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
 
       for (const auto &LC : LibraryCalls) {
         Info.setLibcallImpl(LC.Op, LC.Impl);
-        Info.setLibcallCallingConv(LC.Op, LC.CC);
+        Info.setLibcallImplCallingConv(LC.Impl, LC.CC);
       }
     }
   }
@@ -89,7 +89,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
 
     for (const auto &LC : LibraryCalls) {
       Info.setLibcallImpl(LC.Op, LC.Impl);
-      Info.setLibcallCallingConv(LC.Op, LC.CC);
+      Info.setLibcallImplCallingConv(LC.Impl, LC.CC);
     }
   }
 
@@ -199,20 +199,34 @@ static void setMSP430Libcalls(RuntimeLibcallsInfo &Info, const Triple &TT) {
     Info.setLibcallImpl(LC.Op, LC.Impl);
 
   // Several of the runtime library functions use a special calling conv
-  Info.setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::ADD_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::SUB_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::MUL_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::DIV_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::OEQ_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::UNE_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::OGE_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::OLT_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::OLE_F64, CallingConv::MSP430_BUILTIN);
-  Info.setLibcallCallingConv(RTLIB::OGT_F64, CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_divull,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_remull,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_divlli,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_remlli,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_addd,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_subd,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_mpyd,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_divd,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__oeq,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__une,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__oge,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__olt,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__ole,
+                                 CallingConv::MSP430_BUILTIN);
+  Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__ogt,
+                                 CallingConv::MSP430_BUILTIN);
 
   // TODO: __mspabi_srall, __mspabi_srlll, __mspabi_sllll
 }
@@ -361,10 +375,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
       setLibcallImpl(RTLIB::SINCOS_STRET_F32, RTLIB::__sincosf_stret);
       setLibcallImpl(RTLIB::SINCOS_STRET_F64, RTLIB::__sincos_stret);
       if (TT.isWatchABI()) {
-        setLibcallCallingConv(RTLIB::SINCOS_STRET_F32,
-                              CallingConv::ARM_AAPCS_VFP);
-        setLibcallCallingConv(RTLIB::SINCOS_STRET_F64,
-                              CallingConv::ARM_AAPCS_VFP);
+        setLibcallImplCallingConv(RTLIB::__sincosf_stret,
+                                  CallingConv::ARM_AAPCS_VFP);
+        setLibcallImplCallingConv(RTLIB::__sincos_stret,
+                                  CallingConv::ARM_AAPCS_VFP);
       }
     }
 
@@ -453,7 +467,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
 
     for (const auto &LC : LibraryCalls) {
       setLibcallImpl(LC.Op, LC.Impl);
-      setLibcallCallingConv(LC.Op, LC.CC);
+      setLibcallImplCallingConv(LC.Impl, LC.CC);
     }
   }
 
@@ -461,10 +475,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
     setARMLibcallNames(*this, TT, FloatABI, EABIVersion);
   else if (TT.getArch() == Triple::ArchType::avr) {
     // Several of the runtime library functions use a special calling conv
-    setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::AVR_BUILTIN);
-    setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::AVR_BUILTIN);
-    setLibcallCallingConv(RTLIB::UDIVREM_I8, CallingConv::AVR_BUILTIN);
-    setLibcallCallingConv(RTLIB::UDIVREM_I16, CallingConv::AVR_BUILTIN);
+    setLibcallImplCallingConv(RTLIB::__divmodqi4, CallingConv::AVR_BUILTIN);
+    setLibcallImplCallingConv(RTLIB::__divmodhi4, CallingConv::AVR_BUILTIN);
+    setLibcallImplCallingConv(RTLIB::__udivmodqi4, CallingConv::AVR_BUILTIN);
+    setLibcallImplCallingConv(RTLIB::__udivmodhi4, CallingConv::AVR_BUILTIN);
   }
 
   if (!TT.isWasm()) {
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 478791699df88..85f0d99923f90 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -686,7 +686,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
 
     for (const auto &LC : LibraryCalls) {
       setLibcallImpl(LC.Op, LC.Impl);
-      setLibcallCallingConv(LC.Op, LC.CC);
+      setLibcallImplCallingConv(LC.Impl, LC.CC);
       if (LC.Cond != CmpInst::BAD_ICMP_PREDICATE)
         setCmpLibcallCC(LC.Op, LC.Cond);
     }
@@ -725,7 +725,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
 
       for (const auto &LC : MemOpsLibraryCalls) {
         setLibcallImpl(LC.Op, LC.Impl);
-        setLibcallCallingConv(LC.Op, LC.CC);
+        setLibcallImplCallingConv(LC.Impl, LC.CC);
       }
     }
   }
@@ -735,13 +735,19 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
   // hard-float calling convention by default.
   if (!TT.isWatchABI()) {
     if (TM.isAAPCS_ABI()) {
-      setLibcallCallingConv(RTLIB::FPROUND_F32_F16, CallingConv::ARM_AAPCS);
-      setLibcallCallingConv(RTLIB::FPROUND_F64_F16, CallingConv::ARM_AAPCS);
-      setLibcallCallingConv(RTLIB::FPEXT_F16_F32, CallingConv::ARM_AAPCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F32_F16),
+                                CallingConv::ARM_AAPCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F64_F16),
+                                CallingConv::ARM_AAPCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPEXT_F16_F32),
+                                CallingConv::ARM_AAPCS);
     } else {
-      setLibcallCallingConv(RTLIB::FPROUND_F32_F16, CallingConv::ARM_APCS);
-      setLibcallCallingConv(RTLIB::FPROUND_F64_F16, CallingConv::ARM_APCS);
-      setLibcallCallingConv(RTLIB::FPEXT_F16_F32, CallingConv::ARM_APCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F32_F16),
+                                CallingConv::ARM_APCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F64_F16),
+                                CallingConv::ARM_APCS);
+      setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPEXT_F16_F32),
+                                CallingConv::ARM_APCS);
     }
   }
 
@@ -763,7 +769,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
 
     for (const auto &LC : LibraryCalls) {
       setLibcallImpl(LC.Op, LC.Impl);
-      setLibcallCallingConv(LC.Op, LC.CC);
+      setLibcallImplCallingConv(LC.Impl, LC.CC);
     }
   } else if (!TT.isOSBinFormatMachO()) {
     setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__gnu_f2h_ieee);
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index 7781817aef71a..a00c2870c9afc 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -151,8 +151,8 @@ LanaiTargetLowering::LanaiTargetLowering(const TargetMachine &TM,
   setMinimumJumpTableEntries(100);
 
   // Use fast calling convention for library functions.
-  for (RTLIB::Libcall LC : RTLIB::libcalls())
-    setLibcallCallingConv(LC, CallingConv::Fast);
+  for (RTLIB::LibcallImpl LC : RTLIB::libcall_impls())
+    setLibcallImplCallingConv(LC, CallingConv::Fast);
 
   MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
   MaxStoresPerMemsetOptSize = 8;
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index f8f688c8fbb14..d558dd253dc46 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -208,7 +208,8 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
     for (const auto &LC : LibraryCalls) {
       setLibcallImpl(LC.Op, LC.Impl);
     }
-    setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::MSP430_BUILTIN);
+    setLibcallImplCallingConv(RTLIB::__mspabi_mpyll,
+                              CallingConv::MSP430_BUILTIN);
   }
 
   setMinFunctionAlignment(Align(2));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants