xref: /src/contrib/llvm-project/llvm/lib/Analysis/TargetLibraryInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15a5ac124SDimitry Andric //===-- TargetLibraryInfo.cpp - Runtime library information ----------------==//
25a5ac124SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a5ac124SDimitry Andric //
75a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
85a5ac124SDimitry Andric //
95a5ac124SDimitry Andric // This file implements the TargetLibraryInfo class.
105a5ac124SDimitry Andric //
115a5ac124SDimitry Andric //===----------------------------------------------------------------------===//
125a5ac124SDimitry Andric 
135a5ac124SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
14b1c73532SDimitry Andric #include "llvm/ADT/DenseMap.h"
15b1c73532SDimitry Andric #include "llvm/ADT/SmallString.h"
16b5630dbaSDimitry Andric #include "llvm/IR/Constants.h"
17ac9a064cSDimitry Andric #include "llvm/IR/Module.h"
18706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
195a5ac124SDimitry Andric #include "llvm/Support/CommandLine.h"
207fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
215a5ac124SDimitry Andric using namespace llvm;
225a5ac124SDimitry Andric 
235a5ac124SDimitry Andric static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary(
245a5ac124SDimitry Andric     "vector-library", cl::Hidden, cl::desc("Vector functions library"),
255a5ac124SDimitry Andric     cl::init(TargetLibraryInfoImpl::NoLibrary),
265a5ac124SDimitry Andric     cl::values(clEnumValN(TargetLibraryInfoImpl::NoLibrary, "none",
275a5ac124SDimitry Andric                           "No vector functions library"),
285a5ac124SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate",
295a5ac124SDimitry Andric                           "Accelerate framework"),
30344a3780SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::DarwinLibSystemM,
31344a3780SDimitry Andric                           "Darwin_libsystem_m", "Darwin libsystem_m"),
32b60736ecSDimitry Andric                clEnumValN(TargetLibraryInfoImpl::LIBMVEC_X86, "LIBMVEC-X86",
33b60736ecSDimitry Andric                           "GLIBC Vector Math library"),
34e6d15924SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV",
35e6d15924SDimitry Andric                           "IBM MASS vector library"),
36b915e9e0SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::SVML, "SVML",
37e3b55780SDimitry Andric                           "Intel SVML library"),
38e3b55780SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::SLEEFGNUABI, "sleefgnuabi",
397fa27ce4SDimitry Andric                           "SIMD Library for Evaluating Elementary Functions"),
407fa27ce4SDimitry Andric                clEnumValN(TargetLibraryInfoImpl::ArmPL, "ArmPL",
41ac9a064cSDimitry Andric                           "Arm Performance Libraries"),
42ac9a064cSDimitry Andric                clEnumValN(TargetLibraryInfoImpl::AMDLIBM, "AMDLIBM",
43ac9a064cSDimitry Andric                           "AMD vector math library")));
445a5ac124SDimitry Andric 
451d5ae102SDimitry Andric StringLiteral const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] =
461d5ae102SDimitry Andric     {
475a5ac124SDimitry Andric #define TLI_DEFINE_STRING
485a5ac124SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.def"
495a5ac124SDimitry Andric };
505a5ac124SDimitry Andric 
getVectorFunctionABIVariantString() const51b1c73532SDimitry Andric std::string VecDesc::getVectorFunctionABIVariantString() const {
52b1c73532SDimitry Andric   assert(!VectorFnName.empty() && "Vector function name must not be empty.");
53b1c73532SDimitry Andric   SmallString<256> Buffer;
54b1c73532SDimitry Andric   llvm::raw_svector_ostream Out(Buffer);
55b1c73532SDimitry Andric   Out << VABIPrefix << "_" << ScalarFnName << "(" << VectorFnName << ")";
56b1c73532SDimitry Andric   return std::string(Out.str());
57b1c73532SDimitry Andric }
58b1c73532SDimitry Andric 
59e3b55780SDimitry Andric // Recognized types of library function arguments and return types.
60e3b55780SDimitry Andric enum FuncArgTypeID : char {
61e3b55780SDimitry Andric   Void = 0, // Must be zero.
62e3b55780SDimitry Andric   Bool,     // 8 bits on all targets
63e3b55780SDimitry Andric   Int16,
64e3b55780SDimitry Andric   Int32,
65e3b55780SDimitry Andric   Int,
66e3b55780SDimitry Andric   IntPlus, // Int or bigger.
67e3b55780SDimitry Andric   Long,    // Either 32 or 64 bits.
68e3b55780SDimitry Andric   IntX,    // Any integer type.
69e3b55780SDimitry Andric   Int64,
70e3b55780SDimitry Andric   LLong,    // 64 bits on all targets.
71e3b55780SDimitry Andric   SizeT,    // size_t.
72e3b55780SDimitry Andric   SSizeT,   // POSIX ssize_t.
73e3b55780SDimitry Andric   Flt,      // IEEE float.
74e3b55780SDimitry Andric   Dbl,      // IEEE double.
75e3b55780SDimitry Andric   LDbl,     // Any floating type (TODO: tighten this up).
76e3b55780SDimitry Andric   Floating, // Any floating type.
77e3b55780SDimitry Andric   Ptr,      // Any pointer type.
78e3b55780SDimitry Andric   Struct,   // Any struct type.
79e3b55780SDimitry Andric   Ellip,    // The ellipsis (...).
80e3b55780SDimitry Andric   Same,     // Same argument type as the previous one.
81e3b55780SDimitry Andric };
82e3b55780SDimitry Andric 
83e3b55780SDimitry Andric typedef std::array<FuncArgTypeID, 8> FuncProtoTy;
84e3b55780SDimitry Andric 
85e3b55780SDimitry Andric static const FuncProtoTy Signatures[] = {
86e3b55780SDimitry Andric #define TLI_DEFINE_SIG
87e3b55780SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.def"
88e3b55780SDimitry Andric };
89e3b55780SDimitry Andric 
90e3b55780SDimitry Andric static_assert(sizeof Signatures / sizeof *Signatures == LibFunc::NumLibFuncs,
91e3b55780SDimitry Andric               "Missing library function signatures");
92e3b55780SDimitry Andric 
hasSinCosPiStret(const Triple & T)935a5ac124SDimitry Andric static bool hasSinCosPiStret(const Triple &T) {
945a5ac124SDimitry Andric   // Only Darwin variants have _stret versions of combined trig functions.
955a5ac124SDimitry Andric   if (!T.isOSDarwin())
965a5ac124SDimitry Andric     return false;
975a5ac124SDimitry Andric 
985a5ac124SDimitry Andric   // The ABI is rather complicated on x86, so don't do anything special there.
995a5ac124SDimitry Andric   if (T.getArch() == Triple::x86)
1005a5ac124SDimitry Andric     return false;
1015a5ac124SDimitry Andric 
1025a5ac124SDimitry Andric   if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9))
1035a5ac124SDimitry Andric     return false;
1045a5ac124SDimitry Andric 
1055a5ac124SDimitry Andric   if (T.isiOS() && T.isOSVersionLT(7, 0))
1065a5ac124SDimitry Andric     return false;
1075a5ac124SDimitry Andric 
1085a5ac124SDimitry Andric   return true;
1095a5ac124SDimitry Andric }
1105a5ac124SDimitry Andric 
hasBcmp(const Triple & TT)111e6d15924SDimitry Andric static bool hasBcmp(const Triple &TT) {
112e6d15924SDimitry Andric   // Posix removed support from bcmp() in 2001, but the glibc and several
113e6d15924SDimitry Andric   // implementations of the libc still have it.
114e6d15924SDimitry Andric   if (TT.isOSLinux())
115e6d15924SDimitry Andric     return TT.isGNUEnvironment() || TT.isMusl();
116e6d15924SDimitry Andric   // Both NetBSD and OpenBSD are planning to remove the function. Windows does
117e6d15924SDimitry Andric   // not have it.
1181d5ae102SDimitry Andric   return TT.isOSFreeBSD() || TT.isOSSolaris();
119e6d15924SDimitry Andric }
120e6d15924SDimitry Andric 
isCallingConvCCompatible(CallingConv::ID CC,StringRef TT,FunctionType * FuncTy)121344a3780SDimitry Andric static bool isCallingConvCCompatible(CallingConv::ID CC, StringRef TT,
122344a3780SDimitry Andric                                      FunctionType *FuncTy) {
123344a3780SDimitry Andric   switch (CC) {
124344a3780SDimitry Andric   default:
125344a3780SDimitry Andric     return false;
126344a3780SDimitry Andric   case llvm::CallingConv::C:
127344a3780SDimitry Andric     return true;
128344a3780SDimitry Andric   case llvm::CallingConv::ARM_APCS:
129344a3780SDimitry Andric   case llvm::CallingConv::ARM_AAPCS:
130344a3780SDimitry Andric   case llvm::CallingConv::ARM_AAPCS_VFP: {
131344a3780SDimitry Andric 
132344a3780SDimitry Andric     // The iOS ABI diverges from the standard in some cases, so for now don't
133344a3780SDimitry Andric     // try to simplify those calls.
134344a3780SDimitry Andric     if (Triple(TT).isiOS())
135344a3780SDimitry Andric       return false;
136344a3780SDimitry Andric 
137344a3780SDimitry Andric     if (!FuncTy->getReturnType()->isPointerTy() &&
138344a3780SDimitry Andric         !FuncTy->getReturnType()->isIntegerTy() &&
139344a3780SDimitry Andric         !FuncTy->getReturnType()->isVoidTy())
140344a3780SDimitry Andric       return false;
141344a3780SDimitry Andric 
142344a3780SDimitry Andric     for (auto *Param : FuncTy->params()) {
143344a3780SDimitry Andric       if (!Param->isPointerTy() && !Param->isIntegerTy())
144344a3780SDimitry Andric         return false;
145344a3780SDimitry Andric     }
146344a3780SDimitry Andric     return true;
147344a3780SDimitry Andric   }
148344a3780SDimitry Andric   }
149344a3780SDimitry Andric   return false;
150344a3780SDimitry Andric }
151344a3780SDimitry Andric 
isCallingConvCCompatible(CallBase * CI)152344a3780SDimitry Andric bool TargetLibraryInfoImpl::isCallingConvCCompatible(CallBase *CI) {
153344a3780SDimitry Andric   return ::isCallingConvCCompatible(CI->getCallingConv(),
154344a3780SDimitry Andric                                     CI->getModule()->getTargetTriple(),
155344a3780SDimitry Andric                                     CI->getFunctionType());
156344a3780SDimitry Andric }
157344a3780SDimitry Andric 
isCallingConvCCompatible(Function * F)158344a3780SDimitry Andric bool TargetLibraryInfoImpl::isCallingConvCCompatible(Function *F) {
159344a3780SDimitry Andric   return ::isCallingConvCCompatible(F->getCallingConv(),
160344a3780SDimitry Andric                                     F->getParent()->getTargetTriple(),
161344a3780SDimitry Andric                                     F->getFunctionType());
162344a3780SDimitry Andric }
163344a3780SDimitry Andric 
initializeBase(TargetLibraryInfoImpl & TLI,const Triple & T)164ac9a064cSDimitry Andric static void initializeBase(TargetLibraryInfoImpl &TLI, const Triple &T) {
165ac9a064cSDimitry Andric   bool ShouldExtI32Param, ShouldExtI32Return;
166ac9a064cSDimitry Andric   bool ShouldSignExtI32Param, ShouldSignExtI32Return;
167ac9a064cSDimitry Andric   TargetLibraryInfo::initExtensionsForTriple(
168ac9a064cSDimitry Andric       ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param,
169ac9a064cSDimitry Andric       ShouldSignExtI32Return, T);
170ac9a064cSDimitry Andric   TLI.setShouldExtI32Param(ShouldExtI32Param);
171ac9a064cSDimitry Andric   TLI.setShouldExtI32Return(ShouldExtI32Return);
172ac9a064cSDimitry Andric   TLI.setShouldSignExtI32Param(ShouldSignExtI32Param);
173ac9a064cSDimitry Andric   TLI.setShouldSignExtI32Return(ShouldSignExtI32Return);
174ac9a064cSDimitry Andric 
175ac9a064cSDimitry Andric   // Let's assume by default that the size of int is 32 bits, unless the target
176ac9a064cSDimitry Andric   // is a 16-bit architecture because then it most likely is 16 bits. If that
177ac9a064cSDimitry Andric   // isn't true for a target those defaults should be overridden below.
178ac9a064cSDimitry Andric   TLI.setIntSize(T.isArch16Bit() ? 16 : 32);
179ac9a064cSDimitry Andric }
180ac9a064cSDimitry Andric 
181044eb2f6SDimitry Andric /// Initialize the set of available library functions based on the specified
182044eb2f6SDimitry Andric /// target triple. This should be carefully written so that a missing target
183044eb2f6SDimitry Andric /// triple gets a sane set of defaults.
initializeLibCalls(TargetLibraryInfoImpl & TLI,const Triple & T,ArrayRef<StringLiteral> StandardNames)184ac9a064cSDimitry Andric static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T,
1851d5ae102SDimitry Andric                                ArrayRef<StringLiteral> StandardNames) {
186eb11fae6SDimitry Andric   // Set IO unlocked variants as unavailable
187eb11fae6SDimitry Andric   // Set them as available per system below
188c0981da4SDimitry Andric   TLI.setUnavailable(LibFunc_getc_unlocked);
189eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_getchar_unlocked);
190eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_putc_unlocked);
191eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_putchar_unlocked);
192eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fputc_unlocked);
193eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fgetc_unlocked);
194eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fread_unlocked);
195eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fwrite_unlocked);
196eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fputs_unlocked);
197eb11fae6SDimitry Andric   TLI.setUnavailable(LibFunc_fgets_unlocked);
198eb11fae6SDimitry Andric 
199c0981da4SDimitry Andric   // There is really no runtime library on AMDGPU, apart from
200c0981da4SDimitry Andric   // __kmpc_alloc/free_shared.
201cfca06d7SDimitry Andric   if (T.isAMDGPU()) {
202c0981da4SDimitry Andric     TLI.disableAllFunctions();
203344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared);
204344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc___kmpc_free_shared);
2055a5ac124SDimitry Andric     return;
2065a5ac124SDimitry Andric   }
2075a5ac124SDimitry Andric 
208f65dcba8SDimitry Andric   // memset_pattern{4,8,16} is only available on iOS 3.0 and Mac OS X 10.5 and
209f65dcba8SDimitry Andric   // later. All versions of watchOS support it.
2105a5ac124SDimitry Andric   if (T.isMacOSX()) {
211eb11fae6SDimitry Andric     // available IO unlocked variants on Mac OS X
212eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_getc_unlocked);
213eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_getchar_unlocked);
214eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_putc_unlocked);
215eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_putchar_unlocked);
216b1c73532SDimitry Andric     TLI.setUnavailable(LibFunc_memrchr);
217eb11fae6SDimitry Andric 
218f65dcba8SDimitry Andric     if (T.isMacOSXVersionLT(10, 5)) {
219f65dcba8SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern4);
220f65dcba8SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern8);
22171d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern16);
222f65dcba8SDimitry Andric     }
2235a5ac124SDimitry Andric   } else if (T.isiOS()) {
224f65dcba8SDimitry Andric     if (T.isOSVersionLT(3, 0)) {
225f65dcba8SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern4);
226f65dcba8SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern8);
22771d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_memset_pattern16);
228f65dcba8SDimitry Andric     }
229dd58ef01SDimitry Andric   } else if (!T.isWatchOS()) {
230f65dcba8SDimitry Andric     TLI.setUnavailable(LibFunc_memset_pattern4);
231f65dcba8SDimitry Andric     TLI.setUnavailable(LibFunc_memset_pattern8);
23271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_memset_pattern16);
2335a5ac124SDimitry Andric   }
2345a5ac124SDimitry Andric 
2355a5ac124SDimitry Andric   if (!hasSinCosPiStret(T)) {
23671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sinpi);
23771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sinpif);
23871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_cospi);
23971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_cospif);
24071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sincospi_stret);
24171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sincospif_stret);
2425a5ac124SDimitry Andric   }
2435a5ac124SDimitry Andric 
244e6d15924SDimitry Andric   if (!hasBcmp(T))
245e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_bcmp);
246e6d15924SDimitry Andric 
2475a5ac124SDimitry Andric   if (T.isMacOSX() && T.getArch() == Triple::x86 &&
2485a5ac124SDimitry Andric       !T.isMacOSXVersionLT(10, 7)) {
2495a5ac124SDimitry Andric     // x86-32 OSX has a scheme where fwrite and fputs (and some other functions
2505a5ac124SDimitry Andric     // we don't care about) have two versions; on recent OSX, the one we want
2515a5ac124SDimitry Andric     // has a $UNIX2003 suffix. The two implementations are identical except
2525a5ac124SDimitry Andric     // for the return value in some edge cases.  However, we don't want to
2535a5ac124SDimitry Andric     // generate code that depends on the old symbols.
25471d5a254SDimitry Andric     TLI.setAvailableWithName(LibFunc_fwrite, "fwrite$UNIX2003");
25571d5a254SDimitry Andric     TLI.setAvailableWithName(LibFunc_fputs, "fputs$UNIX2003");
2565a5ac124SDimitry Andric   }
2575a5ac124SDimitry Andric 
258e6d15924SDimitry Andric   // iprintf and friends are only available on XCore, TCE, and Emscripten.
259e6d15924SDimitry Andric   if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce &&
260e6d15924SDimitry Andric       T.getOS() != Triple::Emscripten) {
26171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_iprintf);
26271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_siprintf);
26371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fiprintf);
2645a5ac124SDimitry Andric   }
2655a5ac124SDimitry Andric 
266e6d15924SDimitry Andric   // __small_printf and friends are only available on Emscripten.
267e6d15924SDimitry Andric   if (T.getOS() != Triple::Emscripten) {
268e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_small_printf);
269e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_small_sprintf);
270e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_small_fprintf);
271e6d15924SDimitry Andric   }
272e6d15924SDimitry Andric 
2735a5ac124SDimitry Andric   if (T.isOSWindows() && !T.isOSCygMing()) {
274e6d15924SDimitry Andric     // XXX: The earliest documentation available at the moment is for VS2015/VC19:
275e6d15924SDimitry Andric     // https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015
276e6d15924SDimitry Andric     // XXX: In order to use an MSVCRT older than VC19,
277e6d15924SDimitry Andric     // the specific library version must be explicit in the target triple,
278e6d15924SDimitry Andric     // e.g., x86_64-pc-windows-msvc18.
279e6d15924SDimitry Andric     bool hasPartialC99 = true;
280e6d15924SDimitry Andric     if (T.isKnownWindowsMSVCEnvironment()) {
28177fc4c14SDimitry Andric       VersionTuple Version = T.getEnvironmentVersion();
28277fc4c14SDimitry Andric       hasPartialC99 = (Version.getMajor() == 0 || Version.getMajor() >= 19);
283e6d15924SDimitry Andric     }
284e6d15924SDimitry Andric 
285e6d15924SDimitry Andric     // Latest targets support C89 math functions, in part.
286e6d15924SDimitry Andric     bool isARM = (T.getArch() == Triple::aarch64 ||
287e6d15924SDimitry Andric                   T.getArch() == Triple::arm);
288e6d15924SDimitry Andric     bool hasPartialFloat = (isARM ||
289e6d15924SDimitry Andric                             T.getArch() == Triple::x86_64);
290e6d15924SDimitry Andric 
291e6d15924SDimitry Andric     // Win32 does not support float C89 math functions, in general.
292e6d15924SDimitry Andric     if (!hasPartialFloat) {
293e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_acosf);
294e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_asinf);
295e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_atan2f);
296e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_atanf);
297e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_ceilf);
298e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_cosf);
299e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_coshf);
300e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_expf);
301e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_floorf);
302e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fmodf);
303e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_log10f);
304e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_logf);
305e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_modff);
306e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_powf);
307cfca06d7SDimitry Andric       TLI.setUnavailable(LibFunc_remainderf);
308ac9a064cSDimitry Andric       TLI.setUnavailable(LibFunc_remquof);
309e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_sinf);
310e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_sinhf);
311e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_sqrtf);
312e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_tanf);
313e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_tanhf);
314e6d15924SDimitry Andric     }
315e6d15924SDimitry Andric     if (!isARM)
316e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fabsf);
317e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_frexpf);
318e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_ldexpf);
319e6d15924SDimitry Andric 
320e6d15924SDimitry Andric     // Win32 does not support long double C89 math functions.
32171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_acosl);
32271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_asinl);
32371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_atan2l);
324e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_atanl);
32571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ceill);
32671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_cosl);
32771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_coshl);
32871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_expl);
32971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fabsl);
33071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_floorl);
33171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fmodl);
33271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_frexpl);
33371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ldexpl);
334e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_log10l);
33571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_logl);
33671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_modfl);
33771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_powl);
338cfca06d7SDimitry Andric     TLI.setUnavailable(LibFunc_remainderl);
339ac9a064cSDimitry Andric     TLI.setUnavailable(LibFunc_remquol);
34071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sinl);
34171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sinhl);
34271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_sqrtl);
34371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_tanl);
34471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_tanhl);
3455a5ac124SDimitry Andric 
346e6d15924SDimitry Andric     // Win32 does not fully support C99 math functions.
347e6d15924SDimitry Andric     if (!hasPartialC99) {
34871d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_acosh);
34971d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_acoshf);
35071d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_asinh);
35171d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_asinhf);
35271d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_atanh);
35371d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_atanhf);
354e6d15924SDimitry Andric       TLI.setAvailableWithName(LibFunc_cabs, "_cabs");
355044eb2f6SDimitry Andric       TLI.setUnavailable(LibFunc_cabsf);
35671d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_cbrt);
35771d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_cbrtf);
358e6d15924SDimitry Andric       TLI.setAvailableWithName(LibFunc_copysign, "_copysign");
359e6d15924SDimitry Andric       TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf");
36071d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp2);
36171d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp2f);
36271d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_expm1);
36371d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_expm1f);
364e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fmax);
365e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fmaxf);
366e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fmin);
367e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_fminf);
36871d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_log1p);
36971d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_log1pf);
370e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_log2);
371e6d15924SDimitry Andric       TLI.setUnavailable(LibFunc_log2f);
372e6d15924SDimitry Andric       TLI.setAvailableWithName(LibFunc_logb, "_logb");
373e6d15924SDimitry Andric       if (hasPartialFloat)
374e6d15924SDimitry Andric         TLI.setAvailableWithName(LibFunc_logbf, "_logbf");
375e6d15924SDimitry Andric       else
37671d5a254SDimitry Andric         TLI.setUnavailable(LibFunc_logbf);
37771d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_rint);
37871d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_rintf);
37971d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_round);
38071d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_roundf);
38171d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_trunc);
38271d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_truncf);
3835a5ac124SDimitry Andric     }
3845a5ac124SDimitry Andric 
385e6d15924SDimitry Andric     // Win32 does not support long double C99 math functions.
386e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_acoshl);
387e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_asinhl);
388e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_atanhl);
389e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_cabsl);
390e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_cbrtl);
391e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_copysignl);
392e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_exp2l);
393e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_expm1l);
394e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_fmaxl);
395e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_fminl);
396e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_log1pl);
397e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_log2l);
398e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_logbl);
399e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_nearbyintl);
400e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_rintl);
401e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_roundl);
402e6d15924SDimitry Andric     TLI.setUnavailable(LibFunc_truncl);
403e6d15924SDimitry Andric 
404e6d15924SDimitry Andric     // Win32 does not support these functions, but
405e6d15924SDimitry Andric     // they are generally available on POSIX-compliant systems.
40671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_access);
407344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_chmod);
408344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_closedir);
409344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_fdopen);
410344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_fileno);
411344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_fseeko);
412344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_fstat);
413344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_ftello);
414344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_gettimeofday);
415344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_memccpy);
416344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_mkdir);
417344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_open);
418344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_opendir);
419344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_pclose);
420344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_popen);
421344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_read);
422344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_rmdir);
423344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_stat);
424344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_strcasecmp);
425344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_strncasecmp);
426344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_unlink);
427344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_utime);
428344a3780SDimitry Andric     TLI.setUnavailable(LibFunc_write);
429344a3780SDimitry Andric   }
430344a3780SDimitry Andric 
431344a3780SDimitry Andric   if (T.isOSWindows() && !T.isWindowsCygwinEnvironment()) {
432344a3780SDimitry Andric     // These functions aren't available in either MSVC or MinGW environments.
43371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_bcmp);
43471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_bcopy);
43571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_bzero);
43671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_chown);
43771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ctermid);
43871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ffs);
43971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_flockfile);
44071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fstatvfs);
44171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ftrylockfile);
44271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_funlockfile);
44371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_getitimer);
44471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_getlogin_r);
44571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_getpwnam);
44671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_htonl);
44771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_htons);
44871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_lchown);
44971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_lstat);
450e3b55780SDimitry Andric     TLI.setUnavailable(LibFunc_memrchr);
45171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ntohl);
45271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ntohs);
45371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_pread);
45471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_pwrite);
45571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_readlink);
45671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_realpath);
45771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_setitimer);
45871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_statvfs);
45971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_stpcpy);
46071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_stpncpy);
46171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_times);
46271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_uname);
46371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_unsetenv);
46471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_utimes);
465ac9a064cSDimitry Andric 
466ac9a064cSDimitry Andric     // MinGW does have ldexpf, but it is a plain wrapper over regular ldexp.
467ac9a064cSDimitry Andric     // Therefore it's not beneficial to transform code to use it, i.e.
468ac9a064cSDimitry Andric     // just pretend that the function is not available.
469ac9a064cSDimitry Andric     TLI.setUnavailable(LibFunc_ldexpf);
4705a5ac124SDimitry Andric   }
4715a5ac124SDimitry Andric 
472c0981da4SDimitry Andric   // Pick just one set of new/delete variants.
473c0981da4SDimitry Andric   if (T.isOSMSVCRT()) {
474c0981da4SDimitry Andric     // MSVC, doesn't have the Itanium new/delete.
475c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPv);
476c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvRKSt9nothrow_t);
477c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvSt11align_val_t);
478c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t);
479c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvj);
480c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvjSt11align_val_t);
481c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvm);
482c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvmSt11align_val_t);
483c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPv);
484c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvRKSt9nothrow_t);
485c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvSt11align_val_t);
486c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t);
487c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvj);
488c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvjSt11align_val_t);
489c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvm);
490c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvmSt11align_val_t);
491c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znaj);
492c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajRKSt9nothrow_t);
493c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajSt11align_val_t);
494c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajSt11align_val_tRKSt9nothrow_t);
495c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znam);
496c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamRKSt9nothrow_t);
4977fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t);
498c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamSt11align_val_t);
499c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamSt11align_val_tRKSt9nothrow_t);
500c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znwj);
501c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjRKSt9nothrow_t);
502c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjSt11align_val_t);
503c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t);
504c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znwm);
505c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmRKSt9nothrow_t);
5067fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t);
507c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmSt11align_val_t);
508c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t);
5097fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_Znwm12__hot_cold_t);
5107fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmSt11align_val_t12__hot_cold_t);
5117fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t);
5127fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_Znam12__hot_cold_t);
5137fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamSt11align_val_t12__hot_cold_t);
5147fa27ce4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t);
515c0981da4SDimitry Andric   } else {
516c0981da4SDimitry Andric     // Not MSVC, assume it's Itanium.
517c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_int);
518c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_int_nothrow);
519c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_longlong);
520c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_longlong_nothrow);
521c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr32);
522c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr32_nothrow);
523c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr32_int);
524c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr64);
525c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr64_nothrow);
526c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_ptr64_longlong);
527c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_array_int);
528c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_array_int_nothrow);
529c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_array_longlong);
530c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_new_array_longlong_nothrow);
531c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32);
532c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32_nothrow);
533c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr32_int);
534c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64);
535c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64_nothrow);
536c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_msvc_delete_array_ptr64_longlong);
537c0981da4SDimitry Andric   }
538c0981da4SDimitry Andric 
5395a5ac124SDimitry Andric   switch (T.getOS()) {
5405a5ac124SDimitry Andric   case Triple::MacOSX:
5415a5ac124SDimitry Andric     // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0
5425a5ac124SDimitry Andric     // and their names are __exp10 and __exp10f. exp10l is not available on
5435a5ac124SDimitry Andric     // OS X or iOS.
54471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_exp10l);
5455a5ac124SDimitry Andric     if (T.isMacOSXVersionLT(10, 9)) {
54671d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp10);
54771d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp10f);
5485a5ac124SDimitry Andric     } else {
54971d5a254SDimitry Andric       TLI.setAvailableWithName(LibFunc_exp10, "__exp10");
55071d5a254SDimitry Andric       TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f");
5515a5ac124SDimitry Andric     }
5525a5ac124SDimitry Andric     break;
5535a5ac124SDimitry Andric   case Triple::IOS:
554dd58ef01SDimitry Andric   case Triple::TvOS:
555dd58ef01SDimitry Andric   case Triple::WatchOS:
5564df029ccSDimitry Andric   case Triple::XROS:
55771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_exp10l);
558706b4fc4SDimitry Andric     if (!T.isWatchOS() &&
559706b4fc4SDimitry Andric         (T.isOSVersionLT(7, 0) || (T.isOSVersionLT(9, 0) && T.isX86()))) {
56071d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp10);
56171d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_exp10f);
5625a5ac124SDimitry Andric     } else {
56371d5a254SDimitry Andric       TLI.setAvailableWithName(LibFunc_exp10, "__exp10");
56471d5a254SDimitry Andric       TLI.setAvailableWithName(LibFunc_exp10f, "__exp10f");
5655a5ac124SDimitry Andric     }
5665a5ac124SDimitry Andric     break;
5675a5ac124SDimitry Andric   case Triple::Linux:
5685a5ac124SDimitry Andric     // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely
5695a5ac124SDimitry Andric     // buggy prior to glibc version 2.18. Until this version is widely deployed
5705a5ac124SDimitry Andric     // or we have a reasonable detection strategy, we cannot use exp10 reliably
5715a5ac124SDimitry Andric     // on Linux.
5725a5ac124SDimitry Andric     //
5735a5ac124SDimitry Andric     // Fall through to disable all of them.
574e3b55780SDimitry Andric     [[fallthrough]];
5755a5ac124SDimitry Andric   default:
57671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_exp10);
57771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_exp10f);
57871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_exp10l);
5795a5ac124SDimitry Andric   }
5805a5ac124SDimitry Andric 
5815a5ac124SDimitry Andric   // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and
5825a5ac124SDimitry Andric   // Linux (GLIBC):
5835a5ac124SDimitry Andric   // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html
584dd58ef01SDimitry Andric   // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c
5855a5ac124SDimitry Andric   // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html
5865a5ac124SDimitry Andric   switch (T.getOS()) {
5875a5ac124SDimitry Andric   case Triple::Darwin:
5885a5ac124SDimitry Andric   case Triple::MacOSX:
5895a5ac124SDimitry Andric   case Triple::IOS:
590dd58ef01SDimitry Andric   case Triple::TvOS:
591dd58ef01SDimitry Andric   case Triple::WatchOS:
5924df029ccSDimitry Andric   case Triple::XROS:
5935a5ac124SDimitry Andric   case Triple::FreeBSD:
5945a5ac124SDimitry Andric   case Triple::Linux:
5955a5ac124SDimitry Andric     break;
5965a5ac124SDimitry Andric   default:
59771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ffsl);
5985a5ac124SDimitry Andric   }
5995a5ac124SDimitry Andric 
6005a5ac124SDimitry Andric   // ffsll is available on at least FreeBSD and Linux (GLIBC):
601dd58ef01SDimitry Andric   // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c
6025a5ac124SDimitry Andric   // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html
6035a5ac124SDimitry Andric   switch (T.getOS()) {
604dd58ef01SDimitry Andric   case Triple::Darwin:
605dd58ef01SDimitry Andric   case Triple::MacOSX:
606dd58ef01SDimitry Andric   case Triple::IOS:
607dd58ef01SDimitry Andric   case Triple::TvOS:
608dd58ef01SDimitry Andric   case Triple::WatchOS:
6094df029ccSDimitry Andric   case Triple::XROS:
6105a5ac124SDimitry Andric   case Triple::FreeBSD:
6115a5ac124SDimitry Andric   case Triple::Linux:
6125a5ac124SDimitry Andric     break;
6135a5ac124SDimitry Andric   default:
61471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ffsll);
6155a5ac124SDimitry Andric   }
6165a5ac124SDimitry Andric 
617dd58ef01SDimitry Andric   // The following functions are available on at least FreeBSD:
618dd58ef01SDimitry Andric   // http://svn.freebsd.org/base/head/lib/libc/string/fls.c
619dd58ef01SDimitry Andric   // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c
620dd58ef01SDimitry Andric   // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c
621dd58ef01SDimitry Andric   if (!T.isOSFreeBSD()) {
62271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fls);
62371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_flsl);
62471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_flsll);
625dd58ef01SDimitry Andric   }
626dd58ef01SDimitry Andric 
627d8e91e46SDimitry Andric   // The following functions are only available on GNU/Linux (using glibc).
628d8e91e46SDimitry Andric   // Linux variants without glibc (eg: bionic, musl) may have some subset.
629d8e91e46SDimitry Andric   if (!T.isOSLinux() || !T.isGNUEnvironment()) {
63071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_dunder_strdup);
63171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_dunder_strtok_r);
63271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_dunder_isoc99_scanf);
63371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_dunder_isoc99_sscanf);
63471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_under_IO_getc);
63571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_under_IO_putc);
636d8e91e46SDimitry Andric     // But, Android and musl have memalign.
637d8e91e46SDimitry Andric     if (!T.isAndroid() && !T.isMusl())
63871d5a254SDimitry Andric       TLI.setUnavailable(LibFunc_memalign);
63971d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fopen64);
64071d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fseeko64);
64171d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fstat64);
64271d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_fstatvfs64);
64371d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_ftello64);
64471d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_lstat64);
64571d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_open64);
64671d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_stat64);
64771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_statvfs64);
64871d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_tmpfile64);
649eb11fae6SDimitry Andric 
650eb11fae6SDimitry Andric     // Relaxed math functions are included in math-finite.h on Linux (GLIBC).
651cfca06d7SDimitry Andric     // Note that math-finite.h is no longer supported by top-of-tree GLIBC,
652cfca06d7SDimitry Andric     // so we keep these functions around just so that they're recognized by
653cfca06d7SDimitry Andric     // the ConstantFolder.
654eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acos_finite);
655eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acosf_finite);
656eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acosl_finite);
657eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acosh_finite);
658eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acoshf_finite);
659eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_acoshl_finite);
660eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_asin_finite);
661eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_asinf_finite);
662eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_asinl_finite);
663eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atan2_finite);
664eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atan2f_finite);
665eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atan2l_finite);
666eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atanh_finite);
667eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atanhf_finite);
668eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_atanhl_finite);
669eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_cosh_finite);
670eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_coshf_finite);
671eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_coshl_finite);
672eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp10_finite);
673eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp10f_finite);
674eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp10l_finite);
675eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp2_finite);
676eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp2f_finite);
677eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp2l_finite);
678eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_exp_finite);
679eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_expf_finite);
680eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_expl_finite);
681eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log10_finite);
682eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log10f_finite);
683eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log10l_finite);
684eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log2_finite);
685eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log2f_finite);
686eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log2l_finite);
687eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_log_finite);
688eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_logf_finite);
689eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_logl_finite);
690eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_pow_finite);
691eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_powf_finite);
692eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_powl_finite);
693eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_sinh_finite);
694eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_sinhf_finite);
695eb11fae6SDimitry Andric     TLI.setUnavailable(LibFunc_sinhl_finite);
696c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_sqrt_finite);
697c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_sqrtf_finite);
698c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_sqrtl_finite);
699eb11fae6SDimitry Andric   }
700eb11fae6SDimitry Andric 
701eb11fae6SDimitry Andric   if ((T.isOSLinux() && T.isGNUEnvironment()) ||
702eb11fae6SDimitry Andric       (T.isAndroid() && !T.isAndroidVersionLT(28))) {
703eb11fae6SDimitry Andric     // available IO unlocked variants on GNU/Linux and Android P or later
704eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_getc_unlocked);
705eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_getchar_unlocked);
706eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_putc_unlocked);
707eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_putchar_unlocked);
708eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fputc_unlocked);
709eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fgetc_unlocked);
710eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fread_unlocked);
711eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fwrite_unlocked);
712eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fputs_unlocked);
713eb11fae6SDimitry Andric     TLI.setAvailable(LibFunc_fgets_unlocked);
7145a5ac124SDimitry Andric   }
7155a5ac124SDimitry Andric 
716c0981da4SDimitry Andric   if (T.isAndroid() && T.isAndroidVersionLT(21)) {
717c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpcpy);
718c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpncpy);
719c0981da4SDimitry Andric   }
720c0981da4SDimitry Andric 
721145449b1SDimitry Andric   if (T.isPS()) {
722145449b1SDimitry Andric     // PS4/PS5 do have memalign.
723c0981da4SDimitry Andric     TLI.setAvailable(LibFunc_memalign);
724c0981da4SDimitry Andric 
725145449b1SDimitry Andric     // PS4/PS5 do not have new/delete with "unsigned int" size parameter;
726145449b1SDimitry Andric     // they only have the "unsigned long" versions.
727c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvj);
728c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdaPvjSt11align_val_t);
729c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvj);
730c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZdlPvjSt11align_val_t);
731c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znaj);
732c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajRKSt9nothrow_t);
733c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajSt11align_val_t);
734c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnajSt11align_val_tRKSt9nothrow_t);
735c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_Znwj);
736c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjRKSt9nothrow_t);
737c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjSt11align_val_t);
738c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t);
739c0981da4SDimitry Andric 
740c0981da4SDimitry Andric     // None of the *_chk functions.
741c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memccpy_chk);
742c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memcpy_chk);
743c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memmove_chk);
744c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_mempcpy_chk);
745c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memset_chk);
746c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_snprintf_chk);
747c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_sprintf_chk);
748c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpcpy_chk);
749c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpncpy_chk);
750c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strcat_chk);
751c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strcpy_chk);
752c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strlcat_chk);
753c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strlcpy_chk);
754c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strlen_chk);
755c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strncat_chk);
756c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strncpy_chk);
757c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_vsnprintf_chk);
758c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_vsprintf_chk);
759c0981da4SDimitry Andric 
760c0981da4SDimitry Andric     // Various Posix system functions.
761c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_access);
762c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_chmod);
763c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_chown);
764c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_closedir);
765c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ctermid);
766c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execl);
767c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execle);
768c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execlp);
769c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execv);
770c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execvP);
771c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execve);
772c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execvp);
773c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_execvpe);
774c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_fork);
775c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_fstat);
776c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_fstatvfs);
777c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_getenv);
778c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_getitimer);
779c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_getlogin_r);
780c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_getpwnam);
781c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_gettimeofday);
782c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_lchown);
783c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_lstat);
784c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_mkdir);
785c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_open);
786c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_opendir);
787c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_pclose);
788c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_popen);
789c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_pread);
790c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_pwrite);
791c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_read);
792c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_readlink);
793c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_realpath);
794c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_rename);
795c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_rmdir);
796c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_setitimer);
797c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stat);
798c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_statvfs);
799c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_system);
800c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_times);
801c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_tmpfile);
802c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_unlink);
803c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_uname);
804c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_unsetenv);
805c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_utime);
806c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_utimes);
807c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_valloc);
808c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_write);
809c0981da4SDimitry Andric 
810c0981da4SDimitry Andric     // Miscellaneous other functions not provided.
811c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_atomic_load);
812c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_atomic_store);
813c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc___kmpc_alloc_shared);
814c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc___kmpc_free_shared);
815c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_dunder_strndup);
816c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_bcmp);
817c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_bcopy);
818c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_bzero);
819c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_cabs);
820c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_cabsf);
821c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_cabsl);
822c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ffs);
823c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_flockfile);
824c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_fseeko);
825c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ftello);
826c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ftrylockfile);
827c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_funlockfile);
828c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_htonl);
829c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_htons);
830c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_isascii);
831c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memccpy);
832c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_mempcpy);
833c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_memrchr);
834c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ntohl);
835c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_ntohs);
836c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_reallocf);
837c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_roundeven);
838c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_roundevenf);
839c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_roundevenl);
840c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpcpy);
841c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_stpncpy);
842c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strlcat);
843c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strlcpy);
844c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strndup);
845c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_strnlen);
846c0981da4SDimitry Andric     TLI.setUnavailable(LibFunc_toascii);
847c0981da4SDimitry Andric   }
848c0981da4SDimitry Andric 
84901095a5dSDimitry Andric   // As currently implemented in clang, NVPTX code has no standard library to
85001095a5dSDimitry Andric   // speak of.  Headers provide a standard-ish library implementation, but many
85101095a5dSDimitry Andric   // of the signatures are wrong -- for example, many libm functions are not
85201095a5dSDimitry Andric   // extern "C".
85301095a5dSDimitry Andric   //
85401095a5dSDimitry Andric   // libdevice, an IR library provided by nvidia, is linked in by the front-end,
85501095a5dSDimitry Andric   // but only used functions are provided to llvm.  Moreover, most of the
85601095a5dSDimitry Andric   // functions in libdevice don't map precisely to standard library functions.
85701095a5dSDimitry Andric   //
85801095a5dSDimitry Andric   // FIXME: Having no standard library prevents e.g. many fastmath
85901095a5dSDimitry Andric   // optimizations, so this situation should be fixed.
86001095a5dSDimitry Andric   if (T.isNVPTX()) {
86101095a5dSDimitry Andric     TLI.disableAllFunctions();
86271d5a254SDimitry Andric     TLI.setAvailable(LibFunc_nvvm_reflect);
863344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc_malloc);
864344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc_free);
865344a3780SDimitry Andric 
866344a3780SDimitry Andric     // TODO: We could enable the following two according to [0] but we haven't
867344a3780SDimitry Andric     //       done an evaluation wrt. the performance implications.
868344a3780SDimitry Andric     // [0]
869344a3780SDimitry Andric     // https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#dynamic-global-memory-allocation-and-operations
870344a3780SDimitry Andric     //
871344a3780SDimitry Andric     //    TLI.setAvailable(llvm::LibFunc_memcpy);
872344a3780SDimitry Andric     //    TLI.setAvailable(llvm::LibFunc_memset);
873344a3780SDimitry Andric 
874344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc___kmpc_alloc_shared);
875344a3780SDimitry Andric     TLI.setAvailable(llvm::LibFunc___kmpc_free_shared);
87601095a5dSDimitry Andric   } else {
87771d5a254SDimitry Andric     TLI.setUnavailable(LibFunc_nvvm_reflect);
87801095a5dSDimitry Andric   }
87901095a5dSDimitry Andric 
880b60736ecSDimitry Andric   // These vec_malloc/free routines are only available on AIX.
881b60736ecSDimitry Andric   if (!T.isOSAIX()) {
882b60736ecSDimitry Andric     TLI.setUnavailable(LibFunc_vec_calloc);
883b60736ecSDimitry Andric     TLI.setUnavailable(LibFunc_vec_malloc);
884b60736ecSDimitry Andric     TLI.setUnavailable(LibFunc_vec_realloc);
885b60736ecSDimitry Andric     TLI.setUnavailable(LibFunc_vec_free);
886b60736ecSDimitry Andric   }
887b60736ecSDimitry Andric 
888ac9a064cSDimitry Andric   if (T.isOSAIX())
889ac9a064cSDimitry Andric     TLI.setUnavailable(LibFunc_memrchr);
890ac9a064cSDimitry Andric 
891e3b55780SDimitry Andric   TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary, T);
8925a5ac124SDimitry Andric }
8935a5ac124SDimitry Andric 
894ac9a064cSDimitry Andric /// Initialize the set of available library functions based on the specified
895ac9a064cSDimitry Andric /// target triple. This should be carefully written so that a missing target
896ac9a064cSDimitry Andric /// triple gets a sane set of defaults.
initialize(TargetLibraryInfoImpl & TLI,const Triple & T,ArrayRef<StringLiteral> StandardNames)897ac9a064cSDimitry Andric static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
898ac9a064cSDimitry Andric                        ArrayRef<StringLiteral> StandardNames) {
899ac9a064cSDimitry Andric   initializeBase(TLI, T);
900ac9a064cSDimitry Andric   initializeLibCalls(TLI, T, StandardNames);
901ac9a064cSDimitry Andric }
9025a5ac124SDimitry Andric 
TargetLibraryInfoImpl()903ac9a064cSDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl() {
904ac9a064cSDimitry Andric   // Default to nothing being available.
905ac9a064cSDimitry Andric   memset(AvailableArray, 0, sizeof(AvailableArray));
906ac9a064cSDimitry Andric   initializeBase(*this, Triple());
9075a5ac124SDimitry Andric }
9085a5ac124SDimitry Andric 
TargetLibraryInfoImpl(const Triple & T)9095a5ac124SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {
9105a5ac124SDimitry Andric   // Default to everything being available.
9115a5ac124SDimitry Andric   memset(AvailableArray, -1, sizeof(AvailableArray));
9125a5ac124SDimitry Andric 
9135a5ac124SDimitry Andric   initialize(*this, T, StandardNames);
9145a5ac124SDimitry Andric }
9155a5ac124SDimitry Andric 
TargetLibraryInfoImpl(const TargetLibraryInfoImpl & TLI)9165a5ac124SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
917b915e9e0SDimitry Andric     : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param),
918b915e9e0SDimitry Andric       ShouldExtI32Return(TLI.ShouldExtI32Return),
919344a3780SDimitry Andric       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
920e3b55780SDimitry Andric       ShouldSignExtI32Return(TLI.ShouldSignExtI32Return),
921344a3780SDimitry Andric       SizeOfInt(TLI.SizeOfInt) {
9225a5ac124SDimitry Andric   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
9235a5ac124SDimitry Andric   VectorDescs = TLI.VectorDescs;
9245a5ac124SDimitry Andric   ScalarDescs = TLI.ScalarDescs;
9255a5ac124SDimitry Andric }
9265a5ac124SDimitry Andric 
TargetLibraryInfoImpl(TargetLibraryInfoImpl && TLI)9275a5ac124SDimitry Andric TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
928b915e9e0SDimitry Andric     : CustomNames(std::move(TLI.CustomNames)),
929b915e9e0SDimitry Andric       ShouldExtI32Param(TLI.ShouldExtI32Param),
930b915e9e0SDimitry Andric       ShouldExtI32Return(TLI.ShouldExtI32Return),
931344a3780SDimitry Andric       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
932e3b55780SDimitry Andric       ShouldSignExtI32Return(TLI.ShouldSignExtI32Return),
933344a3780SDimitry Andric       SizeOfInt(TLI.SizeOfInt) {
9345a5ac124SDimitry Andric   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
9355a5ac124SDimitry Andric             AvailableArray);
9365a5ac124SDimitry Andric   VectorDescs = TLI.VectorDescs;
9375a5ac124SDimitry Andric   ScalarDescs = TLI.ScalarDescs;
9385a5ac124SDimitry Andric }
9395a5ac124SDimitry Andric 
operator =(const TargetLibraryInfoImpl & TLI)9405a5ac124SDimitry Andric TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) {
9415a5ac124SDimitry Andric   CustomNames = TLI.CustomNames;
942b915e9e0SDimitry Andric   ShouldExtI32Param = TLI.ShouldExtI32Param;
943b915e9e0SDimitry Andric   ShouldExtI32Return = TLI.ShouldExtI32Return;
944b915e9e0SDimitry Andric   ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
945e3b55780SDimitry Andric   ShouldSignExtI32Return = TLI.ShouldSignExtI32Return;
946344a3780SDimitry Andric   SizeOfInt = TLI.SizeOfInt;
9475a5ac124SDimitry Andric   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
9485a5ac124SDimitry Andric   return *this;
9495a5ac124SDimitry Andric }
9505a5ac124SDimitry Andric 
operator =(TargetLibraryInfoImpl && TLI)9515a5ac124SDimitry Andric TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) {
9525a5ac124SDimitry Andric   CustomNames = std::move(TLI.CustomNames);
953b915e9e0SDimitry Andric   ShouldExtI32Param = TLI.ShouldExtI32Param;
954b915e9e0SDimitry Andric   ShouldExtI32Return = TLI.ShouldExtI32Return;
955b915e9e0SDimitry Andric   ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
956e3b55780SDimitry Andric   ShouldSignExtI32Return = TLI.ShouldSignExtI32Return;
957344a3780SDimitry Andric   SizeOfInt = TLI.SizeOfInt;
9585a5ac124SDimitry Andric   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
9595a5ac124SDimitry Andric             AvailableArray);
9605a5ac124SDimitry Andric   return *this;
9615a5ac124SDimitry Andric }
9625a5ac124SDimitry Andric 
sanitizeFunctionName(StringRef funcName)9635a5ac124SDimitry Andric static StringRef sanitizeFunctionName(StringRef funcName) {
9645a5ac124SDimitry Andric   // Filter out empty names and names containing null bytes, those can't be in
9655a5ac124SDimitry Andric   // our table.
966c0981da4SDimitry Andric   if (funcName.empty() || funcName.contains('\0'))
9675a5ac124SDimitry Andric     return StringRef();
9685a5ac124SDimitry Andric 
9695a5ac124SDimitry Andric   // Check for \01 prefix that is used to mangle __asm declarations and
9705a5ac124SDimitry Andric   // strip it if present.
9716b3f41edSDimitry Andric   return GlobalValue::dropLLVMManglingEscape(funcName);
9725a5ac124SDimitry Andric }
9735a5ac124SDimitry Andric 
974b1c73532SDimitry Andric static DenseMap<StringRef, LibFunc>
buildIndexMap(ArrayRef<StringLiteral> StandardNames)975b1c73532SDimitry Andric buildIndexMap(ArrayRef<StringLiteral> StandardNames) {
976b1c73532SDimitry Andric   DenseMap<StringRef, LibFunc> Indices;
977b1c73532SDimitry Andric   unsigned Idx = 0;
978b1c73532SDimitry Andric   Indices.reserve(LibFunc::NumLibFuncs);
979b1c73532SDimitry Andric   for (const auto &Func : StandardNames)
980b1c73532SDimitry Andric     Indices[Func] = static_cast<LibFunc>(Idx++);
981b1c73532SDimitry Andric   return Indices;
982b1c73532SDimitry Andric }
983b1c73532SDimitry Andric 
getLibFunc(StringRef funcName,LibFunc & F) const9841d5ae102SDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, LibFunc &F) const {
9855a5ac124SDimitry Andric   funcName = sanitizeFunctionName(funcName);
9865a5ac124SDimitry Andric   if (funcName.empty())
9875a5ac124SDimitry Andric     return false;
9885a5ac124SDimitry Andric 
989b1c73532SDimitry Andric   static const DenseMap<StringRef, LibFunc> Indices =
990b1c73532SDimitry Andric       buildIndexMap(StandardNames);
991b1c73532SDimitry Andric 
992b1c73532SDimitry Andric   if (auto Loc = Indices.find(funcName); Loc != Indices.end()) {
993b1c73532SDimitry Andric     F = Loc->second;
9945a5ac124SDimitry Andric     return true;
9955a5ac124SDimitry Andric   }
9965a5ac124SDimitry Andric   return false;
9975a5ac124SDimitry Andric }
9985a5ac124SDimitry Andric 
999e3b55780SDimitry Andric // Return true if ArgTy matches Ty.
1000e3b55780SDimitry Andric 
matchType(FuncArgTypeID ArgTy,const Type * Ty,unsigned IntBits,unsigned SizeTBits)1001e3b55780SDimitry Andric static bool matchType(FuncArgTypeID ArgTy, const Type *Ty, unsigned IntBits,
1002e3b55780SDimitry Andric                       unsigned SizeTBits) {
1003e3b55780SDimitry Andric   switch (ArgTy) {
1004e3b55780SDimitry Andric   case Void:
1005e3b55780SDimitry Andric     return Ty->isVoidTy();
1006e3b55780SDimitry Andric   case Bool:
1007e3b55780SDimitry Andric     return Ty->isIntegerTy(8);
1008e3b55780SDimitry Andric   case Int16:
1009e3b55780SDimitry Andric     return Ty->isIntegerTy(16);
1010e3b55780SDimitry Andric   case Int32:
1011e3b55780SDimitry Andric     return Ty->isIntegerTy(32);
1012e3b55780SDimitry Andric   case Int:
1013e3b55780SDimitry Andric     return Ty->isIntegerTy(IntBits);
1014e3b55780SDimitry Andric   case IntPlus:
1015e3b55780SDimitry Andric     return Ty->isIntegerTy() && Ty->getPrimitiveSizeInBits() >= IntBits;
1016e3b55780SDimitry Andric   case IntX:
1017e3b55780SDimitry Andric     return Ty->isIntegerTy();
1018e3b55780SDimitry Andric   case Long:
1019e3b55780SDimitry Andric     // TODO: Figure out and use long size.
1020e3b55780SDimitry Andric     return Ty->isIntegerTy() && Ty->getPrimitiveSizeInBits() >= IntBits;
1021e3b55780SDimitry Andric   case Int64:
1022e3b55780SDimitry Andric     return Ty->isIntegerTy(64);
1023e3b55780SDimitry Andric   case LLong:
1024e3b55780SDimitry Andric     return Ty->isIntegerTy(64);
1025e3b55780SDimitry Andric   case SizeT:
1026e3b55780SDimitry Andric   case SSizeT:
1027e3b55780SDimitry Andric     return Ty->isIntegerTy(SizeTBits);
1028e3b55780SDimitry Andric   case Flt:
1029e3b55780SDimitry Andric     return Ty->isFloatTy();
1030e3b55780SDimitry Andric   case Dbl:
1031e3b55780SDimitry Andric     return Ty->isDoubleTy();
1032e3b55780SDimitry Andric     // TODO: Tighten this up.
1033e3b55780SDimitry Andric   case LDbl:
1034e3b55780SDimitry Andric     return Ty->isFloatingPointTy();
1035e3b55780SDimitry Andric   case Floating:
1036e3b55780SDimitry Andric     return Ty->isFloatingPointTy();
1037e3b55780SDimitry Andric   case Ptr:
1038e3b55780SDimitry Andric     return Ty->isPointerTy();
1039e3b55780SDimitry Andric   case Struct:
1040e3b55780SDimitry Andric     return Ty->isStructTy();
1041e3b55780SDimitry Andric   default:
1042e3b55780SDimitry Andric     break;
1043e3b55780SDimitry Andric   }
1044e3b55780SDimitry Andric 
1045e3b55780SDimitry Andric   llvm_unreachable("Invalid type");
1046e3b55780SDimitry Andric }
1047e3b55780SDimitry Andric 
isValidProtoForLibFunc(const FunctionType & FTy,LibFunc F,const Module & M) const104801095a5dSDimitry Andric bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
104971d5a254SDimitry Andric                                                    LibFunc F,
1050c0981da4SDimitry Andric                                                    const Module &M) const {
105101095a5dSDimitry Andric   unsigned NumParams = FTy.getNumParams();
105201095a5dSDimitry Andric 
105301095a5dSDimitry Andric   switch (F) {
1054e3b55780SDimitry Andric     // Special handling for <complex.h> functions:
1055044eb2f6SDimitry Andric   case LibFunc_cabs:
1056044eb2f6SDimitry Andric   case LibFunc_cabsf:
1057044eb2f6SDimitry Andric   case LibFunc_cabsl: {
1058044eb2f6SDimitry Andric     Type *RetTy = FTy.getReturnType();
1059044eb2f6SDimitry Andric     if (!RetTy->isFloatingPointTy())
1060044eb2f6SDimitry Andric       return false;
1061044eb2f6SDimitry Andric 
1062e3b55780SDimitry Andric     Type *ParamTy = FTy.getParamType(0);
1063044eb2f6SDimitry Andric     // NOTE: These prototypes are target specific and currently support
1064044eb2f6SDimitry Andric     // "complex" passed as an array or discrete real & imaginary parameters.
1065044eb2f6SDimitry Andric     // Add other calling conventions to enable libcall optimizations.
1066044eb2f6SDimitry Andric     if (NumParams == 1)
1067e3b55780SDimitry Andric       return (ParamTy->isArrayTy() && ParamTy->getArrayNumElements() == 2 &&
1068e3b55780SDimitry Andric               ParamTy->getArrayElementType() == RetTy);
1069044eb2f6SDimitry Andric     else if (NumParams == 2)
1070e3b55780SDimitry Andric       return ParamTy == RetTy && FTy.getParamType(1) == RetTy;
1071e3b55780SDimitry Andric 
1072044eb2f6SDimitry Andric     return false;
1073044eb2f6SDimitry Andric   }
1074e3b55780SDimitry Andric     // Special handling for the sincospi functions that return either
1075e3b55780SDimitry Andric     // a struct or vector:
1076e3b55780SDimitry Andric   case LibFunc_sincospi_stret:
1077e3b55780SDimitry Andric   case LibFunc_sincospif_stret: {
1078e3b55780SDimitry Andric     if (NumParams != 1)
1079e3b55780SDimitry Andric       return false;
1080e3b55780SDimitry Andric 
1081e3b55780SDimitry Andric     Type *RetTy = FTy.getReturnType();
1082e3b55780SDimitry Andric     Type *ParamTy = FTy.getParamType(0);
1083e3b55780SDimitry Andric     if (auto *Ty = dyn_cast<StructType>(RetTy)) {
1084e3b55780SDimitry Andric       if (Ty->getNumElements() != 2)
1085e3b55780SDimitry Andric         return false;
1086e3b55780SDimitry Andric       return (Ty->getElementType(0) == ParamTy &&
1087e3b55780SDimitry Andric               Ty->getElementType(1) == ParamTy);
1088e3b55780SDimitry Andric     }
1089e3b55780SDimitry Andric 
1090e3b55780SDimitry Andric     if (auto *Ty = dyn_cast<FixedVectorType>(RetTy)) {
1091e3b55780SDimitry Andric       if (Ty->getNumElements() != 2)
1092e3b55780SDimitry Andric         return false;
1093e3b55780SDimitry Andric       return Ty->getElementType() == ParamTy;
1094e3b55780SDimitry Andric     }
1095e3b55780SDimitry Andric 
1096e3b55780SDimitry Andric     return false;
1097e3b55780SDimitry Andric   }
1098e3b55780SDimitry Andric 
1099e3b55780SDimitry Andric   default:
110071d5a254SDimitry Andric     break;
110101095a5dSDimitry Andric   }
110271d5a254SDimitry Andric 
1103e3b55780SDimitry Andric   unsigned IntBits = getIntSize();
1104e3b55780SDimitry Andric   unsigned SizeTBits = getSizeTSize(M);
1105e3b55780SDimitry Andric   unsigned Idx = 0;
1106e3b55780SDimitry Andric 
1107e3b55780SDimitry Andric   // Iterate over the type ids in the function prototype, matching each
1108e3b55780SDimitry Andric   // against the function's type FTy, starting with its return type.
1109e3b55780SDimitry Andric   // Return true if both match in number and kind, inclduing the ellipsis.
1110e3b55780SDimitry Andric   Type *Ty = FTy.getReturnType(), *LastTy = Ty;
1111e3b55780SDimitry Andric   const auto &ProtoTypes = Signatures[F];
1112e3b55780SDimitry Andric   for (auto TyID : ProtoTypes) {
1113e3b55780SDimitry Andric     if (Idx && TyID == Void)
1114e3b55780SDimitry Andric       // Except in the first position where it designates the function's
1115e3b55780SDimitry Andric       // return type Void ends the argument list.
1116e3b55780SDimitry Andric       break;
1117e3b55780SDimitry Andric 
1118e3b55780SDimitry Andric     if (TyID == Ellip) {
1119e3b55780SDimitry Andric       // The ellipsis ends the protoype list but is not a part of FTy's
1120e3b55780SDimitry Andric       // argument list.  Except when it's last it must be followed by
1121e3b55780SDimitry Andric       // Void.
1122e3b55780SDimitry Andric       assert(Idx == ProtoTypes.size() - 1 || ProtoTypes[Idx + 1] == Void);
1123e3b55780SDimitry Andric       return FTy.isFunctionVarArg();
1124e3b55780SDimitry Andric     }
1125e3b55780SDimitry Andric 
1126e3b55780SDimitry Andric     if (TyID == Same) {
1127e3b55780SDimitry Andric       assert(Idx != 0 && "Type ID 'Same' must not be first!");
1128e3b55780SDimitry Andric       if (Ty != LastTy)
1129e3b55780SDimitry Andric         return false;
1130e3b55780SDimitry Andric     } else {
1131e3b55780SDimitry Andric       if (!Ty || !matchType(TyID, Ty, IntBits, SizeTBits))
1132e3b55780SDimitry Andric         return false;
1133e3b55780SDimitry Andric       LastTy = Ty;
1134e3b55780SDimitry Andric     }
1135e3b55780SDimitry Andric 
1136e3b55780SDimitry Andric     if (Idx == NumParams) {
1137e3b55780SDimitry Andric       // There's at least one and at most two more type ids than there are
1138e3b55780SDimitry Andric       // arguments in FTy's argument list.
1139e3b55780SDimitry Andric       Ty = nullptr;
1140e3b55780SDimitry Andric       ++Idx;
1141e3b55780SDimitry Andric       continue;
1142e3b55780SDimitry Andric     }
1143e3b55780SDimitry Andric 
1144e3b55780SDimitry Andric     Ty = FTy.getParamType(Idx++);
1145e3b55780SDimitry Andric   }
1146e3b55780SDimitry Andric 
1147e3b55780SDimitry Andric   // Return success only if all entries on both lists have been processed
1148e3b55780SDimitry Andric   // and the function is not a variadic one.
1149e3b55780SDimitry Andric   return Idx == NumParams + 1 && !FTy.isFunctionVarArg();
115001095a5dSDimitry Andric }
115101095a5dSDimitry Andric 
getLibFunc(const Function & FDecl,LibFunc & F) const115201095a5dSDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
115371d5a254SDimitry Andric                                        LibFunc &F) const {
1154e6d15924SDimitry Andric   // Intrinsics don't overlap w/libcalls; if our module has a large number of
1155e6d15924SDimitry Andric   // intrinsics, this ends up being an interesting compile time win since we
1156e6d15924SDimitry Andric   // avoid string normalization and comparison.
1157e6d15924SDimitry Andric   if (FDecl.isIntrinsic()) return false;
1158e6d15924SDimitry Andric 
1159c0981da4SDimitry Andric   const Module *M = FDecl.getParent();
1160c0981da4SDimitry Andric   assert(M && "Expecting FDecl to be connected to a Module.");
1161c0981da4SDimitry Andric 
1162b1c73532SDimitry Andric   if (FDecl.LibFuncCache == Function::UnknownLibFunc)
1163b1c73532SDimitry Andric     if (!getLibFunc(FDecl.getName(), FDecl.LibFuncCache))
1164b1c73532SDimitry Andric       FDecl.LibFuncCache = NotLibFunc;
1165b1c73532SDimitry Andric 
1166b1c73532SDimitry Andric   if (FDecl.LibFuncCache == NotLibFunc)
1167b1c73532SDimitry Andric     return false;
1168b1c73532SDimitry Andric 
1169b1c73532SDimitry Andric   F = FDecl.LibFuncCache;
1170b1c73532SDimitry Andric   return isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M);
117101095a5dSDimitry Andric }
117201095a5dSDimitry Andric 
getLibFunc(unsigned int Opcode,Type * Ty,LibFunc & F) const117399aabd70SDimitry Andric bool TargetLibraryInfoImpl::getLibFunc(unsigned int Opcode, Type *Ty,
117499aabd70SDimitry Andric                                        LibFunc &F) const {
117599aabd70SDimitry Andric   // Must be a frem instruction with float or double arguments.
117699aabd70SDimitry Andric   if (Opcode != Instruction::FRem || (!Ty->isDoubleTy() && !Ty->isFloatTy()))
117799aabd70SDimitry Andric     return false;
117899aabd70SDimitry Andric 
117999aabd70SDimitry Andric   F = Ty->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf;
118099aabd70SDimitry Andric   return true;
118199aabd70SDimitry Andric }
118299aabd70SDimitry Andric 
disableAllFunctions()11835a5ac124SDimitry Andric void TargetLibraryInfoImpl::disableAllFunctions() {
11845a5ac124SDimitry Andric   memset(AvailableArray, 0, sizeof(AvailableArray));
11855a5ac124SDimitry Andric }
11865a5ac124SDimitry Andric 
compareByScalarFnName(const VecDesc & LHS,const VecDesc & RHS)11875a5ac124SDimitry Andric static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) {
1188b1c73532SDimitry Andric   return LHS.getScalarFnName() < RHS.getScalarFnName();
11895a5ac124SDimitry Andric }
11905a5ac124SDimitry Andric 
compareByVectorFnName(const VecDesc & LHS,const VecDesc & RHS)11915a5ac124SDimitry Andric static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) {
1192b1c73532SDimitry Andric   return LHS.getVectorFnName() < RHS.getVectorFnName();
11935a5ac124SDimitry Andric }
11945a5ac124SDimitry Andric 
compareWithScalarFnName(const VecDesc & LHS,StringRef S)11955a5ac124SDimitry Andric static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) {
1196b1c73532SDimitry Andric   return LHS.getScalarFnName() < S;
11975a5ac124SDimitry Andric }
11985a5ac124SDimitry Andric 
addVectorizableFunctions(ArrayRef<VecDesc> Fns)11995a5ac124SDimitry Andric void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
1200b60736ecSDimitry Andric   llvm::append_range(VectorDescs, Fns);
1201d8e91e46SDimitry Andric   llvm::sort(VectorDescs, compareByScalarFnName);
12025a5ac124SDimitry Andric 
1203b60736ecSDimitry Andric   llvm::append_range(ScalarDescs, Fns);
1204d8e91e46SDimitry Andric   llvm::sort(ScalarDescs, compareByVectorFnName);
12055a5ac124SDimitry Andric }
12065a5ac124SDimitry Andric 
1207ac9a064cSDimitry Andric static const VecDesc VecFuncs_Accelerate[] = {
1208e6d15924SDimitry Andric #define TLI_DEFINE_ACCELERATE_VECFUNCS
1209e6d15924SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1210ac9a064cSDimitry Andric #undef TLI_DEFINE_ACCELERATE_VECFUNCS
1211e6d15924SDimitry Andric };
1212ac9a064cSDimitry Andric 
1213ac9a064cSDimitry Andric static const VecDesc VecFuncs_DarwinLibSystemM[] = {
1214344a3780SDimitry Andric #define TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS
1215344a3780SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1216ac9a064cSDimitry Andric #undef TLI_DEFINE_DARWIN_LIBSYSTEM_M_VECFUNCS
1217344a3780SDimitry Andric };
1218ac9a064cSDimitry Andric 
1219ac9a064cSDimitry Andric static const VecDesc VecFuncs_LIBMVEC_X86[] = {
1220b60736ecSDimitry Andric #define TLI_DEFINE_LIBMVEC_X86_VECFUNCS
1221b60736ecSDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1222ac9a064cSDimitry Andric #undef TLI_DEFINE_LIBMVEC_X86_VECFUNCS
1223b60736ecSDimitry Andric };
1224ac9a064cSDimitry Andric 
1225ac9a064cSDimitry Andric static const VecDesc VecFuncs_MASSV[] = {
1226e6d15924SDimitry Andric #define TLI_DEFINE_MASSV_VECFUNCS
1227e6d15924SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1228ac9a064cSDimitry Andric #undef TLI_DEFINE_MASSV_VECFUNCS
12295a5ac124SDimitry Andric };
1230ac9a064cSDimitry Andric 
1231ac9a064cSDimitry Andric static const VecDesc VecFuncs_SVML[] = {
1232e6d15924SDimitry Andric #define TLI_DEFINE_SVML_VECFUNCS
1233e6d15924SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1234ac9a064cSDimitry Andric #undef TLI_DEFINE_SVML_VECFUNCS
1235b915e9e0SDimitry Andric };
1236ac9a064cSDimitry Andric 
1237ac9a064cSDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VF2[] = {
1238e3b55780SDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS
1239b1c73532SDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX)                         \
1240b1c73532SDimitry Andric   {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX},
1241e3b55780SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1242ac9a064cSDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_VF2_VECFUNCS
1243e3b55780SDimitry Andric };
1244ac9a064cSDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VF4[] = {
1245e3b55780SDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS
1246b1c73532SDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, VABI_PREFIX)                         \
1247b1c73532SDimitry Andric   {SCAL, VEC, VF, /* MASK = */ false, VABI_PREFIX},
12487fa27ce4SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1249ac9a064cSDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_VF4_VECFUNCS
12507fa27ce4SDimitry Andric };
1251ac9a064cSDimitry Andric static const VecDesc VecFuncs_SLEEFGNUABI_VFScalable[] = {
12527fa27ce4SDimitry Andric #define TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS
1253b1c73532SDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX)                   \
1254b1c73532SDimitry Andric   {SCAL, VEC, VF, MASK, VABI_PREFIX},
1255e3b55780SDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1256ac9a064cSDimitry Andric #undef TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS
1257e3b55780SDimitry Andric };
1258e3b55780SDimitry Andric 
1259ac9a064cSDimitry Andric static const VecDesc VecFuncs_ArmPL[] = {
1260ac9a064cSDimitry Andric #define TLI_DEFINE_ARMPL_VECFUNCS
1261ac9a064cSDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX)                   \
1262ac9a064cSDimitry Andric   {SCAL, VEC, VF, MASK, VABI_PREFIX},
1263ac9a064cSDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1264ac9a064cSDimitry Andric #undef TLI_DEFINE_ARMPL_VECFUNCS
1265ac9a064cSDimitry Andric };
1266ac9a064cSDimitry Andric 
1267ac9a064cSDimitry Andric const VecDesc VecFuncs_AMDLIBM[] = {
1268ac9a064cSDimitry Andric #define TLI_DEFINE_AMDLIBM_VECFUNCS
1269ac9a064cSDimitry Andric #define TLI_DEFINE_VECFUNC(SCAL, VEC, VF, MASK, VABI_PREFIX)                   \
1270ac9a064cSDimitry Andric   {SCAL, VEC, VF, MASK, VABI_PREFIX},
1271ac9a064cSDimitry Andric #include "llvm/Analysis/VecFuncs.def"
1272ac9a064cSDimitry Andric #undef TLI_DEFINE_AMDLIBM_VECFUNCS
1273ac9a064cSDimitry Andric };
1274ac9a064cSDimitry Andric 
addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib,const llvm::Triple & TargetTriple)1275ac9a064cSDimitry Andric void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
1276ac9a064cSDimitry Andric     enum VectorLibrary VecLib, const llvm::Triple &TargetTriple) {
1277ac9a064cSDimitry Andric   switch (VecLib) {
1278ac9a064cSDimitry Andric   case Accelerate: {
1279ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_Accelerate);
1280ac9a064cSDimitry Andric     break;
1281ac9a064cSDimitry Andric   }
1282ac9a064cSDimitry Andric   case DarwinLibSystemM: {
1283ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_DarwinLibSystemM);
1284ac9a064cSDimitry Andric     break;
1285ac9a064cSDimitry Andric   }
1286ac9a064cSDimitry Andric   case LIBMVEC_X86: {
1287ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_LIBMVEC_X86);
1288ac9a064cSDimitry Andric     break;
1289ac9a064cSDimitry Andric   }
1290ac9a064cSDimitry Andric   case MASSV: {
1291ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_MASSV);
1292ac9a064cSDimitry Andric     break;
1293ac9a064cSDimitry Andric   }
1294ac9a064cSDimitry Andric   case SVML: {
1295ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_SVML);
1296ac9a064cSDimitry Andric     break;
1297ac9a064cSDimitry Andric   }
1298ac9a064cSDimitry Andric   case SLEEFGNUABI: {
1299e3b55780SDimitry Andric     switch (TargetTriple.getArch()) {
1300e3b55780SDimitry Andric     default:
1301e3b55780SDimitry Andric       break;
1302e3b55780SDimitry Andric     case llvm::Triple::aarch64:
1303e3b55780SDimitry Andric     case llvm::Triple::aarch64_be:
1304ac9a064cSDimitry Andric       addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF2);
1305ac9a064cSDimitry Andric       addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VF4);
1306ac9a064cSDimitry Andric       addVectorizableFunctions(VecFuncs_SLEEFGNUABI_VFScalable);
13077fa27ce4SDimitry Andric       break;
13087fa27ce4SDimitry Andric     }
13097fa27ce4SDimitry Andric     break;
13107fa27ce4SDimitry Andric   }
13117fa27ce4SDimitry Andric   case ArmPL: {
13127fa27ce4SDimitry Andric     switch (TargetTriple.getArch()) {
13137fa27ce4SDimitry Andric     default:
13147fa27ce4SDimitry Andric       break;
13157fa27ce4SDimitry Andric     case llvm::Triple::aarch64:
13167fa27ce4SDimitry Andric     case llvm::Triple::aarch64_be:
1317ac9a064cSDimitry Andric       addVectorizableFunctions(VecFuncs_ArmPL);
1318e3b55780SDimitry Andric       break;
1319e3b55780SDimitry Andric     }
1320e3b55780SDimitry Andric     break;
1321e3b55780SDimitry Andric   }
1322ac9a064cSDimitry Andric   case AMDLIBM: {
1323ac9a064cSDimitry Andric     addVectorizableFunctions(VecFuncs_AMDLIBM);
1324ac9a064cSDimitry Andric     break;
1325ac9a064cSDimitry Andric   }
13265a5ac124SDimitry Andric   case NoLibrary:
13275a5ac124SDimitry Andric     break;
13285a5ac124SDimitry Andric   }
13295a5ac124SDimitry Andric }
13305a5ac124SDimitry Andric 
isFunctionVectorizable(StringRef funcName) const13315a5ac124SDimitry Andric bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
13325a5ac124SDimitry Andric   funcName = sanitizeFunctionName(funcName);
13335a5ac124SDimitry Andric   if (funcName.empty())
13345a5ac124SDimitry Andric     return false;
13355a5ac124SDimitry Andric 
1336e6d15924SDimitry Andric   std::vector<VecDesc>::const_iterator I =
1337e6d15924SDimitry Andric       llvm::lower_bound(VectorDescs, funcName, compareWithScalarFnName);
1338b1c73532SDimitry Andric   return I != VectorDescs.end() && StringRef(I->getScalarFnName()) == funcName;
13395a5ac124SDimitry Andric }
13405a5ac124SDimitry Andric 
getVectorizedFunction(StringRef F,const ElementCount & VF,bool Masked) const13417fa27ce4SDimitry Andric StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
13427fa27ce4SDimitry Andric                                                        const ElementCount &VF,
13437fa27ce4SDimitry Andric                                                        bool Masked) const {
1344b1c73532SDimitry Andric   const VecDesc *VD = getVectorMappingInfo(F, VF, Masked);
1345b1c73532SDimitry Andric   if (VD)
1346b1c73532SDimitry Andric     return VD->getVectorFnName();
1347b1c73532SDimitry Andric   return StringRef();
1348b1c73532SDimitry Andric }
1349b1c73532SDimitry Andric 
1350b1c73532SDimitry Andric const VecDesc *
getVectorMappingInfo(StringRef F,const ElementCount & VF,bool Masked) const1351b1c73532SDimitry Andric TargetLibraryInfoImpl::getVectorMappingInfo(StringRef F, const ElementCount &VF,
1352b1c73532SDimitry Andric                                             bool Masked) const {
13535a5ac124SDimitry Andric   F = sanitizeFunctionName(F);
13545a5ac124SDimitry Andric   if (F.empty())
1355b1c73532SDimitry Andric     return nullptr;
1356e6d15924SDimitry Andric   std::vector<VecDesc>::const_iterator I =
1357e6d15924SDimitry Andric       llvm::lower_bound(VectorDescs, F, compareWithScalarFnName);
1358b1c73532SDimitry Andric   while (I != VectorDescs.end() && StringRef(I->getScalarFnName()) == F) {
1359b1c73532SDimitry Andric     if ((I->getVectorizationFactor() == VF) && (I->isMasked() == Masked))
1360b1c73532SDimitry Andric       return &(*I);
13615a5ac124SDimitry Andric     ++I;
13625a5ac124SDimitry Andric   }
1363b1c73532SDimitry Andric   return nullptr;
13645a5ac124SDimitry Andric }
13655a5ac124SDimitry Andric 
run(const Function & F,FunctionAnalysisManager &)1366706b4fc4SDimitry Andric TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F,
136701095a5dSDimitry Andric                                              FunctionAnalysisManager &) {
1368706b4fc4SDimitry Andric   if (!BaselineInfoImpl)
1369706b4fc4SDimitry Andric     BaselineInfoImpl =
1370706b4fc4SDimitry Andric         TargetLibraryInfoImpl(Triple(F.getParent()->getTargetTriple()));
1371706b4fc4SDimitry Andric   return TargetLibraryInfo(*BaselineInfoImpl, &F);
13725a5ac124SDimitry Andric }
13735a5ac124SDimitry Andric 
getWCharSize(const Module & M) const1374b5630dbaSDimitry Andric unsigned TargetLibraryInfoImpl::getWCharSize(const Module &M) const {
1375b5630dbaSDimitry Andric   if (auto *ShortWChar = cast_or_null<ConstantAsMetadata>(
1376b5630dbaSDimitry Andric       M.getModuleFlag("wchar_size")))
1377b5630dbaSDimitry Andric     return cast<ConstantInt>(ShortWChar->getValue())->getZExtValue();
1378044eb2f6SDimitry Andric   return 0;
1379b5630dbaSDimitry Andric }
13805a5ac124SDimitry Andric 
getSizeTSize(const Module & M) const1381e3b55780SDimitry Andric unsigned TargetLibraryInfoImpl::getSizeTSize(const Module &M) const {
1382e3b55780SDimitry Andric   // There is really no guarantee that sizeof(size_t) is equal to sizeof(int*).
1383e3b55780SDimitry Andric   // If that isn't true then it should be possible to derive the SizeTTy from
1384e3b55780SDimitry Andric   // the target triple here instead and do an early return.
1385e3b55780SDimitry Andric 
1386e3b55780SDimitry Andric   // Historically LLVM assume that size_t has same size as intptr_t (hence
1387e3b55780SDimitry Andric   // deriving the size from sizeof(int*) in address space zero). This should
1388e3b55780SDimitry Andric   // work for most targets. For future consideration: DataLayout also implement
1389e3b55780SDimitry Andric   // getIndexSizeInBits which might map better to size_t compared to
1390e3b55780SDimitry Andric   // getPointerSizeInBits. Hard coding address space zero here might be
1391e3b55780SDimitry Andric   // unfortunate as well. Maybe getDefaultGlobalsAddressSpace() or
1392e3b55780SDimitry Andric   // getAllocaAddrSpace() is better.
1393e3b55780SDimitry Andric   unsigned AddressSpace = 0;
1394e3b55780SDimitry Andric   return M.getDataLayout().getPointerSizeInBits(AddressSpace);
1395e3b55780SDimitry Andric }
1396e3b55780SDimitry Andric 
TargetLibraryInfoWrapperPass()13975a5ac124SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass()
1398706b4fc4SDimitry Andric     : ImmutablePass(ID), TLA(TargetLibraryInfoImpl()) {
13995a5ac124SDimitry Andric   initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
14005a5ac124SDimitry Andric }
14015a5ac124SDimitry Andric 
TargetLibraryInfoWrapperPass(const Triple & T)14025a5ac124SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T)
1403706b4fc4SDimitry Andric     : ImmutablePass(ID), TLA(TargetLibraryInfoImpl(T)) {
14045a5ac124SDimitry Andric   initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
14055a5ac124SDimitry Andric }
14065a5ac124SDimitry Andric 
TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl & TLIImpl)14075a5ac124SDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(
14085a5ac124SDimitry Andric     const TargetLibraryInfoImpl &TLIImpl)
1409706b4fc4SDimitry Andric     : ImmutablePass(ID), TLA(TLIImpl) {
14105a5ac124SDimitry Andric   initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
14115a5ac124SDimitry Andric }
14125a5ac124SDimitry Andric 
TargetLibraryInfoWrapperPass(const TargetLibraryInfo & TLIOther)1413ac9a064cSDimitry Andric TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(
1414ac9a064cSDimitry Andric     const TargetLibraryInfo &TLIOther)
1415ac9a064cSDimitry Andric     : TargetLibraryInfoWrapperPass(*TLIOther.Impl) {}
1416ac9a064cSDimitry Andric 
1417b915e9e0SDimitry Andric AnalysisKey TargetLibraryAnalysis::Key;
14185a5ac124SDimitry Andric 
14195a5ac124SDimitry Andric // Register the basic pass.
14205a5ac124SDimitry Andric INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo",
14215a5ac124SDimitry Andric                 "Target Library Information", false, true)
14225a5ac124SDimitry Andric char TargetLibraryInfoWrapperPass::ID = 0;
14235a5ac124SDimitry Andric 
anchor()14245a5ac124SDimitry Andric void TargetLibraryInfoWrapperPass::anchor() {}
1425706b4fc4SDimitry Andric 
getWidestVF(StringRef ScalarF,ElementCount & FixedVF,ElementCount & ScalableVF) const1426344a3780SDimitry Andric void TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF,
1427344a3780SDimitry Andric                                         ElementCount &FixedVF,
1428344a3780SDimitry Andric                                         ElementCount &ScalableVF) const {
1429706b4fc4SDimitry Andric   ScalarF = sanitizeFunctionName(ScalarF);
1430344a3780SDimitry Andric   // Use '0' here because a type of the form <vscale x 1 x ElTy> is not the
1431344a3780SDimitry Andric   // same as a scalar.
1432344a3780SDimitry Andric   ScalableVF = ElementCount::getScalable(0);
1433344a3780SDimitry Andric   FixedVF = ElementCount::getFixed(1);
1434706b4fc4SDimitry Andric   if (ScalarF.empty())
1435344a3780SDimitry Andric     return;
1436706b4fc4SDimitry Andric 
1437706b4fc4SDimitry Andric   std::vector<VecDesc>::const_iterator I =
1438706b4fc4SDimitry Andric       llvm::lower_bound(VectorDescs, ScalarF, compareWithScalarFnName);
1439b1c73532SDimitry Andric   while (I != VectorDescs.end() && StringRef(I->getScalarFnName()) == ScalarF) {
1440344a3780SDimitry Andric     ElementCount *VF =
1441b1c73532SDimitry Andric         I->getVectorizationFactor().isScalable() ? &ScalableVF : &FixedVF;
1442b1c73532SDimitry Andric     if (ElementCount::isKnownGT(I->getVectorizationFactor(), *VF))
1443b1c73532SDimitry Andric       *VF = I->getVectorizationFactor();
1444706b4fc4SDimitry Andric     ++I;
1445706b4fc4SDimitry Andric   }
1446706b4fc4SDimitry Andric }
1447