xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/TargetLibraryInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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