diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index 162b0fa7d2e9b..85db45e27e912 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -174,6 +174,10 @@ struct RuntimeLibcallsInfo { (TT.isAndroid() && !TT.isAndroidVersionLT(9)); } + static bool hasSinCos_f32_f64(const Triple &TT) { + return hasSinCos(TT) || TT.isPS(); + } + LLVM_ABI void initDefaultLibCallImpls(); /// Generated by tablegen. diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index ff343f30f0325..267ca6f653eab 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -17,12 +17,23 @@ class DuplicateLibcallImplWithPrefix /// Libcall Predicates def isOSDarwin : RuntimeLibcallPredicate<"TT.isOSDarwin()">; +def isOSOpenBSD : RuntimeLibcallPredicate<"TT.isOSOpenBSD()">; def isOSWindows : RuntimeLibcallPredicate<"TT.isOSWindows()">; +def isNotOSWindows : RuntimeLibcallPredicate<"!TT.isOSWindows()">; +def isNotOSMSVCRT : RuntimeLibcallPredicate<"!TT.isOSMSVCRT()">; +def isPS : RuntimeLibcallPredicate<"TT.isPS()">; +def isNotOSWindowsOrIsCygwinMinGW + : RuntimeLibcallPredicate<"!TT.isOSWindows() || TT.isOSCygMing()">; + +def isGNUEnvironment : RuntimeLibcallPredicate<"TT.isGNUEnvironment()">; def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">; def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">; def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">; +// FIXME: Way to combine predicates +def hasSinCos_f32_f64 : RuntimeLibcallPredicate<"hasSinCos_f32_f64(TT)">; + //-------------------------------------------------------------------- // Declare all kinds of used libcalls //-------------------------------------------------------------------- @@ -514,11 +525,13 @@ def __divxf3 : RuntimeLibcallImpl; def __divtf3 : RuntimeLibcallImpl; def __gcc_qdiv : RuntimeLibcallImpl; +defset list PowiLibcallImpls = { def __powisf2 : RuntimeLibcallImpl; def __powidf2 : RuntimeLibcallImpl; def __powixf2 : RuntimeLibcallImpl; def __powitf2_f128 : RuntimeLibcallImpl; def __powitf2_ppc128 : RuntimeLibcallImpl; +} // Conversion def __extendbfsf2 : RuntimeLibcallImpl; @@ -1084,6 +1097,29 @@ defvar LibmHasSinCosF80 = LibcallImpls<(add sincos_f80), hasSinCos>; defvar LibmHasSinCosF128 = LibcallImpls<(add sincos_f128), hasSinCos>; defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincos_ppcf128), hasSinCos>; +defvar WindowsMathRemovals = [ + ldexpf, ldexp_f80, ldexp_f128, ldexp_ppcf128, + frexpf, frexp_f80, frexp_f128, frexp_ppcf128 +]; + +defvar MostPowI = !listremove(PowiLibcallImpls, [__powitf2_f128, __powitf2_ppc128]); +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 LibmHasFrexpF32 = LibcallImpls<(add frexpf), isNotOSWindowsOrIsCygwinMinGW>; +defvar LibmHasLdexpF32 = LibcallImpls<(add ldexpf), isNotOSWindowsOrIsCygwinMinGW>; + +defvar LibmHasFrexpF80 = LibcallImpls<(add frexp_f80), isNotOSWindowsOrIsCygwinMinGW>; +defvar LibmHasLdexpF80 = LibcallImpls<(add ldexp_f80), isNotOSWindowsOrIsCygwinMinGW>; + +defvar LibmHasFrexpF128 = LibcallImpls<(add frexp_f128), isNotOSWindowsOrIsCygwinMinGW>; +defvar LibmHasLdexpF128 = LibcallImpls<(add ldexp_f128), isNotOSWindowsOrIsCygwinMinGW>; + + //===----------------------------------------------------------------------===// // Objective-C Runtime Libcalls //===----------------------------------------------------------------------===// @@ -1151,7 +1187,10 @@ def isAArch64_ILP64 : RuntimeLibcallPredicate<"TT.isAArch64(64)">; def AArch64SystemLibrary : SystemRuntimeLibrary< isAArch64_ExceptArm64EC, - (add DefaultRuntimeLibcallImpls, + (add Win64DefaultLibcallImpls, + LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>, + LibmHasFrexpF32, LibmHasLdexpF32, + LibmHasFrexpF128, LibmHasLdexpF128, AArch64LibcallImpls, LibcallImpls<(add Int128RTLibcalls), isAArch64_ILP64>, LibcallImpls<(add bzero), isOSDarwin>, @@ -1161,7 +1200,7 @@ def AArch64SystemLibrary : SystemRuntimeLibrary< // Prepend a # to every name defset list WinArm64ECDefaultRuntimeLibcallImpls = { - foreach libcall = DefaultLibcallImpls64 in { + foreach libcall = Win64DefaultLibcallImpls in { def arm64ec_#libcall : DuplicateLibcallImplWithPrefix; } @@ -1418,11 +1457,15 @@ def isARMOrThumb : RuntimeLibcallPredicate<"TT.isARM() || TT.isThumb()">; def ARMSystemLibrary : SystemRuntimeLibrary, + LibmHasFrexpF32, LibmHasLdexpF32, + LibmHasFrexpF128, LibmHasLdexpF128, WindowARMDivRemCalls, WindowARMFPIntCasts, AEABIDivRemCalls, DarwinSinCosStret, DarwinExp10, + LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, // Use divmod compiler-rt calls for iOS 5.0 and later. LibcallImpls<(add __divmodsi4, __udivmodsi4), @@ -1916,6 +1959,8 @@ def PPCSystemLibrary __extendkftf2, __trunctfkf2, DefaultRuntimeLibcallImpls_ppcf128, LibmF128Libcalls, AIX32Calls, AIX64Calls, + LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, + LibmHasSinCosPPCF128, AvailableIf, LibcallImpls<(add Int128RTLibcalls), isPPC64>)>; @@ -2003,13 +2048,13 @@ def SPARCSystemLibrary // Windows Runtime Libcalls //===----------------------------------------------------------------------===// -// TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment() - +defset list WindowsDivRemMulLibcalls = { def _alldiv : RuntimeLibcallImpl; def _aulldiv : RuntimeLibcallImpl; def _allrem : RuntimeLibcallImpl; def _aullrem : RuntimeLibcallImpl; def _allmul : RuntimeLibcallImpl; +} //===----------------------------------------------------------------------===// // X86 Runtime Libcalls @@ -2017,14 +2062,48 @@ def _allmul : RuntimeLibcallImpl; def isX86_32 : RuntimeLibcallPredicate<"TT.getArch() == Triple::x86">; def isX86_64 : RuntimeLibcallPredicate<"TT.getArch() == Triple::x86_64">; +def isX86 : RuntimeLibcallPredicate<"TT.isX86()">; + +// Some darwins have an optimized __bzero/bzero function. +def darwinHas__bzero : RuntimeLibcallPredicate<"TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)">; + +// FIXME: This is has ldexpl/frexpl plus use f128 for long double. +def hasFrexplLdexplF128 + : RuntimeLibcallPredicate<[{(!TT.isOSWindows() || TT.isOSCygMing()) && !TT.isGNUEnvironment()}]>; + +// Use the f128 variants of math functions on x86 +defvar X86_F128_Libcalls = LibcallImpls<(add LibmF128Libcalls, LibmF128FiniteLibcalls), isGNUEnvironment>; + +defvar SinCosF32F64Libcalls = LibcallImpls<(add sincosf, sincos), hasSinCos_f32_f64>; + +defvar X86CommonLibcalls = + (add DarwinSinCosStret, DarwinExp10, + X86_F128_Libcalls, + LibmHasSinCosF80, // FIXME: Depends on long double + SinCosF32F64Libcalls, + LibcallImpls<(add __bzero), darwinHas__bzero>, + LibmHasFrexpF32, LibmHasLdexpF32, + LibmHasFrexpF80, LibmHasLdexpF80, + LibcallImpls<(add frexp_f128, ldexp_f128), hasFrexplLdexplF128>, + DefaultRuntimeLibcallImpls_f80, + // FIXME: MSVCRT doesn't have powi. The f128 case is added as a + // hack for one test relying on it. + __powitf2_f128, + LibcallImpls<(add MostPowI), isNotOSMSVCRT> +); + +defvar Windows32DivRemMulCalls = + LibcallImpls<(add WindowsDivRemMulLibcalls), + RuntimeLibcallPredicate<"TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()">>; def X86_32SystemLibrary : SystemRuntimeLibrary; + (add X86CommonLibcalls, + Windows32DivRemMulCalls, Win32DefaultLibcallImpls)>; def X86_64SystemLibrary : SystemRuntimeLibrary; + (add X86CommonLibcalls, Win64DefaultLibcallImpls, Int128RTLibcalls)>; //===----------------------------------------------------------------------===// // XCore Runtime Libcalls diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 39863ecb89873..84c67010ca716 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -61,69 +61,6 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, Info.setLibcallImplCallingConv(Impl, CallingConv::ARM_AAPCS); } -static void setLongDoubleIsF128Libm(RuntimeLibcallsInfo &Info, - bool FiniteOnlyFuncs = false) { - Info.setLibcallImpl(RTLIB::REM_F128, RTLIB::fmodf128); - Info.setLibcallImpl(RTLIB::FMA_F128, RTLIB::fmaf128); - Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::sqrtf128); - Info.setLibcallImpl(RTLIB::CBRT_F128, RTLIB::cbrtf128); - Info.setLibcallImpl(RTLIB::LOG_F128, RTLIB::logf128); - Info.setLibcallImpl(RTLIB::LOG2_F128, RTLIB::log2f128); - Info.setLibcallImpl(RTLIB::LOG10_F128, RTLIB::log10f128); - Info.setLibcallImpl(RTLIB::EXP_F128, RTLIB::expf128); - Info.setLibcallImpl(RTLIB::EXP2_F128, RTLIB::exp2f128); - Info.setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10f128); - Info.setLibcallImpl(RTLIB::SIN_F128, RTLIB::sinf128); - Info.setLibcallImpl(RTLIB::COS_F128, RTLIB::cosf128); - Info.setLibcallImpl(RTLIB::TAN_F128, RTLIB::tanf128); - Info.setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincosf128); - Info.setLibcallImpl(RTLIB::ASIN_F128, RTLIB::asinf128); - Info.setLibcallImpl(RTLIB::ACOS_F128, RTLIB::acosf128); - Info.setLibcallImpl(RTLIB::ATAN_F128, RTLIB::atanf128); - Info.setLibcallImpl(RTLIB::ATAN2_F128, RTLIB::atan2f128); - Info.setLibcallImpl(RTLIB::SINH_F128, RTLIB::sinhf128); - Info.setLibcallImpl(RTLIB::COSH_F128, RTLIB::coshf128); - Info.setLibcallImpl(RTLIB::TANH_F128, RTLIB::tanhf128); - Info.setLibcallImpl(RTLIB::POW_F128, RTLIB::powf128); - Info.setLibcallImpl(RTLIB::CEIL_F128, RTLIB::ceilf128); - Info.setLibcallImpl(RTLIB::TRUNC_F128, RTLIB::truncf128); - Info.setLibcallImpl(RTLIB::RINT_F128, RTLIB::rintf128); - Info.setLibcallImpl(RTLIB::NEARBYINT_F128, RTLIB::nearbyintf128); - Info.setLibcallImpl(RTLIB::ROUND_F128, RTLIB::roundf128); - Info.setLibcallImpl(RTLIB::ROUNDEVEN_F128, RTLIB::roundevenf128); - Info.setLibcallImpl(RTLIB::FLOOR_F128, RTLIB::floorf128); - Info.setLibcallImpl(RTLIB::COPYSIGN_F128, RTLIB::copysignf128); - Info.setLibcallImpl(RTLIB::FMIN_F128, RTLIB::fminf128); - Info.setLibcallImpl(RTLIB::FMAX_F128, RTLIB::fmaxf128); - Info.setLibcallImpl(RTLIB::FMINIMUM_F128, RTLIB::fminimumf128); - Info.setLibcallImpl(RTLIB::FMAXIMUM_F128, RTLIB::fmaximumf128); - Info.setLibcallImpl(RTLIB::FMINIMUM_NUM_F128, RTLIB::fminimum_numf128); - Info.setLibcallImpl(RTLIB::FMAXIMUM_NUM_F128, RTLIB::fmaximum_numf128); - Info.setLibcallImpl(RTLIB::LROUND_F128, RTLIB::lroundf128); - Info.setLibcallImpl(RTLIB::LLROUND_F128, RTLIB::llroundf128); - Info.setLibcallImpl(RTLIB::LRINT_F128, RTLIB::lrintf128); - Info.setLibcallImpl(RTLIB::LLRINT_F128, RTLIB::llrintf128); - Info.setLibcallImpl(RTLIB::LDEXP_F128, RTLIB::ldexpf128); - Info.setLibcallImpl(RTLIB::FREXP_F128, RTLIB::frexpf128); - Info.setLibcallImpl(RTLIB::MODF_F128, RTLIB::modff128); - - if (FiniteOnlyFuncs) { - Info.setLibcallImpl(RTLIB::LOG_FINITE_F128, RTLIB::__logf128_finite); - Info.setLibcallImpl(RTLIB::LOG2_FINITE_F128, RTLIB::__log2f128_finite); - Info.setLibcallImpl(RTLIB::LOG10_FINITE_F128, RTLIB::__log10f128_finite); - Info.setLibcallImpl(RTLIB::EXP_FINITE_F128, RTLIB::__expf128_finite); - Info.setLibcallImpl(RTLIB::EXP2_FINITE_F128, RTLIB::__exp2f128_finite); - Info.setLibcallImpl(RTLIB::POW_FINITE_F128, RTLIB::__powf128_finite); - } else { - Info.setLibcallImpl(RTLIB::LOG_FINITE_F128, RTLIB::Unsupported); - Info.setLibcallImpl(RTLIB::LOG2_FINITE_F128, RTLIB::Unsupported); - Info.setLibcallImpl(RTLIB::LOG10_FINITE_F128, RTLIB::Unsupported); - Info.setLibcallImpl(RTLIB::EXP_FINITE_F128, RTLIB::Unsupported); - Info.setLibcallImpl(RTLIB::EXP2_FINITE_F128, RTLIB::Unsupported); - Info.setLibcallImpl(RTLIB::POW_FINITE_F128, RTLIB::Unsupported); - } -} - void RTLIB::RuntimeLibcallsInfo::initDefaultLibCallImpls() { std::memcpy(LibcallImpls, DefaultLibcallImpls, sizeof(LibcallImpls)); static_assert(sizeof(LibcallImpls) == sizeof(DefaultLibcallImpls), @@ -142,10 +79,6 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, if (TT.isAMDGPU() || TT.isNVPTX() || TT.isWasm()) return; - // Use the f128 variants of math functions on x86 - if (TT.isX86() && TT.isGNUEnvironment()) - setLongDoubleIsF128Libm(*this, /*FiniteOnlyFuncs=*/true); - if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) { if (ExceptionModel == ExceptionHandling::SjLj) setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume); @@ -159,85 +92,32 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setLibcallImpl(RTLIB::FPEXT_F16_F32, RTLIB::__extendhfsf2); setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__truncsfhf2); - // Some darwins have an optimized __bzero/bzero function. - if (TT.isX86()) { - if (TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)) - setLibcallImpl(RTLIB::BZERO, RTLIB::__bzero); - } - - if (darwinHasSinCosStret(TT)) { - setLibcallImpl(RTLIB::SINCOS_STRET_F32, RTLIB::__sincosf_stret); - setLibcallImpl(RTLIB::SINCOS_STRET_F64, RTLIB::__sincos_stret); - } - - if (darwinHasExp10(TT)) { - setLibcallImpl(RTLIB::EXP10_F32, RTLIB::__exp10f); - setLibcallImpl(RTLIB::EXP10_F64, RTLIB::__exp10); - } else { + if (!darwinHasExp10(TT)) { setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported); setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported); } } - if (hasSinCos(TT)) { - setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); - setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); - setLibcallImpl(RTLIB::SINCOS_F80, RTLIB::sincos_f80); - setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); - setLibcallImpl(RTLIB::SINCOS_PPCF128, RTLIB::sincos_ppcf128); - } - - if (TT.isPS()) { - setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); - setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); - } - if (TT.isOSOpenBSD()) { setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported); } - if (TT.isOSWindows() && !TT.isOSCygMing()) { - setLibcallImpl(RTLIB::LDEXP_F32, RTLIB::Unsupported); - setLibcallImpl(RTLIB::LDEXP_F80, RTLIB::Unsupported); - setLibcallImpl(RTLIB::LDEXP_F128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::LDEXP_PPCF128, RTLIB::Unsupported); - - setLibcallImpl(RTLIB::FREXP_F32, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_F80, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_F128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_PPCF128, RTLIB::Unsupported); - } + // Skip default manual processing for targets that have been fully ported to + // tablegen for now. Eventually the rest of this should be deleted. + if (TT.isX86() || TT.isAArch64() || TT.isWasm()) + return; - if (TT.isOSMSVCRT()) { - // MSVCRT doesn't have powi; fall back to pow - setLibcallImpl(RTLIB::POWI_F32, RTLIB::Unsupported); - setLibcallImpl(RTLIB::POWI_F64, RTLIB::Unsupported); + if (TT.isARM() || TT.isThumb()) { + setARMLibcallNames(*this, TT, FloatABI, EABIVersion); + return; } - // Setup Windows compiler runtime calls. - if (TT.getArch() == Triple::x86 && - (TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment())) { - static const struct { - const RTLIB::Libcall Op; - const RTLIB::LibcallImpl Impl; - const CallingConv::ID CC; - } LibraryCalls[] = { - {RTLIB::SDIV_I64, RTLIB::_alldiv, CallingConv::X86_StdCall}, - {RTLIB::UDIV_I64, RTLIB::_aulldiv, CallingConv::X86_StdCall}, - {RTLIB::SREM_I64, RTLIB::_allrem, CallingConv::X86_StdCall}, - {RTLIB::UREM_I64, RTLIB::_aullrem, CallingConv::X86_StdCall}, - {RTLIB::MUL_I64, RTLIB::_allmul, CallingConv::X86_StdCall}, - }; - - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - setLibcallImplCallingConv(LC.Impl, LC.CC); - } + if (hasSinCos(TT)) { + setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); + setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); + setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); } - if (TT.isARM() || TT.isThumb()) - setARMLibcallNames(*this, TT, FloatABI, EABIVersion); - // These libcalls are only available in compiler-rt, not libgcc. if (TT.isArch64Bit()) { setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3);