diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2025-07-18 13:26:00 -0700 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2025-07-18 13:26:00 -0700 |
| commit | 9bf3524731070cadc6175707314f3b6ca37190d5 (patch) | |
| tree | 86dcab7604336b01ae938fe81062c29ff69efba8 /llvm/lib/IR/RuntimeLibcalls.cpp | |
| parent | 3a84c15cc13b6daf8e812592898ab6c7f19091a9 (diff) | |
| parent | 4f43f0606c3d7e1ce6d069583b5e59f036e112ce (diff) | |
Created using spr 1.3.6-beta.1
Diffstat (limited to 'llvm/lib/IR/RuntimeLibcalls.cpp')
| -rw-r--r-- | llvm/lib/IR/RuntimeLibcalls.cpp | 252 |
1 files changed, 63 insertions, 189 deletions
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index 64c9415c54d4..5936ac7d0287 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/RuntimeLibcalls.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/ADT/StringTable.h" using namespace llvm; using namespace RTLIB; @@ -18,10 +18,6 @@ using namespace RTLIB; #undef GET_INIT_RUNTIME_LIBCALL_NAMES #undef GET_SET_TARGET_RUNTIME_LIBCALL_SETS -static cl::opt<bool> - HexagonEnableFastMathRuntimeCalls("hexagon-fast-math", cl::Hidden, - cl::desc("Enable Fast Math processing")); - static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, FloatABI::ABIType FloatABIType, EABI EABIVersion) { @@ -66,69 +62,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), @@ -143,9 +76,9 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, EABI EABIVersion, StringRef ABIName) { setTargetRuntimeLibcallSets(TT, FloatABI); - // Use the f128 variants of math functions on x86 - if (TT.isX86() && TT.isGNUEnvironment()) - setLongDoubleIsF128Libm(*this, /*FiniteOnlyFuncs=*/true); + // Early exit for targets that have fully ported to tablegen. + if (TT.isAMDGPU() || TT.isNVPTX() || TT.isWasm()) + return; if (TT.isX86() || TT.isVE() || TT.isARM() || TT.isThumb()) { if (ExceptionModel == ExceptionHandling::SjLj) @@ -160,150 +93,91 @@ 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 (TT.isWatchABI()) { - setLibcallImplCallingConv(RTLIB::__sincosf_stret, - CallingConv::ARM_AAPCS_VFP); - setLibcallImplCallingConv(RTLIB::__sincos_stret, - CallingConv::ARM_AAPCS_VFP); - } - } - - 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); + setLibcallImpl(RTLIB::STACK_SMASH_HANDLER, RTLIB::__stack_smash_handler); } - 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); + // 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; - setLibcallImpl(RTLIB::FREXP_F32, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_F80, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_F128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::FREXP_PPCF128, RTLIB::Unsupported); + if (TT.isARM() || TT.isThumb()) { + setARMLibcallNames(*this, TT, FloatABI, EABIVersion); + 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 (hasSinCos(TT)) { + setLibcallImpl(RTLIB::SINCOS_F32, RTLIB::sincosf); + setLibcallImpl(RTLIB::SINCOS_F64, RTLIB::sincos); + setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128); } - // 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}, - }; + // These libcalls are only available in compiler-rt, not libgcc. + if (TT.isArch64Bit()) { + setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3); + setLibcallImpl(RTLIB::SRL_I128, RTLIB::__lshrti3); + setLibcallImpl(RTLIB::SRA_I128, RTLIB::__ashrti3); + setLibcallImpl(RTLIB::MUL_I128, RTLIB::__multi3); + setLibcallImpl(RTLIB::MULO_I64, RTLIB::__mulodi4); + } - for (const auto &LC : LibraryCalls) { - setLibcallImpl(LC.Op, LC.Impl); - setLibcallImplCallingConv(LC.Impl, LC.CC); - } + if (TT.getArch() == Triple::ArchType::msp430) { + setLibcallImplCallingConv(RTLIB::__mspabi_mpyll, + CallingConv::MSP430_BUILTIN); } +} - if (TT.isARM() || TT.isThumb()) - setARMLibcallNames(*this, TT, FloatABI, EABIVersion); +RTLIB::LibcallImpl +RuntimeLibcallsInfo::getSupportedLibcallImpl(StringRef FuncName) const { + const ArrayRef<uint16_t> RuntimeLibcallNameOffsets( + RuntimeLibcallNameOffsetTable); - if (!TT.isWasm()) { - // These libcalls are only available in compiler-rt, not libgcc. - if (TT.isArch32Bit()) { - setLibcallImpl(RTLIB::SHL_I128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::SRL_I128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::SRA_I128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::MUL_I128, RTLIB::Unsupported); - setLibcallImpl(RTLIB::MULO_I64, RTLIB::Unsupported); - } + iterator_range<ArrayRef<uint16_t>::const_iterator> Range = + getRecognizedLibcallImpls(FuncName); + + for (auto I = Range.begin(); I != Range.end(); ++I) { + RTLIB::LibcallImpl Impl = + static_cast<RTLIB::LibcallImpl>(I - RuntimeLibcallNameOffsets.begin()); - setLibcallImpl(RTLIB::MULO_I128, RTLIB::Unsupported); + // FIXME: This should not depend on looking up ImplToLibcall, only the list + // of libcalls for the module. + RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]]; + if (Recognized != RTLIB::Unsupported) + return Recognized; } - if (TT.getArch() == Triple::ArchType::hexagon) { - setLibcallImpl(RTLIB::SDIV_I32, RTLIB::__hexagon_divsi3); - setLibcallImpl(RTLIB::SDIV_I64, RTLIB::__hexagon_divdi3); - setLibcallImpl(RTLIB::UDIV_I32, RTLIB::__hexagon_udivsi3); - setLibcallImpl(RTLIB::UDIV_I64, RTLIB::__hexagon_udivdi3); - setLibcallImpl(RTLIB::SREM_I32, RTLIB::__hexagon_modsi3); - setLibcallImpl(RTLIB::SREM_I64, RTLIB::__hexagon_moddi3); - setLibcallImpl(RTLIB::UREM_I32, RTLIB::__hexagon_umodsi3); - setLibcallImpl(RTLIB::UREM_I64, RTLIB::__hexagon_umoddi3); + return RTLIB::Unsupported; +} - const bool FastMath = HexagonEnableFastMathRuntimeCalls; - // This is the only fast library function for sqrtd. - if (FastMath) - setLibcallImpl(RTLIB::SQRT_F64, RTLIB::__hexagon_fast2_sqrtdf2); +iterator_range<ArrayRef<uint16_t>::const_iterator> +RuntimeLibcallsInfo::getRecognizedLibcallImpls(StringRef FuncName) { + StringTable::Iterator It = lower_bound(RuntimeLibcallImplNameTable, FuncName); + if (It == RuntimeLibcallImplNameTable.end() || *It != FuncName) + return iterator_range(ArrayRef<uint16_t>()); - // Prefix is: nothing for "slow-math", - // "fast2_" for V5+ fast-math double-precision - // (actually, keep fast-math and fast-math2 separate for now) - if (FastMath) { - setLibcallImpl(RTLIB::ADD_F64, RTLIB::__hexagon_fast_adddf3); - setLibcallImpl(RTLIB::SUB_F64, RTLIB::__hexagon_fast_subdf3); - setLibcallImpl(RTLIB::MUL_F64, RTLIB::__hexagon_fast_muldf3); - setLibcallImpl(RTLIB::DIV_F64, RTLIB::__hexagon_fast_divdf3); - setLibcallImpl(RTLIB::DIV_F32, RTLIB::__hexagon_fast_divsf3); - } else { - setLibcallImpl(RTLIB::ADD_F64, RTLIB::__hexagon_adddf3); - setLibcallImpl(RTLIB::SUB_F64, RTLIB::__hexagon_subdf3); - setLibcallImpl(RTLIB::MUL_F64, RTLIB::__hexagon_muldf3); - setLibcallImpl(RTLIB::DIV_F64, RTLIB::__hexagon_divdf3); - setLibcallImpl(RTLIB::DIV_F32, RTLIB::__hexagon_divsf3); - } + uint16_t IndexVal = It.offset().value(); + const ArrayRef<uint16_t> TableRef(RuntimeLibcallNameOffsetTable); - if (FastMath) - setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_fast2_sqrtf); - else - setLibcallImpl(RTLIB::SQRT_F32, RTLIB::__hexagon_sqrtf); + ArrayRef<uint16_t>::const_iterator E = TableRef.end(); + ArrayRef<uint16_t>::const_iterator EntriesBegin = + std::lower_bound(TableRef.begin(), E, IndexVal); + ArrayRef<uint16_t>::const_iterator EntriesEnd = EntriesBegin; - setLibcallImpl( - RTLIB::HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES, - RTLIB::__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes); - } + while (EntriesEnd != E && *EntriesEnd == IndexVal) + ++EntriesEnd; - if (TT.getArch() == Triple::ArchType::msp430) { - setLibcallImplCallingConv(RTLIB::__mspabi_mpyll, - CallingConv::MSP430_BUILTIN); - } + assert(EntriesBegin != E && + "libcall found in name table but not offset table"); + + return make_range(EntriesBegin, EntriesEnd); } bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) { |
