162d4215bSChandler Carruth //===-- TargetLibraryInfo.cpp - Runtime library information ----------------==// 262d4215bSChandler Carruth // 362d4215bSChandler Carruth // The LLVM Compiler Infrastructure 462d4215bSChandler Carruth // 562d4215bSChandler Carruth // This file is distributed under the University of Illinois Open Source 662d4215bSChandler Carruth // License. See LICENSE.TXT for details. 762d4215bSChandler Carruth // 862d4215bSChandler Carruth //===----------------------------------------------------------------------===// 962d4215bSChandler Carruth // 1062d4215bSChandler Carruth // This file implements the TargetLibraryInfo class. 1162d4215bSChandler Carruth // 1262d4215bSChandler Carruth //===----------------------------------------------------------------------===// 1362d4215bSChandler Carruth 1462d4215bSChandler Carruth #include "llvm/Analysis/TargetLibraryInfo.h" 1562d4215bSChandler Carruth #include "llvm/ADT/Triple.h" 166d8a2aa9SMichael Zolotukhin #include "llvm/Support/CommandLine.h" 1762d4215bSChandler Carruth using namespace llvm; 1862d4215bSChandler Carruth 196d8a2aa9SMichael Zolotukhin static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary( 206d8a2aa9SMichael Zolotukhin "vector-library", cl::Hidden, cl::desc("Vector functions library"), 216d8a2aa9SMichael Zolotukhin cl::init(TargetLibraryInfoImpl::NoLibrary), 226d8a2aa9SMichael Zolotukhin cl::values(clEnumValN(TargetLibraryInfoImpl::NoLibrary, "none", 236d8a2aa9SMichael Zolotukhin "No vector functions library"), 246d8a2aa9SMichael Zolotukhin clEnumValN(TargetLibraryInfoImpl::Accelerate, "Accelerate", 256d8a2aa9SMichael Zolotukhin "Accelerate framework"), 26a6669a1eSMatt Masten clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", 27*732afdd0SMehdi Amini "Intel SVML library"))); 286d8a2aa9SMichael Zolotukhin 299a72cd7bSMehdi Amini StringRef const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = { 30cd3d25a2SJan Wen Voung #define TLI_DEFINE_STRING 31cd3d25a2SJan Wen Voung #include "llvm/Analysis/TargetLibraryInfo.def" 3262d4215bSChandler Carruth }; 3362d4215bSChandler Carruth 3462d4215bSChandler Carruth static bool hasSinCosPiStret(const Triple &T) { 3562d4215bSChandler Carruth // Only Darwin variants have _stret versions of combined trig functions. 3662d4215bSChandler Carruth if (!T.isOSDarwin()) 3762d4215bSChandler Carruth return false; 3862d4215bSChandler Carruth 3962d4215bSChandler Carruth // The ABI is rather complicated on x86, so don't do anything special there. 4062d4215bSChandler Carruth if (T.getArch() == Triple::x86) 4162d4215bSChandler Carruth return false; 4262d4215bSChandler Carruth 4362d4215bSChandler Carruth if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9)) 4462d4215bSChandler Carruth return false; 4562d4215bSChandler Carruth 4662d4215bSChandler Carruth if (T.isiOS() && T.isOSVersionLT(7, 0)) 4762d4215bSChandler Carruth return false; 4862d4215bSChandler Carruth 4962d4215bSChandler Carruth return true; 5062d4215bSChandler Carruth } 5162d4215bSChandler Carruth 5262d4215bSChandler Carruth /// initialize - Initialize the set of available library functions based on the 5362d4215bSChandler Carruth /// specified target triple. This should be carefully written so that a missing 5462d4215bSChandler Carruth /// target triple gets a sane set of defaults. 55c0291865SChandler Carruth static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, 569a72cd7bSMehdi Amini ArrayRef<StringRef> StandardNames) { 5762d4215bSChandler Carruth // Verify that the StandardNames array is in alphabetical order. 58e30b8ca1SCraig Topper assert(std::is_sorted(StandardNames.begin(), StandardNames.end(), 599a72cd7bSMehdi Amini [](StringRef LHS, StringRef RHS) { 609a72cd7bSMehdi Amini return LHS < RHS; 61e30b8ca1SCraig Topper }) && 62e30b8ca1SCraig Topper "TargetLibraryInfoImpl function names must be sorted"); 6362d4215bSChandler Carruth 6478fd4f08SNicolai Hahnle if (T.getArch() == Triple::r600 || 6578fd4f08SNicolai Hahnle T.getArch() == Triple::amdgcn) { 6678fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexp); 6778fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexpf); 6878fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexpl); 69377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10); 70377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10f); 71377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10l); 72377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10); 73377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10f); 74377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10l); 7578fd4f08SNicolai Hahnle } 7678fd4f08SNicolai Hahnle 7762d4215bSChandler Carruth // There are no library implementations of mempcy and memset for AMD gpus and 7862d4215bSChandler Carruth // these can be difficult to lower in the backend. 7962d4215bSChandler Carruth if (T.getArch() == Triple::r600 || 8005532995SDan Gohman T.getArch() == Triple::amdgcn) { 8162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memcpy); 8262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset); 8362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 8462d4215bSChandler Carruth return; 8562d4215bSChandler Carruth } 8662d4215bSChandler Carruth 8762d4215bSChandler Carruth // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. 888b40366bSTim Northover // All versions of watchOS support it. 8962d4215bSChandler Carruth if (T.isMacOSX()) { 9062d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 5)) 9162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 9262d4215bSChandler Carruth } else if (T.isiOS()) { 9362d4215bSChandler Carruth if (T.isOSVersionLT(3, 0)) 9462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 958b40366bSTim Northover } else if (!T.isWatchOS()) { 9662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 9762d4215bSChandler Carruth } 9862d4215bSChandler Carruth 9962d4215bSChandler Carruth if (!hasSinCosPiStret(T)) { 10062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpi); 10162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpif); 10262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospi); 10362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospif); 10462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospi_stret); 10562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospif_stret); 10662d4215bSChandler Carruth } 10762d4215bSChandler Carruth 10862d4215bSChandler Carruth if (T.isMacOSX() && T.getArch() == Triple::x86 && 10962d4215bSChandler Carruth !T.isMacOSXVersionLT(10, 7)) { 11062d4215bSChandler Carruth // x86-32 OSX has a scheme where fwrite and fputs (and some other functions 11162d4215bSChandler Carruth // we don't care about) have two versions; on recent OSX, the one we want 11262d4215bSChandler Carruth // has a $UNIX2003 suffix. The two implementations are identical except 11362d4215bSChandler Carruth // for the return value in some edge cases. However, we don't want to 11462d4215bSChandler Carruth // generate code that depends on the old symbols. 11562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); 11662d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); 11762d4215bSChandler Carruth } 11862d4215bSChandler Carruth 11962d4215bSChandler Carruth // iprintf and friends are only available on XCore and TCE. 12062d4215bSChandler Carruth if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { 12162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::iprintf); 12262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::siprintf); 12362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fiprintf); 12462d4215bSChandler Carruth } 12562d4215bSChandler Carruth 12662d4215bSChandler Carruth if (T.isOSWindows() && !T.isOSCygMing()) { 12762d4215bSChandler Carruth // Win32 does not support long double 12862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosl); 12962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinl); 13062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanl); 13162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2l); 13262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceill); 13362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignl); 13462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosl); 13562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshl); 13662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expl); 13762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf 13862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsl); 13962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorl); 14062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxl); 14162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminl); 14262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodl); 14362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpl); 14462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpf); 14562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpl); 14662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logl); 14762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::modfl); 14862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powl); 14962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinl); 15062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhl); 15162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtl); 15262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanl); 15362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhl); 15462d4215bSChandler Carruth 15562d4215bSChandler Carruth // Win32 only has C89 math 15662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosh); 15762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshf); 15862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshl); 15962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinh); 16062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhf); 16162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhl); 16262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanh); 16362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhf); 16462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhl); 16562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrt); 16662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtf); 16762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtl); 16862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2); 16962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2f); 17062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2l); 17162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1); 17262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1f); 17362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1l); 17462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2); 17562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2f); 17662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2l); 17762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1p); 17862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pf); 17962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pl); 18062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logb); 18162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbf); 18262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbl); 18362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyint); 18462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintf); 18562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintl); 18662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rint); 18762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintf); 18862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintl); 18962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::round); 19062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundf); 19162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundl); 19262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::trunc); 19362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncf); 19462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncl); 19562d4215bSChandler Carruth 19662d4215bSChandler Carruth // Win32 provides some C99 math with mangled names 19762d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); 19862d4215bSChandler Carruth 19962d4215bSChandler Carruth if (T.getArch() == Triple::x86) { 20062d4215bSChandler Carruth // Win32 on x86 implements single-precision math functions as macros 20162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosf); 20262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinf); 20362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanf); 20462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2f); 20562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceilf); 20662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignf); 20762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosf); 20862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshf); 20962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expf); 21062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorf); 21162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminf); 21262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxf); 21362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodf); 21462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logf); 215eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::log10f); 216eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::modff); 21762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powf); 21862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinf); 21962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhf); 22062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtf); 22162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanf); 22262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhf); 22362d4215bSChandler Carruth } 22462d4215bSChandler Carruth 22562d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 22662d4215bSChandler Carruth // generally available on POSIX-compliant systems: 22762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::access); 22862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcmp); 22962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcopy); 23062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bzero); 23162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chmod); 23262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chown); 23362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::closedir); 23462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ctermid); 23562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fdopen); 23662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffs); 23762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fileno); 23862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::flockfile); 23962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko); 24062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat); 24162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs); 24262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello); 24362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftrylockfile); 24462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::funlockfile); 24562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getc_unlocked); 24662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getitimer); 24762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getlogin_r); 24862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getpwnam); 24962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::gettimeofday); 25062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htonl); 25162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htons); 25262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lchown); 25362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat); 25462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memccpy); 25562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::mkdir); 25662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohl); 25762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohs); 25862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open); 25962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::opendir); 26062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pclose); 26162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::popen); 26262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pread); 26362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pwrite); 26462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::read); 26562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::readlink); 26662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::realpath); 26762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rmdir); 26862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::setitimer); 26962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat); 27062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs); 27162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpcpy); 27262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpncpy); 27362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strcasecmp); 27462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strncasecmp); 27562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::times); 27662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::uname); 27762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unlink); 27862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unsetenv); 27962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utime); 28062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utimes); 28162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::write); 28262d4215bSChandler Carruth 28362d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 28462d4215bSChandler Carruth // specified by C99: 28562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atoll); 28662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpf); 28762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::llabs); 28862d4215bSChandler Carruth } 28962d4215bSChandler Carruth 29062d4215bSChandler Carruth switch (T.getOS()) { 29162d4215bSChandler Carruth case Triple::MacOSX: 29262d4215bSChandler Carruth // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 29362d4215bSChandler Carruth // and their names are __exp10 and __exp10f. exp10l is not available on 29462d4215bSChandler Carruth // OS X or iOS. 29562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 29662d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 9)) { 29762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 29862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 29962d4215bSChandler Carruth } else { 30062d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 30162d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 30262d4215bSChandler Carruth } 30362d4215bSChandler Carruth break; 30462d4215bSChandler Carruth case Triple::IOS: 30589a6eefeSTim Northover case Triple::TvOS: 3068b40366bSTim Northover case Triple::WatchOS: 30762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 3088b40366bSTim Northover if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || 3098b40366bSTim Northover (T.isOSVersionLT(9, 0) && 3108b40366bSTim Northover (T.getArch() == Triple::x86 || 3118b40366bSTim Northover T.getArch() == Triple::x86_64)))) { 31262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 31362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 31462d4215bSChandler Carruth } else { 31562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 31662d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 31762d4215bSChandler Carruth } 31862d4215bSChandler Carruth break; 31962d4215bSChandler Carruth case Triple::Linux: 32062d4215bSChandler Carruth // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely 32162d4215bSChandler Carruth // buggy prior to glibc version 2.18. Until this version is widely deployed 32262d4215bSChandler Carruth // or we have a reasonable detection strategy, we cannot use exp10 reliably 32362d4215bSChandler Carruth // on Linux. 32462d4215bSChandler Carruth // 32562d4215bSChandler Carruth // Fall through to disable all of them. 326cd1d5aafSJustin Bogner LLVM_FALLTHROUGH; 32762d4215bSChandler Carruth default: 32862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 32962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 33062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 33162d4215bSChandler Carruth } 33262d4215bSChandler Carruth 33362d4215bSChandler Carruth // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and 33462d4215bSChandler Carruth // Linux (GLIBC): 33562d4215bSChandler Carruth // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html 33683b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c 33762d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html 33862d4215bSChandler Carruth switch (T.getOS()) { 33962d4215bSChandler Carruth case Triple::Darwin: 34062d4215bSChandler Carruth case Triple::MacOSX: 34162d4215bSChandler Carruth case Triple::IOS: 34289a6eefeSTim Northover case Triple::TvOS: 3438b40366bSTim Northover case Triple::WatchOS: 34462d4215bSChandler Carruth case Triple::FreeBSD: 34562d4215bSChandler Carruth case Triple::Linux: 34662d4215bSChandler Carruth break; 34762d4215bSChandler Carruth default: 34862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsl); 34962d4215bSChandler Carruth } 35062d4215bSChandler Carruth 35162d4215bSChandler Carruth // ffsll is available on at least FreeBSD and Linux (GLIBC): 35283b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c 35362d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html 35462d4215bSChandler Carruth switch (T.getOS()) { 35589a6eefeSTim Northover case Triple::Darwin: 35689a6eefeSTim Northover case Triple::MacOSX: 35789a6eefeSTim Northover case Triple::IOS: 35889a6eefeSTim Northover case Triple::TvOS: 35989a6eefeSTim Northover case Triple::WatchOS: 36062d4215bSChandler Carruth case Triple::FreeBSD: 36162d4215bSChandler Carruth case Triple::Linux: 36262d4215bSChandler Carruth break; 36362d4215bSChandler Carruth default: 36462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsll); 36562d4215bSChandler Carruth } 36662d4215bSChandler Carruth 367bfd3082eSDavide Italiano // The following functions are available on at least FreeBSD: 368bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/fls.c 369bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c 370bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c 371bfd3082eSDavide Italiano if (!T.isOSFreeBSD()) { 372bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::fls); 373bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsl); 374bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsll); 375bfd3082eSDavide Italiano } 376bfd3082eSDavide Italiano 37762d4215bSChandler Carruth // The following functions are available on at least Linux: 37862d4215bSChandler Carruth if (!T.isOSLinux()) { 37962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strdup); 38062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strtok_r); 38162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); 38262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); 38362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_getc); 38462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_putc); 38562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memalign); 38662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fopen64); 38762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko64); 38862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat64); 38962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs64); 39062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello64); 39162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat64); 39262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open64); 39362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat64); 39462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs64); 39562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tmpfile64); 39662d4215bSChandler Carruth } 3976d8a2aa9SMichael Zolotukhin 39851132881SJustin Lebar // As currently implemented in clang, NVPTX code has no standard library to 39951132881SJustin Lebar // speak of. Headers provide a standard-ish library implementation, but many 40051132881SJustin Lebar // of the signatures are wrong -- for example, many libm functions are not 40151132881SJustin Lebar // extern "C". 40251132881SJustin Lebar // 40351132881SJustin Lebar // libdevice, an IR library provided by nvidia, is linked in by the front-end, 40451132881SJustin Lebar // but only used functions are provided to llvm. Moreover, most of the 40551132881SJustin Lebar // functions in libdevice don't map precisely to standard library functions. 40651132881SJustin Lebar // 40751132881SJustin Lebar // FIXME: Having no standard library prevents e.g. many fastmath 40851132881SJustin Lebar // optimizations, so this situation should be fixed. 409ae272d71SDavid Majnemer if (T.isNVPTX()) { 41051132881SJustin Lebar TLI.disableAllFunctions(); 411ae272d71SDavid Majnemer TLI.setAvailable(LibFunc::nvvm_reflect); 412ae272d71SDavid Majnemer } else { 413ae272d71SDavid Majnemer TLI.setUnavailable(LibFunc::nvvm_reflect); 414ae272d71SDavid Majnemer } 41551132881SJustin Lebar 4166d8a2aa9SMichael Zolotukhin TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); 41762d4215bSChandler Carruth } 41862d4215bSChandler Carruth 419c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl() { 42062d4215bSChandler Carruth // Default to everything being available. 42162d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 42262d4215bSChandler Carruth 42362d4215bSChandler Carruth initialize(*this, Triple(), StandardNames); 42462d4215bSChandler Carruth } 42562d4215bSChandler Carruth 426c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { 42762d4215bSChandler Carruth // Default to everything being available. 42862d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 42962d4215bSChandler Carruth 43062d4215bSChandler Carruth initialize(*this, T, StandardNames); 43162d4215bSChandler Carruth } 43262d4215bSChandler Carruth 433c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) 4348ca43224SChandler Carruth : CustomNames(TLI.CustomNames) { 43562d4215bSChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 436e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 437e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4388ca43224SChandler Carruth } 4398ca43224SChandler Carruth 440c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) 4418ca43224SChandler Carruth : CustomNames(std::move(TLI.CustomNames)) { 4428ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4438ca43224SChandler Carruth AvailableArray); 444e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 445e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4468ca43224SChandler Carruth } 4478ca43224SChandler Carruth 448c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { 44962d4215bSChandler Carruth CustomNames = TLI.CustomNames; 4508ca43224SChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 4518ca43224SChandler Carruth return *this; 4528ca43224SChandler Carruth } 4538ca43224SChandler Carruth 454c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { 4558ca43224SChandler Carruth CustomNames = std::move(TLI.CustomNames); 4568ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4578ca43224SChandler Carruth AvailableArray); 4588ca43224SChandler Carruth return *this; 45962d4215bSChandler Carruth } 46062d4215bSChandler Carruth 46121abdf98SMichael Zolotukhin static StringRef sanitizeFunctionName(StringRef funcName) { 46262d4215bSChandler Carruth // Filter out empty names and names containing null bytes, those can't be in 46362d4215bSChandler Carruth // our table. 46462d4215bSChandler Carruth if (funcName.empty() || funcName.find('\0') != StringRef::npos) 46521abdf98SMichael Zolotukhin return StringRef(); 46662d4215bSChandler Carruth 46762d4215bSChandler Carruth // Check for \01 prefix that is used to mangle __asm declarations and 46862d4215bSChandler Carruth // strip it if present. 469cde33036SDavid Majnemer return GlobalValue::getRealLinkageName(funcName); 47021abdf98SMichael Zolotukhin } 47121abdf98SMichael Zolotukhin 47221abdf98SMichael Zolotukhin bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, 47321abdf98SMichael Zolotukhin LibFunc::Func &F) const { 4749a72cd7bSMehdi Amini StringRef const *Start = &StandardNames[0]; 4759a72cd7bSMehdi Amini StringRef const *End = &StandardNames[LibFunc::NumLibFuncs]; 47621abdf98SMichael Zolotukhin 47721abdf98SMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 47821abdf98SMichael Zolotukhin if (funcName.empty()) 47921abdf98SMichael Zolotukhin return false; 48021abdf98SMichael Zolotukhin 4819a72cd7bSMehdi Amini StringRef const *I = std::lower_bound( 4829a72cd7bSMehdi Amini Start, End, funcName, [](StringRef LHS, StringRef RHS) { 4839a72cd7bSMehdi Amini return LHS < RHS; 484d3b76a3bSMichael Zolotukhin }); 48562d4215bSChandler Carruth if (I != End && *I == funcName) { 48662d4215bSChandler Carruth F = (LibFunc::Func)(I - Start); 48762d4215bSChandler Carruth return true; 48862d4215bSChandler Carruth } 48962d4215bSChandler Carruth return false; 49062d4215bSChandler Carruth } 49162d4215bSChandler Carruth 492d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, 493d765a82bSAhmed Bougacha LibFunc::Func F, 494d765a82bSAhmed Bougacha const DataLayout *DL) const { 495d765a82bSAhmed Bougacha LLVMContext &Ctx = FTy.getContext(); 496d765a82bSAhmed Bougacha Type *PCharTy = Type::getInt8PtrTy(Ctx); 497d765a82bSAhmed Bougacha Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AS=*/0) : nullptr; 498d765a82bSAhmed Bougacha auto IsSizeTTy = [SizeTTy](Type *Ty) { 499d765a82bSAhmed Bougacha return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy(); 500d765a82bSAhmed Bougacha }; 501d765a82bSAhmed Bougacha unsigned NumParams = FTy.getNumParams(); 502d765a82bSAhmed Bougacha 503d765a82bSAhmed Bougacha switch (F) { 504d765a82bSAhmed Bougacha case LibFunc::strlen: 505d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && 506d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 507d765a82bSAhmed Bougacha 508d765a82bSAhmed Bougacha case LibFunc::strchr: 509d765a82bSAhmed Bougacha case LibFunc::strrchr: 510d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 511d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 512d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy()); 513d765a82bSAhmed Bougacha 514d765a82bSAhmed Bougacha case LibFunc::strtol: 515d765a82bSAhmed Bougacha case LibFunc::strtod: 516d765a82bSAhmed Bougacha case LibFunc::strtof: 517d765a82bSAhmed Bougacha case LibFunc::strtoul: 518d765a82bSAhmed Bougacha case LibFunc::strtoll: 519d765a82bSAhmed Bougacha case LibFunc::strtold: 520d765a82bSAhmed Bougacha case LibFunc::strtoull: 521d765a82bSAhmed Bougacha return ((NumParams == 2 || NumParams == 3) && 522d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 523d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 524d765a82bSAhmed Bougacha case LibFunc::strcat: 525d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 526d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 527d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType()); 528d765a82bSAhmed Bougacha 529d765a82bSAhmed Bougacha case LibFunc::strncat: 530d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && 531d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 532d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType() && 533d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 534d765a82bSAhmed Bougacha 535d765a82bSAhmed Bougacha case LibFunc::strcpy_chk: 536d765a82bSAhmed Bougacha case LibFunc::stpcpy_chk: 537d765a82bSAhmed Bougacha --NumParams; 538d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 539d765a82bSAhmed Bougacha return false; 540b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 541d765a82bSAhmed Bougacha case LibFunc::strcpy: 542d765a82bSAhmed Bougacha case LibFunc::stpcpy: 543d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && 544d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 545d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy); 546d765a82bSAhmed Bougacha 547d765a82bSAhmed Bougacha case LibFunc::strncpy_chk: 548d765a82bSAhmed Bougacha case LibFunc::stpncpy_chk: 549d765a82bSAhmed Bougacha --NumParams; 550d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 551d765a82bSAhmed Bougacha return false; 552b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 553d765a82bSAhmed Bougacha case LibFunc::strncpy: 554d765a82bSAhmed Bougacha case LibFunc::stpncpy: 555d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 556d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 557d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy && 558d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 559d765a82bSAhmed Bougacha 560d765a82bSAhmed Bougacha case LibFunc::strxfrm: 561d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 562d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 563d765a82bSAhmed Bougacha 564d765a82bSAhmed Bougacha case LibFunc::strcmp: 565d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && 566d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 567d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 568d765a82bSAhmed Bougacha 569d765a82bSAhmed Bougacha case LibFunc::strncmp: 570d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && 571d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 572d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 573d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 574d765a82bSAhmed Bougacha 575d765a82bSAhmed Bougacha case LibFunc::strspn: 576d765a82bSAhmed Bougacha case LibFunc::strcspn: 577d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 578d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 579d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 580d765a82bSAhmed Bougacha 581d765a82bSAhmed Bougacha case LibFunc::strcoll: 582d765a82bSAhmed Bougacha case LibFunc::strcasecmp: 583d765a82bSAhmed Bougacha case LibFunc::strncasecmp: 584d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 585d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 586d765a82bSAhmed Bougacha 587d765a82bSAhmed Bougacha case LibFunc::strstr: 588d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 589d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 590d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 591d765a82bSAhmed Bougacha 592d765a82bSAhmed Bougacha case LibFunc::strpbrk: 593d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 594d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 595d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 596d765a82bSAhmed Bougacha 597d765a82bSAhmed Bougacha case LibFunc::strtok: 598d765a82bSAhmed Bougacha case LibFunc::strtok_r: 599d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 600d765a82bSAhmed Bougacha case LibFunc::scanf: 601d765a82bSAhmed Bougacha case LibFunc::setbuf: 602d765a82bSAhmed Bougacha case LibFunc::setvbuf: 603d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 604d765a82bSAhmed Bougacha case LibFunc::strdup: 605d765a82bSAhmed Bougacha case LibFunc::strndup: 606d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 607d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 6089cc0bca2SDavide Italiano case LibFunc::sscanf: 609d765a82bSAhmed Bougacha case LibFunc::stat: 610d765a82bSAhmed Bougacha case LibFunc::statvfs: 611d765a82bSAhmed Bougacha case LibFunc::sprintf: 612d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 613d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 614d765a82bSAhmed Bougacha case LibFunc::snprintf: 615d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 616d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 617d765a82bSAhmed Bougacha case LibFunc::setitimer: 618d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 619d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 620d765a82bSAhmed Bougacha case LibFunc::system: 621d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 622d765a82bSAhmed Bougacha case LibFunc::malloc: 623d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); 624d765a82bSAhmed Bougacha case LibFunc::memcmp: 625d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 626d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 627d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy(32)); 628d765a82bSAhmed Bougacha 629d765a82bSAhmed Bougacha case LibFunc::memchr: 630d765a82bSAhmed Bougacha case LibFunc::memrchr: 631d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 632d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy(32) && 633d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 634d765a82bSAhmed Bougacha FTy.getReturnType()->isPointerTy()); 635d765a82bSAhmed Bougacha case LibFunc::modf: 636d765a82bSAhmed Bougacha case LibFunc::modff: 637d765a82bSAhmed Bougacha case LibFunc::modfl: 638d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 639d765a82bSAhmed Bougacha 640d765a82bSAhmed Bougacha case LibFunc::memcpy_chk: 641d765a82bSAhmed Bougacha case LibFunc::memmove_chk: 642d765a82bSAhmed Bougacha --NumParams; 643d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 644d765a82bSAhmed Bougacha return false; 645b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 646d765a82bSAhmed Bougacha case LibFunc::memcpy: 647b99d1cc7SAndrew Kaylor case LibFunc::mempcpy: 648d765a82bSAhmed Bougacha case LibFunc::memmove: 649d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 650d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 651d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 652d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 653d765a82bSAhmed Bougacha 654d765a82bSAhmed Bougacha case LibFunc::memset_chk: 655d765a82bSAhmed Bougacha --NumParams; 656d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 657d765a82bSAhmed Bougacha return false; 658b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 659d765a82bSAhmed Bougacha case LibFunc::memset: 660d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 661d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 662d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 663d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 664d765a82bSAhmed Bougacha 665d765a82bSAhmed Bougacha case LibFunc::memccpy: 666d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 667d765a82bSAhmed Bougacha case LibFunc::memalign: 668d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 669d765a82bSAhmed Bougacha case LibFunc::realloc: 670d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 671d765a82bSAhmed Bougacha FTy.getReturnType()->isPointerTy()); 672d765a82bSAhmed Bougacha case LibFunc::read: 673d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 674d765a82bSAhmed Bougacha case LibFunc::rewind: 675d765a82bSAhmed Bougacha case LibFunc::rmdir: 676d765a82bSAhmed Bougacha case LibFunc::remove: 677d765a82bSAhmed Bougacha case LibFunc::realpath: 678d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 679d765a82bSAhmed Bougacha case LibFunc::rename: 680d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 681d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 682d765a82bSAhmed Bougacha case LibFunc::readlink: 683d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 684d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 685d765a82bSAhmed Bougacha case LibFunc::write: 686d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 687d765a82bSAhmed Bougacha case LibFunc::bcopy: 688d765a82bSAhmed Bougacha case LibFunc::bcmp: 689d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 690d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 691d765a82bSAhmed Bougacha case LibFunc::bzero: 692d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 693d765a82bSAhmed Bougacha case LibFunc::calloc: 694d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); 6951fe3f1caSAhmed Bougacha 6961fe3f1caSAhmed Bougacha case LibFunc::atof: 697d765a82bSAhmed Bougacha case LibFunc::atoi: 698d765a82bSAhmed Bougacha case LibFunc::atol: 699d765a82bSAhmed Bougacha case LibFunc::atoll: 7001fe3f1caSAhmed Bougacha case LibFunc::ferror: 7011fe3f1caSAhmed Bougacha case LibFunc::getenv: 7021fe3f1caSAhmed Bougacha case LibFunc::getpwnam: 7031fe3f1caSAhmed Bougacha case LibFunc::pclose: 7041fe3f1caSAhmed Bougacha case LibFunc::perror: 7051fe3f1caSAhmed Bougacha case LibFunc::printf: 7061fe3f1caSAhmed Bougacha case LibFunc::puts: 7071fe3f1caSAhmed Bougacha case LibFunc::uname: 7081fe3f1caSAhmed Bougacha case LibFunc::under_IO_getc: 7091fe3f1caSAhmed Bougacha case LibFunc::unlink: 7101fe3f1caSAhmed Bougacha case LibFunc::unsetenv: 711d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 7121fe3f1caSAhmed Bougacha 7131fe3f1caSAhmed Bougacha case LibFunc::chmod: 7141fe3f1caSAhmed Bougacha case LibFunc::chown: 7151fe3f1caSAhmed Bougacha case LibFunc::clearerr: 7161fe3f1caSAhmed Bougacha case LibFunc::closedir: 7171fe3f1caSAhmed Bougacha case LibFunc::ctermid: 7181fe3f1caSAhmed Bougacha case LibFunc::fclose: 7191fe3f1caSAhmed Bougacha case LibFunc::feof: 7201fe3f1caSAhmed Bougacha case LibFunc::fflush: 7211fe3f1caSAhmed Bougacha case LibFunc::fgetc: 7221fe3f1caSAhmed Bougacha case LibFunc::fileno: 7231fe3f1caSAhmed Bougacha case LibFunc::flockfile: 7241fe3f1caSAhmed Bougacha case LibFunc::free: 7251fe3f1caSAhmed Bougacha case LibFunc::fseek: 726201b97f5SAhmed Bougacha case LibFunc::fseeko64: 7271fe3f1caSAhmed Bougacha case LibFunc::fseeko: 7281fe3f1caSAhmed Bougacha case LibFunc::fsetpos: 7291fe3f1caSAhmed Bougacha case LibFunc::ftell: 730201b97f5SAhmed Bougacha case LibFunc::ftello64: 7311fe3f1caSAhmed Bougacha case LibFunc::ftello: 7321fe3f1caSAhmed Bougacha case LibFunc::ftrylockfile: 7331fe3f1caSAhmed Bougacha case LibFunc::funlockfile: 7341fe3f1caSAhmed Bougacha case LibFunc::getc: 7351fe3f1caSAhmed Bougacha case LibFunc::getc_unlocked: 7361fe3f1caSAhmed Bougacha case LibFunc::getlogin_r: 7371fe3f1caSAhmed Bougacha case LibFunc::mkdir: 7381fe3f1caSAhmed Bougacha case LibFunc::mktime: 7391fe3f1caSAhmed Bougacha case LibFunc::times: 7401fe3f1caSAhmed Bougacha return (NumParams != 0 && FTy.getParamType(0)->isPointerTy()); 7411fe3f1caSAhmed Bougacha 742d765a82bSAhmed Bougacha case LibFunc::access: 743d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 744d765a82bSAhmed Bougacha case LibFunc::fopen: 745d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 746d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 747d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 748d765a82bSAhmed Bougacha case LibFunc::fdopen: 749d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 750d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 751d765a82bSAhmed Bougacha case LibFunc::fputc: 752d765a82bSAhmed Bougacha case LibFunc::fstat: 753d765a82bSAhmed Bougacha case LibFunc::frexp: 754d765a82bSAhmed Bougacha case LibFunc::frexpf: 755d765a82bSAhmed Bougacha case LibFunc::frexpl: 756d765a82bSAhmed Bougacha case LibFunc::fstatvfs: 757d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 758d765a82bSAhmed Bougacha case LibFunc::fgets: 759d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 760d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 761d765a82bSAhmed Bougacha case LibFunc::fread: 762d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 763d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 764d765a82bSAhmed Bougacha case LibFunc::fwrite: 765d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && 766d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 767d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 768d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 769d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 770d765a82bSAhmed Bougacha case LibFunc::fputs: 771d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 772d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 773d765a82bSAhmed Bougacha case LibFunc::fscanf: 774d765a82bSAhmed Bougacha case LibFunc::fprintf: 775d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 776d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 777d765a82bSAhmed Bougacha case LibFunc::fgetpos: 778d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 779d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 780d765a82bSAhmed Bougacha case LibFunc::gets: 781d765a82bSAhmed Bougacha case LibFunc::getchar: 782d765a82bSAhmed Bougacha case LibFunc::getitimer: 783d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 784d765a82bSAhmed Bougacha case LibFunc::ungetc: 785d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 786d765a82bSAhmed Bougacha case LibFunc::utime: 787d765a82bSAhmed Bougacha case LibFunc::utimes: 788d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 789d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 790d765a82bSAhmed Bougacha case LibFunc::putc: 791d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 792d765a82bSAhmed Bougacha case LibFunc::pread: 793d765a82bSAhmed Bougacha case LibFunc::pwrite: 794d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); 795d765a82bSAhmed Bougacha case LibFunc::popen: 796d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 797d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 798d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 799d765a82bSAhmed Bougacha case LibFunc::vscanf: 800d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 801d765a82bSAhmed Bougacha case LibFunc::vsscanf: 802d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 803d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 804d765a82bSAhmed Bougacha case LibFunc::vfscanf: 805d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 806d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 807d765a82bSAhmed Bougacha case LibFunc::valloc: 808d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 809d765a82bSAhmed Bougacha case LibFunc::vprintf: 810d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 811d765a82bSAhmed Bougacha case LibFunc::vfprintf: 812d765a82bSAhmed Bougacha case LibFunc::vsprintf: 813d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 814d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 815d765a82bSAhmed Bougacha case LibFunc::vsnprintf: 816d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 817d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 818d765a82bSAhmed Bougacha case LibFunc::open: 819d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 820d765a82bSAhmed Bougacha case LibFunc::opendir: 821d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && 822d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 823d765a82bSAhmed Bougacha case LibFunc::tmpfile: 824d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 825d765a82bSAhmed Bougacha case LibFunc::htonl: 826d765a82bSAhmed Bougacha case LibFunc::htons: 827d765a82bSAhmed Bougacha case LibFunc::ntohl: 828d765a82bSAhmed Bougacha case LibFunc::ntohs: 829d765a82bSAhmed Bougacha case LibFunc::lstat: 830d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 831d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 832d765a82bSAhmed Bougacha case LibFunc::lchown: 833d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); 834d765a82bSAhmed Bougacha case LibFunc::qsort: 835d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); 836d765a82bSAhmed Bougacha case LibFunc::dunder_strdup: 837d765a82bSAhmed Bougacha case LibFunc::dunder_strndup: 838d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 839d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 840d765a82bSAhmed Bougacha case LibFunc::dunder_strtok_r: 841d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 842d765a82bSAhmed Bougacha case LibFunc::under_IO_putc: 843d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 844d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_scanf: 845d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 846d765a82bSAhmed Bougacha case LibFunc::stat64: 847d765a82bSAhmed Bougacha case LibFunc::lstat64: 848d765a82bSAhmed Bougacha case LibFunc::statvfs64: 84979dcc274SMichael Kuperstein return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 850d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 851d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_sscanf: 85279dcc274SMichael Kuperstein return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 853d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 854d765a82bSAhmed Bougacha case LibFunc::fopen64: 855d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 856d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 857d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 858d765a82bSAhmed Bougacha case LibFunc::tmpfile64: 859d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 860d765a82bSAhmed Bougacha case LibFunc::fstat64: 861d765a82bSAhmed Bougacha case LibFunc::fstatvfs64: 862d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 863d765a82bSAhmed Bougacha case LibFunc::open64: 864d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 865d765a82bSAhmed Bougacha case LibFunc::gettimeofday: 866d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 867d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 868d765a82bSAhmed Bougacha 869d765a82bSAhmed Bougacha case LibFunc::Znwj: // new(unsigned int); 870d765a82bSAhmed Bougacha case LibFunc::Znwm: // new(unsigned long); 871d765a82bSAhmed Bougacha case LibFunc::Znaj: // new[](unsigned int); 872d765a82bSAhmed Bougacha case LibFunc::Znam: // new[](unsigned long); 873d765a82bSAhmed Bougacha case LibFunc::msvc_new_int: // new(unsigned int); 874d765a82bSAhmed Bougacha case LibFunc::msvc_new_longlong: // new(unsigned long long); 875d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_int: // new[](unsigned int); 876d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); 877d765a82bSAhmed Bougacha return (NumParams == 1); 878d765a82bSAhmed Bougacha 879d765a82bSAhmed Bougacha case LibFunc::memset_pattern16: 880d765a82bSAhmed Bougacha return (!FTy.isVarArg() && NumParams == 3 && 881d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(0)) && 882d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(1)) && 883d765a82bSAhmed Bougacha isa<IntegerType>(FTy.getParamType(2))); 884d765a82bSAhmed Bougacha 885d765a82bSAhmed Bougacha // int __nvvm_reflect(const char *); 886d765a82bSAhmed Bougacha case LibFunc::nvvm_reflect: 887d765a82bSAhmed Bougacha return (NumParams == 1 && isa<PointerType>(FTy.getParamType(0))); 888d765a82bSAhmed Bougacha 889d765a82bSAhmed Bougacha case LibFunc::sin: 890d765a82bSAhmed Bougacha case LibFunc::sinf: 891d765a82bSAhmed Bougacha case LibFunc::sinl: 892d765a82bSAhmed Bougacha case LibFunc::cos: 893d765a82bSAhmed Bougacha case LibFunc::cosf: 894d765a82bSAhmed Bougacha case LibFunc::cosl: 895b62692e2SDavid Majnemer case LibFunc::tan: 896b62692e2SDavid Majnemer case LibFunc::tanf: 897b62692e2SDavid Majnemer case LibFunc::tanl: 898d765a82bSAhmed Bougacha case LibFunc::exp: 899d765a82bSAhmed Bougacha case LibFunc::expf: 900d765a82bSAhmed Bougacha case LibFunc::expl: 901d765a82bSAhmed Bougacha case LibFunc::exp2: 902d765a82bSAhmed Bougacha case LibFunc::exp2f: 903d765a82bSAhmed Bougacha case LibFunc::exp2l: 904d765a82bSAhmed Bougacha case LibFunc::log: 905d765a82bSAhmed Bougacha case LibFunc::logf: 906d765a82bSAhmed Bougacha case LibFunc::logl: 907d765a82bSAhmed Bougacha case LibFunc::log10: 908d765a82bSAhmed Bougacha case LibFunc::log10f: 909d765a82bSAhmed Bougacha case LibFunc::log10l: 910d765a82bSAhmed Bougacha case LibFunc::log2: 911d765a82bSAhmed Bougacha case LibFunc::log2f: 912d765a82bSAhmed Bougacha case LibFunc::log2l: 913d765a82bSAhmed Bougacha case LibFunc::fabs: 914d765a82bSAhmed Bougacha case LibFunc::fabsf: 915d765a82bSAhmed Bougacha case LibFunc::fabsl: 916d765a82bSAhmed Bougacha case LibFunc::floor: 917d765a82bSAhmed Bougacha case LibFunc::floorf: 918d765a82bSAhmed Bougacha case LibFunc::floorl: 919d765a82bSAhmed Bougacha case LibFunc::ceil: 920d765a82bSAhmed Bougacha case LibFunc::ceilf: 921d765a82bSAhmed Bougacha case LibFunc::ceill: 922d765a82bSAhmed Bougacha case LibFunc::trunc: 923d765a82bSAhmed Bougacha case LibFunc::truncf: 924d765a82bSAhmed Bougacha case LibFunc::truncl: 925d765a82bSAhmed Bougacha case LibFunc::rint: 926d765a82bSAhmed Bougacha case LibFunc::rintf: 927d765a82bSAhmed Bougacha case LibFunc::rintl: 928d765a82bSAhmed Bougacha case LibFunc::nearbyint: 929d765a82bSAhmed Bougacha case LibFunc::nearbyintf: 930d765a82bSAhmed Bougacha case LibFunc::nearbyintl: 931d765a82bSAhmed Bougacha case LibFunc::round: 932d765a82bSAhmed Bougacha case LibFunc::roundf: 933d765a82bSAhmed Bougacha case LibFunc::roundl: 934d765a82bSAhmed Bougacha case LibFunc::sqrt: 935d765a82bSAhmed Bougacha case LibFunc::sqrtf: 936d765a82bSAhmed Bougacha case LibFunc::sqrtl: 937d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && 938d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 939d765a82bSAhmed Bougacha 940d765a82bSAhmed Bougacha case LibFunc::fmin: 941d765a82bSAhmed Bougacha case LibFunc::fminf: 942d765a82bSAhmed Bougacha case LibFunc::fminl: 943d765a82bSAhmed Bougacha case LibFunc::fmax: 944d765a82bSAhmed Bougacha case LibFunc::fmaxf: 945d765a82bSAhmed Bougacha case LibFunc::fmaxl: 946d765a82bSAhmed Bougacha case LibFunc::copysign: 947d765a82bSAhmed Bougacha case LibFunc::copysignf: 948d765a82bSAhmed Bougacha case LibFunc::copysignl: 949d765a82bSAhmed Bougacha case LibFunc::pow: 950d765a82bSAhmed Bougacha case LibFunc::powf: 951d765a82bSAhmed Bougacha case LibFunc::powl: 952d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && 953d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 954d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(1)); 955d765a82bSAhmed Bougacha 956d765a82bSAhmed Bougacha case LibFunc::ffs: 957d765a82bSAhmed Bougacha case LibFunc::ffsl: 958d765a82bSAhmed Bougacha case LibFunc::ffsll: 95904949fafSSanjay Patel return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && 96004949fafSSanjay Patel FTy.getParamType(0)->isIntegerTy()); 96104949fafSSanjay Patel 962d765a82bSAhmed Bougacha case LibFunc::isdigit: 963d765a82bSAhmed Bougacha case LibFunc::isascii: 964d765a82bSAhmed Bougacha case LibFunc::toascii: 965d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && 96604949fafSSanjay Patel FTy.getReturnType() == FTy.getParamType(0)); 967d765a82bSAhmed Bougacha 968d765a82bSAhmed Bougacha case LibFunc::fls: 969d765a82bSAhmed Bougacha case LibFunc::flsl: 970d765a82bSAhmed Bougacha case LibFunc::flsll: 971d765a82bSAhmed Bougacha case LibFunc::abs: 972d765a82bSAhmed Bougacha case LibFunc::labs: 973d765a82bSAhmed Bougacha case LibFunc::llabs: 974d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && 975d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 976d765a82bSAhmed Bougacha 977d765a82bSAhmed Bougacha case LibFunc::cxa_atexit: 978d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && 979d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 980d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 981d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 982d765a82bSAhmed Bougacha 983d765a82bSAhmed Bougacha case LibFunc::sinpi: 984d765a82bSAhmed Bougacha case LibFunc::cospi: 985d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && 986d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 987d765a82bSAhmed Bougacha 988d765a82bSAhmed Bougacha case LibFunc::sinpif: 989d765a82bSAhmed Bougacha case LibFunc::cospif: 990d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && 991d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 992d765a82bSAhmed Bougacha 993d765a82bSAhmed Bougacha default: 994d765a82bSAhmed Bougacha // Assume the other functions are correct. 995d765a82bSAhmed Bougacha // FIXME: It'd be really nice to cover them all. 996d765a82bSAhmed Bougacha return true; 997d765a82bSAhmed Bougacha } 998d765a82bSAhmed Bougacha } 999d765a82bSAhmed Bougacha 1000d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, 1001d765a82bSAhmed Bougacha LibFunc::Func &F) const { 1002d765a82bSAhmed Bougacha const DataLayout *DL = 1003d765a82bSAhmed Bougacha FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; 1004d765a82bSAhmed Bougacha return getLibFunc(FDecl.getName(), F) && 1005d765a82bSAhmed Bougacha isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL); 1006d765a82bSAhmed Bougacha } 1007d765a82bSAhmed Bougacha 1008c0291865SChandler Carruth void TargetLibraryInfoImpl::disableAllFunctions() { 100962d4215bSChandler Carruth memset(AvailableArray, 0, sizeof(AvailableArray)); 101062d4215bSChandler Carruth } 1011b98f63dbSChandler Carruth 1012e8f2551fSMichael Zolotukhin static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) { 10139a72cd7bSMehdi Amini return LHS.ScalarFnName < RHS.ScalarFnName; 1014e8f2551fSMichael Zolotukhin } 1015e8f2551fSMichael Zolotukhin 1016e8f2551fSMichael Zolotukhin static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) { 10179a72cd7bSMehdi Amini return LHS.VectorFnName < RHS.VectorFnName; 1018e8f2551fSMichael Zolotukhin } 1019e8f2551fSMichael Zolotukhin 1020e8f2551fSMichael Zolotukhin static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) { 10219a72cd7bSMehdi Amini return LHS.ScalarFnName < S; 1022e8f2551fSMichael Zolotukhin } 1023e8f2551fSMichael Zolotukhin 1024e8f2551fSMichael Zolotukhin static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) { 10259a72cd7bSMehdi Amini return LHS.VectorFnName < S; 1026e8f2551fSMichael Zolotukhin } 1027e8f2551fSMichael Zolotukhin 1028e8f2551fSMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) { 1029e8f2551fSMichael Zolotukhin VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end()); 1030e8f2551fSMichael Zolotukhin std::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName); 1031e8f2551fSMichael Zolotukhin 1032e8f2551fSMichael Zolotukhin ScalarDescs.insert(ScalarDescs.end(), Fns.begin(), Fns.end()); 1033e8f2551fSMichael Zolotukhin std::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName); 1034e8f2551fSMichael Zolotukhin } 1035e8f2551fSMichael Zolotukhin 10366d8a2aa9SMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( 10376d8a2aa9SMichael Zolotukhin enum VectorLibrary VecLib) { 10386d8a2aa9SMichael Zolotukhin switch (VecLib) { 10396d8a2aa9SMichael Zolotukhin case Accelerate: { 10406d8a2aa9SMichael Zolotukhin const VecDesc VecFuncs[] = { 1041de63aaceSMichael Zolotukhin // Floating-Point Arithmetic and Auxiliary Functions 1042de63aaceSMichael Zolotukhin {"ceilf", "vceilf", 4}, 10436d8a2aa9SMichael Zolotukhin {"fabsf", "vfabsf", 4}, 10446d8a2aa9SMichael Zolotukhin {"llvm.fabs.f32", "vfabsf", 4}, 1045de63aaceSMichael Zolotukhin {"floorf", "vfloorf", 4}, 1046de63aaceSMichael Zolotukhin {"sqrtf", "vsqrtf", 4}, 1047de63aaceSMichael Zolotukhin {"llvm.sqrt.f32", "vsqrtf", 4}, 1048de63aaceSMichael Zolotukhin 1049de63aaceSMichael Zolotukhin // Exponential and Logarithmic Functions 1050de63aaceSMichael Zolotukhin {"expf", "vexpf", 4}, 1051de63aaceSMichael Zolotukhin {"llvm.exp.f32", "vexpf", 4}, 1052de63aaceSMichael Zolotukhin {"expm1f", "vexpm1f", 4}, 1053de63aaceSMichael Zolotukhin {"logf", "vlogf", 4}, 1054de63aaceSMichael Zolotukhin {"llvm.log.f32", "vlogf", 4}, 1055de63aaceSMichael Zolotukhin {"log1pf", "vlog1pf", 4}, 1056de63aaceSMichael Zolotukhin {"log10f", "vlog10f", 4}, 1057de63aaceSMichael Zolotukhin {"llvm.log10.f32", "vlog10f", 4}, 1058de63aaceSMichael Zolotukhin {"logbf", "vlogbf", 4}, 1059de63aaceSMichael Zolotukhin 1060de63aaceSMichael Zolotukhin // Trigonometric Functions 1061de63aaceSMichael Zolotukhin {"sinf", "vsinf", 4}, 1062de63aaceSMichael Zolotukhin {"llvm.sin.f32", "vsinf", 4}, 1063de63aaceSMichael Zolotukhin {"cosf", "vcosf", 4}, 1064de63aaceSMichael Zolotukhin {"llvm.cos.f32", "vcosf", 4}, 1065de63aaceSMichael Zolotukhin {"tanf", "vtanf", 4}, 1066de63aaceSMichael Zolotukhin {"asinf", "vasinf", 4}, 1067de63aaceSMichael Zolotukhin {"acosf", "vacosf", 4}, 1068de63aaceSMichael Zolotukhin {"atanf", "vatanf", 4}, 1069de63aaceSMichael Zolotukhin 1070de63aaceSMichael Zolotukhin // Hyperbolic Functions 1071de63aaceSMichael Zolotukhin {"sinhf", "vsinhf", 4}, 1072de63aaceSMichael Zolotukhin {"coshf", "vcoshf", 4}, 1073de63aaceSMichael Zolotukhin {"tanhf", "vtanhf", 4}, 1074de63aaceSMichael Zolotukhin {"asinhf", "vasinhf", 4}, 1075de63aaceSMichael Zolotukhin {"acoshf", "vacoshf", 4}, 1076de63aaceSMichael Zolotukhin {"atanhf", "vatanhf", 4}, 10776d8a2aa9SMichael Zolotukhin }; 10786d8a2aa9SMichael Zolotukhin addVectorizableFunctions(VecFuncs); 10796d8a2aa9SMichael Zolotukhin break; 10806d8a2aa9SMichael Zolotukhin } 1081a6669a1eSMatt Masten case SVML: { 1082a6669a1eSMatt Masten const VecDesc VecFuncs[] = { 1083a6669a1eSMatt Masten {"sin", "__svml_sin2", 2}, 1084a6669a1eSMatt Masten {"sin", "__svml_sin4", 4}, 1085a6669a1eSMatt Masten {"sin", "__svml_sin8", 8}, 1086a6669a1eSMatt Masten 1087a6669a1eSMatt Masten {"sinf", "__svml_sinf4", 4}, 1088a6669a1eSMatt Masten {"sinf", "__svml_sinf8", 8}, 1089a6669a1eSMatt Masten {"sinf", "__svml_sinf16", 16}, 1090a6669a1eSMatt Masten 1091a6669a1eSMatt Masten {"cos", "__svml_cos2", 2}, 1092a6669a1eSMatt Masten {"cos", "__svml_cos4", 4}, 1093a6669a1eSMatt Masten {"cos", "__svml_cos8", 8}, 1094a6669a1eSMatt Masten 1095a6669a1eSMatt Masten {"cosf", "__svml_cosf4", 4}, 1096a6669a1eSMatt Masten {"cosf", "__svml_cosf8", 8}, 1097a6669a1eSMatt Masten {"cosf", "__svml_cosf16", 16}, 1098a6669a1eSMatt Masten 1099a6669a1eSMatt Masten {"pow", "__svml_pow2", 2}, 1100a6669a1eSMatt Masten {"pow", "__svml_pow4", 4}, 1101a6669a1eSMatt Masten {"pow", "__svml_pow8", 8}, 1102a6669a1eSMatt Masten 1103a6669a1eSMatt Masten {"powf", "__svml_powf4", 4}, 1104a6669a1eSMatt Masten {"powf", "__svml_powf8", 8}, 1105a6669a1eSMatt Masten {"powf", "__svml_powf16", 16}, 1106a6669a1eSMatt Masten 1107a6669a1eSMatt Masten {"llvm.pow.f64", "__svml_pow2", 2}, 1108a6669a1eSMatt Masten {"llvm.pow.f64", "__svml_pow4", 4}, 1109a6669a1eSMatt Masten {"llvm.pow.f64", "__svml_pow8", 8}, 1110a6669a1eSMatt Masten 1111a6669a1eSMatt Masten {"llvm.pow.f32", "__svml_powf4", 4}, 1112a6669a1eSMatt Masten {"llvm.pow.f32", "__svml_powf8", 8}, 1113a6669a1eSMatt Masten {"llvm.pow.f32", "__svml_powf16", 16}, 1114a6669a1eSMatt Masten 1115a6669a1eSMatt Masten {"exp", "__svml_exp2", 2}, 1116a6669a1eSMatt Masten {"exp", "__svml_exp4", 4}, 1117a6669a1eSMatt Masten {"exp", "__svml_exp8", 8}, 1118a6669a1eSMatt Masten 1119a6669a1eSMatt Masten {"expf", "__svml_expf4", 4}, 1120a6669a1eSMatt Masten {"expf", "__svml_expf8", 8}, 1121a6669a1eSMatt Masten {"expf", "__svml_expf16", 16}, 1122a6669a1eSMatt Masten 1123a6669a1eSMatt Masten {"llvm.exp.f64", "__svml_exp2", 2}, 1124a6669a1eSMatt Masten {"llvm.exp.f64", "__svml_exp4", 4}, 1125a6669a1eSMatt Masten {"llvm.exp.f64", "__svml_exp8", 8}, 1126a6669a1eSMatt Masten 1127a6669a1eSMatt Masten {"llvm.exp.f32", "__svml_expf4", 4}, 1128a6669a1eSMatt Masten {"llvm.exp.f32", "__svml_expf8", 8}, 1129a6669a1eSMatt Masten {"llvm.exp.f32", "__svml_expf16", 16}, 1130a6669a1eSMatt Masten 1131a6669a1eSMatt Masten {"log", "__svml_log2", 2}, 1132a6669a1eSMatt Masten {"log", "__svml_log4", 4}, 1133a6669a1eSMatt Masten {"log", "__svml_log8", 8}, 1134a6669a1eSMatt Masten 1135a6669a1eSMatt Masten {"logf", "__svml_logf4", 4}, 1136a6669a1eSMatt Masten {"logf", "__svml_logf8", 8}, 1137a6669a1eSMatt Masten {"logf", "__svml_logf16", 16}, 1138a6669a1eSMatt Masten 1139a6669a1eSMatt Masten {"llvm.log.f64", "__svml_log2", 2}, 1140a6669a1eSMatt Masten {"llvm.log.f64", "__svml_log4", 4}, 1141a6669a1eSMatt Masten {"llvm.log.f64", "__svml_log8", 8}, 1142a6669a1eSMatt Masten 1143a6669a1eSMatt Masten {"llvm.log.f32", "__svml_logf4", 4}, 1144a6669a1eSMatt Masten {"llvm.log.f32", "__svml_logf8", 8}, 1145a6669a1eSMatt Masten {"llvm.log.f32", "__svml_logf16", 16}, 1146a6669a1eSMatt Masten }; 1147a6669a1eSMatt Masten addVectorizableFunctions(VecFuncs); 1148a6669a1eSMatt Masten break; 1149a6669a1eSMatt Masten } 11506d8a2aa9SMichael Zolotukhin case NoLibrary: 11516d8a2aa9SMichael Zolotukhin break; 11526d8a2aa9SMichael Zolotukhin } 11536d8a2aa9SMichael Zolotukhin } 11546d8a2aa9SMichael Zolotukhin 1155e8f2551fSMichael Zolotukhin bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const { 1156e8f2551fSMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 1157e8f2551fSMichael Zolotukhin if (funcName.empty()) 1158e8f2551fSMichael Zolotukhin return false; 1159e8f2551fSMichael Zolotukhin 1160e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1161e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), funcName, 1162e8f2551fSMichael Zolotukhin compareWithScalarFnName); 1163e8f2551fSMichael Zolotukhin return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName; 1164e8f2551fSMichael Zolotukhin } 1165e8f2551fSMichael Zolotukhin 1166e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F, 1167e8f2551fSMichael Zolotukhin unsigned VF) const { 1168e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1169e8f2551fSMichael Zolotukhin if (F.empty()) 1170e8f2551fSMichael Zolotukhin return F; 1171e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1172e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), F, compareWithScalarFnName); 1173e8f2551fSMichael Zolotukhin while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) { 1174e8f2551fSMichael Zolotukhin if (I->VectorizationFactor == VF) 1175e8f2551fSMichael Zolotukhin return I->VectorFnName; 1176e8f2551fSMichael Zolotukhin ++I; 1177e8f2551fSMichael Zolotukhin } 1178e8f2551fSMichael Zolotukhin return StringRef(); 1179e8f2551fSMichael Zolotukhin } 1180e8f2551fSMichael Zolotukhin 1181e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F, 1182e8f2551fSMichael Zolotukhin unsigned &VF) const { 1183e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1184e8f2551fSMichael Zolotukhin if (F.empty()) 1185e8f2551fSMichael Zolotukhin return F; 1186e8f2551fSMichael Zolotukhin 1187e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1188e8f2551fSMichael Zolotukhin ScalarDescs.begin(), ScalarDescs.end(), F, compareWithVectorFnName); 1189e8f2551fSMichael Zolotukhin if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F) 1190e8f2551fSMichael Zolotukhin return StringRef(); 1191e8f2551fSMichael Zolotukhin VF = I->VectorizationFactor; 1192e8f2551fSMichael Zolotukhin return I->ScalarFnName; 1193e8f2551fSMichael Zolotukhin } 1194e8f2551fSMichael Zolotukhin 1195164a2aa6SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Module &M, 1196164a2aa6SChandler Carruth ModuleAnalysisManager &) { 1197c0291865SChandler Carruth if (PresetInfoImpl) 1198c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1199c0291865SChandler Carruth 1200c0291865SChandler Carruth return TargetLibraryInfo(lookupInfoImpl(Triple(M.getTargetTriple()))); 1201c0291865SChandler Carruth } 1202c0291865SChandler Carruth 1203164a2aa6SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Function &F, 1204164a2aa6SChandler Carruth FunctionAnalysisManager &) { 1205c0291865SChandler Carruth if (PresetInfoImpl) 1206c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1207c0291865SChandler Carruth 1208c0291865SChandler Carruth return TargetLibraryInfo( 1209c0291865SChandler Carruth lookupInfoImpl(Triple(F.getParent()->getTargetTriple()))); 1210c0291865SChandler Carruth } 1211c0291865SChandler Carruth 1212c321e534SBenjamin Kramer TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(const Triple &T) { 1213c0291865SChandler Carruth std::unique_ptr<TargetLibraryInfoImpl> &Impl = 1214c0291865SChandler Carruth Impls[T.normalize()]; 1215c0291865SChandler Carruth if (!Impl) 1216c0291865SChandler Carruth Impl.reset(new TargetLibraryInfoImpl(T)); 1217c0291865SChandler Carruth 1218c0291865SChandler Carruth return *Impl; 1219c0291865SChandler Carruth } 1220c0291865SChandler Carruth 1221c0291865SChandler Carruth 1222b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() 1223c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) { 1224b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1225b98f63dbSChandler Carruth } 1226b98f63dbSChandler Carruth 1227b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T) 1228c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) { 1229b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1230b98f63dbSChandler Carruth } 1231b98f63dbSChandler Carruth 1232b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 1233c0291865SChandler Carruth const TargetLibraryInfoImpl &TLIImpl) 1234c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) { 1235b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1236b98f63dbSChandler Carruth } 1237b98f63dbSChandler Carruth 1238b4faf13cSChandler Carruth char TargetLibraryAnalysis::PassID; 1239df0cd726SNAKAMURA Takumi 1240b98f63dbSChandler Carruth // Register the basic pass. 1241b98f63dbSChandler Carruth INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", 1242b98f63dbSChandler Carruth "Target Library Information", false, true) 1243b98f63dbSChandler Carruth char TargetLibraryInfoWrapperPass::ID = 0; 1244b98f63dbSChandler Carruth 1245b98f63dbSChandler Carruth void TargetLibraryInfoWrapperPass::anchor() {} 1246