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"), 266d8a2aa9SMichael Zolotukhin clEnumValEnd)); 276d8a2aa9SMichael Zolotukhin 2857a3d084SBenjamin Kramer const char *const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = { 29cd3d25a2SJan Wen Voung #define TLI_DEFINE_STRING 30cd3d25a2SJan Wen Voung #include "llvm/Analysis/TargetLibraryInfo.def" 3162d4215bSChandler Carruth }; 3262d4215bSChandler Carruth 3362d4215bSChandler Carruth static bool hasSinCosPiStret(const Triple &T) { 3462d4215bSChandler Carruth // Only Darwin variants have _stret versions of combined trig functions. 3562d4215bSChandler Carruth if (!T.isOSDarwin()) 3662d4215bSChandler Carruth return false; 3762d4215bSChandler Carruth 3862d4215bSChandler Carruth // The ABI is rather complicated on x86, so don't do anything special there. 3962d4215bSChandler Carruth if (T.getArch() == Triple::x86) 4062d4215bSChandler Carruth return false; 4162d4215bSChandler Carruth 4262d4215bSChandler Carruth if (T.isMacOSX() && T.isMacOSXVersionLT(10, 9)) 4362d4215bSChandler Carruth return false; 4462d4215bSChandler Carruth 4562d4215bSChandler Carruth if (T.isiOS() && T.isOSVersionLT(7, 0)) 4662d4215bSChandler Carruth return false; 4762d4215bSChandler Carruth 4862d4215bSChandler Carruth return true; 4962d4215bSChandler Carruth } 5062d4215bSChandler Carruth 5162d4215bSChandler Carruth /// initialize - Initialize the set of available library functions based on the 5262d4215bSChandler Carruth /// specified target triple. This should be carefully written so that a missing 5362d4215bSChandler Carruth /// target triple gets a sane set of defaults. 54c0291865SChandler Carruth static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, 55e30b8ca1SCraig Topper ArrayRef<const char *> StandardNames) { 5662d4215bSChandler Carruth // Verify that the StandardNames array is in alphabetical order. 57e30b8ca1SCraig Topper assert(std::is_sorted(StandardNames.begin(), StandardNames.end(), 58e30b8ca1SCraig Topper [](const char *LHS, const char *RHS) { 59e30b8ca1SCraig Topper return strcmp(LHS, RHS) < 0; 60e30b8ca1SCraig Topper }) && 61e30b8ca1SCraig Topper "TargetLibraryInfoImpl function names must be sorted"); 6262d4215bSChandler Carruth 6378fd4f08SNicolai Hahnle if (T.getArch() == Triple::r600 || 6478fd4f08SNicolai Hahnle T.getArch() == Triple::amdgcn) { 6578fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexp); 6678fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexpf); 6778fd4f08SNicolai Hahnle TLI.setUnavailable(LibFunc::ldexpl); 68377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10); 69377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10f); 70377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::exp10l); 71377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10); 72377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10f); 73377975f2SNicolai Haehnle TLI.setUnavailable(LibFunc::log10l); 7478fd4f08SNicolai Hahnle } 7578fd4f08SNicolai Hahnle 7662d4215bSChandler Carruth // There are no library implementations of mempcy and memset for AMD gpus and 7762d4215bSChandler Carruth // these can be difficult to lower in the backend. 7862d4215bSChandler Carruth if (T.getArch() == Triple::r600 || 7905532995SDan Gohman T.getArch() == Triple::amdgcn) { 8062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memcpy); 8162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset); 8262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 8362d4215bSChandler Carruth return; 8462d4215bSChandler Carruth } 8562d4215bSChandler Carruth 8662d4215bSChandler Carruth // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. 878b40366bSTim Northover // All versions of watchOS support it. 8862d4215bSChandler Carruth if (T.isMacOSX()) { 8962d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 5)) 9062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 9162d4215bSChandler Carruth } else if (T.isiOS()) { 9262d4215bSChandler Carruth if (T.isOSVersionLT(3, 0)) 9362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 948b40366bSTim Northover } else if (!T.isWatchOS()) { 9562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 9662d4215bSChandler Carruth } 9762d4215bSChandler Carruth 9862d4215bSChandler Carruth if (!hasSinCosPiStret(T)) { 9962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpi); 10062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpif); 10162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospi); 10262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospif); 10362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospi_stret); 10462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospif_stret); 10562d4215bSChandler Carruth } 10662d4215bSChandler Carruth 10762d4215bSChandler Carruth if (T.isMacOSX() && T.getArch() == Triple::x86 && 10862d4215bSChandler Carruth !T.isMacOSXVersionLT(10, 7)) { 10962d4215bSChandler Carruth // x86-32 OSX has a scheme where fwrite and fputs (and some other functions 11062d4215bSChandler Carruth // we don't care about) have two versions; on recent OSX, the one we want 11162d4215bSChandler Carruth // has a $UNIX2003 suffix. The two implementations are identical except 11262d4215bSChandler Carruth // for the return value in some edge cases. However, we don't want to 11362d4215bSChandler Carruth // generate code that depends on the old symbols. 11462d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); 11562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); 11662d4215bSChandler Carruth } 11762d4215bSChandler Carruth 11862d4215bSChandler Carruth // iprintf and friends are only available on XCore and TCE. 11962d4215bSChandler Carruth if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { 12062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::iprintf); 12162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::siprintf); 12262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fiprintf); 12362d4215bSChandler Carruth } 12462d4215bSChandler Carruth 12562d4215bSChandler Carruth if (T.isOSWindows() && !T.isOSCygMing()) { 12662d4215bSChandler Carruth // Win32 does not support long double 12762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosl); 12862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinl); 12962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanl); 13062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2l); 13162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceill); 13262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignl); 13362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosl); 13462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshl); 13562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expl); 13662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf 13762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsl); 13862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorl); 13962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxl); 14062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminl); 14162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodl); 14262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpl); 14362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpf); 14462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpl); 14562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logl); 14662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::modfl); 14762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powl); 14862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinl); 14962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhl); 15062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtl); 15162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanl); 15262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhl); 15362d4215bSChandler Carruth 15462d4215bSChandler Carruth // Win32 only has C89 math 15562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosh); 15662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshf); 15762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshl); 15862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinh); 15962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhf); 16062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhl); 16162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanh); 16262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhf); 16362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhl); 16462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrt); 16562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtf); 16662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtl); 16762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2); 16862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2f); 16962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2l); 17062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1); 17162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1f); 17262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1l); 17362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2); 17462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2f); 17562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2l); 17662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1p); 17762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pf); 17862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pl); 17962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logb); 18062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbf); 18162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbl); 18262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyint); 18362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintf); 18462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintl); 18562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rint); 18662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintf); 18762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintl); 18862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::round); 18962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundf); 19062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundl); 19162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::trunc); 19262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncf); 19362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncl); 19462d4215bSChandler Carruth 19562d4215bSChandler Carruth // Win32 provides some C99 math with mangled names 19662d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); 19762d4215bSChandler Carruth 19862d4215bSChandler Carruth if (T.getArch() == Triple::x86) { 19962d4215bSChandler Carruth // Win32 on x86 implements single-precision math functions as macros 20062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosf); 20162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinf); 20262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanf); 20362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2f); 20462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceilf); 20562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignf); 20662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosf); 20762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshf); 20862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expf); 20962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorf); 21062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminf); 21162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxf); 21262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodf); 21362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logf); 214eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::log10f); 215eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::modff); 21662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powf); 21762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinf); 21862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhf); 21962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtf); 22062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanf); 22162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhf); 22262d4215bSChandler Carruth } 22362d4215bSChandler Carruth 22462d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 22562d4215bSChandler Carruth // generally available on POSIX-compliant systems: 22662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::access); 22762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcmp); 22862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcopy); 22962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bzero); 23062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chmod); 23162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chown); 23262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::closedir); 23362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ctermid); 23462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fdopen); 23562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffs); 23662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fileno); 23762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::flockfile); 23862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko); 23962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat); 24062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs); 24162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello); 24262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftrylockfile); 24362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::funlockfile); 24462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getc_unlocked); 24562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getitimer); 24662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getlogin_r); 24762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getpwnam); 24862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::gettimeofday); 24962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htonl); 25062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htons); 25162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lchown); 25262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat); 25362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memccpy); 25462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::mkdir); 25562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohl); 25662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohs); 25762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open); 25862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::opendir); 25962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pclose); 26062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::popen); 26162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pread); 26262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pwrite); 26362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::read); 26462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::readlink); 26562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::realpath); 26662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rmdir); 26762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::setitimer); 26862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat); 26962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs); 27062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpcpy); 27162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpncpy); 27262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strcasecmp); 27362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strncasecmp); 27462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::times); 27562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::uname); 27662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unlink); 27762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unsetenv); 27862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utime); 27962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utimes); 28062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::write); 28162d4215bSChandler Carruth 28262d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 28362d4215bSChandler Carruth // specified by C99: 28462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atoll); 28562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpf); 28662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::llabs); 28762d4215bSChandler Carruth } 28862d4215bSChandler Carruth 28962d4215bSChandler Carruth switch (T.getOS()) { 29062d4215bSChandler Carruth case Triple::MacOSX: 29162d4215bSChandler Carruth // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 29262d4215bSChandler Carruth // and their names are __exp10 and __exp10f. exp10l is not available on 29362d4215bSChandler Carruth // OS X or iOS. 29462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 29562d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 9)) { 29662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 29762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 29862d4215bSChandler Carruth } else { 29962d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 30062d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 30162d4215bSChandler Carruth } 30262d4215bSChandler Carruth break; 30362d4215bSChandler Carruth case Triple::IOS: 30489a6eefeSTim Northover case Triple::TvOS: 3058b40366bSTim Northover case Triple::WatchOS: 30662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 3078b40366bSTim Northover if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || 3088b40366bSTim Northover (T.isOSVersionLT(9, 0) && 3098b40366bSTim Northover (T.getArch() == Triple::x86 || 3108b40366bSTim Northover T.getArch() == Triple::x86_64)))) { 31162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 31262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 31362d4215bSChandler Carruth } else { 31462d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 31562d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 31662d4215bSChandler Carruth } 31762d4215bSChandler Carruth break; 31862d4215bSChandler Carruth case Triple::Linux: 31962d4215bSChandler Carruth // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely 32062d4215bSChandler Carruth // buggy prior to glibc version 2.18. Until this version is widely deployed 32162d4215bSChandler Carruth // or we have a reasonable detection strategy, we cannot use exp10 reliably 32262d4215bSChandler Carruth // on Linux. 32362d4215bSChandler Carruth // 32462d4215bSChandler Carruth // Fall through to disable all of them. 32562d4215bSChandler Carruth default: 32662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 32762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 32862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 32962d4215bSChandler Carruth } 33062d4215bSChandler Carruth 33162d4215bSChandler Carruth // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and 33262d4215bSChandler Carruth // Linux (GLIBC): 33362d4215bSChandler Carruth // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html 33483b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c 33562d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html 33662d4215bSChandler Carruth switch (T.getOS()) { 33762d4215bSChandler Carruth case Triple::Darwin: 33862d4215bSChandler Carruth case Triple::MacOSX: 33962d4215bSChandler Carruth case Triple::IOS: 34089a6eefeSTim Northover case Triple::TvOS: 3418b40366bSTim Northover case Triple::WatchOS: 34262d4215bSChandler Carruth case Triple::FreeBSD: 34362d4215bSChandler Carruth case Triple::Linux: 34462d4215bSChandler Carruth break; 34562d4215bSChandler Carruth default: 34662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsl); 34762d4215bSChandler Carruth } 34862d4215bSChandler Carruth 34962d4215bSChandler Carruth // ffsll is available on at least FreeBSD and Linux (GLIBC): 35083b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c 35162d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html 35262d4215bSChandler Carruth switch (T.getOS()) { 35389a6eefeSTim Northover case Triple::Darwin: 35489a6eefeSTim Northover case Triple::MacOSX: 35589a6eefeSTim Northover case Triple::IOS: 35689a6eefeSTim Northover case Triple::TvOS: 35789a6eefeSTim Northover case Triple::WatchOS: 35862d4215bSChandler Carruth case Triple::FreeBSD: 35962d4215bSChandler Carruth case Triple::Linux: 36062d4215bSChandler Carruth break; 36162d4215bSChandler Carruth default: 36262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsll); 36362d4215bSChandler Carruth } 36462d4215bSChandler Carruth 365bfd3082eSDavide Italiano // The following functions are available on at least FreeBSD: 366bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/fls.c 367bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c 368bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c 369bfd3082eSDavide Italiano if (!T.isOSFreeBSD()) { 370bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::fls); 371bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsl); 372bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsll); 373bfd3082eSDavide Italiano } 374bfd3082eSDavide Italiano 37562d4215bSChandler Carruth // The following functions are available on at least Linux: 37662d4215bSChandler Carruth if (!T.isOSLinux()) { 37762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strdup); 37862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strtok_r); 37962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); 38062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); 38162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_getc); 38262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_putc); 38362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memalign); 38462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fopen64); 38562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko64); 38662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat64); 38762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs64); 38862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello64); 38962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat64); 39062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open64); 39162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat64); 39262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs64); 39362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tmpfile64); 39462d4215bSChandler Carruth } 3956d8a2aa9SMichael Zolotukhin 39651132881SJustin Lebar // As currently implemented in clang, NVPTX code has no standard library to 39751132881SJustin Lebar // speak of. Headers provide a standard-ish library implementation, but many 39851132881SJustin Lebar // of the signatures are wrong -- for example, many libm functions are not 39951132881SJustin Lebar // extern "C". 40051132881SJustin Lebar // 40151132881SJustin Lebar // libdevice, an IR library provided by nvidia, is linked in by the front-end, 40251132881SJustin Lebar // but only used functions are provided to llvm. Moreover, most of the 40351132881SJustin Lebar // functions in libdevice don't map precisely to standard library functions. 40451132881SJustin Lebar // 40551132881SJustin Lebar // FIXME: Having no standard library prevents e.g. many fastmath 40651132881SJustin Lebar // optimizations, so this situation should be fixed. 407ae272d71SDavid Majnemer if (T.isNVPTX()) { 40851132881SJustin Lebar TLI.disableAllFunctions(); 409ae272d71SDavid Majnemer TLI.setAvailable(LibFunc::nvvm_reflect); 410ae272d71SDavid Majnemer } else { 411ae272d71SDavid Majnemer TLI.setUnavailable(LibFunc::nvvm_reflect); 412ae272d71SDavid Majnemer } 41351132881SJustin Lebar 4146d8a2aa9SMichael Zolotukhin TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); 41562d4215bSChandler Carruth } 41662d4215bSChandler Carruth 417c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl() { 41862d4215bSChandler Carruth // Default to everything being available. 41962d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 42062d4215bSChandler Carruth 42162d4215bSChandler Carruth initialize(*this, Triple(), StandardNames); 42262d4215bSChandler Carruth } 42362d4215bSChandler Carruth 424c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { 42562d4215bSChandler Carruth // Default to everything being available. 42662d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 42762d4215bSChandler Carruth 42862d4215bSChandler Carruth initialize(*this, T, StandardNames); 42962d4215bSChandler Carruth } 43062d4215bSChandler Carruth 431c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) 4328ca43224SChandler Carruth : CustomNames(TLI.CustomNames) { 43362d4215bSChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 434e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 435e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4368ca43224SChandler Carruth } 4378ca43224SChandler Carruth 438c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) 4398ca43224SChandler Carruth : CustomNames(std::move(TLI.CustomNames)) { 4408ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4418ca43224SChandler Carruth AvailableArray); 442e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 443e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4448ca43224SChandler Carruth } 4458ca43224SChandler Carruth 446c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { 44762d4215bSChandler Carruth CustomNames = TLI.CustomNames; 4488ca43224SChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 4498ca43224SChandler Carruth return *this; 4508ca43224SChandler Carruth } 4518ca43224SChandler Carruth 452c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { 4538ca43224SChandler Carruth CustomNames = std::move(TLI.CustomNames); 4548ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4558ca43224SChandler Carruth AvailableArray); 4568ca43224SChandler Carruth return *this; 45762d4215bSChandler Carruth } 45862d4215bSChandler Carruth 45921abdf98SMichael Zolotukhin static StringRef sanitizeFunctionName(StringRef funcName) { 46062d4215bSChandler Carruth // Filter out empty names and names containing null bytes, those can't be in 46162d4215bSChandler Carruth // our table. 46262d4215bSChandler Carruth if (funcName.empty() || funcName.find('\0') != StringRef::npos) 46321abdf98SMichael Zolotukhin return StringRef(); 46462d4215bSChandler Carruth 46562d4215bSChandler Carruth // Check for \01 prefix that is used to mangle __asm declarations and 46662d4215bSChandler Carruth // strip it if present. 467cde33036SDavid Majnemer return GlobalValue::getRealLinkageName(funcName); 46821abdf98SMichael Zolotukhin } 46921abdf98SMichael Zolotukhin 47021abdf98SMichael Zolotukhin bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, 47121abdf98SMichael Zolotukhin LibFunc::Func &F) const { 47257a3d084SBenjamin Kramer const char *const *Start = &StandardNames[0]; 47357a3d084SBenjamin Kramer const char *const *End = &StandardNames[LibFunc::NumLibFuncs]; 47421abdf98SMichael Zolotukhin 47521abdf98SMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 47621abdf98SMichael Zolotukhin if (funcName.empty()) 47721abdf98SMichael Zolotukhin return false; 47821abdf98SMichael Zolotukhin 47957a3d084SBenjamin Kramer const char *const *I = std::lower_bound( 480d3b76a3bSMichael Zolotukhin Start, End, funcName, [](const char *LHS, StringRef RHS) { 481d3b76a3bSMichael Zolotukhin return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; 482d3b76a3bSMichael Zolotukhin }); 48362d4215bSChandler Carruth if (I != End && *I == funcName) { 48462d4215bSChandler Carruth F = (LibFunc::Func)(I - Start); 48562d4215bSChandler Carruth return true; 48662d4215bSChandler Carruth } 48762d4215bSChandler Carruth return false; 48862d4215bSChandler Carruth } 48962d4215bSChandler Carruth 490d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, 491d765a82bSAhmed Bougacha LibFunc::Func F, 492d765a82bSAhmed Bougacha const DataLayout *DL) const { 493d765a82bSAhmed Bougacha LLVMContext &Ctx = FTy.getContext(); 494d765a82bSAhmed Bougacha Type *PCharTy = Type::getInt8PtrTy(Ctx); 495d765a82bSAhmed Bougacha Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AS=*/0) : nullptr; 496d765a82bSAhmed Bougacha auto IsSizeTTy = [SizeTTy](Type *Ty) { 497d765a82bSAhmed Bougacha return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy(); 498d765a82bSAhmed Bougacha }; 499d765a82bSAhmed Bougacha unsigned NumParams = FTy.getNumParams(); 500d765a82bSAhmed Bougacha 501d765a82bSAhmed Bougacha switch (F) { 502d765a82bSAhmed Bougacha case LibFunc::strlen: 503d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && 504d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 505d765a82bSAhmed Bougacha 506d765a82bSAhmed Bougacha case LibFunc::strchr: 507d765a82bSAhmed Bougacha case LibFunc::strrchr: 508d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 509d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 510d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy()); 511d765a82bSAhmed Bougacha 512d765a82bSAhmed Bougacha case LibFunc::strtol: 513d765a82bSAhmed Bougacha case LibFunc::strtod: 514d765a82bSAhmed Bougacha case LibFunc::strtof: 515d765a82bSAhmed Bougacha case LibFunc::strtoul: 516d765a82bSAhmed Bougacha case LibFunc::strtoll: 517d765a82bSAhmed Bougacha case LibFunc::strtold: 518d765a82bSAhmed Bougacha case LibFunc::strtoull: 519d765a82bSAhmed Bougacha return ((NumParams == 2 || NumParams == 3) && 520d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 521d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 522d765a82bSAhmed Bougacha case LibFunc::strcat: 523d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 524d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 525d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType()); 526d765a82bSAhmed Bougacha 527d765a82bSAhmed Bougacha case LibFunc::strncat: 528d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && 529d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 530d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType() && 531d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 532d765a82bSAhmed Bougacha 533d765a82bSAhmed Bougacha case LibFunc::strcpy_chk: 534d765a82bSAhmed Bougacha case LibFunc::stpcpy_chk: 535d765a82bSAhmed Bougacha --NumParams; 536d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 537d765a82bSAhmed Bougacha return false; 538d765a82bSAhmed Bougacha // fallthrough 539d765a82bSAhmed Bougacha case LibFunc::strcpy: 540d765a82bSAhmed Bougacha case LibFunc::stpcpy: 541d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && 542d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 543d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy); 544d765a82bSAhmed Bougacha 545d765a82bSAhmed Bougacha case LibFunc::strncpy_chk: 546d765a82bSAhmed Bougacha case LibFunc::stpncpy_chk: 547d765a82bSAhmed Bougacha --NumParams; 548d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 549d765a82bSAhmed Bougacha return false; 550d765a82bSAhmed Bougacha // fallthrough 551d765a82bSAhmed Bougacha case LibFunc::strncpy: 552d765a82bSAhmed Bougacha case LibFunc::stpncpy: 553d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 554d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 555d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy && 556d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 557d765a82bSAhmed Bougacha 558d765a82bSAhmed Bougacha case LibFunc::strxfrm: 559d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 560d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 561d765a82bSAhmed Bougacha 562d765a82bSAhmed Bougacha case LibFunc::strcmp: 563d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && 564d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 565d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 566d765a82bSAhmed Bougacha 567d765a82bSAhmed Bougacha case LibFunc::strncmp: 568d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && 569d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 570d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 571d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 572d765a82bSAhmed Bougacha 573d765a82bSAhmed Bougacha case LibFunc::strspn: 574d765a82bSAhmed Bougacha case LibFunc::strcspn: 575d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 576d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 577d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 578d765a82bSAhmed Bougacha 579d765a82bSAhmed Bougacha case LibFunc::strcoll: 580d765a82bSAhmed Bougacha case LibFunc::strcasecmp: 581d765a82bSAhmed Bougacha case LibFunc::strncasecmp: 582d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 583d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 584d765a82bSAhmed Bougacha 585d765a82bSAhmed Bougacha case LibFunc::strstr: 586d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 587d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 588d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 589d765a82bSAhmed Bougacha 590d765a82bSAhmed Bougacha case LibFunc::strpbrk: 591d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 592d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 593d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 594d765a82bSAhmed Bougacha 595d765a82bSAhmed Bougacha case LibFunc::strtok: 596d765a82bSAhmed Bougacha case LibFunc::strtok_r: 597d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 598d765a82bSAhmed Bougacha case LibFunc::scanf: 599d765a82bSAhmed Bougacha case LibFunc::setbuf: 600d765a82bSAhmed Bougacha case LibFunc::setvbuf: 601d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 602d765a82bSAhmed Bougacha case LibFunc::strdup: 603d765a82bSAhmed Bougacha case LibFunc::strndup: 604d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 605d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 606*9cc0bca2SDavide Italiano case LibFunc::sscanf: 607d765a82bSAhmed Bougacha case LibFunc::stat: 608d765a82bSAhmed Bougacha case LibFunc::statvfs: 609d765a82bSAhmed Bougacha case LibFunc::sprintf: 610d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 611d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 612d765a82bSAhmed Bougacha case LibFunc::snprintf: 613d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 614d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 615d765a82bSAhmed Bougacha case LibFunc::setitimer: 616d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 617d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 618d765a82bSAhmed Bougacha case LibFunc::system: 619d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 620d765a82bSAhmed Bougacha case LibFunc::malloc: 621d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); 622d765a82bSAhmed Bougacha case LibFunc::memcmp: 623d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 624d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 625d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy(32)); 626d765a82bSAhmed Bougacha 627d765a82bSAhmed Bougacha case LibFunc::memchr: 628d765a82bSAhmed Bougacha case LibFunc::memrchr: 629d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 630d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy(32) && 631d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 632d765a82bSAhmed Bougacha FTy.getReturnType()->isPointerTy()); 633d765a82bSAhmed Bougacha case LibFunc::modf: 634d765a82bSAhmed Bougacha case LibFunc::modff: 635d765a82bSAhmed Bougacha case LibFunc::modfl: 636d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 637d765a82bSAhmed Bougacha 638d765a82bSAhmed Bougacha case LibFunc::memcpy_chk: 639d765a82bSAhmed Bougacha case LibFunc::memmove_chk: 640d765a82bSAhmed Bougacha --NumParams; 641d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 642d765a82bSAhmed Bougacha return false; 643d765a82bSAhmed Bougacha // fallthrough 644d765a82bSAhmed Bougacha case LibFunc::memcpy: 645d765a82bSAhmed Bougacha case LibFunc::memmove: 646d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 647d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 648d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 649d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 650d765a82bSAhmed Bougacha 651d765a82bSAhmed Bougacha case LibFunc::memset_chk: 652d765a82bSAhmed Bougacha --NumParams; 653d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 654d765a82bSAhmed Bougacha return false; 655d765a82bSAhmed Bougacha // fallthrough 656d765a82bSAhmed Bougacha case LibFunc::memset: 657d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 658d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 659d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 660d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 661d765a82bSAhmed Bougacha 662d765a82bSAhmed Bougacha case LibFunc::memccpy: 663d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 664d765a82bSAhmed Bougacha case LibFunc::memalign: 665d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 666d765a82bSAhmed Bougacha case LibFunc::realloc: 667d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 668d765a82bSAhmed Bougacha FTy.getReturnType()->isPointerTy()); 669d765a82bSAhmed Bougacha case LibFunc::read: 670d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 671d765a82bSAhmed Bougacha case LibFunc::rewind: 672d765a82bSAhmed Bougacha case LibFunc::rmdir: 673d765a82bSAhmed Bougacha case LibFunc::remove: 674d765a82bSAhmed Bougacha case LibFunc::realpath: 675d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 676d765a82bSAhmed Bougacha case LibFunc::rename: 677d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 678d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 679d765a82bSAhmed Bougacha case LibFunc::readlink: 680d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 681d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 682d765a82bSAhmed Bougacha case LibFunc::write: 683d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 684d765a82bSAhmed Bougacha case LibFunc::bcopy: 685d765a82bSAhmed Bougacha case LibFunc::bcmp: 686d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 687d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 688d765a82bSAhmed Bougacha case LibFunc::bzero: 689d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 690d765a82bSAhmed Bougacha case LibFunc::calloc: 691d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); 6921fe3f1caSAhmed Bougacha 6931fe3f1caSAhmed Bougacha case LibFunc::atof: 694d765a82bSAhmed Bougacha case LibFunc::atoi: 695d765a82bSAhmed Bougacha case LibFunc::atol: 696d765a82bSAhmed Bougacha case LibFunc::atoll: 6971fe3f1caSAhmed Bougacha case LibFunc::ferror: 6981fe3f1caSAhmed Bougacha case LibFunc::getenv: 6991fe3f1caSAhmed Bougacha case LibFunc::getpwnam: 7001fe3f1caSAhmed Bougacha case LibFunc::pclose: 7011fe3f1caSAhmed Bougacha case LibFunc::perror: 7021fe3f1caSAhmed Bougacha case LibFunc::printf: 7031fe3f1caSAhmed Bougacha case LibFunc::puts: 7041fe3f1caSAhmed Bougacha case LibFunc::uname: 7051fe3f1caSAhmed Bougacha case LibFunc::under_IO_getc: 7061fe3f1caSAhmed Bougacha case LibFunc::unlink: 7071fe3f1caSAhmed Bougacha case LibFunc::unsetenv: 708d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 7091fe3f1caSAhmed Bougacha 7101fe3f1caSAhmed Bougacha case LibFunc::chmod: 7111fe3f1caSAhmed Bougacha case LibFunc::chown: 7121fe3f1caSAhmed Bougacha case LibFunc::clearerr: 7131fe3f1caSAhmed Bougacha case LibFunc::closedir: 7141fe3f1caSAhmed Bougacha case LibFunc::ctermid: 7151fe3f1caSAhmed Bougacha case LibFunc::fclose: 7161fe3f1caSAhmed Bougacha case LibFunc::feof: 7171fe3f1caSAhmed Bougacha case LibFunc::fflush: 7181fe3f1caSAhmed Bougacha case LibFunc::fgetc: 7191fe3f1caSAhmed Bougacha case LibFunc::fileno: 7201fe3f1caSAhmed Bougacha case LibFunc::flockfile: 7211fe3f1caSAhmed Bougacha case LibFunc::free: 7221fe3f1caSAhmed Bougacha case LibFunc::fseek: 723201b97f5SAhmed Bougacha case LibFunc::fseeko64: 7241fe3f1caSAhmed Bougacha case LibFunc::fseeko: 7251fe3f1caSAhmed Bougacha case LibFunc::fsetpos: 7261fe3f1caSAhmed Bougacha case LibFunc::ftell: 727201b97f5SAhmed Bougacha case LibFunc::ftello64: 7281fe3f1caSAhmed Bougacha case LibFunc::ftello: 7291fe3f1caSAhmed Bougacha case LibFunc::ftrylockfile: 7301fe3f1caSAhmed Bougacha case LibFunc::funlockfile: 7311fe3f1caSAhmed Bougacha case LibFunc::getc: 7321fe3f1caSAhmed Bougacha case LibFunc::getc_unlocked: 7331fe3f1caSAhmed Bougacha case LibFunc::getlogin_r: 7341fe3f1caSAhmed Bougacha case LibFunc::mkdir: 7351fe3f1caSAhmed Bougacha case LibFunc::mktime: 7361fe3f1caSAhmed Bougacha case LibFunc::times: 7371fe3f1caSAhmed Bougacha return (NumParams != 0 && FTy.getParamType(0)->isPointerTy()); 7381fe3f1caSAhmed Bougacha 739d765a82bSAhmed Bougacha case LibFunc::access: 740d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 741d765a82bSAhmed Bougacha case LibFunc::fopen: 742d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 743d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 744d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 745d765a82bSAhmed Bougacha case LibFunc::fdopen: 746d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 747d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 748d765a82bSAhmed Bougacha case LibFunc::fputc: 749d765a82bSAhmed Bougacha case LibFunc::fstat: 750d765a82bSAhmed Bougacha case LibFunc::frexp: 751d765a82bSAhmed Bougacha case LibFunc::frexpf: 752d765a82bSAhmed Bougacha case LibFunc::frexpl: 753d765a82bSAhmed Bougacha case LibFunc::fstatvfs: 754d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 755d765a82bSAhmed Bougacha case LibFunc::fgets: 756d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 757d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 758d765a82bSAhmed Bougacha case LibFunc::fread: 759d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 760d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 761d765a82bSAhmed Bougacha case LibFunc::fwrite: 762d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && 763d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 764d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 765d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 766d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 767d765a82bSAhmed Bougacha case LibFunc::fputs: 768d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 769d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 770d765a82bSAhmed Bougacha case LibFunc::fscanf: 771d765a82bSAhmed Bougacha case LibFunc::fprintf: 772d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 773d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 774d765a82bSAhmed Bougacha case LibFunc::fgetpos: 775d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 776d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 777d765a82bSAhmed Bougacha case LibFunc::gets: 778d765a82bSAhmed Bougacha case LibFunc::getchar: 779d765a82bSAhmed Bougacha case LibFunc::getitimer: 780d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 781d765a82bSAhmed Bougacha case LibFunc::ungetc: 782d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 783d765a82bSAhmed Bougacha case LibFunc::utime: 784d765a82bSAhmed Bougacha case LibFunc::utimes: 785d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 786d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 787d765a82bSAhmed Bougacha case LibFunc::putc: 788d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 789d765a82bSAhmed Bougacha case LibFunc::pread: 790d765a82bSAhmed Bougacha case LibFunc::pwrite: 791d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); 792d765a82bSAhmed Bougacha case LibFunc::popen: 793d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 794d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 795d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 796d765a82bSAhmed Bougacha case LibFunc::vscanf: 797d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 798d765a82bSAhmed Bougacha case LibFunc::vsscanf: 799d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 800d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 801d765a82bSAhmed Bougacha case LibFunc::vfscanf: 802d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 803d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 804d765a82bSAhmed Bougacha case LibFunc::valloc: 805d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 806d765a82bSAhmed Bougacha case LibFunc::vprintf: 807d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 808d765a82bSAhmed Bougacha case LibFunc::vfprintf: 809d765a82bSAhmed Bougacha case LibFunc::vsprintf: 810d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 811d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 812d765a82bSAhmed Bougacha case LibFunc::vsnprintf: 813d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 814d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 815d765a82bSAhmed Bougacha case LibFunc::open: 816d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 817d765a82bSAhmed Bougacha case LibFunc::opendir: 818d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && 819d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 820d765a82bSAhmed Bougacha case LibFunc::tmpfile: 821d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 822d765a82bSAhmed Bougacha case LibFunc::htonl: 823d765a82bSAhmed Bougacha case LibFunc::htons: 824d765a82bSAhmed Bougacha case LibFunc::ntohl: 825d765a82bSAhmed Bougacha case LibFunc::ntohs: 826d765a82bSAhmed Bougacha case LibFunc::lstat: 827d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 828d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 829d765a82bSAhmed Bougacha case LibFunc::lchown: 830d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); 831d765a82bSAhmed Bougacha case LibFunc::qsort: 832d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); 833d765a82bSAhmed Bougacha case LibFunc::dunder_strdup: 834d765a82bSAhmed Bougacha case LibFunc::dunder_strndup: 835d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 836d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 837d765a82bSAhmed Bougacha case LibFunc::dunder_strtok_r: 838d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 839d765a82bSAhmed Bougacha case LibFunc::under_IO_putc: 840d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 841d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_scanf: 842d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 843d765a82bSAhmed Bougacha case LibFunc::stat64: 844d765a82bSAhmed Bougacha case LibFunc::lstat64: 845d765a82bSAhmed Bougacha case LibFunc::statvfs64: 846d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && 847d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 848d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_sscanf: 849d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && 850d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 851d765a82bSAhmed Bougacha case LibFunc::fopen64: 852d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 853d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 854d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 855d765a82bSAhmed Bougacha case LibFunc::tmpfile64: 856d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 857d765a82bSAhmed Bougacha case LibFunc::fstat64: 858d765a82bSAhmed Bougacha case LibFunc::fstatvfs64: 859d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 860d765a82bSAhmed Bougacha case LibFunc::open64: 861d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 862d765a82bSAhmed Bougacha case LibFunc::gettimeofday: 863d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 864d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 865d765a82bSAhmed Bougacha 866d765a82bSAhmed Bougacha case LibFunc::Znwj: // new(unsigned int); 867d765a82bSAhmed Bougacha case LibFunc::Znwm: // new(unsigned long); 868d765a82bSAhmed Bougacha case LibFunc::Znaj: // new[](unsigned int); 869d765a82bSAhmed Bougacha case LibFunc::Znam: // new[](unsigned long); 870d765a82bSAhmed Bougacha case LibFunc::msvc_new_int: // new(unsigned int); 871d765a82bSAhmed Bougacha case LibFunc::msvc_new_longlong: // new(unsigned long long); 872d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_int: // new[](unsigned int); 873d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); 874d765a82bSAhmed Bougacha return (NumParams == 1); 875d765a82bSAhmed Bougacha 876d765a82bSAhmed Bougacha case LibFunc::memset_pattern16: 877d765a82bSAhmed Bougacha return (!FTy.isVarArg() && NumParams == 3 && 878d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(0)) && 879d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(1)) && 880d765a82bSAhmed Bougacha isa<IntegerType>(FTy.getParamType(2))); 881d765a82bSAhmed Bougacha 882d765a82bSAhmed Bougacha // int __nvvm_reflect(const char *); 883d765a82bSAhmed Bougacha case LibFunc::nvvm_reflect: 884d765a82bSAhmed Bougacha return (NumParams == 1 && isa<PointerType>(FTy.getParamType(0))); 885d765a82bSAhmed Bougacha 886d765a82bSAhmed Bougacha case LibFunc::sin: 887d765a82bSAhmed Bougacha case LibFunc::sinf: 888d765a82bSAhmed Bougacha case LibFunc::sinl: 889d765a82bSAhmed Bougacha case LibFunc::cos: 890d765a82bSAhmed Bougacha case LibFunc::cosf: 891d765a82bSAhmed Bougacha case LibFunc::cosl: 892b62692e2SDavid Majnemer case LibFunc::tan: 893b62692e2SDavid Majnemer case LibFunc::tanf: 894b62692e2SDavid Majnemer case LibFunc::tanl: 895d765a82bSAhmed Bougacha case LibFunc::exp: 896d765a82bSAhmed Bougacha case LibFunc::expf: 897d765a82bSAhmed Bougacha case LibFunc::expl: 898d765a82bSAhmed Bougacha case LibFunc::exp2: 899d765a82bSAhmed Bougacha case LibFunc::exp2f: 900d765a82bSAhmed Bougacha case LibFunc::exp2l: 901d765a82bSAhmed Bougacha case LibFunc::log: 902d765a82bSAhmed Bougacha case LibFunc::logf: 903d765a82bSAhmed Bougacha case LibFunc::logl: 904d765a82bSAhmed Bougacha case LibFunc::log10: 905d765a82bSAhmed Bougacha case LibFunc::log10f: 906d765a82bSAhmed Bougacha case LibFunc::log10l: 907d765a82bSAhmed Bougacha case LibFunc::log2: 908d765a82bSAhmed Bougacha case LibFunc::log2f: 909d765a82bSAhmed Bougacha case LibFunc::log2l: 910d765a82bSAhmed Bougacha case LibFunc::fabs: 911d765a82bSAhmed Bougacha case LibFunc::fabsf: 912d765a82bSAhmed Bougacha case LibFunc::fabsl: 913d765a82bSAhmed Bougacha case LibFunc::floor: 914d765a82bSAhmed Bougacha case LibFunc::floorf: 915d765a82bSAhmed Bougacha case LibFunc::floorl: 916d765a82bSAhmed Bougacha case LibFunc::ceil: 917d765a82bSAhmed Bougacha case LibFunc::ceilf: 918d765a82bSAhmed Bougacha case LibFunc::ceill: 919d765a82bSAhmed Bougacha case LibFunc::trunc: 920d765a82bSAhmed Bougacha case LibFunc::truncf: 921d765a82bSAhmed Bougacha case LibFunc::truncl: 922d765a82bSAhmed Bougacha case LibFunc::rint: 923d765a82bSAhmed Bougacha case LibFunc::rintf: 924d765a82bSAhmed Bougacha case LibFunc::rintl: 925d765a82bSAhmed Bougacha case LibFunc::nearbyint: 926d765a82bSAhmed Bougacha case LibFunc::nearbyintf: 927d765a82bSAhmed Bougacha case LibFunc::nearbyintl: 928d765a82bSAhmed Bougacha case LibFunc::round: 929d765a82bSAhmed Bougacha case LibFunc::roundf: 930d765a82bSAhmed Bougacha case LibFunc::roundl: 931d765a82bSAhmed Bougacha case LibFunc::sqrt: 932d765a82bSAhmed Bougacha case LibFunc::sqrtf: 933d765a82bSAhmed Bougacha case LibFunc::sqrtl: 934d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && 935d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 936d765a82bSAhmed Bougacha 937d765a82bSAhmed Bougacha case LibFunc::fmin: 938d765a82bSAhmed Bougacha case LibFunc::fminf: 939d765a82bSAhmed Bougacha case LibFunc::fminl: 940d765a82bSAhmed Bougacha case LibFunc::fmax: 941d765a82bSAhmed Bougacha case LibFunc::fmaxf: 942d765a82bSAhmed Bougacha case LibFunc::fmaxl: 943d765a82bSAhmed Bougacha case LibFunc::copysign: 944d765a82bSAhmed Bougacha case LibFunc::copysignf: 945d765a82bSAhmed Bougacha case LibFunc::copysignl: 946d765a82bSAhmed Bougacha case LibFunc::pow: 947d765a82bSAhmed Bougacha case LibFunc::powf: 948d765a82bSAhmed Bougacha case LibFunc::powl: 949d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && 950d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 951d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(1)); 952d765a82bSAhmed Bougacha 953d765a82bSAhmed Bougacha case LibFunc::ffs: 954d765a82bSAhmed Bougacha case LibFunc::ffsl: 955d765a82bSAhmed Bougacha case LibFunc::ffsll: 956d765a82bSAhmed Bougacha case LibFunc::isdigit: 957d765a82bSAhmed Bougacha case LibFunc::isascii: 958d765a82bSAhmed Bougacha case LibFunc::toascii: 959d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && 960d765a82bSAhmed Bougacha FTy.getParamType(0)->isIntegerTy()); 961d765a82bSAhmed Bougacha 962d765a82bSAhmed Bougacha case LibFunc::fls: 963d765a82bSAhmed Bougacha case LibFunc::flsl: 964d765a82bSAhmed Bougacha case LibFunc::flsll: 965d765a82bSAhmed Bougacha case LibFunc::abs: 966d765a82bSAhmed Bougacha case LibFunc::labs: 967d765a82bSAhmed Bougacha case LibFunc::llabs: 968d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && 969d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 970d765a82bSAhmed Bougacha 971d765a82bSAhmed Bougacha case LibFunc::cxa_atexit: 972d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && 973d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 974d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 975d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 976d765a82bSAhmed Bougacha 977d765a82bSAhmed Bougacha case LibFunc::sinpi: 978d765a82bSAhmed Bougacha case LibFunc::cospi: 979d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && 980d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 981d765a82bSAhmed Bougacha 982d765a82bSAhmed Bougacha case LibFunc::sinpif: 983d765a82bSAhmed Bougacha case LibFunc::cospif: 984d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && 985d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 986d765a82bSAhmed Bougacha 987d765a82bSAhmed Bougacha default: 988d765a82bSAhmed Bougacha // Assume the other functions are correct. 989d765a82bSAhmed Bougacha // FIXME: It'd be really nice to cover them all. 990d765a82bSAhmed Bougacha return true; 991d765a82bSAhmed Bougacha } 992d765a82bSAhmed Bougacha } 993d765a82bSAhmed Bougacha 994d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, 995d765a82bSAhmed Bougacha LibFunc::Func &F) const { 996d765a82bSAhmed Bougacha const DataLayout *DL = 997d765a82bSAhmed Bougacha FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; 998d765a82bSAhmed Bougacha return getLibFunc(FDecl.getName(), F) && 999d765a82bSAhmed Bougacha isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL); 1000d765a82bSAhmed Bougacha } 1001d765a82bSAhmed Bougacha 1002c0291865SChandler Carruth void TargetLibraryInfoImpl::disableAllFunctions() { 100362d4215bSChandler Carruth memset(AvailableArray, 0, sizeof(AvailableArray)); 100462d4215bSChandler Carruth } 1005b98f63dbSChandler Carruth 1006e8f2551fSMichael Zolotukhin static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) { 1007e8f2551fSMichael Zolotukhin return std::strncmp(LHS.ScalarFnName, RHS.ScalarFnName, 1008e8f2551fSMichael Zolotukhin std::strlen(RHS.ScalarFnName)) < 0; 1009e8f2551fSMichael Zolotukhin } 1010e8f2551fSMichael Zolotukhin 1011e8f2551fSMichael Zolotukhin static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) { 1012e8f2551fSMichael Zolotukhin return std::strncmp(LHS.VectorFnName, RHS.VectorFnName, 1013e8f2551fSMichael Zolotukhin std::strlen(RHS.VectorFnName)) < 0; 1014e8f2551fSMichael Zolotukhin } 1015e8f2551fSMichael Zolotukhin 1016e8f2551fSMichael Zolotukhin static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) { 1017e8f2551fSMichael Zolotukhin return std::strncmp(LHS.ScalarFnName, S.data(), S.size()) < 0; 1018e8f2551fSMichael Zolotukhin } 1019e8f2551fSMichael Zolotukhin 1020e8f2551fSMichael Zolotukhin static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) { 1021e8f2551fSMichael Zolotukhin return std::strncmp(LHS.VectorFnName, S.data(), S.size()) < 0; 1022e8f2551fSMichael Zolotukhin } 1023e8f2551fSMichael Zolotukhin 1024e8f2551fSMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) { 1025e8f2551fSMichael Zolotukhin VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end()); 1026e8f2551fSMichael Zolotukhin std::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName); 1027e8f2551fSMichael Zolotukhin 1028e8f2551fSMichael Zolotukhin ScalarDescs.insert(ScalarDescs.end(), Fns.begin(), Fns.end()); 1029e8f2551fSMichael Zolotukhin std::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName); 1030e8f2551fSMichael Zolotukhin } 1031e8f2551fSMichael Zolotukhin 10326d8a2aa9SMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( 10336d8a2aa9SMichael Zolotukhin enum VectorLibrary VecLib) { 10346d8a2aa9SMichael Zolotukhin switch (VecLib) { 10356d8a2aa9SMichael Zolotukhin case Accelerate: { 10366d8a2aa9SMichael Zolotukhin const VecDesc VecFuncs[] = { 1037de63aaceSMichael Zolotukhin // Floating-Point Arithmetic and Auxiliary Functions 1038de63aaceSMichael Zolotukhin {"ceilf", "vceilf", 4}, 10396d8a2aa9SMichael Zolotukhin {"fabsf", "vfabsf", 4}, 10406d8a2aa9SMichael Zolotukhin {"llvm.fabs.f32", "vfabsf", 4}, 1041de63aaceSMichael Zolotukhin {"floorf", "vfloorf", 4}, 1042de63aaceSMichael Zolotukhin {"sqrtf", "vsqrtf", 4}, 1043de63aaceSMichael Zolotukhin {"llvm.sqrt.f32", "vsqrtf", 4}, 1044de63aaceSMichael Zolotukhin 1045de63aaceSMichael Zolotukhin // Exponential and Logarithmic Functions 1046de63aaceSMichael Zolotukhin {"expf", "vexpf", 4}, 1047de63aaceSMichael Zolotukhin {"llvm.exp.f32", "vexpf", 4}, 1048de63aaceSMichael Zolotukhin {"expm1f", "vexpm1f", 4}, 1049de63aaceSMichael Zolotukhin {"logf", "vlogf", 4}, 1050de63aaceSMichael Zolotukhin {"llvm.log.f32", "vlogf", 4}, 1051de63aaceSMichael Zolotukhin {"log1pf", "vlog1pf", 4}, 1052de63aaceSMichael Zolotukhin {"log10f", "vlog10f", 4}, 1053de63aaceSMichael Zolotukhin {"llvm.log10.f32", "vlog10f", 4}, 1054de63aaceSMichael Zolotukhin {"logbf", "vlogbf", 4}, 1055de63aaceSMichael Zolotukhin 1056de63aaceSMichael Zolotukhin // Trigonometric Functions 1057de63aaceSMichael Zolotukhin {"sinf", "vsinf", 4}, 1058de63aaceSMichael Zolotukhin {"llvm.sin.f32", "vsinf", 4}, 1059de63aaceSMichael Zolotukhin {"cosf", "vcosf", 4}, 1060de63aaceSMichael Zolotukhin {"llvm.cos.f32", "vcosf", 4}, 1061de63aaceSMichael Zolotukhin {"tanf", "vtanf", 4}, 1062de63aaceSMichael Zolotukhin {"asinf", "vasinf", 4}, 1063de63aaceSMichael Zolotukhin {"acosf", "vacosf", 4}, 1064de63aaceSMichael Zolotukhin {"atanf", "vatanf", 4}, 1065de63aaceSMichael Zolotukhin 1066de63aaceSMichael Zolotukhin // Hyperbolic Functions 1067de63aaceSMichael Zolotukhin {"sinhf", "vsinhf", 4}, 1068de63aaceSMichael Zolotukhin {"coshf", "vcoshf", 4}, 1069de63aaceSMichael Zolotukhin {"tanhf", "vtanhf", 4}, 1070de63aaceSMichael Zolotukhin {"asinhf", "vasinhf", 4}, 1071de63aaceSMichael Zolotukhin {"acoshf", "vacoshf", 4}, 1072de63aaceSMichael Zolotukhin {"atanhf", "vatanhf", 4}, 10736d8a2aa9SMichael Zolotukhin }; 10746d8a2aa9SMichael Zolotukhin addVectorizableFunctions(VecFuncs); 10756d8a2aa9SMichael Zolotukhin break; 10766d8a2aa9SMichael Zolotukhin } 10776d8a2aa9SMichael Zolotukhin case NoLibrary: 10786d8a2aa9SMichael Zolotukhin break; 10796d8a2aa9SMichael Zolotukhin } 10806d8a2aa9SMichael Zolotukhin } 10816d8a2aa9SMichael Zolotukhin 1082e8f2551fSMichael Zolotukhin bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const { 1083e8f2551fSMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 1084e8f2551fSMichael Zolotukhin if (funcName.empty()) 1085e8f2551fSMichael Zolotukhin return false; 1086e8f2551fSMichael Zolotukhin 1087e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1088e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), funcName, 1089e8f2551fSMichael Zolotukhin compareWithScalarFnName); 1090e8f2551fSMichael Zolotukhin return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName; 1091e8f2551fSMichael Zolotukhin } 1092e8f2551fSMichael Zolotukhin 1093e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F, 1094e8f2551fSMichael Zolotukhin unsigned VF) const { 1095e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1096e8f2551fSMichael Zolotukhin if (F.empty()) 1097e8f2551fSMichael Zolotukhin return F; 1098e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1099e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), F, compareWithScalarFnName); 1100e8f2551fSMichael Zolotukhin while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) { 1101e8f2551fSMichael Zolotukhin if (I->VectorizationFactor == VF) 1102e8f2551fSMichael Zolotukhin return I->VectorFnName; 1103e8f2551fSMichael Zolotukhin ++I; 1104e8f2551fSMichael Zolotukhin } 1105e8f2551fSMichael Zolotukhin return StringRef(); 1106e8f2551fSMichael Zolotukhin } 1107e8f2551fSMichael Zolotukhin 1108e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F, 1109e8f2551fSMichael Zolotukhin unsigned &VF) const { 1110e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1111e8f2551fSMichael Zolotukhin if (F.empty()) 1112e8f2551fSMichael Zolotukhin return F; 1113e8f2551fSMichael Zolotukhin 1114e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1115e8f2551fSMichael Zolotukhin ScalarDescs.begin(), ScalarDescs.end(), F, compareWithVectorFnName); 1116e8f2551fSMichael Zolotukhin if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F) 1117e8f2551fSMichael Zolotukhin return StringRef(); 1118e8f2551fSMichael Zolotukhin VF = I->VectorizationFactor; 1119e8f2551fSMichael Zolotukhin return I->ScalarFnName; 1120e8f2551fSMichael Zolotukhin } 1121e8f2551fSMichael Zolotukhin 1122164a2aa6SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Module &M, 1123164a2aa6SChandler Carruth ModuleAnalysisManager &) { 1124c0291865SChandler Carruth if (PresetInfoImpl) 1125c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1126c0291865SChandler Carruth 1127c0291865SChandler Carruth return TargetLibraryInfo(lookupInfoImpl(Triple(M.getTargetTriple()))); 1128c0291865SChandler Carruth } 1129c0291865SChandler Carruth 1130164a2aa6SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Function &F, 1131164a2aa6SChandler Carruth FunctionAnalysisManager &) { 1132c0291865SChandler Carruth if (PresetInfoImpl) 1133c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1134c0291865SChandler Carruth 1135c0291865SChandler Carruth return TargetLibraryInfo( 1136c0291865SChandler Carruth lookupInfoImpl(Triple(F.getParent()->getTargetTriple()))); 1137c0291865SChandler Carruth } 1138c0291865SChandler Carruth 1139c321e534SBenjamin Kramer TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(const Triple &T) { 1140c0291865SChandler Carruth std::unique_ptr<TargetLibraryInfoImpl> &Impl = 1141c0291865SChandler Carruth Impls[T.normalize()]; 1142c0291865SChandler Carruth if (!Impl) 1143c0291865SChandler Carruth Impl.reset(new TargetLibraryInfoImpl(T)); 1144c0291865SChandler Carruth 1145c0291865SChandler Carruth return *Impl; 1146c0291865SChandler Carruth } 1147c0291865SChandler Carruth 1148c0291865SChandler Carruth 1149b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() 1150c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) { 1151b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1152b98f63dbSChandler Carruth } 1153b98f63dbSChandler Carruth 1154b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T) 1155c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) { 1156b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1157b98f63dbSChandler Carruth } 1158b98f63dbSChandler Carruth 1159b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 1160c0291865SChandler Carruth const TargetLibraryInfoImpl &TLIImpl) 1161c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) { 1162b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1163b98f63dbSChandler Carruth } 1164b98f63dbSChandler Carruth 1165b4faf13cSChandler Carruth char TargetLibraryAnalysis::PassID; 1166df0cd726SNAKAMURA Takumi 1167b98f63dbSChandler Carruth // Register the basic pass. 1168b98f63dbSChandler Carruth INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", 1169b98f63dbSChandler Carruth "Target Library Information", false, true) 1170b98f63dbSChandler Carruth char TargetLibraryInfoWrapperPass::ID = 0; 1171b98f63dbSChandler Carruth 1172b98f63dbSChandler Carruth void TargetLibraryInfoWrapperPass::anchor() {} 1173