[llvm-branch-commits] [llvm] RuntimeLibcalls: Migrate to dag libcall predicates (PR #210674)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jul 20 03:13:57 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/210674

Switch to using dag predicates instead of free-form code predicates.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

>From fdecb09823696c2808fe92babb6f84e5afa01d88 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 18 Jul 2026 07:50:17 +0200
Subject: [PATCH] RuntimeLibcalls: Migrate to dag libcall predicates

Switch to using dag predicates instead of free-form code predicates.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
 llvm/include/llvm/IR/RuntimeLibcalls.h        |  26 --
 llvm/include/llvm/IR/RuntimeLibcalls.td       | 349 ++++++++++++------
 llvm/include/llvm/IR/RuntimeLibcallsImpl.td   |  28 +-
 llvm/lib/IR/RuntimeLibcalls.cpp               |  17 -
 ...lEmitter-bad-system-library-entry-error.td |   3 +-
 .../RuntimeLibcallEmitter-calling-conv.td     |  17 +-
 .../RuntimeLibcallEmitter-conflict-warning.td |  10 +-
 ...eLibcallEmitter-nested-predicates-error.td |  10 +-
 ...RuntimeLibcallEmitter-predicate-cc-sort.td |   3 +-
 ...timeLibcallEmitter-predicate-dag-errors.td |  11 +-
 .../RuntimeLibcallEmitter-predicate-dag.td    |  15 +-
 llvm/test/TableGen/RuntimeLibcallEmitter.td   |  31 +-
 llvm/utils/TableGen/Basic/RuntimeLibcalls.h   |   9 +-
 13 files changed, 314 insertions(+), 215 deletions(-)

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index f43e09ada394e..78b75f3e81c3b 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -210,35 +210,9 @@ struct RuntimeLibcallsInfo {
     return true;
   }
 
-  static bool darwinHasMemsetPattern(const Triple &TT) {
-    // memset_pattern{4,8,16} is only available on iOS 3.0 and Mac OS X 10.5 and
-    // later. All versions of watchOS support it.
-    if (TT.isMacOSX())
-      return !TT.isMacOSXVersionLT(10, 5);
-    if (TT.isiOS())
-      return !TT.isOSVersionLT(3, 0);
-    return TT.isWatchOS();
-  }
-
-  static bool hasAEABILibcalls(const Triple &TT) {
-    return TT.isTargetAEABI() || TT.isTargetGNUAEABI() ||
-           TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isAndroid();
-  }
-
   LLVM_READONLY
   static bool isAAPCS_ABI(const Triple &TT, StringRef ABIName);
 
-  static bool darwinHasExp10(const Triple &TT);
-
-  /// Return true if the target has sincosf/sincos/sincosl functions
-  static bool hasSinCos(const Triple &TT) {
-    return TT.isGNUEnvironment() || TT.isOSFuchsia() || TT.isAndroid();
-  }
-
-  static bool hasSinCos_f32_f64(const Triple &TT) {
-    return hasSinCos(TT) || TT.isPS();
-  }
-
   /// Generated by tablegen.
   void setTargetRuntimeLibcallSets(const Triple &TT,
                                    ExceptionHandling ExceptionModel,
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 802188be31d09..9d07a15fd9e4e 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -15,66 +15,168 @@ include "llvm/IR/RuntimeLibcallsImpl.td"
 class DuplicateLibcallImplWithPrefix<RuntimeLibcallImpl Impl, string prefix>
     : RuntimeLibcallImpl<Impl.Provides, prefix#Impl.LibCallFuncName>;
 
+def IsOSDarwin : LibcallPredicate<[{TT.isOSDarwin()}]>;
+def IsOSOpenBSD : LibcallPredicate<[{TT.isOSOpenBSD()}]>;
+def IsOSWindows : LibcallPredicate<[{TT.isOSWindows()}]>;
+def IsOSLinux : LibcallPredicate<[{TT.isOSLinux()}]>;
+def IsOSMSVCRT : LibcallPredicate<[{TT.isOSMSVCRT()}]>;
+def IsPS : LibcallPredicate<[{TT.isPS()}]>;
+def IsMacOSX : LibcallPredicate<[{TT.isMacOSX()}]>;
+
+def IsWindowsMSVCEnv : LibcallPredicate<[{TT.isWindowsMSVCEnvironment()}]>;
+def IsWindowsItaniumEnv
+  : LibcallPredicate<[{TT.isWindowsItaniumEnvironment()}]>;
+def IsWindowsArm64EC : LibcallPredicate<[{TT.isWindowsArm64EC()}]>;
+
+def IsAndroid : LibcallPredicate<[{TT.isAndroid()}]>;
+def IsGNUEnv : LibcallPredicate<[{TT.isGNUEnvironment()}]>;
+def IsOSFuchsia : LibcallPredicate<[{TT.isOSFuchsia()}]>;
+
+def IsTargetAEABI : LibcallPredicate<[{TT.isTargetAEABI()}]>;
+def IsTargetGNUAEABI : LibcallPredicate<[{TT.isTargetGNUAEABI()}]>;
+def IsTargetMuslAEABI : LibcallPredicate<[{TT.isTargetMuslAEABI()}]>;
+
+def IsOSBinFormatMachO : LibcallPredicate<[{TT.isOSBinFormatMachO()}]>;
+
+def IsAArch64 : LibcallPredicate<[{TT.isAArch64()}]>;
+def IsAArch64_ILP64 : LibcallPredicate<[{TT.isAArch64(64)}]>;
+def IsIsiOS : LibcallPredicate<[{TT.isiOS()}]>;
+def IsIOS : LibcallPredicate<[{TT.getOS() == Triple::IOS}]>;
+def IsTvOS : LibcallPredicate<[{TT.isTvOS()}]>;
+def IsWatchOS : LibcallPredicate<[{TT.isWatchOS()}]>;
+def IsDriverKit : LibcallPredicate<[{TT.isDriverKit()}]>;
+def IsXROS : LibcallPredicate<[{TT.isXROS()}]>;
+def IsBridgeOS : LibcallPredicate<[{TT.getOS() == Triple::BridgeOS}]>;
+
+class MacOSXVersionAtLeast<int major, int minor>
+  : LibcallPredicate<[{!TT.isMacOSXVersionLT(}] # !cast<string>(major)
+                     # [{, }] # !cast<string>(minor) # [{)}]>;
+class OSVersionAtLeast<int major, int minor>
+  : LibcallPredicate<[{!TT.isOSVersionLT(}] # !cast<string>(major)
+                     # [{, }] # !cast<string>(minor) # [{)}]>;
+
+def IsAAPCS_ABI : LibcallPredicate<[{isAAPCS_ABI(TT, ABIName)}]>;
+def IsEABI4 : LibcallPredicate<[{EABIVersion == EABI::EABI4}]>;
+def IsEABI5 : LibcallPredicate<[{EABIVersion == EABI::EABI5}]>;
+
+def IsAMDGPU : LibcallPredicate<[{TT.isAMDGPU()}]>;
+def IsARM : LibcallPredicate<[{TT.isARM()}]>;
+def IsThumb : LibcallPredicate<[{TT.isThumb()}]>;
+def IsAVR : LibcallPredicate<[{TT.getArch() == Triple::avr}]>;
+def IsDXIL : LibcallPredicate<[{TT.isDXIL()}]>;
+def IsHexagon : LibcallPredicate<[{TT.getArch() == Triple::hexagon}]>;
+def IsLanai : LibcallPredicate<[{TT.getArch() == Triple::lanai}]>;
+def IsMSP430 : LibcallPredicate<[{TT.getArch() == Triple::msp430}]>;
+def IsNVPTX : LibcallPredicate<[{TT.isNVPTX()}]>;
+
+def IsPPC : LibcallPredicate<[{TT.isPPC()}]>;
+def IsPPC32 : LibcallPredicate<[{TT.isPPC32()}]>;
+def IsPPC64 : LibcallPredicate<[{TT.isPPC64()}]>;
+def IsOSAIX : LibcallPredicate<[{TT.isOSAIX()}]>;
+
+def IsRISCV : LibcallPredicate<[{TT.isRISCV()}]>;
+def IsRISCV64 : LibcallPredicate<[{TT.isRISCV64()}]>;
+def IsSPARC : LibcallPredicate<[{TT.isSPARC()}]>;
+def IsSPARC32 : LibcallPredicate<[{TT.isSPARC32()}]>;
+def IsSPARC64 : LibcallPredicate<[{TT.isSPARC64()}]>;
+def IsSPIRV : LibcallPredicate<[{TT.isSPIRV()}]>;
+
+def IsX86_32 : LibcallPredicate<[{TT.getArch() == Triple::x86}]>;
+def IsX86_64 : LibcallPredicate<[{TT.getArch() == Triple::x86_64}]>;
+def IsX86 : LibcallPredicate<[{TT.isX86()}]>;
+def IsXCore : LibcallPredicate<[{TT.getArch() == Triple::xcore}]>;
+
+def IsOSzOS : LibcallPredicate<[{TT.isOSzOS()}]>;
+def IsSystemZ : LibcallPredicate<[{TT.isSystemZ()}]>;
+def IsWasm : LibcallPredicate<[{TT.isWasm()}]>;
+def IsOSEmscripten : LibcallPredicate<[{TT.isOSEmscripten()}]>;
+def IsArch64Bit : LibcallPredicate<[{TT.isArch64Bit()}]>;
+
+def IsOSCygMing : LibcallPredicate<[{TT.isOSCygMing()}]>;
+def IsOSWindowsOrUEFI : LibcallPredicate<[{TT.isOSWindowsOrUEFI()}]>;
+
+def IsMIPS : LibcallPredicate<[{TT.isMIPS()}]>;
+def IsLoongArch : LibcallPredicate<[{TT.isLoongArch()}]>;
+def IsVE : LibcallPredicate<[{TT.isVE()}]>;
+def IsBPF : LibcallPredicate<[{TT.isBPF()}]>;
+def IsArchCSKY : LibcallPredicate<[{TT.getArch() == Triple::csky}]>;
+def IsArchArc : LibcallPredicate<[{TT.getArch() == Triple::arc}]>;
+def IsArchM68k : LibcallPredicate<[{TT.getArch() == Triple::m68k}]>;
+def IsArchXtensa : LibcallPredicate<[{TT.getArch() == Triple::xtensa}]>;
+
 /// Libcall Predicates
-def isOSDarwin : RuntimeLibcallAvailability<"TT.isOSDarwin()">;
-def isOSOpenBSD : RuntimeLibcallAvailability<"TT.isOSOpenBSD()">;
-def isNotOSOpenBSD : RuntimeLibcallAvailability<"!TT.isOSOpenBSD()">;
-def isOSWindows : RuntimeLibcallAvailability<"TT.isOSWindows()">;
-def isNotOSWindows : RuntimeLibcallAvailability<"!TT.isOSWindows()">;
-def isNotOSLinux : RuntimeLibcallAvailability<[{!TT.isOSLinux()}]>;
-def isNotOSMSVCRT : RuntimeLibcallAvailability<"!TT.isOSMSVCRT()">;
-def isPS : RuntimeLibcallAvailability<"TT.isPS()">;
-def isMacOSX : RuntimeLibcallAvailability<[{TT.isMacOSX()}]>;
+def isOSDarwin : RuntimeLibcallAvailability<(all_of IsOSDarwin)>;
+def isOSOpenBSD : RuntimeLibcallAvailability<(all_of IsOSOpenBSD)>;
+def isNotOSOpenBSD : RuntimeLibcallAvailability<(not IsOSOpenBSD)>;
+def isOSWindows : RuntimeLibcallAvailability<(all_of IsOSWindows)>;
+def isNotOSWindows : RuntimeLibcallAvailability<(not IsOSWindows)>;
+def isNotOSLinux : RuntimeLibcallAvailability<(not IsOSLinux)>;
+def isNotOSMSVCRT : RuntimeLibcallAvailability<(not IsOSMSVCRT)>;
+def isPS : RuntimeLibcallAvailability<(all_of IsPS)>;
+def isMacOSX : RuntimeLibcallAvailability<(all_of IsMacOSX)>;
 def isNotOSWindowsOrIsCygwinMinGW
-  : RuntimeLibcallAvailability<"!TT.isOSWindows() || TT.isOSCygMing()">;
+  : RuntimeLibcallAvailability<(any_of (not IsOSWindows), IsOSCygMing)>;
 
-def isWindowsMSVCEnvironment : RuntimeLibcallAvailability<
-  [{TT.isWindowsMSVCEnvironment()}]>;
+def isWindowsMSVCEnvironment
+  : RuntimeLibcallAvailability<(all_of IsWindowsMSVCEnv)>;
 
-def isNotOSLinuxAndNotOSOpenBSD : RuntimeLibcallAvailability<
-  [{!TT.isOSLinux() && !TT.isOSOpenBSD()}]>;
+def isNotOSLinuxAndNotOSOpenBSD
+  : RuntimeLibcallAvailability<(all_of (not IsOSLinux), (not IsOSOpenBSD))>;
 
-def isNotOSAIXAndNotOSOpenBSD : RuntimeLibcallAvailability<
-  [{!TT.isOSAIX() && !TT.isOSOpenBSD()}]>;
+def isNotOSAIXAndNotOSOpenBSD
+  : RuntimeLibcallAvailability<(all_of (not IsOSAIX), (not IsOSOpenBSD))>;
 
-def isNotPS : RuntimeLibcallAvailability<
-  [{!TT.isPS()}]>;
+def isNotPS : RuntimeLibcallAvailability<(not IsPS)>;
 
 // OpenBSD uses __guard_local. AIX uses __ssp_canary_word, MSVC/Windows
 // Itanium uses __security_cookie
 def hasStackChkFail : RuntimeLibcallAvailability<
-  [{ !TT.isOSOpenBSD() && !TT.isWindowsMSVCEnvironment() &&
-     !TT.isWindowsItaniumEnvironment()}]>;
+  (all_of (not IsOSOpenBSD), (not IsWindowsMSVCEnv),
+          (not IsWindowsItaniumEnv))>;
 
-def isWindowsMSVCOrItaniumEnvironment : RuntimeLibcallAvailability<
-  [{TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()}]>;
+def isWindowsMSVCOrItaniumEnvironment
+  : RuntimeLibcallAvailability<(any_of IsWindowsMSVCEnv, IsWindowsItaniumEnv)>;
 
-def isAndroid : RuntimeLibcallAvailability<"TT.isAndroid()">;
+def isAndroid : RuntimeLibcallAvailability<(all_of IsAndroid)>;
 
-def isGNUEnvironment : RuntimeLibcallAvailability<"TT.isGNUEnvironment()">;
-def darwinHasSinCosStret : RuntimeLibcallAvailability<"darwinHasSinCosStret(TT)">;
-def darwinHasExp10 : RuntimeLibcallAvailability<"darwinHasExp10(TT)">;
-def darwinHasMemsetPattern : RuntimeLibcallAvailability<[{darwinHasMemsetPattern(TT)}]>;
+def isGNUEnvironment : RuntimeLibcallAvailability<(all_of IsGNUEnv)>;
+def darwinHasSinCosStret : RuntimeLibcallAvailability<
+  (all_of IsOSDarwin, (not IsX86_32),
+          (any_of (all_of IsMacOSX, MacOSXVersionAtLeast<10, 9>, IsArch64Bit),
+                  (all_of IsIsiOS, OSVersionAtLeast<7, 0>),
+                  (all_of (not IsMacOSX), (not IsIsiOS))))>;
 
-def hasExp10 : RuntimeLibcallAvailability<[{!TT.isOSDarwin()}]>;
+def darwinHasExp10 : RuntimeLibcallAvailability<
+  (any_of (all_of IsMacOSX, MacOSXVersionAtLeast<10, 9>),
+          (all_of IsIOS, OSVersionAtLeast<7, 0>),
+          IsDriverKit, IsTvOS, IsWatchOS, IsXROS, IsBridgeOS)>;
 
-def hasSinCos : RuntimeLibcallAvailability<"hasSinCos(TT)">;
+def darwinHasMemsetPattern : RuntimeLibcallAvailability<
+  (any_of (all_of IsMacOSX, MacOSXVersionAtLeast<10, 5>),
+          (all_of IsIsiOS, OSVersionAtLeast<3, 0>),
+          IsWatchOS)>;
 
-// FIXME: Way to combine predicates
-def hasSinCos_f32_f64 : RuntimeLibcallAvailability<"hasSinCos_f32_f64(TT)">;
+def hasExp10 : RuntimeLibcallAvailability<(not IsOSDarwin)>;
 
-def ExceptionModelIsNotNone : RuntimeLibcallAvailability<
-  [{ExceptionModel != ExceptionHandling::None}]
->;
+def hasSinCos
+  : RuntimeLibcallAvailability<(any_of IsGNUEnv, IsOSFuchsia, IsAndroid)>;
+
+def hasSinCos_f32_f64
+  : RuntimeLibcallAvailability<(any_of IsGNUEnv, IsOSFuchsia, IsAndroid, IsPS)>;
+
+def IsExceptionModelNone
+  : LibcallPredicate<[{ExceptionModel == ExceptionHandling::None}]>;
+def IsExceptionModelSjLj
+  : LibcallPredicate<[{ExceptionModel == ExceptionHandling::SjLj}]>;
+
+def ExceptionModelIsNotNone
+  : RuntimeLibcallAvailability<(not IsExceptionModelNone)>;
 
 def ExceptionModelHasUnwindResume : RuntimeLibcallAvailability<
-  [{ExceptionModel != ExceptionHandling::None &&
-    ExceptionModel != ExceptionHandling::SjLj}]
->;
+  (all_of (not IsExceptionModelNone), (not IsExceptionModelSjLj))>;
 
-def ExceptionModelIsSjLj : RuntimeLibcallAvailability<
-  [{ExceptionModel == ExceptionHandling::SjLj}]
->;
+def ExceptionModelIsSjLj
+  : RuntimeLibcallAvailability<(all_of IsExceptionModelSjLj)>;
 
 //--------------------------------------------------------------------
 // Declare all kinds of used libcalls
@@ -1998,9 +2100,10 @@ def SMEABI_LibCalls_PreserveMost_From_X2 : LibcallsWithCC<(add
   SMEABI_PreserveMost_From_X2>;
 
 def isAArch64_ExceptArm64EC
-    : RuntimeLibcallAvailability<"(TT.isAArch64() && !TT.isWindowsArm64EC())">;
-def isWindowsArm64EC : RuntimeLibcallAvailability<"TT.isWindowsArm64EC()">;
-def isAArch64_ILP64  : RuntimeLibcallAvailability<"TT.isAArch64(64)">;
+    : RuntimeLibcallAvailability<(all_of IsAArch64, (not IsWindowsArm64EC))>;
+def isWindowsArm64EC : RuntimeLibcallAvailability<(all_of IsWindowsArm64EC)>;
+def isAArch64_ILP64
+    : RuntimeLibcallAvailability<(all_of IsAArch64_ILP64)>;
 
 
 def AArch64SystemLibrary : SystemRuntimeLibrary<
@@ -2075,7 +2178,7 @@ def WindowsARM64ECSystemLibrary
 // AMDGPU Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isAMDGPU : RuntimeLibcallAvailability<"TT.isAMDGPU()">;
+def isAMDGPU : RuntimeLibcallAvailability<(all_of IsAMDGPU)>;
 
 def __llvm_profile_instrument_gpu : RuntimeLibcallImpl<PROFILE_INSTRUMENT_GPU>;
 def __llvm_profile_sampling_gpu : RuntimeLibcallImpl<PROFILE_SAMPLING_GPU>;
@@ -2088,8 +2191,19 @@ def AMDGPUSystemLibrary
 // ARM Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isTargetAEABIAndAAPCS_ABI : RuntimeLibcallAvailability<
-  [{TT.isTargetAEABI() && isAAPCS_ABI(TT, ABIName)}]>;
+def isTargetAEABIAndAAPCS_ABI
+    : RuntimeLibcallAvailability<(all_of IsTargetAEABI, IsAAPCS_ABI)>;
+
+defvar HasAEABILibcallsDag =
+  (any_of IsTargetAEABI, IsTargetGNUAEABI, IsTargetMuslAEABI,
+          IsOSFuchsia, IsAndroid);
+
+def hasAEABILibcalls : RuntimeLibcallAvailability<HasAEABILibcallsDag>;
+
+def hasAEABILibcallsAndAAPCS_ABI : RuntimeLibcallAvailability<
+  (all_of (any_of IsTargetAEABI, IsTargetGNUAEABI, IsTargetMuslAEABI,
+                  IsOSFuchsia, IsAndroid),
+          IsAAPCS_ABI)>;
 
 // if (isTargetMachO()) {
 // if (Subtarget->isThumb() && Subtarget->hasVFP2Base() &&
@@ -2340,17 +2454,20 @@ def ARMHalfConvertLibcallCallingConv : LibcallCallingConv<
     static_cast<CallingConv::ID>(isAAPCS_ABI(TT, ABIName) ? CallingConv::ARM_AAPCS : CallingConv::ARM_APCS)}]
 >;
 
+def isNotTargetAEABIAndMachO
+    : RuntimeLibcallAvailability<(all_of (not IsTargetAEABI),
+                                            IsOSBinFormatMachO)>;
+def isNotTargetAEABI : RuntimeLibcallAvailability<(not IsTargetAEABI)>;
+
 def ARMLibgccHalfConvertCalls :
-  LibcallImpls<(add __truncsfhf2, __extendhfsf2),
-    RuntimeLibcallAvailability<[{!TT.isTargetAEABI() && TT.isOSBinFormatMachO()}]>> {
+  LibcallImpls<(add __truncsfhf2, __extendhfsf2), isNotTargetAEABIAndMachO> {
   let CallingConv = ARMHalfConvertLibcallCallingConv;
 }
 
 // FIXME: These conditions are probably bugged. We're using the
 // default libgcc call when the other cases are replaced.
 def ARMDoubleToHalfCalls :
-  LibcallImpls<(add __truncdfhf2),
-    RuntimeLibcallAvailability<[{!TT.isTargetAEABI()}]>> {
+  LibcallImpls<(add __truncdfhf2), isNotTargetAEABI> {
   let CallingConv = ARMHalfConvertLibcallCallingConv;
 }
 
@@ -2361,10 +2478,13 @@ def EABIHalfConvertCalls : LibcallImpls<(add __aeabi_f2h, __aeabi_h2f),
   let CallingConv = ARM_AAPCS;
 }
 
+def isNotMachOAndNotTargetAEABI
+    : RuntimeLibcallAvailability<(all_of (not IsOSBinFormatMachO),
+                                            (not IsTargetAEABI))>;
+
 def GNUEABIHalfConvertCalls :
   LibcallImpls<(add __gnu_f2h_ieee, __gnu_h2f_ieee),
-    RuntimeLibcallAvailability<[{!TT.isOSBinFormatMachO() &&
-                              !TT.isTargetAEABI()}]>> {
+    isNotMachOAndNotTargetAEABI> {
   let CallingConv = ARMHalfConvertLibcallCallingConv;
 }
 
@@ -2385,7 +2505,7 @@ def WindowARMFPIntCasts : LibcallImpls<
 def AEABIDivRemCalls : LibcallImpls<
   (add __aeabi_idivmod, __aeabi_ldivmod,
        __aeabi_uidivmod, __aeabi_uldivmod),
-  RuntimeLibcallAvailability<[{hasAEABILibcalls(TT)}]>> {
+  hasAEABILibcalls> {
   let CallingConv = ARM_AAPCS;
 }
 
@@ -2466,7 +2586,7 @@ def AEABICalls : LibcallImpls<
       // RTABI chapter 4.3.1
       __aeabi_idiv,
       __aeabi_uidiv),
-  RuntimeLibcallAvailability<[{hasAEABILibcalls(TT) && isAAPCS_ABI(TT, ABIName)}]>> {
+  hasAEABILibcallsAndAAPCS_ABI> {
   let CallingConv = ARM_AAPCS;
 }
 
@@ -2477,9 +2597,11 @@ def AEABI45MemCalls : LibcallImpls<
        __aeabi_memmove, __aeabi_memmove4, __aeabi_memmove8,
        __aeabi_memset, __aeabi_memset4, __aeabi_memset8,
        __aeabi_memclr, __aeabi_memclr4, __aeabi_memclr8),
-  RuntimeLibcallAvailability<[{(EABIVersion == EABI::EABI4 ||
-                             EABIVersion == EABI::EABI5) &&
-                             hasAEABILibcalls(TT) && isAAPCS_ABI(TT, ABIName)}]>> {
+  RuntimeLibcallAvailability<
+    (all_of (any_of IsEABI4, IsEABI5),
+            (any_of IsTargetAEABI, IsTargetGNUAEABI, IsTargetMuslAEABI,
+                    IsOSFuchsia, IsAndroid),
+            IsAAPCS_ABI)>> {
   let CallingConv = ARM_AAPCS;
 }
 
@@ -2488,11 +2610,11 @@ def AEABI45MemCalls : LibcallImpls<
 def AEABIUnalignedMemCalls : LibcallImpls<
   (add __aeabi_uread4,  __aeabi_uread8,
        __aeabi_uwrite4, __aeabi_uwrite8),
-  RuntimeLibcallAvailability<[{hasAEABILibcalls(TT) && isAAPCS_ABI(TT, ABIName)}]>> {
+  hasAEABILibcallsAndAAPCS_ABI> {
   let CallingConv = ARM_AAPCS;
 }
 
-def isARMOrThumb : RuntimeLibcallAvailability<"TT.isARM() || TT.isThumb()">;
+def isARMOrThumb : RuntimeLibcallAvailability<(any_of IsARM, IsThumb)>;
 
 def ARMSystemLibrary
     : SystemRuntimeLibrary<isARMOrThumb,
@@ -2522,14 +2644,17 @@ def ARMSystemLibrary
            ARMDoubleToHalfCalls,
 
            LibcallImpls<(add AEABIOverrides),
-             RuntimeLibcallAvailability<[{
-               (!hasAEABILibcalls(TT) || !isAAPCS_ABI(TT, ABIName)) &&
-               !TT.isOSWindows()
-            }]>>,
+             RuntimeLibcallAvailability<
+               (all_of (any_of (not (any_of IsTargetAEABI, IsTargetGNUAEABI,
+                                            IsTargetMuslAEABI, IsOSFuchsia, IsAndroid)),
+                               (not IsAAPCS_ABI)),
+                       (not IsOSWindows))>>,
            // Use divmod compiler-rt calls for iOS 5.0 and later.
            LibcallImpls<(add __divmodsi4, __udivmodsi4),
-                        RuntimeLibcallAvailability<[{TT.isOSBinFormatMachO() &&
-                                                  (!TT.isiOS() || !TT.isOSVersionLT(5, 0))}]>>,
+                        RuntimeLibcallAvailability<
+                          (all_of IsOSBinFormatMachO,
+                                  (any_of (not IsIsiOS),
+                                          OSVersionAtLeast<5, 0>))>>,
            DefaultStackProtector,
            DefaultSafeStackGlobals)> {
   let DefaultLibcallCallingConv = LibcallCallingConv<[{
@@ -2557,7 +2682,7 @@ def __udivmodhi4 : RuntimeLibcallImpl<UDIVREM_I16>;
 def avr_sin : RuntimeLibcallImpl<SIN_F32, "sin">;
 def avr_cos : RuntimeLibcallImpl<COS_F32, "cos">;
 
-def isAVR : RuntimeLibcallAvailability<"TT.getArch() == Triple::avr">;
+def isAVR : RuntimeLibcallAvailability<(all_of IsAVR)>;
 
 def AVRSystemLibrary
     : SystemRuntimeLibrary<
@@ -2588,7 +2713,7 @@ def AVRSystemLibrary
 // DXIL Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isDXIL : RuntimeLibcallAvailability<"TT.isDXIL()">;
+def isDXIL : RuntimeLibcallAvailability<(all_of IsDXIL)>;
 
 // No calls
 def DXILSystemLibrary : SystemRuntimeLibrary<isDXIL, (add)>;
@@ -2634,7 +2759,7 @@ def __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
 def hexagon_memcpy_forward_vp4cp4n2 : RuntimeLibcallImpl<HEXAGON_VOLATILE_MEMCPY>;
 }
 
-def isHexagon : RuntimeLibcallAvailability<"TT.getArch() == Triple::hexagon">;
+def isHexagon : RuntimeLibcallAvailability<(all_of IsHexagon)>;
 
 def HexagonSystemLibrary
     : SystemRuntimeLibrary<isHexagon,
@@ -2650,7 +2775,7 @@ def HexagonSystemLibrary
 // Lanai Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isLanai : RuntimeLibcallAvailability<"TT.getArch() == Triple::lanai">;
+def isLanai : RuntimeLibcallAvailability<(all_of IsLanai)>;
 
 // Use fast calling convention for library functions.
 def LanaiSystemLibrary
@@ -2840,7 +2965,7 @@ def __mspabi_mpyll : RuntimeLibcallImpl<MUL_I64>;
 
 // setLibcallCallingConv(MUL_I64, CallingConv::MSP430_BUILTIN);
 
-def isMSP430 : RuntimeLibcallAvailability<"TT.getArch() == Triple::msp430">;
+def isMSP430 : RuntimeLibcallAvailability<(all_of IsMSP430)>;
 
 defvar MSP430DefaultOptOut = [
   __addsf3, __divsf3, __extendsfdf2, __truncdfsf2, __fixsfsi,
@@ -2964,7 +3089,7 @@ def MSP430SystemLibrary
 // NVPTX Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isNVPTX : RuntimeLibcallAvailability<"TT.isNVPTX()">;
+def isNVPTX : RuntimeLibcallAvailability<(all_of IsNVPTX)>;
 
 // No calls.
 def NVPTXSystemLibrary : SystemRuntimeLibrary<isNVPTX, (add)>;
@@ -3032,13 +3157,13 @@ defset list<RuntimeLibcallImpl> PPC32AIXCallList = {
 
 defvar PPCOverrides = !foreach(entry, PPCRuntimeLibcalls, entry.Provides);
 
-def isPPC : RuntimeLibcallAvailability<"TT.isPPC()">;
-def isPPC32 : RuntimeLibcallAvailability<"TT.isPPC32()">;
-def isPPC64 : RuntimeLibcallAvailability<"TT.isPPC64()">;
-def isAIX : RuntimeLibcallAvailability<"TT.isOSAIX()">;
-def isNotAIX : RuntimeLibcallAvailability<"!TT.isOSAIX()">;
-def isPPC32_AIX : RuntimeLibcallAvailability<"(TT.isPPC32() && TT.isOSAIX())">;
-def isPPC64_AIX : RuntimeLibcallAvailability<"(TT.isPPC64() && TT.isOSAIX())">;
+def isPPC : RuntimeLibcallAvailability<(all_of IsPPC)>;
+def isPPC32 : RuntimeLibcallAvailability<(all_of IsPPC32)>;
+def isPPC64 : RuntimeLibcallAvailability<(all_of IsPPC64)>;
+def isAIX : RuntimeLibcallAvailability<(all_of IsOSAIX)>;
+def isNotAIX : RuntimeLibcallAvailability<(not IsOSAIX)>;
+def isPPC32_AIX : RuntimeLibcallAvailability<(all_of IsPPC32, IsOSAIX)>;
+def isPPC64_AIX : RuntimeLibcallAvailability<(all_of IsPPC64, IsOSAIX)>;
 
 def AIX32Calls : LibcallImpls<(add PPC32AIXCallList), isPPC32_AIX>;
 def AIX64Calls : LibcallImpls<(add PPC64AIXCallList), isPPC64_AIX>;
@@ -3074,8 +3199,8 @@ def PPCSystemLibrary
 // RISCV Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isRISCV : RuntimeLibcallAvailability<"TT.isRISCV()">;
-def isRISCV64 : RuntimeLibcallAvailability<"TT.isRISCV64()">;
+def isRISCV : RuntimeLibcallAvailability<(all_of IsRISCV)>;
+def isRISCV64 : RuntimeLibcallAvailability<(all_of IsRISCV64)>;
 
 def RISCVSystemLibrary
     : SystemRuntimeLibrary<isRISCV,
@@ -3137,9 +3262,9 @@ def _Q_qtoull : RuntimeLibcallImpl<FPTOUINT_F128_I64>;
 def _Q_lltoq : RuntimeLibcallImpl<SINTTOFP_I64_F128>;
 def _Q_ulltoq : RuntimeLibcallImpl<UINTTOFP_I64_F128>;
 
-def isSPARC : RuntimeLibcallAvailability<"TT.isSPARC()">;
-def isSPARC32 : RuntimeLibcallAvailability<"TT.isSPARC32()">;
-def isSPARC64 : RuntimeLibcallAvailability<"TT.isSPARC64()">;
+def isSPARC : RuntimeLibcallAvailability<(all_of IsSPARC)>;
+def isSPARC32 : RuntimeLibcallAvailability<(all_of IsSPARC32)>;
+def isSPARC64 : RuntimeLibcallAvailability<(all_of IsSPARC64)>;
 
 defvar SPARC64_MulDivCalls = [
   __mulsi3, __divsi3, __modsi3, __udivsi3, __umodsi3
@@ -3163,7 +3288,7 @@ def SPARCSystemLibrary
 // SPIRV Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isSPIRV : RuntimeLibcallAvailability<"TT.isSPIRV()">;
+def isSPIRV : RuntimeLibcallAvailability<(all_of IsSPIRV)>;
 
 // No calls FIXME: Add memcpy/memset is a hack to skip
 // PreISelIntrinsicLowering in favor of SPIRVPrepareFunctions;
@@ -3191,29 +3316,28 @@ defvar WindowsDivRemMulLibcallOverrides = [
 // X86 Runtime Libcalls
 //===----------------------------------------------------------------------===//
 
-def isX86_32 : RuntimeLibcallAvailability<"TT.getArch() == Triple::x86">;
-def isX86_64 : RuntimeLibcallAvailability<"TT.getArch() == Triple::x86_64">;
-def isX86 : RuntimeLibcallAvailability<"TT.isX86()">;
+def isX86_32 : RuntimeLibcallAvailability<(all_of IsX86_32)>;
+def isX86_64 : RuntimeLibcallAvailability<(all_of IsX86_64)>;
+def isX86 : RuntimeLibcallAvailability<(all_of IsX86)>;
 
-def isCygwinMinGW64 : RuntimeLibcallAvailability<
-  [{TT.isOSCygMing() && TT.getArch() == Triple::x86_64}]>;
-def isCygwinMinGW32 : RuntimeLibcallAvailability<
-  [{TT.isOSCygMing() && TT.getArch() == Triple::x86}]>;
+def isCygwinMinGW64
+  : RuntimeLibcallAvailability<(all_of IsOSCygMing, IsX86_64)>;
+def isCygwinMinGW32
+  : RuntimeLibcallAvailability<(all_of IsOSCygMing, IsX86_32)>;
 
 def isWin32NotCygMing : RuntimeLibcallAvailability<
-  [{TT.getArch() == Triple::x86 &&
-     TT.isOSWindowsOrUEFI() && !TT.isOSCygMing()}]>;
+  (all_of IsX86_32, IsOSWindowsOrUEFI, (not IsOSCygMing))>;
 def isWin64NotCygMing : RuntimeLibcallAvailability<
-  [{TT.getArch() == Triple::x86_64 &&
-    TT.isOSWindowsOrUEFI() && !TT.isOSCygMing()}]>;
+  (all_of IsX86_64, IsOSWindowsOrUEFI, (not IsOSCygMing))>;
 
 
 // Some darwins have an optimized __bzero/bzero function.
-def darwinHas__bzero : RuntimeLibcallAvailability<"TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)">;
+def darwinHas__bzero : RuntimeLibcallAvailability<
+  (all_of IsMacOSX, MacOSXVersionAtLeast<10, 6>)>;
 
 // FIXME: This is has ldexpl/frexpl plus use f128 for long double.
-def hasExpFrexplLdexplF128
-  : RuntimeLibcallAvailability<[{(!TT.isOSWindows() || TT.isOSCygMing()) && !TT.isGNUEnvironment()}]>;
+def hasExpFrexplLdexplF128 : RuntimeLibcallAvailability<
+  (all_of (any_of (not IsOSWindows), IsOSCygMing), (not IsGNUEnv))>;
 
 // Use the f128 variants of math functions on x86
 defvar X86_F128_Libcalls = LibcallImpls<(add LibmF128Libcalls, LibmF128FiniteLibcalls), isGNUEnvironment>;
@@ -3251,11 +3375,15 @@ defvar X86CommonLibcalls =
 
 defvar Windows32DivRemMulCalls =
   LibcallsWithCC<(add WindowsDivRemMulLibcalls), X86_STDCALL,
-  RuntimeLibcallAvailability<"TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()">>;
+  isWindowsMSVCOrItaniumEnvironment>;
+
+def isNotWindowsMSVCOrItaniumEnvironment
+    : RuntimeLibcallAvailability<(all_of (not IsWindowsMSVCEnv),
+                                            (not IsWindowsItaniumEnv))>;
 
 defvar NotWindows32DivRemMulCalls =
   LibcallImpls<(add WindowsDivRemMulLibcallOverrides),
-    RuntimeLibcallAvailability<"!TT.isWindowsMSVCEnvironment() && !TT.isWindowsItaniumEnvironment()">>;
+    isNotWindowsMSVCOrItaniumEnvironment>;
 
 def X86_32SystemLibrary
     : SystemRuntimeLibrary<isX86_32,
@@ -3273,7 +3401,7 @@ def X86_64SystemLibrary
 
 def __memcpy_4 : RuntimeLibcallImpl<MEMCPY_ALIGN_4>;
 
-def isXCore : RuntimeLibcallAvailability<"TT.getArch() == Triple::xcore">;
+def isXCore : RuntimeLibcallAvailability<(all_of IsXCore)>;
 def XCoreSystemLibrary
     : SystemRuntimeLibrary<isXCore,
     (add DefaultRuntimeLibcallImpls,
@@ -3371,8 +3499,8 @@ defset list<RuntimeLibcallImpl> ZOSRuntimeLibcalls = {
   def zos___LCBT_B : RuntimeLibcallImpl<CBRT_F128, "@@LCBT at B">;
 }
 
-def isSystemZZOS : RuntimeLibcallAvailability<"(TT.isSystemZ() && TT.isOSzOS())">;
-def isZOS : RuntimeLibcallAvailability<"TT.isOSzOS()">;
+def isSystemZZOS : RuntimeLibcallAvailability<(all_of IsSystemZ, IsOSzOS)>;
+def isZOS : RuntimeLibcallAvailability<(all_of IsOSzOS)>;
 def SystemZZOSSystemLibrary
     : SystemRuntimeLibrary<
           isSystemZZOS, (add DefaultLibcallImpls64,
@@ -3388,8 +3516,8 @@ def SystemZZOSSystemLibrary
 // this on emscripten depending on what they end up doing.
 def emscripten_return_address : RuntimeLibcallImpl<RETURN_ADDRESS>;
 
-def isWasm : RuntimeLibcallAvailability<"TT.isWasm()">;
-def isOSEmscripten : RuntimeLibcallAvailability<[{TT.isOSEmscripten()}]>;
+def isWasm : RuntimeLibcallAvailability<(all_of IsWasm)>;
+def isOSEmscripten : RuntimeLibcallAvailability<(all_of IsOSEmscripten)>;
 
 // Define the emscripten name for return address helper.
 // TODO: when implementing other Wasm backends, make this generic or only do
@@ -3411,15 +3539,12 @@ def WasmSystemLibrary
 //===----------------------------------------------------------------------===//
 
 // TODO: Should make every target explicit.
-def isDefaultLibcallArch : RuntimeLibcallAvailability<[{
-  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())
-}]>;
+def isDefaultLibcallArch : RuntimeLibcallAvailability<
+  (any_of IsMIPS, IsLoongArch, IsVE, IsBPF, IsArchCSKY, IsArchArc, IsArchM68k,
+          IsArchXtensa, (all_of IsSystemZ, (not IsOSzOS)))>;
 
 
-def isArch64Bit : RuntimeLibcallAvailability<[{TT.isArch64Bit()}]>;
+def isArch64Bit : RuntimeLibcallAvailability<(all_of IsArch64Bit)>;
 def LegacyDefaultSystemLibrary
     : SystemRuntimeLibrary<isDefaultLibcallArch,
       (add DefaultRuntimeLibcallImpls,
diff --git a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
index e0a6b57bdd2e4..7f52a802c4265 100644
--- a/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
+++ b/llvm/include/llvm/IR/RuntimeLibcallsImpl.td
@@ -23,32 +23,20 @@ class LibcallPredicate<code cond> {
 // a module level property that should only be computed based on the
 // triple.
 //
-// Two forms are accepted:
-//   - a raw C++ `code` condition over `Triple TT`
-//   - a `dag` of LibcallPredicate leaves combined with all_of/any_of/not,
-//     which the emitter lowers to the equivalent C++ boolean.
-// The dag form takes precedence when present.
-//
-// TODO: Remove the C++ form
-class RuntimeLibcallAvailability<code cond = [{}]> {
-  // Expression of an Triple named TT for whether a libcall
-  // should exist.
-  code Cond = cond;
-
-  // Composable form: (all_of/any_of/not <LibcallPredicate>...). Unset (?)
-  // means the `Cond` code form is used instead.
-  dag CondDag = ?;
-}
-
-class RuntimeLibcallAvailabilityDag<dag cond> : RuntimeLibcallAvailability<[{}]> {
-  let CondDag = cond;
+// The condition is expressed as a `dag` of LibcallPredicate leaves combined
+// with the all_of/any_of/not operators, which the emitter lowers to the
+// equivalent C++ boolean over `Triple TT`.
+class RuntimeLibcallAvailability<dag cond = (?)> {
+  // Composable form: (all_of/any_of/not <LibcallPredicate>...). The `(?)`
+  // placeholder default means the libcall is always available.
+  dag CondDag = cond;
 }
 
 // Predicate for whether a libcall should be used for the current
 // function/subtarget.
 class LibcallLoweringPredicate<code cond> { code Cond = cond; }
 
-def AlwaysAvailable : RuntimeLibcallAvailability<[{}]>;
+def AlwaysAvailable : RuntimeLibcallAvailability;
 
 class LibcallCallingConv<code CC = [{}]> {
   // Enum value for the calling convention. Empty string defaults to
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index d72277fa2b179..ad7d3320f8928 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -140,23 +140,6 @@ bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
   return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
 }
 
-bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
-  switch (TT.getOS()) {
-  case Triple::MacOSX:
-    return !TT.isMacOSXVersionLT(10, 9);
-  case Triple::IOS:
-    return !TT.isOSVersionLT(7, 0);
-  case Triple::DriverKit:
-  case Triple::TvOS:
-  case Triple::WatchOS:
-  case Triple::XROS:
-  case Triple::BridgeOS:
-    return true;
-  default:
-    return false;
-  }
-}
-
 /// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
 /// size of the default address space. This matches TargetLibraryInfo and should
 /// be kept in sync.
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-bad-system-library-entry-error.td b/llvm/test/TableGen/RuntimeLibcallEmitter-bad-system-library-entry-error.td
index 7f1ca855cc1a5..d546fefde31a0 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-bad-system-library-entry-error.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-bad-system-library-entry-error.td
@@ -5,7 +5,8 @@ include "llvm/IR/RuntimeLibcallsImpl.td"
 def SOME_FUNC : RuntimeLibcall;
 def func_a : RuntimeLibcallImpl<SOME_FUNC>;
 
-def isTargetArchA : RuntimeLibcallAvailability<[{isTargetArchA()}]>;
+def IsTargetArchA : LibcallPredicate<[{isTargetArchA()}]>;
+def isTargetArchA : RuntimeLibcallAvailability<(all_of IsTargetArchA)>;
 
 // CHECK: [[@LINE+4]]:5: error: entry for SystemLibrary is not a RuntimeLibcallImpl
 // CHECK-NEXT: def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
index 61142167247dd..c4bf02c08dd2d 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
@@ -16,10 +16,15 @@ def __target_override_cc : RuntimeLibcallImpl<TARGET_OVERRIDE_CC>;
 
 def malloc : RuntimeLibcallImpl<MALLOC>;
 
-def isAVR : RuntimeLibcallAvailability<[{TT.getArch() == Triple::avr}]>;
+def IsAVR : LibcallPredicate<[{TT.getArch() == Triple::avr}]>;
+def IsOSHurd : LibcallPredicate<[{TT.isOSHurd()}]>;
+def IsMSP430 : LibcallPredicate<[{TT.getArch() == Triple::msp430}]>;
+def IsFooLeaf : LibcallPredicate<[{ isFoo() }]>;
+def IsBarLeaf : LibcallPredicate<[{ isBar() }]>;
 
-def isAVRHurd : RuntimeLibcallAvailability<
-  [{TT.getArch() == Triple::avr && TT.isOSHurd()}]>;
+def isAVR : RuntimeLibcallAvailability<(all_of IsAVR)>;
+
+def isAVRHurd : RuntimeLibcallAvailability<(all_of IsAVR, IsOSHurd)>;
 
 def AVRLibrary : SystemRuntimeLibrary<isAVR,
   (add malloc, LibcallsWithCC<(add __divmodqi4, __udivmodhi4), AVR_BUILTIN>)
@@ -32,12 +37,12 @@ def AVRHurdLibrary : SystemRuntimeLibrary<isAVRHurd,
     = LibcallCallingConv<[{isFoo() ? CallingConv::Fast : CallingConv::GHC}]>;
 }
 
-def isMSP430 : RuntimeLibcallAvailability<[{TT.getArch() == Triple::msp430}]>;
+def isMSP430 : RuntimeLibcallAvailability<(all_of IsMSP430)>;
 
 def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
   (add malloc,
-       LibcallsWithCC<(add __divmodqi4), AVR_BUILTIN, RuntimeLibcallAvailability<[{ isFoo() }]>>,
-       LibcallsWithCC<(add __udivmodhi4), MSP430_BUILTIN, RuntimeLibcallAvailability<[{ isBar() }]>>)
+       LibcallsWithCC<(add __divmodqi4), AVR_BUILTIN, RuntimeLibcallAvailability<(all_of IsFooLeaf)>>,
+       LibcallsWithCC<(add __udivmodhi4), MSP430_BUILTIN, RuntimeLibcallAvailability<(all_of IsBarLeaf)>>)
 >;
 
 
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td b/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
index dd485f1a3c445..7b88483c3673a 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
@@ -10,9 +10,13 @@ def SOME_FUNC : RuntimeLibcall;
 def OTHER_FUNC : RuntimeLibcall;
 def ANOTHER_DUP : RuntimeLibcall;
 
-def isTargetArchA : RuntimeLibcallAvailability<[{isTargetArchA()}]>;
-def isTargetArchB : RuntimeLibcallAvailability<[{isTargetArchB()}]>;
-def isTargetArchC : RuntimeLibcallAvailability<[{isTargetArchC()}]>;
+def IsTargetArchA : LibcallPredicate<[{isTargetArchA()}]>;
+def IsTargetArchB : LibcallPredicate<[{isTargetArchB()}]>;
+def IsTargetArchC : LibcallPredicate<[{isTargetArchC()}]>;
+
+def isTargetArchA : RuntimeLibcallAvailability<(all_of IsTargetArchA)>;
+def isTargetArchB : RuntimeLibcallAvailability<(all_of IsTargetArchB)>;
+def isTargetArchC : RuntimeLibcallAvailability<(all_of IsTargetArchC)>;
 
 def func_a : RuntimeLibcallImpl<SOME_FUNC>;
 def func_b : RuntimeLibcallImpl<SOME_FUNC>;
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td b/llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td
index 34ddc3ccd5202..63588ef89daa5 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-nested-predicates-error.td
@@ -5,9 +5,13 @@ include "llvm/IR/RuntimeLibcallsImpl.td"
 def FUNC0 : RuntimeLibcall;
 def FUNC1 : RuntimeLibcall;
 
-def isFoo : RuntimeLibcallAvailability<[{isFoo()}]>;
-def isBar : RuntimeLibcallAvailability<[{isBar()}]>;
-def isTargetArch : RuntimeLibcallAvailability<[{isTargetArch()}]>;
+def IsFoo : LibcallPredicate<[{isFoo()}]>;
+def IsBar : LibcallPredicate<[{isBar()}]>;
+def IsTargetArch : LibcallPredicate<[{isTargetArch()}]>;
+
+def isFoo : RuntimeLibcallAvailability<(all_of IsFoo)>;
+def isBar : RuntimeLibcallAvailability<(all_of IsBar)>;
+def isTargetArch : RuntimeLibcallAvailability<(all_of IsTargetArch)>;
 
 def func0 : RuntimeLibcallImpl<FUNC0>;
 def func1 : RuntimeLibcallImpl<FUNC1>;
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-cc-sort.td b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-cc-sort.td
index f841bf781f1f9..6596c2b62e46e 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-cc-sort.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-cc-sort.td
@@ -12,7 +12,8 @@ def FUNC_DEFAULT : RuntimeLibcall;
 def impl_aapcs : RuntimeLibcallImpl<FUNC_AAPCS>;
 def impl_default : RuntimeLibcallImpl<FUNC_DEFAULT>;
 
-def isWin : RuntimeLibcallAvailability<[{TT.isOSWindows()}]>;
+def IsWin : LibcallPredicate<[{TT.isOSWindows()}]>;
+def isWin : RuntimeLibcallAvailability<(all_of IsWin)>;
 
 def WinLibrary : SystemRuntimeLibrary<isWin,
   (add LibcallsWithCC<(add impl_aapcs), ARM_AAPCS, isWin>,
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag-errors.td b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag-errors.td
index e81c427174b89..5df0c20136512 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag-errors.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag-errors.td
@@ -15,27 +15,28 @@ def IsA : LibcallPredicate<[{TT.isAArch64()}]>;
 def IsB : LibcallPredicate<[{TT.isOSDarwin()}]>;
 def NotAnAtom : RuntimeLibcall;
 
-def isArch : RuntimeLibcallAvailability<[{isArch()}]>;
+def IsArch : LibcallPredicate<[{isArch()}]>;
+def isArch : RuntimeLibcallAvailability<(all_of IsArch)>;
 
 #ifdef ERR_NOT_ATOM
 // NOT-ATOM: error: predicate dag leaf 'NotAnAtom' is not a LibcallPredicate
-def badpred : RuntimeLibcallAvailabilityDag<(all_of NotAnAtom)>;
+def badpred : RuntimeLibcallAvailability<(all_of NotAnAtom)>;
 #endif
 
 #ifdef ERR_BAD_OP
 // A defined record that isn't all_of/any_of/not used as the dag operator.
 // BAD-OP: error: unknown predicate dag operator 'IsA'; expected all_of/any_of/not
-def badpred : RuntimeLibcallAvailabilityDag<(IsA IsB)>;
+def badpred : RuntimeLibcallAvailability<(IsA IsB)>;
 #endif
 
 #ifdef ERR_NOT_ARITY
 // NOT-ARITY: error: 'not' takes exactly one operand
-def badpred : RuntimeLibcallAvailabilityDag<(not IsA, IsB)>;
+def badpred : RuntimeLibcallAvailability<(not IsA, IsB)>;
 #endif
 
 #ifdef ERR_EMPTY
 // EMPTY: error: 'all_of' requires at least one operand
-def badpred : RuntimeLibcallAvailabilityDag<(all_of)>;
+def badpred : RuntimeLibcallAvailability<(all_of)>;
 #endif
 
 def Sys : SystemRuntimeLibrary<isArch,
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag.td b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag.td
index 573ab1af1105c..d7e8cf5c28d04 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-predicate-dag.td
@@ -28,24 +28,25 @@ def IsWindowsArm64EC : LibcallPredicate<[{TT.isWindowsArm64EC()}]>;
 def IsX86_32 : LibcallPredicate<[{TT.getArch() == Triple::x86}]>;
 
 def isAArch64_ExceptArm64EC
-    : RuntimeLibcallAvailabilityDag<(all_of IsAArch64, (not IsWindowsArm64EC))>;
+    : RuntimeLibcallAvailability<(all_of IsAArch64, (not IsWindowsArm64EC))>;
 
-def isDarwinOrGNU : RuntimeLibcallAvailabilityDag<(any_of IsOSDarwin, IsGNUEnv)>;
+def isDarwinOrGNU : RuntimeLibcallAvailability<(any_of IsOSDarwin, IsGNUEnv)>;
 
-def isNotDarwin : RuntimeLibcallAvailabilityDag<(not IsOSDarwin)>;
+def isNotDarwin : RuntimeLibcallAvailability<(not IsOSDarwin)>;
 
 // Nested any_of inside all_of, plus a negated leaf.
-def isAArch64DarwinOrGNU : RuntimeLibcallAvailabilityDag<
+def isAArch64DarwinOrGNU : RuntimeLibcallAvailability<
   (all_of IsAArch64, (any_of IsOSDarwin, IsGNUEnv), (not IsWindowsArm64EC))>;
 
 // Not wrapping a nested any_of.
-def isAArch64OrNotDarwinGNU : RuntimeLibcallAvailabilityDag<
+def isAArch64OrNotDarwinGNU : RuntimeLibcallAvailability<
   (any_of IsAArch64, (not (any_of IsOSDarwin, IsGNUEnv)))>;
 
 // Negated leaf whose Cond contains an operator: `!(TT.getArch() == ...)`.
-def isNotX86_32 : RuntimeLibcallAvailabilityDag<(not IsX86_32)>;
+def isNotX86_32 : RuntimeLibcallAvailability<(not IsX86_32)>;
 
-def isTargetArch : RuntimeLibcallAvailability<[{isTargetArch()}]>;
+def IsTargetArch : LibcallPredicate<[{isTargetArch()}]>;
+def isTargetArch : RuntimeLibcallAvailability<(all_of IsTargetArch)>;
 
 def TheSystemLibrary : SystemRuntimeLibrary<isTargetArch,
   (add LibcallImpls<(add impl0), isAArch64_ExceptArm64EC>,
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td
index bd4a12e433a76..d34c24a241bd6 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td
@@ -33,21 +33,32 @@ def calloc  : RuntimeLibcallImpl<CALLOC, "calloc">;
 def CompilerRTLibcalls : LibcallImpls<(add __ashlsi3, __lshrdi3)>;
 def LibmLibcalls : LibcallImpls<(add sqrtl_f80)>;
 
-def isSimpleArch : RuntimeLibcallAvailability<[{TT.getArch() == Triple::simple}]>;
-def isFooArch : RuntimeLibcallAvailability<[{TT.getArch() == Triple::foo}]>;
+def IsSimpleArch : LibcallPredicate<[{TT.getArch() == Triple::simple}]>;
+def IsFooArch : LibcallPredicate<[{TT.getArch() == Triple::foo}]>;
+def IsZOS : LibcallPredicate<[{TT.getOS() == Triple::zos}]>;
+def IsPPCLeaf : LibcallPredicate<[{TT.getArch().isPPC()}]>;
+def IsPPC64Leaf : LibcallPredicate<[{TT.getArch().isPPC64()}]>;
+def IsFoo : LibcallPredicate<[{isFOO()}]>;
+def IsBarOS : LibcallPredicate<[{TT.getOS() == Triple::bar}]>;
+def IsBuzzArch : LibcallPredicate<[{TT.getArch() == Triple::buzz}]>;
+def IsBlahArch : LibcallPredicate<[{TT.getArch() == Triple::blah}]>;
+def HasCompilerRT : LibcallPredicate<[{TT.hasCompilerRT()}]>;
 
+def isSimpleArch : RuntimeLibcallAvailability<(all_of IsSimpleArch)>;
+def isFooArch : RuntimeLibcallAvailability<(all_of IsFooArch)>;
 
-def isZOS : RuntimeLibcallAvailability<[{TT.getOS() == Triple::zos}]>;
-def isPPC : RuntimeLibcallAvailability<[{TT.getArch().isPPC()}]>;
-def isPPC64 : RuntimeLibcallAvailability<[{TT.getArch().isPPC64()}]>;
 
+def isZOS : RuntimeLibcallAvailability<(all_of IsZOS)>;
+def isPPC : RuntimeLibcallAvailability<(all_of IsPPCLeaf)>;
+def isPPC64 : RuntimeLibcallAvailability<(all_of IsPPC64Leaf)>;
 
-def isFoo : RuntimeLibcallAvailability<[{isFOO()}]>;
-def isBarOS : RuntimeLibcallAvailability<[{TT.getOS() == Triple::bar}]>;
-def isBuzzArch : RuntimeLibcallAvailability<[{TT.getArch() == Triple::buzz}]>;
-def isBlahArch : RuntimeLibcallAvailability<[{TT.getArch() == Triple::blah}]>;
 
-def hasCompilerRT : RuntimeLibcallAvailability<[{TT.hasCompilerRT()}]>;
+def isFoo : RuntimeLibcallAvailability<(all_of IsFoo)>;
+def isBarOS : RuntimeLibcallAvailability<(all_of IsBarOS)>;
+def isBuzzArch : RuntimeLibcallAvailability<(all_of IsBuzzArch)>;
+def isBlahArch : RuntimeLibcallAvailability<(all_of IsBlahArch)>;
+
+def hasCompilerRT : RuntimeLibcallAvailability<(all_of HasCompilerRT)>;
 
 
 def SimpleLibrary : SystemRuntimeLibrary<isSimpleArch,
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcalls.h b/llvm/utils/TableGen/Basic/RuntimeLibcalls.h
index 771292e47ee79..57ad3565e385f 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcalls.h
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcalls.h
@@ -24,13 +24,14 @@ class AvailabilityPredicate {
   AvailabilityPredicate(const Record *Def) : TheDef(Def) {
     if (!TheDef)
       return;
+    // The condition is a composable dag (all_of/any_of/not over
+    // LibcallPredicate leaves) lowered to a C++ boolean. An unset CondDag, or a
+    // `(?)` placeholder dag, means the libcall is always available.
     if (const RecordVal *RV = TheDef->getValue("CondDag")) {
-      if (const auto *Dag = dyn_cast_or_null<DagInit>(RV->getValue())) {
+      if (const auto *Dag = dyn_cast_or_null<DagInit>(RV->getValue());
+          Dag && !isa<UnsetInit>(Dag->getOperator()))
         PredicateString = lowerCondDag(TheDef, Dag);
-        return;
-      }
     }
-    PredicateString = TheDef->getValueAsString("Cond").str();
   }
 
   const Record *getDef() const { return TheDef; }



More information about the llvm-branch-commits mailing list