[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