diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index f39e2e3c26900..6fb9b480c57a1 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -196,6 +196,7 @@ struct RuntimeLibcallsInfo { /// Generated by tablegen. void setTargetRuntimeLibcallSets(const Triple &TT, + ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI); /// Set default libcall names. If a target wants to opt-out of a libcall it diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index df472d4b9cfee..eb97e3ac87c0d 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -39,6 +39,14 @@ def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">; // FIXME: Way to combine predicates def hasSinCos_f32_f64 : RuntimeLibcallPredicate<"hasSinCos_f32_f64(TT)">; +def ExceptionModelIsNotNone : RuntimeLibcallPredicate< + [{ExceptionModel != ExceptionHandling::None}] +>; + +def ExceptionModelIsSjLj : RuntimeLibcallPredicate< + [{ExceptionModel == ExceptionHandling::SjLj}] +>; + //-------------------------------------------------------------------- // Declare all kinds of used libcalls //-------------------------------------------------------------------- @@ -695,10 +703,6 @@ foreach MemSize = [ 1, 2, 4, 8, 16 ] in { !cast("MEMSET_ELEMENT_UNORDERED_ATOMIC_"#MemSize)>; } -// Exception handling -def _Unwind_Resume : RuntimeLibcallImpl; -def __cxa_end_cleanup : RuntimeLibcallImpl; - // Atomic '__sync_*' libcalls. foreach lc = LibCalls__sync in { def __#!tolower(!cast(lc)) : RuntimeLibcallImpl; @@ -1002,9 +1006,20 @@ defm sincos : LibmLongDoubleLibCall; def bzero : RuntimeLibcallImpl; def __bzero : RuntimeLibcallImpl; -def _Unwind_SjLj_Resume : RuntimeLibcallImpl; -def _Unwind_SjLj_Register : RuntimeLibcallImpl; -def _Unwind_SjLj_Unregister : RuntimeLibcallImpl; + +// Exception handling +defset list DefaultExceptionHandlingLibcalls = { + def _Unwind_Resume : RuntimeLibcallImpl; + def __cxa_end_cleanup : RuntimeLibcallImpl; +} + +defset list SjLjExceptionHandlingLibcalls = { + def _Unwind_SjLj_Resume : RuntimeLibcallImpl; + def _Unwind_SjLj_Register : RuntimeLibcallImpl; + def _Unwind_SjLj_Unregister : RuntimeLibcallImpl; +} + +// Only used on wasm? def _Unwind_CallPersonality : RuntimeLibcallImpl; // Used on OpenBSD @@ -1080,6 +1095,13 @@ defset list LibmF128FiniteLibcalls = { // Common Libcall Sets //===----------------------------------------------------------------------===// +defvar ExceptionModelCalls = (add + LibcallImpls<(add DefaultExceptionHandlingLibcalls), + ExceptionModelIsNotNone>, + LibcallImpls<(add SjLjExceptionHandlingLibcalls), + ExceptionModelIsSjLj> +); + // FIXME: Should move to explicit opt-in to different sets of libcalls // instead of trying to remove from a default set. We have // unreasonable defaults like reporting f80 calls on most targets when @@ -1100,19 +1122,25 @@ defvar DefaultRuntimeLibcallImpls_f128 = !filter(entry, AllDefaultRuntimeLibcallImpls, !match(!cast(entry.Provides), "_F128")); -defvar DefaultRuntimeLibcallImpls = +// FIXME: Ideally we would just use dags everywhere, but for the +// arm64ec case we need iterable lists so we can add the # prefix +defvar DefaultRuntimeLibcallImplsList = !listremove( !listremove( !listremove(AllDefaultRuntimeLibcallImpls, Int128RTLibcalls), DefaultRuntimeLibcallImpls_f80), DefaultRuntimeLibcallImpls_ppcf128); +defvar DefaultRuntimeLibcallImpls = (add DefaultRuntimeLibcallImplsList, ExceptionModelCalls); + /// Default set of libcall impls for 32-bit architectures. -defvar DefaultLibcallImpls32 = DefaultRuntimeLibcallImpls; +defvar DefaultLibcallImpls32List = DefaultRuntimeLibcallImplsList; +defvar DefaultLibcallImpls32 = (add DefaultRuntimeLibcallImpls); /// Default set of libcall impls for 64-bit architectures. -defvar DefaultLibcallImpls64 = !listconcat(DefaultRuntimeLibcallImpls, - Int128RTLibcalls); +defvar DefaultLibcallImpls64List = !listconcat(DefaultRuntimeLibcallImplsList, + Int128RTLibcalls); +defvar DefaultLibcallImpls64 = (add DefaultLibcallImpls32List); defvar DarwinSinCosStret = LibcallImpls<(add __sincosf_stret, __sincos_stret), darwinHasSinCosStret>; @@ -1148,8 +1176,12 @@ defvar WindowsExclusions = !listconcat(WindowsMathRemovals, MostPowI); // Targets which support windows should start with these as a base and // add in calls for other OSes -defvar Win32DefaultLibcallImpls = !listremove(DefaultLibcallImpls32, WindowsExclusions); -defvar Win64DefaultLibcallImpls = !listremove(DefaultLibcallImpls64, WindowsExclusions); +defvar Win32DefaultLibcallImpls = (sub DefaultLibcallImpls32, WindowsExclusions); +defvar Win64DefaultLibcallImpls = (sub DefaultLibcallImpls64, WindowsExclusions); + +// We need a list (not-dag) to use foreach to define all the prefixed +// versions, and there isn't an easy way to flatten a dag into a list. +defvar Win64DefaultLibcallImplsList = !listremove(DefaultLibcallImpls64List, WindowsExclusions); defvar LibmHasFrexpF32 = LibcallImpls<(add frexpf), isNotOSWindowsOrIsCygwinMinGW>; defvar LibmHasLdexpF32 = LibcallImpls<(add ldexpf), isNotOSWindowsOrIsCygwinMinGW>; @@ -1244,12 +1276,13 @@ def AArch64SystemLibrary : SystemRuntimeLibrary< LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, DefaultLibmExp10, DefaultStackProtector, - SecurityCheckCookieIfWinMSVC) + SecurityCheckCookieIfWinMSVC, + ExceptionModelCalls) >; // Prepend a # to every name defset list WinArm64ECDefaultRuntimeLibcallImpls = { - foreach libcall = Win64DefaultLibcallImpls in { + foreach libcall = Win64DefaultLibcallImplsList in { def arm64ec_#libcall : DuplicateLibcallImplWithPrefix; } @@ -1260,12 +1293,32 @@ defset list WinArm64ECDefaultRuntimeLibcallImpls = { def arm64ec___stack_chk_fail : DuplicateLibcallImplWithPrefix<__stack_chk_fail, "#">; +defset list WinArm64ECDefaultExceptionHandlingLibcalls = { + foreach libcall = DefaultExceptionHandlingLibcalls in { + def arm64ec_#libcall : DuplicateLibcallImplWithPrefix; + } +} + +defset list WinArm64ECSjLjExceptionHandlingLibcalls = { + foreach libcall = SjLjExceptionHandlingLibcalls in { + def arm64ec_#libcall : DuplicateLibcallImplWithPrefix; + } +} + +defvar ExceptionModelCallsArm64EC = (add + LibcallImpls<(add WinArm64ECDefaultExceptionHandlingLibcalls), + ExceptionModelIsNotNone>, + LibcallImpls<(add WinArm64ECSjLjExceptionHandlingLibcalls), + ExceptionModelIsSjLj> +); + def WindowsARM64ECSystemLibrary : SystemRuntimeLibrary)>; + isWindowsMSVCEnvironment>, + ExceptionModelCallsArm64EC)>; //===----------------------------------------------------------------------===// // AMDGPU Runtime Libcalls @@ -2176,7 +2229,8 @@ defvar X86CommonLibcalls = // FIXME: MSVCRT doesn't have powi. The f128 case is added as a // hack for one test relying on it. __powitf2_f128, - DefaultStackProtector + DefaultStackProtector, + ExceptionModelCalls ); defvar Windows32DivRemMulCalls = @@ -2321,6 +2375,7 @@ def WasmSystemLibrary (add DefaultRuntimeLibcallImpls, Int128RTLibcalls, CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls, exp10f, exp10, + _Unwind_CallPersonality, emscripten_return_address, __stack_chk_fail)>; diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index a8e6c7938cf54..5c53cdbf0be9d 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -69,10 +69,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName) { - setTargetRuntimeLibcallSets(TT, FloatABI); - - if (ExceptionModel == ExceptionHandling::SjLj) - setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); + setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI); if (TT.isARM() || TT.isThumb()) { setARMLibcallNames(*this, TT, FloatABI, EABIVersion); diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td index 49d5ecaa0e5c5..2a9beaca7947c 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td @@ -41,7 +41,7 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary; -// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, FloatABI::ABIType FloatABI) { +// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI) { // CHECK: if (TT.getArch() == Triple::avr && TT.isOSHurd()) { // CHECK-NEXT: const CallingConv::ID DefaultCC = isFoo() ? CallingConv::Fast : CallingConv::GHC; // CHECK-NEXT: for (CallingConv::ID &Entry : LibcallImplCallingConvs) { diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 642f8b85a89c6..45cae1cbbcb32 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -150,7 +150,7 @@ def BlahLibrary : SystemRuntimeLibrary