summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/RuntimeLibcalls.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2025-07-18 13:26:00 -0700
committerPeter Collingbourne <peter@pcc.me.uk>2025-07-18 13:26:00 -0700
commit9bf3524731070cadc6175707314f3b6ca37190d5 (patch)
tree86dcab7604336b01ae938fe81062c29ff69efba8 /llvm/lib/IR/RuntimeLibcalls.cpp
parent3a84c15cc13b6daf8e812592898ab6c7f19091a9 (diff)
parent4f43f0606c3d7e1ce6d069583b5e59f036e112ce (diff)
Created using spr 1.3.6-beta.1
Diffstat (limited to 'llvm/lib/IR/RuntimeLibcalls.cpp')
-rw-r--r--llvm/lib/IR/RuntimeLibcalls.cpp252
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) {