10b57cec5SDimitry Andric //===-- TargetLibraryInfo.cpp - Runtime library information ----------------==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the TargetLibraryInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 145f757f3fSDimitry Andric #include "llvm/ADT/DenseMap.h" 155f757f3fSDimitry Andric #include "llvm/ADT/SmallString.h" 160b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 17*0fca6ea1SDimitry Andric #include "llvm/IR/Module.h" 18480093f4SDimitry Andric #include "llvm/InitializePasses.h" 190b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 2006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary( 240b57cec5SDimitry Andric "vector-library", cl::Hidden, cl::desc("Vector functions library"), 250b57cec5SDimitry Andric cl::init(TargetLibraryInfoImpl::NoLibrary), 260b57cec5SDimitry Andric cl::values(clEnumValN(TargetLibraryInfoImpl::NoLibrary, "none", 270b57cec5SDimitry Andric "No vector functions library"), 280b57cec5SDimitry Andric clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate", 290b57cec5SDimitry Andric "Accelerate framework"), 30fe6060f1SDimitry Andric clEnumValN(TargetLibraryInfoImpl::DarwinLibSystemM, 31fe6060f1SDimitry Andric "Darwin_libsystem_m", "Darwin libsystem_m"), 32e8d8bef9SDimitry Andric clEnumValN(TargetLibraryInfoImpl::LIBMVEC_X86, "LIBMVEC-X86", 33e8d8bef9SDimitry Andric "GLIBC Vector Math library"), 340b57cec5SDimitry Andric clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV", 350b57cec5SDimitry Andric "IBM MASS vector library"), 360b57cec5SDimitry Andric clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", 37bdd1243dSDimitry Andric "Intel SVML library"), 38bdd1243dSDimitry Andric clEnumValN(TargetLibraryInfoImpl::SLEEFGNUABI, "sleefgnuabi", 3906c3fb27SDimitry Andric "SIMD Library for Evaluating Elementary Functions"), 4006c3fb27SDimitry Andric clEnumValN(TargetLibraryInfoImpl::ArmPL, "ArmPL", 41*0fca6ea1SDimitry Andric "Arm Performance Libraries"), 42*0fca6ea1SDimitry Andric clEnumValN(TargetLibraryInfoImpl::AMDLIBM, "AMDLIBM", 43*0fca6ea1SDimitry Andric "AMD vector math library"))); 440b57cec5SDimitry Andric 458bcb0991SDimitry Andric StringLiteral const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = 468bcb0991SDimitry Andric { 470b57cec5SDimitry Andric #define TLI_DEFINE_STRING 480b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.def" 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric 515f757f3fSDimitry Andric std::string VecDesc::getVectorFunctionABIVariantString() const { 525f757f3fSDimitry Andric assert(!VectorFnName.empty() && "Vector function name must not be empty."); 535f757f3fSDimitry Andric SmallString<256> Buffer; 545f757f3fSDimitry Andric llvm::raw_svector_ostream Out(Buffer); 555f757f3fSDimitry Andric Out << VABIPrefix << "_" << ScalarFnName << "(" << VectorFnName << ")"; 565f757f3fSDimitry Andric return std::string(Out.str()); 575f757f3fSDimitry Andric } 585f757f3fSDimitry Andric 59bdd1243dSDimitry Andric // Recognized types of library function arguments and return types. 60bdd1243dSDimitry Andric enum FuncArgTypeID : char { 61bdd1243dSDimitry Andric Void = 0, // Must be zero. 62bdd1243dSDimitry Andric Bool, // 8 bits on all targets 63bdd1243dSDimitry Andric Int16, 64bdd1243dSDimitry Andric Int32, 65bdd1243dSDimitry Andric Int, 66bdd1243dSDimitry Andric IntPlus, // Int or bigger. 67bdd1243dSDimitry Andric Long, // Either 32 or 64 bits. 68bdd1243dSDimitry Andric IntX, // Any integer type. 69bdd1243dSDimitry Andric Int64, 70bdd1243dSDimitry Andric LLong, // 64 bits on all targets. 71bdd1243dSDimitry Andric SizeT, // size_t. 72bdd1243dSDimitry Andric SSizeT, // POSIX ssize_t. 73bdd1243dSDimitry Andric Flt, // IEEE float. 74bdd1243dSDimitry Andric Dbl, // IEEE double. 75bdd1243dSDimitry Andric LDbl, // Any floating type (TODO: tighten this up). 76bdd1243dSDimitry Andric Floating, // Any floating type. 77bdd1243dSDimitry Andric Ptr, // Any pointer type. 78bdd1243dSDimitry Andric Struct, // Any struct type. 79bdd1243dSDimitry Andric Ellip, // The ellipsis (...). 80bdd1243dSDimitry Andric Same, // Same argument type as the previous one. 81bdd1243dSDimitry Andric }; 82bdd1243dSDimitry Andric 83bdd1243dSDimitry Andric typedef std::array<FuncArgTypeID, 8> FuncProtoTy; 84bdd1243dSDimitry Andric 85bdd1243dSDimitry Andric static const FuncProtoTy Signatures[] = { 86bdd1243dSDimitry Andric #define TLI_DEFINE_SIG 87bdd1243dSDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.def" 88bdd1243dSDimitry Andric }; 89bdd1243dSDimitry Andric 90bdd1243dSDimitry Andric static_assert(sizeof Signatures / sizeof *Signatures == LibFunc::NumLibFuncs, 91bdd1243dSDimitry Andric "Missing library function signatures"); 92bdd1243dSDimitry Andric 930b57cec5SDimitry Andric static bool hasSinCosPiStret(const Triple &T) { 940b57cec5SDimitry Andric // Only Darwin variants have _stret versions of combined trig functions. 950b57cec5SDimitry Andric if (!T.isOSDarwin()) 960b57cec5SDimitry Andric return false; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // The ABI is rather complicated on x86, so don't do anything special there. 990b57cec5SDimitry Andric if (T.getArch() == Triple::x86) 1000b57cec5SDimitry Andric return false; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9)) 1030b57cec5SDimitry Andric return false; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric if (T.isiOS() && T.isOSVersionLT(7, 0)) 1060b57cec5SDimitry Andric return false; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric return true; 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric static bool hasBcmp(const Triple &TT) { 1120b57cec5SDimitry Andric // Posix removed support from bcmp() in 2001, but the glibc and several 1130b57cec5SDimitry Andric // implementations of the libc still have it. 1140b57cec5SDimitry Andric if (TT.isOSLinux()) 1150b57cec5SDimitry Andric return TT.isGNUEnvironment() || TT.isMusl(); 1160b57cec5SDimitry Andric // Both NetBSD and OpenBSD are planning to remove the function. Windows does 1170b57cec5SDimitry Andric // not have it. 1188bcb0991SDimitry Andric return TT.isOSFreeBSD() || TT.isOSSolaris(); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 121fe6060f1SDimitry Andric static bool isCallingConvCCompatible(CallingConv::ID CC, StringRef TT, 122fe6060f1SDimitry Andric FunctionType *FuncTy) { 123fe6060f1SDimitry Andric switch (CC) { 124fe6060f1SDimitry Andric default: 125fe6060f1SDimitry Andric return false; 126fe6060f1SDimitry Andric case llvm::CallingConv::C: 127fe6060f1SDimitry Andric return true; 128fe6060f1SDimitry Andric case llvm::CallingConv::ARM_APCS: 129fe6060f1SDimitry Andric case llvm::CallingConv::ARM_AAPCS: 130fe6060f1SDimitry Andric case llvm::CallingConv::ARM_AAPCS_VFP: { 131fe6060f1SDimitry Andric 132fe6060f1SDimitry Andric // The iOS ABI diverges from the standard in some cases, so for now don't 133fe6060f1SDimitry Andric // try to simplify those calls. 134fe6060f1SDimitry Andric if (Triple(TT).isiOS()) 135fe6060f1SDimitry Andric return false; 136fe6060f1SDimitry Andric 137fe6060f1SDimitry Andric if (!FuncTy->getReturnType()->isPointerTy() && 138fe6060f1SDimitry Andric !FuncTy->getReturnType()->isIntegerTy() && 139fe6060f1SDimitry Andric !FuncTy->getReturnType()->isVoidTy()) 140fe6060f1SDimitry Andric return false; 141fe6060f1SDimitry Andric 142fe6060f1SDimitry Andric for (auto *Param : FuncTy->params()) { 143fe6060f1SDimitry Andric if (!Param->isPointerTy() && !Param->isIntegerTy()) 144fe6060f1SDimitry Andric return false; 145fe6060f1SDimitry Andric } 146fe6060f1SDimitry Andric return true; 147fe6060f1SDimitry Andric } 148fe6060f1SDimitry Andric } 149fe6060f1SDimitry Andric return false; 150fe6060f1SDimitry Andric } 151fe6060f1SDimitry Andric 152fe6060f1SDimitry Andric bool TargetLibraryInfoImpl::isCallingConvCCompatible(CallBase *CI) { 153fe6060f1SDimitry Andric return ::isCallingConvCCompatible(CI->getCallingConv(), 154fe6060f1SDimitry Andric CI->getModule()->getTargetTriple(), 155fe6060f1SDimitry Andric CI->getFunctionType()); 156fe6060f1SDimitry Andric } 157fe6060f1SDimitry Andric 158fe6060f1SDimitry Andric bool TargetLibraryInfoImpl::isCallingConvCCompatible(Function *F) { 159fe6060f1SDimitry Andric return ::isCallingConvCCompatible(F->getCallingConv(), 160fe6060f1SDimitry Andric F->getParent()->getTargetTriple(), 161fe6060f1SDimitry Andric F->getFunctionType()); 162fe6060f1SDimitry Andric } 163fe6060f1SDimitry Andric 164*0fca6ea1SDimitry Andric static void initializeBase(TargetLibraryInfoImpl &TLI, const Triple &T) { 165*0fca6ea1SDimitry Andric bool ShouldExtI32Param, ShouldExtI32Return; 166*0fca6ea1SDimitry Andric bool ShouldSignExtI32Param, ShouldSignExtI32Return; 167*0fca6ea1SDimitry Andric TargetLibraryInfo::initExtensionsForTriple( 168*0fca6ea1SDimitry Andric ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param, 169*0fca6ea1SDimitry Andric ShouldSignExtI32Return, T); 170*0fca6ea1SDimitry Andric TLI.setShouldExtI32Param(ShouldExtI32Param); 171*0fca6ea1SDimitry Andric TLI.setShouldExtI32Return(ShouldExtI32Return); 172*0fca6ea1SDimitry Andric TLI.setShouldSignExtI32Param(ShouldSignExtI32Param); 173*0fca6ea1SDimitry Andric TLI.setShouldSignExtI32Return(ShouldSignExtI32Return); 174*0fca6ea1SDimitry Andric 175*0fca6ea1SDimitry Andric // Let's assume by default that the size of int is 32 bits, unless the target 176*0fca6ea1SDimitry Andric // is a 16-bit architecture because then it most likely is 16 bits. If that 177*0fca6ea1SDimitry Andric // isn't true for a target those defaults should be overridden below. 178*0fca6ea1SDimitry Andric TLI.setIntSize(T.isArch16Bit() ? 16 : 32); 179*0fca6ea1SDimitry Andric } 180*0fca6ea1SDimitry Andric 1810b57cec5SDimitry Andric /// Initialize the set of available library functions based on the specified 1820b57cec5SDimitry Andric /// target triple. This should be carefully written so that a missing target 1830b57cec5SDimitry Andric /// triple gets a sane set of defaults. 184*0fca6ea1SDimitry Andric static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T, 1858bcb0991SDimitry Andric ArrayRef<StringLiteral> StandardNames) { 1860b57cec5SDimitry Andric // Set IO unlocked variants as unavailable 1870b57cec5SDimitry Andric // Set them as available per system below 188349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_getc_unlocked); 1890b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_getchar_unlocked); 1900b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_putc_unlocked); 1910b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_putchar_unlocked); 1920b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fputc_unlocked); 1930b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fgetc_unlocked); 1940b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fread_unlocked); 1950b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fwrite_unlocked); 1960b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fputs_unlocked); 1970b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fgets_unlocked); 1980b57cec5SDimitry Andric 199349cc55cSDimitry Andric // There is really no runtime library on AMDGPU, apart from 200349cc55cSDimitry Andric // __kmpc_alloc/free_shared. 2015ffd83dbSDimitry Andric if (T.isAMDGPU()) { 202349cc55cSDimitry Andric TLI.disableAllFunctions(); 203fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared); 204fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc___kmpc_free_shared); 2050b57cec5SDimitry Andric return; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2084824e7fdSDimitry Andric // memset_pattern{4,8,16} is only available on iOS 3.0 and Mac OS X 10.5 and 2094824e7fdSDimitry Andric // later. All versions of watchOS support it. 2100b57cec5SDimitry Andric if (T.isMacOSX()) { 2110b57cec5SDimitry Andric // available IO unlocked variants on Mac OS X 2120b57cec5SDimitry Andric TLI.setAvailable(LibFunc_getc_unlocked); 2130b57cec5SDimitry Andric TLI.setAvailable(LibFunc_getchar_unlocked); 2140b57cec5SDimitry Andric TLI.setAvailable(LibFunc_putc_unlocked); 2150b57cec5SDimitry Andric TLI.setAvailable(LibFunc_putchar_unlocked); 2165f757f3fSDimitry Andric TLI.setUnavailable(LibFunc_memrchr); 2170b57cec5SDimitry Andric 2184824e7fdSDimitry Andric if (T.isMacOSXVersionLT(10, 5)) { 2194824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern4); 2204824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern8); 2210b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern16); 2224824e7fdSDimitry Andric } 2230b57cec5SDimitry Andric } else if (T.isiOS()) { 2244824e7fdSDimitry Andric if (T.isOSVersionLT(3, 0)) { 2254824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern4); 2264824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern8); 2270b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern16); 2284824e7fdSDimitry Andric } 2290b57cec5SDimitry Andric } else if (!T.isWatchOS()) { 2304824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern4); 2314824e7fdSDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern8); 2320b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_memset_pattern16); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric if (!hasSinCosPiStret(T)) { 2360b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinpi); 2370b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinpif); 2380b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cospi); 2390b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cospif); 2400b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sincospi_stret); 2410b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sincospif_stret); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric if (!hasBcmp(T)) 2450b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_bcmp); 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric if (T.isMacOSX() && T.getArch() == Triple::x86 && 2480b57cec5SDimitry Andric !T.isMacOSXVersionLT(10, 7)) { 2490b57cec5SDimitry Andric // x86-32 OSX has a scheme where fwrite and fputs (and some other functions 2500b57cec5SDimitry Andric // we don't care about) have two versions; on recent OSX, the one we want 2510b57cec5SDimitry Andric // has a $UNIX2003 suffix. The two implementations are identical except 2520b57cec5SDimitry Andric // for the return value in some edge cases. However, we don't want to 2530b57cec5SDimitry Andric // generate code that depends on the old symbols. 2540b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_fwrite, "fwrite$UNIX2003"); 2550b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_fputs, "fputs$UNIX2003"); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric // iprintf and friends are only available on XCore, TCE, and Emscripten. 2590b57cec5SDimitry Andric if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce && 2600b57cec5SDimitry Andric T.getOS() != Triple::Emscripten) { 2610b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_iprintf); 2620b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_siprintf); 2630b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fiprintf); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric // __small_printf and friends are only available on Emscripten. 2670b57cec5SDimitry Andric if (T.getOS() != Triple::Emscripten) { 2680b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_small_printf); 2690b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_small_sprintf); 2700b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_small_fprintf); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric if (T.isOSWindows() && !T.isOSCygMing()) { 2740b57cec5SDimitry Andric // XXX: The earliest documentation available at the moment is for VS2015/VC19: 2750b57cec5SDimitry Andric // https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015 2760b57cec5SDimitry Andric // XXX: In order to use an MSVCRT older than VC19, 2770b57cec5SDimitry Andric // the specific library version must be explicit in the target triple, 2780b57cec5SDimitry Andric // e.g., x86_64-pc-windows-msvc18. 2790b57cec5SDimitry Andric bool hasPartialC99 = true; 2800b57cec5SDimitry Andric if (T.isKnownWindowsMSVCEnvironment()) { 2810eae32dcSDimitry Andric VersionTuple Version = T.getEnvironmentVersion(); 2820eae32dcSDimitry Andric hasPartialC99 = (Version.getMajor() == 0 || Version.getMajor() >= 19); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // Latest targets support C89 math functions, in part. 2860b57cec5SDimitry Andric bool isARM = (T.getArch() == Triple::aarch64 || 2870b57cec5SDimitry Andric T.getArch() == Triple::arm); 2880b57cec5SDimitry Andric bool hasPartialFloat = (isARM || 2890b57cec5SDimitry Andric T.getArch() == Triple::x86_64); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // Win32 does not support float C89 math functions, in general. 2920b57cec5SDimitry Andric if (!hasPartialFloat) { 2930b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosf); 2940b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinf); 2950b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atan2f); 2960b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanf); 2970b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ceilf); 2980b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cosf); 2990b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_coshf); 3000b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expf); 3010b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_floorf); 3020b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmodf); 3030b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log10f); 3040b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logf); 3050b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_modff); 3060b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_powf); 3075ffd83dbSDimitry Andric TLI.setUnavailable(LibFunc_remainderf); 308*0fca6ea1SDimitry Andric TLI.setUnavailable(LibFunc_remquof); 3090b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinf); 3100b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinhf); 3110b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sqrtf); 3120b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_tanf); 3130b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_tanhf); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric if (!isARM) 3160b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fabsf); 3170b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_frexpf); 3180b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ldexpf); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // Win32 does not support long double C89 math functions. 3210b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosl); 3220b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinl); 3230b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atan2l); 3240b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanl); 3250b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ceill); 3260b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cosl); 3270b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_coshl); 3280b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expl); 3290b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fabsl); 3300b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_floorl); 3310b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmodl); 3320b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_frexpl); 3330b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ldexpl); 3340b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log10l); 3350b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logl); 3360b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_modfl); 3370b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_powl); 3385ffd83dbSDimitry Andric TLI.setUnavailable(LibFunc_remainderl); 339*0fca6ea1SDimitry Andric TLI.setUnavailable(LibFunc_remquol); 3400b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinl); 3410b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinhl); 3420b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sqrtl); 3430b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_tanl); 3440b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_tanhl); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric // Win32 does not fully support C99 math functions. 3470b57cec5SDimitry Andric if (!hasPartialC99) { 3480b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosh); 3490b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acoshf); 3500b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinh); 3510b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinhf); 3520b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanh); 3530b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanhf); 3540b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_cabs, "_cabs"); 3550b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cabsf); 3560b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cbrt); 3570b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cbrtf); 3580b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_copysign, "_copysign"); 3590b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf"); 3600b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2); 3610b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2f); 3620b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expm1); 3630b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expm1f); 3640b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmax); 3650b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmaxf); 3660b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmin); 3670b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fminf); 3680b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log1p); 3690b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log1pf); 3700b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2); 3710b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2f); 3720b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_logb, "_logb"); 3730b57cec5SDimitry Andric if (hasPartialFloat) 3740b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_logbf, "_logbf"); 3750b57cec5SDimitry Andric else 3760b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logbf); 3770b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_rint); 3780b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_rintf); 3790b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_round); 3800b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_roundf); 3810b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_trunc); 3820b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_truncf); 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric // Win32 does not support long double C99 math functions. 3860b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acoshl); 3870b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinhl); 3880b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanhl); 3890b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cabsl); 3900b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cbrtl); 3910b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_copysignl); 3920b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2l); 3930b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expm1l); 3940b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fmaxl); 3950b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fminl); 3960b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log1pl); 3970b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2l); 3980b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logbl); 3990b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_nearbyintl); 4000b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_rintl); 4010b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_roundl); 4020b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_truncl); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // Win32 does not support these functions, but 4050b57cec5SDimitry Andric // they are generally available on POSIX-compliant systems. 4060b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_access); 407fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_chmod); 408fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_closedir); 409fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_fdopen); 410fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_fileno); 411fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_fseeko); 412fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_fstat); 413fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_ftello); 414fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_gettimeofday); 415fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_memccpy); 416fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_mkdir); 417fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_open); 418fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_opendir); 419fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_pclose); 420fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_popen); 421fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_read); 422fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_rmdir); 423fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_stat); 424fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_strcasecmp); 425fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_strncasecmp); 426fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_unlink); 427fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_utime); 428fe6060f1SDimitry Andric TLI.setUnavailable(LibFunc_write); 429fe6060f1SDimitry Andric } 430fe6060f1SDimitry Andric 431fe6060f1SDimitry Andric if (T.isOSWindows() && !T.isWindowsCygwinEnvironment()) { 432fe6060f1SDimitry Andric // These functions aren't available in either MSVC or MinGW environments. 4330b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_bcmp); 4340b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_bcopy); 4350b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_bzero); 4360b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_chown); 4370b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ctermid); 4380b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ffs); 4390b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_flockfile); 4400b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fstatvfs); 4410b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ftrylockfile); 4420b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_funlockfile); 4430b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_getitimer); 4440b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_getlogin_r); 4450b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_getpwnam); 4460b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_htonl); 4470b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_htons); 4480b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_lchown); 4490b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_lstat); 450bdd1243dSDimitry Andric TLI.setUnavailable(LibFunc_memrchr); 4510b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ntohl); 4520b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ntohs); 4530b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_pread); 4540b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_pwrite); 4550b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_readlink); 4560b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_realpath); 4570b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_setitimer); 4580b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_statvfs); 4590b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_stpcpy); 4600b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_stpncpy); 4610b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_times); 4620b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_uname); 4630b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_unsetenv); 4640b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_utimes); 465*0fca6ea1SDimitry Andric 466*0fca6ea1SDimitry Andric // MinGW does have ldexpf, but it is a plain wrapper over regular ldexp. 467*0fca6ea1SDimitry Andric // Therefore it's not beneficial to transform code to use it, i.e. 468*0fca6ea1SDimitry Andric // just pretend that the function is not available. 469*0fca6ea1SDimitry Andric TLI.setUnavailable(LibFunc_ldexpf); 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 472349cc55cSDimitry Andric // Pick just one set of new/delete variants. 473349cc55cSDimitry Andric if (T.isOSMSVCRT()) { 474349cc55cSDimitry Andric // MSVC, doesn't have the Itanium new/delete. 475349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPv); 476349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvRKSt9nothrow_t); 477349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvSt11align_val_t); 478349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t); 479349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvj); 480349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvjSt11align_val_t); 481349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvm); 482349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvmSt11align_val_t); 483349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPv); 484349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvRKSt9nothrow_t); 485349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvSt11align_val_t); 486349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t); 487349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvj); 488349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvjSt11align_val_t); 489349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvm); 490349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvmSt11align_val_t); 491349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znaj); 492349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajRKSt9nothrow_t); 493349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajSt11align_val_t); 494349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajSt11align_val_tRKSt9nothrow_t); 495349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znam); 496349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnamRKSt9nothrow_t); 49706c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t); 498349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnamSt11align_val_t); 499349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnamSt11align_val_tRKSt9nothrow_t); 500349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znwj); 501349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjRKSt9nothrow_t); 502349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjSt11align_val_t); 503349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t); 504349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znwm); 505349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwmRKSt9nothrow_t); 50606c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t); 507349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwmSt11align_val_t); 508349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t); 50906c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_Znwm12__hot_cold_t); 51006c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnwmSt11align_val_t12__hot_cold_t); 51106c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t); 51206c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_Znam12__hot_cold_t); 51306c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnamSt11align_val_t12__hot_cold_t); 51406c3fb27SDimitry Andric TLI.setUnavailable(LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t); 515349cc55cSDimitry Andric } else { 516349cc55cSDimitry Andric // Not MSVC, assume it's Itanium. 517349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_int); 518349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_int_nothrow); 519349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_longlong); 520349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_longlong_nothrow); 521349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr32); 522349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr32_nothrow); 523349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr32_int); 524349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr64); 525349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr64_nothrow); 526349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_ptr64_longlong); 527349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_array_int); 528349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_array_int_nothrow); 529349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_array_longlong); 530349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_new_array_longlong_nothrow); 531349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32); 532349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32_nothrow); 533349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32_int); 534349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64); 535349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64_nothrow); 536349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64_longlong); 537349cc55cSDimitry Andric } 538349cc55cSDimitry Andric 5390b57cec5SDimitry Andric switch (T.getOS()) { 5400b57cec5SDimitry Andric case Triple::MacOSX: 5410b57cec5SDimitry Andric // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 5420b57cec5SDimitry Andric // and their names are __exp10 and __exp10f. exp10l is not available on 5430b57cec5SDimitry Andric // OS X or iOS. 5440b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10l); 5450b57cec5SDimitry Andric if (T.isMacOSXVersionLT(10, 9)) { 5460b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10); 5470b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10f); 5480b57cec5SDimitry Andric } else { 5490b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); 5500b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric break; 5530b57cec5SDimitry Andric case Triple::IOS: 5540b57cec5SDimitry Andric case Triple::TvOS: 5550b57cec5SDimitry Andric case Triple::WatchOS: 5567a6dacacSDimitry Andric case Triple::XROS: 5570b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10l); 558480093f4SDimitry Andric if (!T.isWatchOS() && 559480093f4SDimitry Andric (T.isOSVersionLT(7, 0) || (T.isOSVersionLT(9, 0) && T.isX86()))) { 5600b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10); 5610b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10f); 5620b57cec5SDimitry Andric } else { 5630b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_exp10, "__exp10"); 5640b57cec5SDimitry Andric TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f"); 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric break; 5670b57cec5SDimitry Andric case Triple::Linux: 5680b57cec5SDimitry Andric // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely 5690b57cec5SDimitry Andric // buggy prior to glibc version 2.18. Until this version is widely deployed 5700b57cec5SDimitry Andric // or we have a reasonable detection strategy, we cannot use exp10 reliably 5710b57cec5SDimitry Andric // on Linux. 5720b57cec5SDimitry Andric // 5730b57cec5SDimitry Andric // Fall through to disable all of them. 574bdd1243dSDimitry Andric [[fallthrough]]; 5750b57cec5SDimitry Andric default: 5760b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10); 5770b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10f); 5780b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10l); 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and 5820b57cec5SDimitry Andric // Linux (GLIBC): 5830b57cec5SDimitry Andric // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html 5840b57cec5SDimitry Andric // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c 5850b57cec5SDimitry Andric // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html 5860b57cec5SDimitry Andric switch (T.getOS()) { 5870b57cec5SDimitry Andric case Triple::Darwin: 5880b57cec5SDimitry Andric case Triple::MacOSX: 5890b57cec5SDimitry Andric case Triple::IOS: 5900b57cec5SDimitry Andric case Triple::TvOS: 5910b57cec5SDimitry Andric case Triple::WatchOS: 5927a6dacacSDimitry Andric case Triple::XROS: 5930b57cec5SDimitry Andric case Triple::FreeBSD: 5940b57cec5SDimitry Andric case Triple::Linux: 5950b57cec5SDimitry Andric break; 5960b57cec5SDimitry Andric default: 5970b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ffsl); 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric // ffsll is available on at least FreeBSD and Linux (GLIBC): 6010b57cec5SDimitry Andric // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c 6020b57cec5SDimitry Andric // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html 6030b57cec5SDimitry Andric switch (T.getOS()) { 6040b57cec5SDimitry Andric case Triple::Darwin: 6050b57cec5SDimitry Andric case Triple::MacOSX: 6060b57cec5SDimitry Andric case Triple::IOS: 6070b57cec5SDimitry Andric case Triple::TvOS: 6080b57cec5SDimitry Andric case Triple::WatchOS: 6097a6dacacSDimitry Andric case Triple::XROS: 6100b57cec5SDimitry Andric case Triple::FreeBSD: 6110b57cec5SDimitry Andric case Triple::Linux: 6120b57cec5SDimitry Andric break; 6130b57cec5SDimitry Andric default: 6140b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ffsll); 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric // The following functions are available on at least FreeBSD: 6180b57cec5SDimitry Andric // http://svn.freebsd.org/base/head/lib/libc/string/fls.c 6190b57cec5SDimitry Andric // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c 6200b57cec5SDimitry Andric // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c 6210b57cec5SDimitry Andric if (!T.isOSFreeBSD()) { 6220b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fls); 6230b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_flsl); 6240b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_flsll); 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric // The following functions are only available on GNU/Linux (using glibc). 6280b57cec5SDimitry Andric // Linux variants without glibc (eg: bionic, musl) may have some subset. 6290b57cec5SDimitry Andric if (!T.isOSLinux() || !T.isGNUEnvironment()) { 6300b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_dunder_strdup); 6310b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_dunder_strtok_r); 6320b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_dunder_isoc99_scanf); 6330b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_dunder_isoc99_sscanf); 6340b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_under_IO_getc); 6350b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_under_IO_putc); 6360b57cec5SDimitry Andric // But, Android and musl have memalign. 6370b57cec5SDimitry Andric if (!T.isAndroid() && !T.isMusl()) 6380b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_memalign); 6390b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fopen64); 6400b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fseeko64); 6410b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fstat64); 6420b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_fstatvfs64); 6430b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_ftello64); 6440b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_lstat64); 6450b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_open64); 6460b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_stat64); 6470b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_statvfs64); 6480b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_tmpfile64); 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric // Relaxed math functions are included in math-finite.h on Linux (GLIBC). 6518c27c554SDimitry Andric // Note that math-finite.h is no longer supported by top-of-tree GLIBC, 6528c27c554SDimitry Andric // so we keep these functions around just so that they're recognized by 6538c27c554SDimitry Andric // the ConstantFolder. 6540b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acos_finite); 6550b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosf_finite); 6560b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosl_finite); 6570b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acosh_finite); 6580b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acoshf_finite); 6590b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_acoshl_finite); 6600b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asin_finite); 6610b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinf_finite); 6620b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_asinl_finite); 6630b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atan2_finite); 6640b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atan2f_finite); 6650b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atan2l_finite); 6660b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanh_finite); 6670b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanhf_finite); 6680b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_atanhl_finite); 6690b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_cosh_finite); 6700b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_coshf_finite); 6710b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_coshl_finite); 6720b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10_finite); 6730b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10f_finite); 6740b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp10l_finite); 6750b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2_finite); 6760b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2f_finite); 6770b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp2l_finite); 6780b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_exp_finite); 6790b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expf_finite); 6800b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_expl_finite); 6810b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log10_finite); 6820b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log10f_finite); 6830b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log10l_finite); 6840b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2_finite); 6850b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2f_finite); 6860b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log2l_finite); 6870b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_log_finite); 6880b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logf_finite); 6890b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_logl_finite); 6900b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_pow_finite); 6910b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_powf_finite); 6920b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_powl_finite); 6930b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinh_finite); 6940b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinhf_finite); 6950b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_sinhl_finite); 696349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_sqrt_finite); 697349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_sqrtf_finite); 698349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_sqrtl_finite); 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric if ((T.isOSLinux() && T.isGNUEnvironment()) || 7020b57cec5SDimitry Andric (T.isAndroid() && !T.isAndroidVersionLT(28))) { 7030b57cec5SDimitry Andric // available IO unlocked variants on GNU/Linux and Android P or later 7040b57cec5SDimitry Andric TLI.setAvailable(LibFunc_getc_unlocked); 7050b57cec5SDimitry Andric TLI.setAvailable(LibFunc_getchar_unlocked); 7060b57cec5SDimitry Andric TLI.setAvailable(LibFunc_putc_unlocked); 7070b57cec5SDimitry Andric TLI.setAvailable(LibFunc_putchar_unlocked); 7080b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fputc_unlocked); 7090b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fgetc_unlocked); 7100b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fread_unlocked); 7110b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fwrite_unlocked); 7120b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fputs_unlocked); 7130b57cec5SDimitry Andric TLI.setAvailable(LibFunc_fgets_unlocked); 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 716349cc55cSDimitry Andric if (T.isAndroid() && T.isAndroidVersionLT(21)) { 717349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpcpy); 718349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpncpy); 719349cc55cSDimitry Andric } 720349cc55cSDimitry Andric 72181ad6265SDimitry Andric if (T.isPS()) { 72281ad6265SDimitry Andric // PS4/PS5 do have memalign. 723349cc55cSDimitry Andric TLI.setAvailable(LibFunc_memalign); 724349cc55cSDimitry Andric 72581ad6265SDimitry Andric // PS4/PS5 do not have new/delete with "unsigned int" size parameter; 72681ad6265SDimitry Andric // they only have the "unsigned long" versions. 727349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvj); 728349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdaPvjSt11align_val_t); 729349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvj); 730349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZdlPvjSt11align_val_t); 731349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znaj); 732349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajRKSt9nothrow_t); 733349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajSt11align_val_t); 734349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnajSt11align_val_tRKSt9nothrow_t); 735349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_Znwj); 736349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjRKSt9nothrow_t); 737349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjSt11align_val_t); 738349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t); 739349cc55cSDimitry Andric 740349cc55cSDimitry Andric // None of the *_chk functions. 741349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memccpy_chk); 742349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memcpy_chk); 743349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memmove_chk); 744349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_mempcpy_chk); 745349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memset_chk); 746349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_snprintf_chk); 747349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_sprintf_chk); 748349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpcpy_chk); 749349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpncpy_chk); 750349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strcat_chk); 751349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strcpy_chk); 752349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strlcat_chk); 753349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strlcpy_chk); 754349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strlen_chk); 755349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strncat_chk); 756349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strncpy_chk); 757349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_vsnprintf_chk); 758349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_vsprintf_chk); 759349cc55cSDimitry Andric 760349cc55cSDimitry Andric // Various Posix system functions. 761349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_access); 762349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_chmod); 763349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_chown); 764349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_closedir); 765349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ctermid); 766349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execl); 767349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execle); 768349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execlp); 769349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execv); 770349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execvP); 771349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execve); 772349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execvp); 773349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_execvpe); 774349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_fork); 775349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_fstat); 776349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_fstatvfs); 777349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_getenv); 778349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_getitimer); 779349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_getlogin_r); 780349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_getpwnam); 781349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_gettimeofday); 782349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_lchown); 783349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_lstat); 784349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_mkdir); 785349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_open); 786349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_opendir); 787349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_pclose); 788349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_popen); 789349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_pread); 790349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_pwrite); 791349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_read); 792349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_readlink); 793349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_realpath); 794349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_rename); 795349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_rmdir); 796349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_setitimer); 797349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stat); 798349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_statvfs); 799349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_system); 800349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_times); 801349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_tmpfile); 802349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_unlink); 803349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_uname); 804349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_unsetenv); 805349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_utime); 806349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_utimes); 807349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_valloc); 808349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_write); 809349cc55cSDimitry Andric 810349cc55cSDimitry Andric // Miscellaneous other functions not provided. 811349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_atomic_load); 812349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_atomic_store); 813349cc55cSDimitry Andric TLI.setUnavailable(LibFunc___kmpc_alloc_shared); 814349cc55cSDimitry Andric TLI.setUnavailable(LibFunc___kmpc_free_shared); 815349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_dunder_strndup); 816349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_bcmp); 817349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_bcopy); 818349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_bzero); 819349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_cabs); 820349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_cabsf); 821349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_cabsl); 822349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ffs); 823349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_flockfile); 824349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_fseeko); 825349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ftello); 826349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ftrylockfile); 827349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_funlockfile); 828349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_htonl); 829349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_htons); 830349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_isascii); 831349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memccpy); 832349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_mempcpy); 833349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_memrchr); 834349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ntohl); 835349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_ntohs); 836349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_reallocf); 837349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_roundeven); 838349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_roundevenf); 839349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_roundevenl); 840349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpcpy); 841349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_stpncpy); 842349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strlcat); 843349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strlcpy); 844349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strndup); 845349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_strnlen); 846349cc55cSDimitry Andric TLI.setUnavailable(LibFunc_toascii); 847349cc55cSDimitry Andric } 848349cc55cSDimitry Andric 8490b57cec5SDimitry Andric // As currently implemented in clang, NVPTX code has no standard library to 8500b57cec5SDimitry Andric // speak of. Headers provide a standard-ish library implementation, but many 8510b57cec5SDimitry Andric // of the signatures are wrong -- for example, many libm functions are not 8520b57cec5SDimitry Andric // extern "C". 8530b57cec5SDimitry Andric // 8540b57cec5SDimitry Andric // libdevice, an IR library provided by nvidia, is linked in by the front-end, 8550b57cec5SDimitry Andric // but only used functions are provided to llvm. Moreover, most of the 8560b57cec5SDimitry Andric // functions in libdevice don't map precisely to standard library functions. 8570b57cec5SDimitry Andric // 8580b57cec5SDimitry Andric // FIXME: Having no standard library prevents e.g. many fastmath 8590b57cec5SDimitry Andric // optimizations, so this situation should be fixed. 8600b57cec5SDimitry Andric if (T.isNVPTX()) { 8610b57cec5SDimitry Andric TLI.disableAllFunctions(); 8620b57cec5SDimitry Andric TLI.setAvailable(LibFunc_nvvm_reflect); 863fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc_malloc); 864fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc_free); 865fe6060f1SDimitry Andric 866fe6060f1SDimitry Andric // TODO: We could enable the following two according to [0] but we haven't 867fe6060f1SDimitry Andric // done an evaluation wrt. the performance implications. 868fe6060f1SDimitry Andric // [0] 869fe6060f1SDimitry Andric // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#dynamic-global-memory-allocation-and-operations 870fe6060f1SDimitry Andric // 871fe6060f1SDimitry Andric // TLI.setAvailable(llvm::LibFunc_memcpy); 872fe6060f1SDimitry Andric // TLI.setAvailable(llvm::LibFunc_memset); 873fe6060f1SDimitry Andric 874fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared); 875fe6060f1SDimitry Andric TLI.setAvailable(llvm::LibFunc___kmpc_free_shared); 8760b57cec5SDimitry Andric } else { 8770b57cec5SDimitry Andric TLI.setUnavailable(LibFunc_nvvm_reflect); 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric 880e8d8bef9SDimitry Andric // These vec_malloc/free routines are only available on AIX. 881e8d8bef9SDimitry Andric if (!T.isOSAIX()) { 882e8d8bef9SDimitry Andric TLI.setUnavailable(LibFunc_vec_calloc); 883e8d8bef9SDimitry Andric TLI.setUnavailable(LibFunc_vec_malloc); 884e8d8bef9SDimitry Andric TLI.setUnavailable(LibFunc_vec_realloc); 885e8d8bef9SDimitry Andric TLI.setUnavailable(LibFunc_vec_free); 886e8d8bef9SDimitry Andric } 887e8d8bef9SDimitry Andric 888*0fca6ea1SDimitry Andric if (T.isOSAIX()) 889*0fca6ea1SDimitry Andric TLI.setUnavailable(LibFunc_memrchr); 890*0fca6ea1SDimitry Andric 891bdd1243dSDimitry Andric TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary, T); 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 894*0fca6ea1SDimitry Andric /// Initialize the set of available library functions based on the specified 895*0fca6ea1SDimitry Andric /// target triple. This should be carefully written so that a missing target 896*0fca6ea1SDimitry Andric /// triple gets a sane set of defaults. 897*0fca6ea1SDimitry Andric static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, 898*0fca6ea1SDimitry Andric ArrayRef<StringLiteral> StandardNames) { 899*0fca6ea1SDimitry Andric initializeBase(TLI, T); 900*0fca6ea1SDimitry Andric initializeLibCalls(TLI, T, StandardNames); 901*0fca6ea1SDimitry Andric } 9020b57cec5SDimitry Andric 903*0fca6ea1SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl() { 904*0fca6ea1SDimitry Andric // Default to nothing being available. 905*0fca6ea1SDimitry Andric memset(AvailableArray, 0, sizeof(AvailableArray)); 906*0fca6ea1SDimitry Andric initializeBase(*this, Triple()); 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { 9100b57cec5SDimitry Andric // Default to everything being available. 9110b57cec5SDimitry Andric memset(AvailableArray, -1, sizeof(AvailableArray)); 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric initialize(*this, T, StandardNames); 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) 9170b57cec5SDimitry Andric : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param), 9180b57cec5SDimitry Andric ShouldExtI32Return(TLI.ShouldExtI32Return), 919fe6060f1SDimitry Andric ShouldSignExtI32Param(TLI.ShouldSignExtI32Param), 920bdd1243dSDimitry Andric ShouldSignExtI32Return(TLI.ShouldSignExtI32Return), 921fe6060f1SDimitry Andric SizeOfInt(TLI.SizeOfInt) { 9220b57cec5SDimitry Andric memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 9230b57cec5SDimitry Andric VectorDescs = TLI.VectorDescs; 9240b57cec5SDimitry Andric ScalarDescs = TLI.ScalarDescs; 9250b57cec5SDimitry Andric } 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) 9280b57cec5SDimitry Andric : CustomNames(std::move(TLI.CustomNames)), 9290b57cec5SDimitry Andric ShouldExtI32Param(TLI.ShouldExtI32Param), 9300b57cec5SDimitry Andric ShouldExtI32Return(TLI.ShouldExtI32Return), 931fe6060f1SDimitry Andric ShouldSignExtI32Param(TLI.ShouldSignExtI32Param), 932bdd1243dSDimitry Andric ShouldSignExtI32Return(TLI.ShouldSignExtI32Return), 933fe6060f1SDimitry Andric SizeOfInt(TLI.SizeOfInt) { 9340b57cec5SDimitry Andric std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 9350b57cec5SDimitry Andric AvailableArray); 9360b57cec5SDimitry Andric VectorDescs = TLI.VectorDescs; 9370b57cec5SDimitry Andric ScalarDescs = TLI.ScalarDescs; 9380b57cec5SDimitry Andric } 9390b57cec5SDimitry Andric 9400b57cec5SDimitry Andric TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { 9410b57cec5SDimitry Andric CustomNames = TLI.CustomNames; 9420b57cec5SDimitry Andric ShouldExtI32Param = TLI.ShouldExtI32Param; 9430b57cec5SDimitry Andric ShouldExtI32Return = TLI.ShouldExtI32Return; 9440b57cec5SDimitry Andric ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; 945bdd1243dSDimitry Andric ShouldSignExtI32Return = TLI.ShouldSignExtI32Return; 946fe6060f1SDimitry Andric SizeOfInt = TLI.SizeOfInt; 9470b57cec5SDimitry Andric memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 9480b57cec5SDimitry Andric return *this; 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { 9520b57cec5SDimitry Andric CustomNames = std::move(TLI.CustomNames); 9530b57cec5SDimitry Andric ShouldExtI32Param = TLI.ShouldExtI32Param; 9540b57cec5SDimitry Andric ShouldExtI32Return = TLI.ShouldExtI32Return; 9550b57cec5SDimitry Andric ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; 956bdd1243dSDimitry Andric ShouldSignExtI32Return = TLI.ShouldSignExtI32Return; 957fe6060f1SDimitry Andric SizeOfInt = TLI.SizeOfInt; 9580b57cec5SDimitry Andric std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 9590b57cec5SDimitry Andric AvailableArray); 9600b57cec5SDimitry Andric return *this; 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric static StringRef sanitizeFunctionName(StringRef funcName) { 9640b57cec5SDimitry Andric // Filter out empty names and names containing null bytes, those can't be in 9650b57cec5SDimitry Andric // our table. 966349cc55cSDimitry Andric if (funcName.empty() || funcName.contains('\0')) 9670b57cec5SDimitry Andric return StringRef(); 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric // Check for \01 prefix that is used to mangle __asm declarations and 9700b57cec5SDimitry Andric // strip it if present. 9710b57cec5SDimitry Andric return GlobalValue::dropLLVMManglingEscape(funcName); 9720b57cec5SDimitry Andric } 9730b57cec5SDimitry Andric 9745f757f3fSDimitry Andric static DenseMap<StringRef, LibFunc> 9755f757f3fSDimitry Andric buildIndexMap(ArrayRef<StringLiteral> StandardNames) { 9765f757f3fSDimitry Andric DenseMap<StringRef, LibFunc> Indices; 9775f757f3fSDimitry Andric unsigned Idx = 0; 9785f757f3fSDimitry Andric Indices.reserve(LibFunc::NumLibFuncs); 9795f757f3fSDimitry Andric for (const auto &Func : StandardNames) 9805f757f3fSDimitry Andric Indices[Func] = static_cast<LibFunc>(Idx++); 9815f757f3fSDimitry Andric return Indices; 9825f757f3fSDimitry Andric } 9835f757f3fSDimitry Andric 9848bcb0991SDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, LibFunc &F) const { 9850b57cec5SDimitry Andric funcName = sanitizeFunctionName(funcName); 9860b57cec5SDimitry Andric if (funcName.empty()) 9870b57cec5SDimitry Andric return false; 9880b57cec5SDimitry Andric 9895f757f3fSDimitry Andric static const DenseMap<StringRef, LibFunc> Indices = 9905f757f3fSDimitry Andric buildIndexMap(StandardNames); 9915f757f3fSDimitry Andric 9925f757f3fSDimitry Andric if (auto Loc = Indices.find(funcName); Loc != Indices.end()) { 9935f757f3fSDimitry Andric F = Loc->second; 9940b57cec5SDimitry Andric return true; 9950b57cec5SDimitry Andric } 9960b57cec5SDimitry Andric return false; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric 999bdd1243dSDimitry Andric // Return true if ArgTy matches Ty. 1000bdd1243dSDimitry Andric 1001bdd1243dSDimitry Andric static bool matchType(FuncArgTypeID ArgTy, const Type *Ty, unsigned IntBits, 1002bdd1243dSDimitry Andric unsigned SizeTBits) { 1003bdd1243dSDimitry Andric switch (ArgTy) { 1004bdd1243dSDimitry Andric case Void: 1005bdd1243dSDimitry Andric return Ty->isVoidTy(); 1006bdd1243dSDimitry Andric case Bool: 1007bdd1243dSDimitry Andric return Ty->isIntegerTy(8); 1008bdd1243dSDimitry Andric case Int16: 1009bdd1243dSDimitry Andric return Ty->isIntegerTy(16); 1010bdd1243dSDimitry Andric case Int32: 1011bdd1243dSDimitry Andric return Ty->isIntegerTy(32); 1012bdd1243dSDimitry Andric case Int: 1013bdd1243dSDimitry Andric return Ty->isIntegerTy(IntBits); 1014bdd1243dSDimitry Andric case IntPlus: 1015bdd1243dSDimitry Andric return Ty->isIntegerTy() && Ty->getPrimitiveSizeInBits() >= IntBits; 1016bdd1243dSDimitry Andric case IntX: 1017bdd1243dSDimitry Andric return Ty->isIntegerTy(); 1018bdd1243dSDimitry Andric case Long: 1019bdd1243dSDimitry Andric // TODO: Figure out and use long size. 1020bdd1243dSDimitry Andric return Ty->isIntegerTy() && Ty->getPrimitiveSizeInBits() >= IntBits; 1021bdd1243dSDimitry Andric case Int64: 1022bdd1243dSDimitry Andric return Ty->isIntegerTy(64); 1023bdd1243dSDimitry Andric case LLong: 1024bdd1243dSDimitry Andric return Ty->isIntegerTy(64); 1025bdd1243dSDimitry Andric case SizeT: 1026bdd1243dSDimitry Andric case SSizeT: 1027bdd1243dSDimitry Andric return Ty->isIntegerTy(SizeTBits); 1028bdd1243dSDimitry Andric case Flt: 1029bdd1243dSDimitry Andric return Ty->isFloatTy(); 1030bdd1243dSDimitry Andric case Dbl: 1031bdd1243dSDimitry Andric return Ty->isDoubleTy(); 1032bdd1243dSDimitry Andric // TODO: Tighten this up. 1033bdd1243dSDimitry Andric case LDbl: 1034bdd1243dSDimitry Andric return Ty->isFloatingPointTy(); 1035bdd1243dSDimitry Andric case Floating: 1036bdd1243dSDimitry Andric return Ty->isFloatingPointTy(); 1037bdd1243dSDimitry Andric case Ptr: 1038bdd1243dSDimitry Andric return Ty->isPointerTy(); 1039bdd1243dSDimitry Andric case Struct: 1040bdd1243dSDimitry Andric return Ty->isStructTy(); 1041bdd1243dSDimitry Andric default: 1042bdd1243dSDimitry Andric break; 1043bdd1243dSDimitry Andric } 1044bdd1243dSDimitry Andric 1045bdd1243dSDimitry Andric llvm_unreachable("Invalid type"); 1046bdd1243dSDimitry Andric } 1047bdd1243dSDimitry Andric 10480b57cec5SDimitry Andric bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, 10490b57cec5SDimitry Andric LibFunc F, 1050349cc55cSDimitry Andric const Module &M) const { 10510b57cec5SDimitry Andric unsigned NumParams = FTy.getNumParams(); 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric switch (F) { 1054bdd1243dSDimitry Andric // Special handling for <complex.h> functions: 10550b57cec5SDimitry Andric case LibFunc_cabs: 10560b57cec5SDimitry Andric case LibFunc_cabsf: 10570b57cec5SDimitry Andric case LibFunc_cabsl: { 10580b57cec5SDimitry Andric Type *RetTy = FTy.getReturnType(); 10590b57cec5SDimitry Andric if (!RetTy->isFloatingPointTy()) 10600b57cec5SDimitry Andric return false; 10610b57cec5SDimitry Andric 1062bdd1243dSDimitry Andric Type *ParamTy = FTy.getParamType(0); 10630b57cec5SDimitry Andric // NOTE: These prototypes are target specific and currently support 10640b57cec5SDimitry Andric // "complex" passed as an array or discrete real & imaginary parameters. 10650b57cec5SDimitry Andric // Add other calling conventions to enable libcall optimizations. 10660b57cec5SDimitry Andric if (NumParams == 1) 1067bdd1243dSDimitry Andric return (ParamTy->isArrayTy() && ParamTy->getArrayNumElements() == 2 && 1068bdd1243dSDimitry Andric ParamTy->getArrayElementType() == RetTy); 10690b57cec5SDimitry Andric else if (NumParams == 2) 1070bdd1243dSDimitry Andric return ParamTy == RetTy && FTy.getParamType(1) == RetTy; 1071bdd1243dSDimitry Andric 10720b57cec5SDimitry Andric return false; 10730b57cec5SDimitry Andric } 1074bdd1243dSDimitry Andric // Special handling for the sincospi functions that return either 1075bdd1243dSDimitry Andric // a struct or vector: 1076bdd1243dSDimitry Andric case LibFunc_sincospi_stret: 1077bdd1243dSDimitry Andric case LibFunc_sincospif_stret: { 1078bdd1243dSDimitry Andric if (NumParams != 1) 1079bdd1243dSDimitry Andric return false; 1080bdd1243dSDimitry Andric 1081bdd1243dSDimitry Andric Type *RetTy = FTy.getReturnType(); 1082bdd1243dSDimitry Andric Type *ParamTy = FTy.getParamType(0); 1083bdd1243dSDimitry Andric if (auto *Ty = dyn_cast<StructType>(RetTy)) { 1084bdd1243dSDimitry Andric if (Ty->getNumElements() != 2) 1085bdd1243dSDimitry Andric return false; 1086bdd1243dSDimitry Andric return (Ty->getElementType(0) == ParamTy && 1087bdd1243dSDimitry Andric Ty->getElementType(1) == ParamTy); 1088bdd1243dSDimitry Andric } 1089bdd1243dSDimitry Andric 1090bdd1243dSDimitry Andric if (auto *Ty = dyn_cast<FixedVectorType>(RetTy)) { 1091bdd1243dSDimitry Andric if (Ty->getNumElements() != 2) 1092bdd1243dSDimitry Andric return false; 1093bdd1243dSDimitry Andric return Ty->getElementType() == ParamTy; 1094bdd1243dSDimitry Andric } 1095bdd1243dSDimitry Andric 1096bdd1243dSDimitry Andric return false; 1097bdd1243dSDimitry Andric } 1098bdd1243dSDimitry Andric 1099bdd1243dSDimitry Andric default: 11000b57cec5SDimitry Andric break; 11010b57cec5SDimitry Andric } 11020b57cec5SDimitry Andric 1103bdd1243dSDimitry Andric unsigned IntBits = getIntSize(); 1104bdd1243dSDimitry Andric unsigned SizeTBits = getSizeTSize(M); 1105bdd1243dSDimitry Andric unsigned Idx = 0; 1106bdd1243dSDimitry Andric 1107bdd1243dSDimitry Andric // Iterate over the type ids in the function prototype, matching each 1108bdd1243dSDimitry Andric // against the function's type FTy, starting with its return type. 1109bdd1243dSDimitry Andric // Return true if both match in number and kind, inclduing the ellipsis. 1110bdd1243dSDimitry Andric Type *Ty = FTy.getReturnType(), *LastTy = Ty; 1111bdd1243dSDimitry Andric const auto &ProtoTypes = Signatures[F]; 1112bdd1243dSDimitry Andric for (auto TyID : ProtoTypes) { 1113bdd1243dSDimitry Andric if (Idx && TyID == Void) 1114bdd1243dSDimitry Andric // Except in the first position where it designates the function's 1115bdd1243dSDimitry Andric // return type Void ends the argument list. 1116bdd1243dSDimitry Andric break; 1117bdd1243dSDimitry Andric 1118bdd1243dSDimitry Andric if (TyID == Ellip) { 1119bdd1243dSDimitry Andric // The ellipsis ends the protoype list but is not a part of FTy's 1120bdd1243dSDimitry Andric // argument list. Except when it's last it must be followed by 1121bdd1243dSDimitry Andric // Void. 1122bdd1243dSDimitry Andric assert(Idx == ProtoTypes.size() - 1 || ProtoTypes[Idx + 1] == Void); 1123bdd1243dSDimitry Andric return FTy.isFunctionVarArg(); 1124bdd1243dSDimitry Andric } 1125bdd1243dSDimitry Andric 1126bdd1243dSDimitry Andric if (TyID == Same) { 1127bdd1243dSDimitry Andric assert(Idx != 0 && "Type ID 'Same' must not be first!"); 1128bdd1243dSDimitry Andric if (Ty != LastTy) 1129bdd1243dSDimitry Andric return false; 1130bdd1243dSDimitry Andric } else { 1131bdd1243dSDimitry Andric if (!Ty || !matchType(TyID, Ty, IntBits, SizeTBits)) 1132bdd1243dSDimitry Andric return false; 1133bdd1243dSDimitry Andric LastTy = Ty; 1134bdd1243dSDimitry Andric } 1135bdd1243dSDimitry Andric 1136bdd1243dSDimitry Andric if (Idx == NumParams) { 1137bdd1243dSDimitry Andric // There's at least one and at most two more type ids than there are 1138bdd1243dSDimitry Andric // arguments in FTy's argument list. 1139bdd1243dSDimitry Andric Ty = nullptr; 1140bdd1243dSDimitry Andric ++Idx; 1141bdd1243dSDimitry Andric continue; 1142bdd1243dSDimitry Andric } 1143bdd1243dSDimitry Andric 1144bdd1243dSDimitry Andric Ty = FTy.getParamType(Idx++); 1145bdd1243dSDimitry Andric } 1146bdd1243dSDimitry Andric 1147bdd1243dSDimitry Andric // Return success only if all entries on both lists have been processed 1148bdd1243dSDimitry Andric // and the function is not a variadic one. 1149bdd1243dSDimitry Andric return Idx == NumParams + 1 && !FTy.isFunctionVarArg(); 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, 11530b57cec5SDimitry Andric LibFunc &F) const { 11540b57cec5SDimitry Andric // Intrinsics don't overlap w/libcalls; if our module has a large number of 11550b57cec5SDimitry Andric // intrinsics, this ends up being an interesting compile time win since we 11560b57cec5SDimitry Andric // avoid string normalization and comparison. 11570b57cec5SDimitry Andric if (FDecl.isIntrinsic()) return false; 11580b57cec5SDimitry Andric 1159349cc55cSDimitry Andric const Module *M = FDecl.getParent(); 1160349cc55cSDimitry Andric assert(M && "Expecting FDecl to be connected to a Module."); 1161349cc55cSDimitry Andric 11625f757f3fSDimitry Andric if (FDecl.LibFuncCache == Function::UnknownLibFunc) 11635f757f3fSDimitry Andric if (!getLibFunc(FDecl.getName(), FDecl.LibFuncCache)) 11645f757f3fSDimitry Andric FDecl.LibFuncCache = NotLibFunc; 11655f757f3fSDimitry Andric 11665f757f3fSDimitry Andric if (FDecl.LibFuncCache == NotLibFunc) 11675f757f3fSDimitry Andric return false; 11685f757f3fSDimitry Andric 11695f757f3fSDimitry Andric F = FDecl.LibFuncCache; 11705f757f3fSDimitry Andric return isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M); 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric 1173cb14a3feSDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(unsigned int Opcode, Type *Ty, 1174cb14a3feSDimitry Andric LibFunc &F) const { 1175cb14a3feSDimitry Andric // Must be a frem instruction with float or double arguments. 1176cb14a3feSDimitry Andric if (Opcode != Instruction::FRem || (!Ty->isDoubleTy() && !Ty->isFloatTy())) 1177cb14a3feSDimitry Andric return false; 1178cb14a3feSDimitry Andric 1179cb14a3feSDimitry Andric F = Ty->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf; 1180cb14a3feSDimitry Andric return true; 1181cb14a3feSDimitry Andric } 1182cb14a3feSDimitry Andric 11830b57cec5SDimitry Andric void TargetLibraryInfoImpl::disableAllFunctions() { 11840b57cec5SDimitry Andric memset(AvailableArray, 0, sizeof(AvailableArray)); 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) { 11885f757f3fSDimitry Andric return LHS.getScalarFnName() < RHS.getScalarFnName(); 11890b57cec5SDimitry Andric } 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) { 11925f757f3fSDimitry Andric return LHS.getVectorFnName() < RHS.getVectorFnName(); 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric 11950b57cec5SDimitry Andric static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) { 11965f757f3fSDimitry Andric return LHS.getScalarFnName() < S; 11970b57cec5SDimitry Andric } 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) { 1200e8d8bef9SDimitry Andric llvm::append_range(VectorDescs, Fns); 12010b57cec5SDimitry Andric llvm::sort(VectorDescs, compareByScalarFnName); 12020b57cec5SDimitry Andric 1203e8d8bef9SDimitry Andric llvm::append_range(ScalarDescs, Fns); 12040b57cec5SDimitry Andric llvm::sort(ScalarDescs, compareByVectorFnName); 12050b57cec5SDimitry Andric } 12060b57cec5SDimitry Andric 1207*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_Accelerate[] = { 12080b57cec5SDimitry Andric #define TLI_DEFINE_ACCELERATE_VECFUNCS 12090b57cec5SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1210*0fca6ea1SDimitry Andric #undef TLI_DEFINE_ACCELERATE_VECFUNCS 12110b57cec5SDimitry Andric }; 1212*0fca6ea1SDimitry Andric 1213*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_DarwinLibSystemM[] = { 1214fe6060f1SDimitry Andric #define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS 1215fe6060f1SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1216*0fca6ea1SDimitry Andric #undef TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS 1217fe6060f1SDimitry Andric }; 1218*0fca6ea1SDimitry Andric 1219*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_LIBMVEC_X86[] = { 1220e8d8bef9SDimitry Andric #define TLI_DEFINE_LIBMVEC_X86_VECFUNCS 1221e8d8bef9SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1222*0fca6ea1SDimitry Andric #undef TLI_DEFINE_LIBMVEC_X86_VECFUNCS 1223e8d8bef9SDimitry Andric }; 1224*0fca6ea1SDimitry Andric 1225*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_MASSV[] = { 12260b57cec5SDimitry Andric #define TLI_DEFINE_MASSV_VECFUNCS 12270b57cec5SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1228*0fca6ea1SDimitry Andric #undef TLI_DEFINE_MASSV_VECFUNCS 12290b57cec5SDimitry Andric }; 1230*0fca6ea1SDimitry Andric 1231*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_SVML[] = { 12320b57cec5SDimitry Andric #define TLI_DEFINE_SVML_VECFUNCS 12330b57cec5SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1234*0fca6ea1SDimitry Andric #undef TLI_DEFINE_SVML_VECFUNCS 12350b57cec5SDimitry Andric }; 1236*0fca6ea1SDimitry Andric 1237*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VF2[] = { 1238bdd1243dSDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS 12395f757f3fSDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ 12405f757f3fSDimitry Andric {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, 1241bdd1243dSDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1242*0fca6ea1SDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS 1243bdd1243dSDimitry Andric }; 1244*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VF4[] = { 1245bdd1243dSDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS 12465f757f3fSDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX) \ 12475f757f3fSDimitry Andric {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX}, 124806c3fb27SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1249*0fca6ea1SDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS 125006c3fb27SDimitry Andric }; 1251*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VFScalable[] = { 125206c3fb27SDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS 12535f757f3fSDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ 12545f757f3fSDimitry Andric {SCAL, VEC, VF, MASK, VABI_PREFIX}, 1255bdd1243dSDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1256*0fca6ea1SDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS 1257bdd1243dSDimitry Andric }; 1258bdd1243dSDimitry Andric 1259*0fca6ea1SDimitry Andric static const VecDesc VecFuncs_ArmPL[] = { 1260*0fca6ea1SDimitry Andric #define TLI_DEFINE_ARMPL_VECFUNCS 1261*0fca6ea1SDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ 1262*0fca6ea1SDimitry Andric {SCAL, VEC, VF, MASK, VABI_PREFIX}, 1263*0fca6ea1SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1264*0fca6ea1SDimitry Andric #undef TLI_DEFINE_ARMPL_VECFUNCS 1265*0fca6ea1SDimitry Andric }; 1266*0fca6ea1SDimitry Andric 1267*0fca6ea1SDimitry Andric const VecDesc VecFuncs_AMDLIBM[] = { 1268*0fca6ea1SDimitry Andric #define TLI_DEFINE_AMDLIBM_VECFUNCS 1269*0fca6ea1SDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX) \ 1270*0fca6ea1SDimitry Andric {SCAL, VEC, VF, MASK, VABI_PREFIX}, 1271*0fca6ea1SDimitry Andric #include "llvm/Analysis/VecFuncs.def" 1272*0fca6ea1SDimitry Andric #undef TLI_DEFINE_AMDLIBM_VECFUNCS 1273*0fca6ea1SDimitry Andric }; 1274*0fca6ea1SDimitry Andric 1275*0fca6ea1SDimitry Andric void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( 1276*0fca6ea1SDimitry Andric enum VectorLibrary VecLib, const llvm::Triple &TargetTriple) { 1277*0fca6ea1SDimitry Andric switch (VecLib) { 1278*0fca6ea1SDimitry Andric case Accelerate: { 1279*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_Accelerate); 1280*0fca6ea1SDimitry Andric break; 1281*0fca6ea1SDimitry Andric } 1282*0fca6ea1SDimitry Andric case DarwinLibSystemM: { 1283*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_DarwinLibSystemM); 1284*0fca6ea1SDimitry Andric break; 1285*0fca6ea1SDimitry Andric } 1286*0fca6ea1SDimitry Andric case LIBMVEC_X86: { 1287*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_LIBMVEC_X86); 1288*0fca6ea1SDimitry Andric break; 1289*0fca6ea1SDimitry Andric } 1290*0fca6ea1SDimitry Andric case MASSV: { 1291*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_MASSV); 1292*0fca6ea1SDimitry Andric break; 1293*0fca6ea1SDimitry Andric } 1294*0fca6ea1SDimitry Andric case SVML: { 1295*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_SVML); 1296*0fca6ea1SDimitry Andric break; 1297*0fca6ea1SDimitry Andric } 1298*0fca6ea1SDimitry Andric case SLEEFGNUABI: { 1299bdd1243dSDimitry Andric switch (TargetTriple.getArch()) { 1300bdd1243dSDimitry Andric default: 1301bdd1243dSDimitry Andric break; 1302bdd1243dSDimitry Andric case llvm::Triple::aarch64: 1303bdd1243dSDimitry Andric case llvm::Triple::aarch64_be: 1304*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF2); 1305*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF4); 1306*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalable); 130706c3fb27SDimitry Andric break; 130806c3fb27SDimitry Andric } 130906c3fb27SDimitry Andric break; 131006c3fb27SDimitry Andric } 131106c3fb27SDimitry Andric case ArmPL: { 131206c3fb27SDimitry Andric switch (TargetTriple.getArch()) { 131306c3fb27SDimitry Andric default: 131406c3fb27SDimitry Andric break; 131506c3fb27SDimitry Andric case llvm::Triple::aarch64: 131606c3fb27SDimitry Andric case llvm::Triple::aarch64_be: 1317*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_ArmPL); 1318bdd1243dSDimitry Andric break; 1319bdd1243dSDimitry Andric } 1320bdd1243dSDimitry Andric break; 1321bdd1243dSDimitry Andric } 1322*0fca6ea1SDimitry Andric case AMDLIBM: { 1323*0fca6ea1SDimitry Andric addVectorizableFunctions(VecFuncs_AMDLIBM); 1324*0fca6ea1SDimitry Andric break; 1325*0fca6ea1SDimitry Andric } 13260b57cec5SDimitry Andric case NoLibrary: 13270b57cec5SDimitry Andric break; 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric } 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const { 13320b57cec5SDimitry Andric funcName = sanitizeFunctionName(funcName); 13330b57cec5SDimitry Andric if (funcName.empty()) 13340b57cec5SDimitry Andric return false; 13350b57cec5SDimitry Andric 13360b57cec5SDimitry Andric std::vector<VecDesc>::const_iterator I = 13370b57cec5SDimitry Andric llvm::lower_bound(VectorDescs, funcName, compareWithScalarFnName); 13385f757f3fSDimitry Andric return I != VectorDescs.end() && StringRef(I->getScalarFnName()) == funcName; 13390b57cec5SDimitry Andric } 13400b57cec5SDimitry Andric 134106c3fb27SDimitry Andric StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F, 134206c3fb27SDimitry Andric const ElementCount &VF, 134306c3fb27SDimitry Andric bool Masked) const { 13445f757f3fSDimitry Andric const VecDesc *VD = getVectorMappingInfo(F, VF, Masked); 13455f757f3fSDimitry Andric if (VD) 13465f757f3fSDimitry Andric return VD->getVectorFnName(); 13475f757f3fSDimitry Andric return StringRef(); 13485f757f3fSDimitry Andric } 13495f757f3fSDimitry Andric 13505f757f3fSDimitry Andric const VecDesc * 13515f757f3fSDimitry Andric TargetLibraryInfoImpl::getVectorMappingInfo(StringRef F, const ElementCount &VF, 13525f757f3fSDimitry Andric bool Masked) const { 13530b57cec5SDimitry Andric F = sanitizeFunctionName(F); 13540b57cec5SDimitry Andric if (F.empty()) 13555f757f3fSDimitry Andric return nullptr; 13560b57cec5SDimitry Andric std::vector<VecDesc>::const_iterator I = 13570b57cec5SDimitry Andric llvm::lower_bound(VectorDescs, F, compareWithScalarFnName); 13585f757f3fSDimitry Andric while (I != VectorDescs.end() && StringRef(I->getScalarFnName()) == F) { 13595f757f3fSDimitry Andric if ((I->getVectorizationFactor() == VF) && (I->isMasked() == Masked)) 13605f757f3fSDimitry Andric return &(*I); 13610b57cec5SDimitry Andric ++I; 13620b57cec5SDimitry Andric } 13635f757f3fSDimitry Andric return nullptr; 13640b57cec5SDimitry Andric } 13650b57cec5SDimitry Andric 1366480093f4SDimitry Andric TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F, 13670b57cec5SDimitry Andric FunctionAnalysisManager &) { 1368480093f4SDimitry Andric if (!BaselineInfoImpl) 1369480093f4SDimitry Andric BaselineInfoImpl = 1370480093f4SDimitry Andric TargetLibraryInfoImpl(Triple(F.getParent()->getTargetTriple())); 1371480093f4SDimitry Andric return TargetLibraryInfo(*BaselineInfoImpl, &F); 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric unsigned TargetLibraryInfoImpl::getWCharSize(const Module &M) const { 13750b57cec5SDimitry Andric if (auto *ShortWChar = cast_or_null<ConstantAsMetadata>( 13760b57cec5SDimitry Andric M.getModuleFlag("wchar_size"))) 13770b57cec5SDimitry Andric return cast<ConstantInt>(ShortWChar->getValue())->getZExtValue(); 13780b57cec5SDimitry Andric return 0; 13790b57cec5SDimitry Andric } 13800b57cec5SDimitry Andric 1381bdd1243dSDimitry Andric unsigned TargetLibraryInfoImpl::getSizeTSize(const Module &M) const { 1382bdd1243dSDimitry Andric // There is really no guarantee that sizeof(size_t) is equal to sizeof(int*). 1383bdd1243dSDimitry Andric // If that isn't true then it should be possible to derive the SizeTTy from 1384bdd1243dSDimitry Andric // the target triple here instead and do an early return. 1385bdd1243dSDimitry Andric 1386bdd1243dSDimitry Andric // Historically LLVM assume that size_t has same size as intptr_t (hence 1387bdd1243dSDimitry Andric // deriving the size from sizeof(int*) in address space zero). This should 1388bdd1243dSDimitry Andric // work for most targets. For future consideration: DataLayout also implement 1389bdd1243dSDimitry Andric // getIndexSizeInBits which might map better to size_t compared to 1390bdd1243dSDimitry Andric // getPointerSizeInBits. Hard coding address space zero here might be 1391bdd1243dSDimitry Andric // unfortunate as well. Maybe getDefaultGlobalsAddressSpace() or 1392bdd1243dSDimitry Andric // getAllocaAddrSpace() is better. 1393bdd1243dSDimitry Andric unsigned AddressSpace = 0; 1394bdd1243dSDimitry Andric return M.getDataLayout().getPointerSizeInBits(AddressSpace); 1395bdd1243dSDimitry Andric } 1396bdd1243dSDimitry Andric 13970b57cec5SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() 1398480093f4SDimitry Andric : ImmutablePass(ID), TLA(TargetLibraryInfoImpl()) { 13990b57cec5SDimitry Andric initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 14000b57cec5SDimitry Andric } 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T) 1403480093f4SDimitry Andric : ImmutablePass(ID), TLA(TargetLibraryInfoImpl(T)) { 14040b57cec5SDimitry Andric initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 14050b57cec5SDimitry Andric } 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 14080b57cec5SDimitry Andric const TargetLibraryInfoImpl &TLIImpl) 1409480093f4SDimitry Andric : ImmutablePass(ID), TLA(TLIImpl) { 14100b57cec5SDimitry Andric initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric 1413*0fca6ea1SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 1414*0fca6ea1SDimitry Andric const TargetLibraryInfo &TLIOther) 1415*0fca6ea1SDimitry Andric : TargetLibraryInfoWrapperPass(*TLIOther.Impl) {} 1416*0fca6ea1SDimitry Andric 14170b57cec5SDimitry Andric AnalysisKey TargetLibraryAnalysis::Key; 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric // Register the basic pass. 14200b57cec5SDimitry Andric INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", 14210b57cec5SDimitry Andric "Target Library Information", false, true) 14220b57cec5SDimitry Andric char TargetLibraryInfoWrapperPass::ID = 0; 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric void TargetLibraryInfoWrapperPass::anchor() {} 1425480093f4SDimitry Andric 1426fe6060f1SDimitry Andric void TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF, 1427fe6060f1SDimitry Andric ElementCount &FixedVF, 1428fe6060f1SDimitry Andric ElementCount &ScalableVF) const { 1429480093f4SDimitry Andric ScalarF = sanitizeFunctionName(ScalarF); 1430fe6060f1SDimitry Andric // Use '0' here because a type of the form <vscale x 1 x ElTy> is not the 1431fe6060f1SDimitry Andric // same as a scalar. 1432fe6060f1SDimitry Andric ScalableVF = ElementCount::getScalable(0); 1433fe6060f1SDimitry Andric FixedVF = ElementCount::getFixed(1); 1434480093f4SDimitry Andric if (ScalarF.empty()) 1435fe6060f1SDimitry Andric return; 1436480093f4SDimitry Andric 1437480093f4SDimitry Andric std::vector<VecDesc>::const_iterator I = 1438480093f4SDimitry Andric llvm::lower_bound(VectorDescs, ScalarF, compareWithScalarFnName); 14395f757f3fSDimitry Andric while (I != VectorDescs.end() && StringRef(I->getScalarFnName()) == ScalarF) { 1440fe6060f1SDimitry Andric ElementCount *VF = 14415f757f3fSDimitry Andric I->getVectorizationFactor().isScalable() ? &ScalableVF : &FixedVF; 14425f757f3fSDimitry Andric if (ElementCount::isKnownGT(I->getVectorizationFactor(), *VF)) 14435f757f3fSDimitry Andric *VF = I->getVectorizationFactor(); 1444480093f4SDimitry Andric ++I; 1445480093f4SDimitry Andric } 1446480093f4SDimitry Andric } 1447