[llvm-branch-commits] [llvm] RuntimeLibcalls: Really move default libcall handling to tablegen (PR #148780)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jul 14 23:19:22 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/148780
>From ef419d66cf35792aa8da774e28c71719da32f6a2 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 14 Jul 2025 19:53:22 +0900
Subject: [PATCH] RuntimeLibcalls: Really move default libcall handling to
tablegen
Hack in the default setting so it's consistently generated like
the other cases. Maintain a list of targets where this applies.
The alternative would require new infrastructure to sort the system
library initialization in some way.
I wanted the unhandled target case to be treated as a fatal
error, but it turns out there's a hack in IRSymtab using
RuntimeLibcalls, which will fail out in many tests that
do not have a triple set. Many of the failures are simply
running llvm-as with no triple, which probably should not
depend on knowing an accurate set of calls.
---
llvm/include/llvm/IR/RuntimeLibcalls.h | 5 ---
llvm/include/llvm/IR/RuntimeLibcalls.td | 36 ++++++++++++++--
llvm/lib/IR/RuntimeLibcalls.cpp | 42 ++-----------------
llvm/test/TableGen/RuntimeLibcallEmitter.td | 14 +------
.../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 35 +++-------------
5 files changed, 42 insertions(+), 90 deletions(-)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index 85db45e27e912..7f04a7f4ab5fd 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -128,9 +128,6 @@ struct RuntimeLibcallsInfo {
}
private:
- static const RTLIB::LibcallImpl
- DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1];
-
/// Stores the implementation choice for each each libcall.
RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
RTLIB::Unsupported};
@@ -178,8 +175,6 @@ struct RuntimeLibcallsInfo {
return hasSinCos(TT) || TT.isPS();
}
- LLVM_ABI void initDefaultLibCallImpls();
-
/// Generated by tablegen.
void setTargetRuntimeLibcallSets(const Triple &TT,
FloatABI::ABIType FloatABI);
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 8ab63bd3d6b93..af339e2a55cf2 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1581,7 +1581,9 @@ def HexagonSystemLibrary
(add (sub DefaultLibcallImpls32,
__adddf3, __divsf3, __udivsi3, __udivdi3,
__umoddi3, __divdf3, __muldf3, __divsi3, __subdf3, sqrtf,
- __divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls)>;
+ __divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls,
+ LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+ exp10f, exp10, exp10l_f128)>;
//===----------------------------------------------------------------------===//
// Lanai Runtime Libcalls
@@ -2128,8 +2130,12 @@ def __memcpy_4 : RuntimeLibcallImpl<MEMCPY_ALIGN_4>;
def isXCore : RuntimeLibcallPredicate<"TT.getArch() == Triple::xcore">;
def XCoreSystemLibrary
- : SystemRuntimeLibrary<isXCore, (add DefaultRuntimeLibcallImpls,
- __memcpy_4)>;
+ : SystemRuntimeLibrary<isXCore,
+ (add DefaultRuntimeLibcallImpls,
+ exp10f, exp10, exp10l_f128,
+ __memcpy_4,
+ LibcallImpls<(add LibmF128Libcalls, LibmF128FiniteLibcalls), isGNUEnvironment>
+)>;
//===----------------------------------------------------------------------===//
// ZOS Runtime Libcalls
@@ -2246,3 +2252,27 @@ def WasmSystemLibrary
CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls,
exp10f, exp10,
emscripten_return_address)>;
+
+//===----------------------------------------------------------------------===//
+// Legacy Default Runtime Libcalls
+//===----------------------------------------------------------------------===//
+
+// TODO: Should make every target explicit.
+def isDefaultLibcallArch : RuntimeLibcallPredicate<[{
+ TT.isMIPS() || TT.isLoongArch() || TT.isVE() || TT.isBPF() ||
+ TT.getArch() == Triple::csky || TT.getArch() == Triple::arc ||
+ TT.getArch() == Triple::m68k || TT.getArch() == Triple::xtensa ||
+ (TT.isSystemZ() && !TT.isOSzOS()) ||
+ TT.isSPIRV() || TT.isDXIL()
+}]>;
+
+
+def isArch64Bit : RuntimeLibcallPredicate<[{TT.isArch64Bit()}]>;
+def LegacyDefaultSystemLibrary
+ : SystemRuntimeLibrary<isDefaultLibcallArch,
+ (add DefaultRuntimeLibcallImpls,
+ LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+ exp10f, exp10, exp10l_f128,
+ __powisf2, __powidf2, __powitf2_f128,
+ LibcallImpls<(add Int128RTLibcalls), isArch64Bit>
+)>;
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 8c71dda4cdf67..df529bc013cac 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -7,6 +7,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/RuntimeLibcalls.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "runtime-libcalls-info"
using namespace llvm;
using namespace RTLIB;
@@ -61,12 +64,6 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS);
}
-void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() {
- std::memcpy(LibcallImpls, DefaultLibcallImpls, sizeof(LibcallImpls));
- static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls),
- "libcall array size should match");
-}
-
/// Set default libcall names. If a target wants to opt-out of a libcall it
/// should be placed here.
void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
@@ -75,10 +72,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
EABI EABIVersion, StringRef ABIName) {
setTargetRuntimeLibcallSets(TT, FloatABI);
- // Early exit for targets that have fully ported to tablegen.
- if (TT.isAMDGPU() || TT.isNVPTX() || TT.isWasm())
- return;
-
if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) {
if (ExceptionModel == ExceptionHandling::SjLj)
setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume);
@@ -91,46 +84,17 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
// FIXME: What about other targets?
setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__extendhfsf2);
setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__truncsfhf2);
-
- if (!darwinHasExp10(TT)) {
- setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported);
- setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported);
- }
}
if (TT.isOSOpenBSD()) {
setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
}
- // Skip default manual processing for targets that have been mostly ported to
- // tablegen for now. Eventually the rest of this should be deleted.
- if (TT.isX86() || TT.isAArch64() || TT.isWasm() || TT.isPPC())
- return;
-
if (TT.isARM() || TT.isThumb()) {
setARMLibcallNames(*this, TT, FloatABI, EABIVersion);
return;
}
- if (hasSinCos(TT)) {
- setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf);
- setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos);
- setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128);
- }
-
- setLibcallImpl(RTLIB::EXP10_F32, RTLIB::exp10f);
- setLibcallImpl(RTLIB::EXP10_F64, RTLIB::exp10);
- setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10l_f128);
-
- // These libcalls are only available in compiler-rt, not libgcc.
- if (TT.isArch64Bit()) {
- setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3);
- setLibcallImpl(RTLIB::SRL_I128, RTLIB::__lshrti3);
- setLibcallImpl(RTLIB::SRA_I128, RTLIB::__ashrti3);
- setLibcallImpl(RTLIB::MUL_I128, RTLIB::__multi3);
- setLibcallImpl(RTLIB::MULO_I64, RTLIB::__mulodi4);
- }
-
if (TT.getArch() == Triple::ArchType::msp430) {
setLibcallImplCallingConv(RTLIB::__mspabi_mpyll,
CallingConv::MSP430_BUILTIN);
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td
index a0061afab1db0..61c0468fbb7a1 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td
@@ -104,18 +104,6 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-NEXT: #endif
// CHECK: #ifdef GET_INIT_RUNTIME_LIBCALL_NAMES
-// CHECK-NEXT: const RTLIB::LibcallImpl llvm::RTLIB::RuntimeLibcallsInfo::DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
-// CHECK-NEXT: RTLIB::Unsupported, // RTLIB::BZERO
-// CHECK-NEXT: RTLIB::Unsupported, // RTLIB::CALLOC
-// CHECK-NEXT: RTLIB::Unsupported, // RTLIB::MEMCPY
-// CHECK-NEXT: RTLIB::Unsupported, // RTLIB::MEMSET
-// CHECK-NEXT: RTLIB::__ashlsi3, // RTLIB::SHL_I32
-// CHECK-NEXT: RTLIB::sqrtl_f80, // RTLIB::SQRT_F80
-// CHECK-NEXT: RTLIB::sqrtl_f128, // RTLIB::SQRT_F128
-// CHECK-NEXT: RTLIB::__lshrdi3, // RTLIB::SRL_I64
-// CHECK-NEXT: RTLIB::Unsupported
-// CHECK-NEXT: };
-// CHECK-EMPTY:
// CHECK-NEXT: const char *const llvm::RTLIB::RuntimeLibcallsInfo::LibCallImplNames[RTLIB::NumLibcallImpls] = {
// CHECK-NEXT: nullptr, // RTLIB::Unsupported
// CHECK-NEXT: "___memcpy", // RTLIB::___memcpy
@@ -236,7 +224,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
-// CHECK-NEXT: initDefaultLibCallImpls();
+// CHECK-NEXT: LLVM_DEBUG(dbgs() << "no system runtime library applied to target \'" << TT.str() << "\'\n");
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK: #endif
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index 68bd1b5c9cb21..11f2075263a94 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -307,29 +307,6 @@ void RuntimeLibcallEmitter::emitGetInitRuntimeLibcallNames(
raw_ostream &OS) const {
// TODO: Emit libcall names as string offset table.
- OS << "const RTLIB::LibcallImpl "
- "llvm::RTLIB::RuntimeLibcallsInfo::"
- "DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {\n";
-
- for (const RuntimeLibcall &LibCall : RuntimeLibcallDefList) {
- auto I = LibCallToDefaultImpl.find(&LibCall);
- if (I == LibCallToDefaultImpl.end()) {
- OS << " RTLIB::Unsupported,";
- } else {
- const RuntimeLibcallImpl *LibCallImpl = I->second;
- OS << " ";
- LibCallImpl->emitEnumEntry(OS);
- OS << ',';
- }
-
- OS << " // ";
- LibCall.emitEnumEntry(OS);
- OS << '\n';
- }
-
- OS << " RTLIB::Unsupported\n"
- "};\n\n";
-
// Emit the implementation names
OS << "const char *const llvm::RTLIB::RuntimeLibcallsInfo::"
"LibCallImplNames[RTLIB::NumLibcallImpls] = {\n"
@@ -528,13 +505,11 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
TopLevelPredicate.emitEndIf(OS);
}
- // Fallback to the old default set for manual table entries.
- //
- // TODO: Remove this when targets have switched to using generated tables by
- // default.
- OS << " initDefaultLibCallImpls();\n";
-
- OS << "}\n\n";
+ // FIXME: This should be a fatal error. A few contexts are improperly relying
+ // on RuntimeLibcalls constructed with fully unknown triples.
+ OS << " LLVM_DEBUG(dbgs() << \"no system runtime library applied to target "
+ "\\'\" << TT.str() << \"\\'\\n\");\n"
+ "}\n\n";
}
void RuntimeLibcallEmitter::run(raw_ostream &OS) {
More information about the llvm-branch-commits
mailing list