[llvm-branch-commits] [llvm] RuntimeLibcalls: Associate calling convention with libcall impls (PR #144979)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jun 23 06:27:07 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/144979
>From 31892e808d070c944dae078d454c7bdbdf293b0e Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 17 Jun 2025 16:25:50 +0900
Subject: [PATCH] RuntimeLibcalls: Associate calling convention with libcall
impls
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.
---
llvm/include/llvm/CodeGen/TargetLowering.h | 16 ++++-
llvm/include/llvm/IR/RuntimeLibcalls.h | 32 ++++++---
llvm/lib/IR/RuntimeLibcalls.cpp | 70 +++++++++++--------
llvm/lib/Target/ARM/ARMISelLowering.cpp | 18 ++---
llvm/lib/Target/Lanai/LanaiISelLowering.cpp | 4 +-
llvm/lib/Target/MSP430/MSP430ISelLowering.cpp | 3 +-
6 files changed, 92 insertions(+), 51 deletions(-)
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 509cc80ff3e42..b963fbf92a5b1 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 34ff7123a35ea..bbed1040b9c2c 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 b4c2ad55d1b33..8ac7438ab7927 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,13 @@ 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(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS);
+ setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS);
+ setLibcallImplCallingConv(RTLIB::__extendhfsf2, 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(RTLIB::__truncsfhf2, CallingConv::ARM_APCS);
+ setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS);
+ setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS);
}
}
@@ -763,7 +763,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 16ea2c8461fa4..ec668ebaeab0d 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));
More information about the llvm-branch-commits
mailing list