https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/217593
When a SystemRuntimeLibrary names LibcallLibrary defs, setTargetRuntimeLibcallSets now dispatches each under an isLibraryAvailable guard, so an impl can be homed into a library without dropping it from the target. Non-library members keep the inline path. No target names a library yet, so output is unchanged. Co-authored-by: Claude (Claude-Opus-4.8) <[email protected]> >From 5a4699f6078d43ea95c4381ace08bb91fb0e0ab7 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Thu, 13 Aug 2026 16:11:18 +0200 Subject: [PATCH] RuntimeLibcalls: Dispatch to library functions from SystemRuntimeLibrary When a SystemRuntimeLibrary names LibcallLibrary defs, setTargetRuntimeLibcallSets now dispatches each under an isLibraryAvailable guard, so an impl can be homed into a library without dropping it from the target. Non-library members keep the inline path. No target names a library yet, so output is unchanged. Co-authored-by: Claude (Claude-Opus-4.8) <[email protected]> --- .../RuntimeLibcallEmitter-library-dispatch.td | 52 +++++++++++++++++++ .../TableGen/Basic/RuntimeLibcallsEmitter.cpp | 41 ++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td b/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td new file mode 100644 index 0000000000000..7705dde4fafbb --- /dev/null +++ b/llvm/test/TableGen/RuntimeLibcallEmitter-library-dispatch.td @@ -0,0 +1,52 @@ +// RUN: llvm-tblgen -gen-runtime-libcalls -I %p/../../include %s | FileCheck %s + +// Check that a SystemRuntimeLibrary naming LibcallLibrary defs dispatches to +// their setAvailableLibFuncs_<name> functions under an isLibraryAvailable guard, +// inside the target's triple block, while bare (non-library) members are still +// emitted inline via the flat path. + +include "llvm/IR/RuntimeLibcallsImpl.td" + +def MEMCPY : RuntimeLibcall; +def SQRT_F64 : RuntimeLibcall; +def EXTRA : RuntimeLibcall; + +def memcpy : RuntimeLibcallImpl<MEMCPY>; +def sqrt : RuntimeLibcallImpl<SQRT_F64, "sqrt">; +def extra : RuntimeLibcallImpl<EXTRA>; + +def IsX86 : LibcallPredicate<[{TT.isX86()}]>; +def isX86 : RuntimeLibcallAvailability<(all_of IsX86)>; + +def Libc : LibcallLibrary<"libc", (add memcpy)>; +def Libm : LibcallLibrary<"libm", (add sqrt)>; + +// Pulls two named libraries plus one bare inline member. +def X86System : SystemRuntimeLibrary<isX86, (add Libc, Libm, extra)>; + +// The named libraries still get their standalone implementation functions. + +// CHECK: static void setAvailableLibFuncs_libc( +// CHECK: static void setAvailableLibFuncs_libm( + +// The driver dispatches to each named library under its presence guard, then +// emits the bare member (extra) inline. + +// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, LongDoubleFormat LongDoubleFormat) { +// CHECK: if (TT.isX86()) { +// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({ +// CHECK: AvailableLibcallImpls = SystemAvailableImpls; +// CHECK-EMPTY: +// CHECK-NEXT: if (isLibraryAvailable("libc")) +// CHECK-NEXT: setAvailableLibFuncs_libc(*this, TT, ExceptionModel, FloatABI, EABIVersion, ABIName, LongDoubleFormat); +// CHECK-NEXT: if (isLibraryAvailable("libm")) +// CHECK-NEXT: setAvailableLibFuncs_libm(*this, TT, ExceptionModel, FloatABI, EABIVersion, ABIName, LongDoubleFormat); +// CHECK-EMPTY: +// CHECK-NEXT: static const RTLIB::LibcallImpl LibraryCalls[] = { +// CHECK-NEXT: RTLIB::impl_extra, // extra +// CHECK-NEXT: }; +// CHECK: for (const RTLIB::LibcallImpl Impl : LibraryCalls) { +// CHECK-NEXT: setAvailable(Impl); +// CHECK-NEXT: } +// CHECK: return; +// CHECK-NEXT: } diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp index 2dbff92f623c0..1a90c36f2a879 100644 --- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp +++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp @@ -650,6 +650,29 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( } } + // Split the top-level member list into named LibcallLibrary references, + // which are dispatched to their own setAvailableLibFuncs_<name> function + // under an isLibraryAvailable guard, and the remaining (bare impl / + // LibcallImpls) members, which are emitted inline via the flat path below. + const DagInit *MemberDag = + R->getValueAsDef("MemberList")->getValueAsDag("MemberList"); + SmallVector<StringRef, 4> DispatchLibs; + SmallVector<const Init *, 16> InlineArgs; + SmallVector<const StringInit *, 16> InlineArgNames; + for (auto [Arg, ArgName] : + zip_equal(MemberDag->getArgs(), MemberDag->getArgNames())) { + if (const auto *DI = dyn_cast<DefInit>(Arg); + DI && DI->getDef()->isSubClassOf("LibcallLibrary")) { + DispatchLibs.push_back(DI->getDef()->getValueAsString("LibraryName")); + continue; + } + InlineArgs.push_back(Arg); + InlineArgNames.push_back(ArgName); + } + + const DagInit *InlineDag = + DagInit::get(MemberDag->getOperator(), InlineArgs, InlineArgNames); + SetTheory Sets; DenseMap<const RuntimeLibcallImpl *, @@ -658,8 +681,9 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( Sets.addExpander("LibcallImpls", std::make_unique<LibcallPredicateExpander>( Libcalls, Func2Preds)); - const SetTheory::RecVec *Elements = - Sets.expand(R->getValueAsDef("MemberList")); + SetTheory::RecSet ElementsSet; + Sets.evaluate(InlineDag, ElementsSet, R->getLoc()); + const SetTheory::RecSet *Elements = &ElementsSet; // Sort to get deterministic output SetVector<PredicateWithCC> PredicateSorter; @@ -722,6 +746,19 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( OS << "\n });\n" " AvailableLibcallImpls = SystemAvailableImpls;\n\n"; + // Dispatch to each named library's setup function. This must come after the + // SystemAvailableImpls assignment above (which overwrites the bitset); the + // library functions union their members in on top via setAvailable. + for (StringRef LibName : DispatchLibs) { + OS << indent(4) << "if (isLibraryAvailable(\"" << LibName << "\"))\n" + << indent(6) << "setAvailableLibFuncs_"; + emitLibFuncSuffix(OS, LibName); + OS << "(*this, TT, ExceptionModel, FloatABI, EABIVersion, ABIName, " + "LongDoubleFormat);\n"; + } + if (!DispatchLibs.empty()) + OS << '\n'; + emitPredicateGroups(OS, R, Pred2Funcs, PredicateSorter, /*BaseIndent=*/2, /*Receiver=*/""); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
