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); 6878fd4f08SNicolai Hahnle } 6978fd4f08SNicolai Hahnle 7062d4215bSChandler Carruth // There are no library implementations of mempcy and memset for AMD gpus and 7162d4215bSChandler Carruth // these can be difficult to lower in the backend. 7262d4215bSChandler Carruth if (T.getArch() == Triple::r600 || 7305532995SDan Gohman T.getArch() == Triple::amdgcn) { 7462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memcpy); 7562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset); 7662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 7762d4215bSChandler Carruth return; 7862d4215bSChandler Carruth } 7962d4215bSChandler Carruth 8062d4215bSChandler Carruth // memset_pattern16 is only available on iOS 3.0 and Mac OS X 10.5 and later. 818b40366bSTim Northover // All versions of watchOS support it. 8262d4215bSChandler Carruth if (T.isMacOSX()) { 8362d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 5)) 8462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 8562d4215bSChandler Carruth } else if (T.isiOS()) { 8662d4215bSChandler Carruth if (T.isOSVersionLT(3, 0)) 8762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 888b40366bSTim Northover } else if (!T.isWatchOS()) { 8962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memset_pattern16); 9062d4215bSChandler Carruth } 9162d4215bSChandler Carruth 9262d4215bSChandler Carruth if (!hasSinCosPiStret(T)) { 9362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpi); 9462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinpif); 9562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospi); 9662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cospif); 9762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospi_stret); 9862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sincospif_stret); 9962d4215bSChandler Carruth } 10062d4215bSChandler Carruth 10162d4215bSChandler Carruth if (T.isMacOSX() && T.getArch() == Triple::x86 && 10262d4215bSChandler Carruth !T.isMacOSXVersionLT(10, 7)) { 10362d4215bSChandler Carruth // x86-32 OSX has a scheme where fwrite and fputs (and some other functions 10462d4215bSChandler Carruth // we don't care about) have two versions; on recent OSX, the one we want 10562d4215bSChandler Carruth // has a $UNIX2003 suffix. The two implementations are identical except 10662d4215bSChandler Carruth // for the return value in some edge cases. However, we don't want to 10762d4215bSChandler Carruth // generate code that depends on the old symbols. 10862d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fwrite, "fwrite$UNIX2003"); 10962d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::fputs, "fputs$UNIX2003"); 11062d4215bSChandler Carruth } 11162d4215bSChandler Carruth 11262d4215bSChandler Carruth // iprintf and friends are only available on XCore and TCE. 11362d4215bSChandler Carruth if (T.getArch() != Triple::xcore && T.getArch() != Triple::tce) { 11462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::iprintf); 11562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::siprintf); 11662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fiprintf); 11762d4215bSChandler Carruth } 11862d4215bSChandler Carruth 11962d4215bSChandler Carruth if (T.isOSWindows() && !T.isOSCygMing()) { 12062d4215bSChandler Carruth // Win32 does not support long double 12162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosl); 12262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinl); 12362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanl); 12462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2l); 12562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceill); 12662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignl); 12762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosl); 12862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshl); 12962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expl); 13062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf 13162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fabsl); 13262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorl); 13362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxl); 13462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminl); 13562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodl); 13662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpl); 13762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpf); 13862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ldexpl); 13962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logl); 14062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::modfl); 14162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powl); 14262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinl); 14362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhl); 14462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtl); 14562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanl); 14662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhl); 14762d4215bSChandler Carruth 14862d4215bSChandler Carruth // Win32 only has C89 math 14962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosh); 15062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshf); 15162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acoshl); 15262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinh); 15362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhf); 15462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinhl); 15562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanh); 15662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhf); 15762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanhl); 15862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrt); 15962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtf); 16062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cbrtl); 16162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2); 16262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2f); 16362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp2l); 16462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1); 16562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1f); 16662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expm1l); 16762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2); 16862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2f); 16962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log2l); 17062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1p); 17162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pf); 17262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::log1pl); 17362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logb); 17462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbf); 17562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logbl); 17662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyint); 17762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintf); 17862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::nearbyintl); 17962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rint); 18062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintf); 18162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rintl); 18262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::round); 18362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundf); 18462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::roundl); 18562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::trunc); 18662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncf); 18762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::truncl); 18862d4215bSChandler Carruth 18962d4215bSChandler Carruth // Win32 provides some C99 math with mangled names 19062d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::copysign, "_copysign"); 19162d4215bSChandler Carruth 19262d4215bSChandler Carruth if (T.getArch() == Triple::x86) { 19362d4215bSChandler Carruth // Win32 on x86 implements single-precision math functions as macros 19462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::acosf); 19562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::asinf); 19662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atanf); 19762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atan2f); 19862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ceilf); 19962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::copysignf); 20062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::cosf); 20162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::coshf); 20262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::expf); 20362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::floorf); 20462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fminf); 20562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmaxf); 20662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fmodf); 20762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::logf); 208*eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::log10f); 209*eac58d8fSDavid Majnemer TLI.setUnavailable(LibFunc::modff); 21062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::powf); 21162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinf); 21262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sinhf); 21362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::sqrtf); 21462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanf); 21562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tanhf); 21662d4215bSChandler Carruth } 21762d4215bSChandler Carruth 21862d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 21962d4215bSChandler Carruth // generally available on POSIX-compliant systems: 22062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::access); 22162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcmp); 22262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bcopy); 22362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::bzero); 22462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chmod); 22562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::chown); 22662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::closedir); 22762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ctermid); 22862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fdopen); 22962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffs); 23062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fileno); 23162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::flockfile); 23262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko); 23362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat); 23462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs); 23562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello); 23662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftrylockfile); 23762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::funlockfile); 23862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getc_unlocked); 23962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getitimer); 24062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getlogin_r); 24162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::getpwnam); 24262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::gettimeofday); 24362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htonl); 24462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::htons); 24562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lchown); 24662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat); 24762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memccpy); 24862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::mkdir); 24962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohl); 25062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ntohs); 25162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open); 25262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::opendir); 25362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pclose); 25462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::popen); 25562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pread); 25662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::pwrite); 25762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::read); 25862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::readlink); 25962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::realpath); 26062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::rmdir); 26162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::setitimer); 26262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat); 26362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs); 26462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpcpy); 26562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stpncpy); 26662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strcasecmp); 26762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::strncasecmp); 26862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::times); 26962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::uname); 27062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unlink); 27162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::unsetenv); 27262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utime); 27362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::utimes); 27462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::write); 27562d4215bSChandler Carruth 27662d4215bSChandler Carruth // Win32 does *not* provide provide these functions, but they are 27762d4215bSChandler Carruth // specified by C99: 27862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::atoll); 27962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::frexpf); 28062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::llabs); 28162d4215bSChandler Carruth } 28262d4215bSChandler Carruth 28362d4215bSChandler Carruth switch (T.getOS()) { 28462d4215bSChandler Carruth case Triple::MacOSX: 28562d4215bSChandler Carruth // exp10 and exp10f are not available on OS X until 10.9 and iOS until 7.0 28662d4215bSChandler Carruth // and their names are __exp10 and __exp10f. exp10l is not available on 28762d4215bSChandler Carruth // OS X or iOS. 28862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 28962d4215bSChandler Carruth if (T.isMacOSXVersionLT(10, 9)) { 29062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 29162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 29262d4215bSChandler Carruth } else { 29362d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 29462d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 29562d4215bSChandler Carruth } 29662d4215bSChandler Carruth break; 29762d4215bSChandler Carruth case Triple::IOS: 29889a6eefeSTim Northover case Triple::TvOS: 2998b40366bSTim Northover case Triple::WatchOS: 30062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 3018b40366bSTim Northover if (!T.isWatchOS() && (T.isOSVersionLT(7, 0) || 3028b40366bSTim Northover (T.isOSVersionLT(9, 0) && 3038b40366bSTim Northover (T.getArch() == Triple::x86 || 3048b40366bSTim Northover T.getArch() == Triple::x86_64)))) { 30562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 30662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 30762d4215bSChandler Carruth } else { 30862d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10, "__exp10"); 30962d4215bSChandler Carruth TLI.setAvailableWithName(LibFunc::exp10f, "__exp10f"); 31062d4215bSChandler Carruth } 31162d4215bSChandler Carruth break; 31262d4215bSChandler Carruth case Triple::Linux: 31362d4215bSChandler Carruth // exp10, exp10f, exp10l is available on Linux (GLIBC) but are extremely 31462d4215bSChandler Carruth // buggy prior to glibc version 2.18. Until this version is widely deployed 31562d4215bSChandler Carruth // or we have a reasonable detection strategy, we cannot use exp10 reliably 31662d4215bSChandler Carruth // on Linux. 31762d4215bSChandler Carruth // 31862d4215bSChandler Carruth // Fall through to disable all of them. 31962d4215bSChandler Carruth default: 32062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10); 32162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10f); 32262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::exp10l); 32362d4215bSChandler Carruth } 32462d4215bSChandler Carruth 32562d4215bSChandler Carruth // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and 32662d4215bSChandler Carruth // Linux (GLIBC): 32762d4215bSChandler Carruth // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html 32883b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsl.c 32962d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html 33062d4215bSChandler Carruth switch (T.getOS()) { 33162d4215bSChandler Carruth case Triple::Darwin: 33262d4215bSChandler Carruth case Triple::MacOSX: 33362d4215bSChandler Carruth case Triple::IOS: 33489a6eefeSTim Northover case Triple::TvOS: 3358b40366bSTim Northover case Triple::WatchOS: 33662d4215bSChandler Carruth case Triple::FreeBSD: 33762d4215bSChandler Carruth case Triple::Linux: 33862d4215bSChandler Carruth break; 33962d4215bSChandler Carruth default: 34062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsl); 34162d4215bSChandler Carruth } 34262d4215bSChandler Carruth 34362d4215bSChandler Carruth // ffsll is available on at least FreeBSD and Linux (GLIBC): 34483b34816SDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/ffsll.c 34562d4215bSChandler Carruth // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html 34662d4215bSChandler Carruth switch (T.getOS()) { 34789a6eefeSTim Northover case Triple::Darwin: 34889a6eefeSTim Northover case Triple::MacOSX: 34989a6eefeSTim Northover case Triple::IOS: 35089a6eefeSTim Northover case Triple::TvOS: 35189a6eefeSTim Northover case Triple::WatchOS: 35262d4215bSChandler Carruth case Triple::FreeBSD: 35362d4215bSChandler Carruth case Triple::Linux: 35462d4215bSChandler Carruth break; 35562d4215bSChandler Carruth default: 35662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ffsll); 35762d4215bSChandler Carruth } 35862d4215bSChandler Carruth 359bfd3082eSDavide Italiano // The following functions are available on at least FreeBSD: 360bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/fls.c 361bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsl.c 362bfd3082eSDavide Italiano // http://svn.freebsd.org/base/head/lib/libc/string/flsll.c 363bfd3082eSDavide Italiano if (!T.isOSFreeBSD()) { 364bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::fls); 365bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsl); 366bfd3082eSDavide Italiano TLI.setUnavailable(LibFunc::flsll); 367bfd3082eSDavide Italiano } 368bfd3082eSDavide Italiano 36962d4215bSChandler Carruth // The following functions are available on at least Linux: 37062d4215bSChandler Carruth if (!T.isOSLinux()) { 37162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strdup); 37262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_strtok_r); 37362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_scanf); 37462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::dunder_isoc99_sscanf); 37562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_getc); 37662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::under_IO_putc); 37762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::memalign); 37862d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fopen64); 37962d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fseeko64); 38062d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstat64); 38162d4215bSChandler Carruth TLI.setUnavailable(LibFunc::fstatvfs64); 38262d4215bSChandler Carruth TLI.setUnavailable(LibFunc::ftello64); 38362d4215bSChandler Carruth TLI.setUnavailable(LibFunc::lstat64); 38462d4215bSChandler Carruth TLI.setUnavailable(LibFunc::open64); 38562d4215bSChandler Carruth TLI.setUnavailable(LibFunc::stat64); 38662d4215bSChandler Carruth TLI.setUnavailable(LibFunc::statvfs64); 38762d4215bSChandler Carruth TLI.setUnavailable(LibFunc::tmpfile64); 38862d4215bSChandler Carruth } 3896d8a2aa9SMichael Zolotukhin 39051132881SJustin Lebar // As currently implemented in clang, NVPTX code has no standard library to 39151132881SJustin Lebar // speak of. Headers provide a standard-ish library implementation, but many 39251132881SJustin Lebar // of the signatures are wrong -- for example, many libm functions are not 39351132881SJustin Lebar // extern "C". 39451132881SJustin Lebar // 39551132881SJustin Lebar // libdevice, an IR library provided by nvidia, is linked in by the front-end, 39651132881SJustin Lebar // but only used functions are provided to llvm. Moreover, most of the 39751132881SJustin Lebar // functions in libdevice don't map precisely to standard library functions. 39851132881SJustin Lebar // 39951132881SJustin Lebar // FIXME: Having no standard library prevents e.g. many fastmath 40051132881SJustin Lebar // optimizations, so this situation should be fixed. 401ae272d71SDavid Majnemer if (T.isNVPTX()) { 40251132881SJustin Lebar TLI.disableAllFunctions(); 403ae272d71SDavid Majnemer TLI.setAvailable(LibFunc::nvvm_reflect); 404ae272d71SDavid Majnemer } else { 405ae272d71SDavid Majnemer TLI.setUnavailable(LibFunc::nvvm_reflect); 406ae272d71SDavid Majnemer } 40751132881SJustin Lebar 4086d8a2aa9SMichael Zolotukhin TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); 40962d4215bSChandler Carruth } 41062d4215bSChandler Carruth 411c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl() { 41262d4215bSChandler Carruth // Default to everything being available. 41362d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 41462d4215bSChandler Carruth 41562d4215bSChandler Carruth initialize(*this, Triple(), StandardNames); 41662d4215bSChandler Carruth } 41762d4215bSChandler Carruth 418c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { 41962d4215bSChandler Carruth // Default to everything being available. 42062d4215bSChandler Carruth memset(AvailableArray, -1, sizeof(AvailableArray)); 42162d4215bSChandler Carruth 42262d4215bSChandler Carruth initialize(*this, T, StandardNames); 42362d4215bSChandler Carruth } 42462d4215bSChandler Carruth 425c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) 4268ca43224SChandler Carruth : CustomNames(TLI.CustomNames) { 42762d4215bSChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 428e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 429e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4308ca43224SChandler Carruth } 4318ca43224SChandler Carruth 432c0291865SChandler Carruth TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) 4338ca43224SChandler Carruth : CustomNames(std::move(TLI.CustomNames)) { 4348ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4358ca43224SChandler Carruth AvailableArray); 436e8f2551fSMichael Zolotukhin VectorDescs = TLI.VectorDescs; 437e8f2551fSMichael Zolotukhin ScalarDescs = TLI.ScalarDescs; 4388ca43224SChandler Carruth } 4398ca43224SChandler Carruth 440c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { 44162d4215bSChandler Carruth CustomNames = TLI.CustomNames; 4428ca43224SChandler Carruth memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); 4438ca43224SChandler Carruth return *this; 4448ca43224SChandler Carruth } 4458ca43224SChandler Carruth 446c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { 4478ca43224SChandler Carruth CustomNames = std::move(TLI.CustomNames); 4488ca43224SChandler Carruth std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), 4498ca43224SChandler Carruth AvailableArray); 4508ca43224SChandler Carruth return *this; 45162d4215bSChandler Carruth } 45262d4215bSChandler Carruth 45321abdf98SMichael Zolotukhin static StringRef sanitizeFunctionName(StringRef funcName) { 45462d4215bSChandler Carruth // Filter out empty names and names containing null bytes, those can't be in 45562d4215bSChandler Carruth // our table. 45662d4215bSChandler Carruth if (funcName.empty() || funcName.find('\0') != StringRef::npos) 45721abdf98SMichael Zolotukhin return StringRef(); 45862d4215bSChandler Carruth 45962d4215bSChandler Carruth // Check for \01 prefix that is used to mangle __asm declarations and 46062d4215bSChandler Carruth // strip it if present. 461cde33036SDavid Majnemer return GlobalValue::getRealLinkageName(funcName); 46221abdf98SMichael Zolotukhin } 46321abdf98SMichael Zolotukhin 46421abdf98SMichael Zolotukhin bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, 46521abdf98SMichael Zolotukhin LibFunc::Func &F) const { 46657a3d084SBenjamin Kramer const char *const *Start = &StandardNames[0]; 46757a3d084SBenjamin Kramer const char *const *End = &StandardNames[LibFunc::NumLibFuncs]; 46821abdf98SMichael Zolotukhin 46921abdf98SMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 47021abdf98SMichael Zolotukhin if (funcName.empty()) 47121abdf98SMichael Zolotukhin return false; 47221abdf98SMichael Zolotukhin 47357a3d084SBenjamin Kramer const char *const *I = std::lower_bound( 474d3b76a3bSMichael Zolotukhin Start, End, funcName, [](const char *LHS, StringRef RHS) { 475d3b76a3bSMichael Zolotukhin return std::strncmp(LHS, RHS.data(), RHS.size()) < 0; 476d3b76a3bSMichael Zolotukhin }); 47762d4215bSChandler Carruth if (I != End && *I == funcName) { 47862d4215bSChandler Carruth F = (LibFunc::Func)(I - Start); 47962d4215bSChandler Carruth return true; 48062d4215bSChandler Carruth } 48162d4215bSChandler Carruth return false; 48262d4215bSChandler Carruth } 48362d4215bSChandler Carruth 484d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, 485d765a82bSAhmed Bougacha LibFunc::Func F, 486d765a82bSAhmed Bougacha const DataLayout *DL) const { 487d765a82bSAhmed Bougacha LLVMContext &Ctx = FTy.getContext(); 488d765a82bSAhmed Bougacha Type *PCharTy = Type::getInt8PtrTy(Ctx); 489d765a82bSAhmed Bougacha Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AS=*/0) : nullptr; 490d765a82bSAhmed Bougacha auto IsSizeTTy = [SizeTTy](Type *Ty) { 491d765a82bSAhmed Bougacha return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy(); 492d765a82bSAhmed Bougacha }; 493d765a82bSAhmed Bougacha unsigned NumParams = FTy.getNumParams(); 494d765a82bSAhmed Bougacha 495d765a82bSAhmed Bougacha switch (F) { 496d765a82bSAhmed Bougacha case LibFunc::strlen: 497d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && 498d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 499d765a82bSAhmed Bougacha 500d765a82bSAhmed Bougacha case LibFunc::strchr: 501d765a82bSAhmed Bougacha case LibFunc::strrchr: 502d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 503d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 504d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy()); 505d765a82bSAhmed Bougacha 506d765a82bSAhmed Bougacha case LibFunc::strtol: 507d765a82bSAhmed Bougacha case LibFunc::strtod: 508d765a82bSAhmed Bougacha case LibFunc::strtof: 509d765a82bSAhmed Bougacha case LibFunc::strtoul: 510d765a82bSAhmed Bougacha case LibFunc::strtoll: 511d765a82bSAhmed Bougacha case LibFunc::strtold: 512d765a82bSAhmed Bougacha case LibFunc::strtoull: 513d765a82bSAhmed Bougacha return ((NumParams == 2 || NumParams == 3) && 514d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 515d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 516d765a82bSAhmed Bougacha case LibFunc::strcat: 517d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 518d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 519d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType()); 520d765a82bSAhmed Bougacha 521d765a82bSAhmed Bougacha case LibFunc::strncat: 522d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && 523d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getReturnType() && 524d765a82bSAhmed Bougacha FTy.getParamType(1) == FTy.getReturnType() && 525d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 526d765a82bSAhmed Bougacha 527d765a82bSAhmed Bougacha case LibFunc::strcpy_chk: 528d765a82bSAhmed Bougacha case LibFunc::stpcpy_chk: 529d765a82bSAhmed Bougacha --NumParams; 530d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 531d765a82bSAhmed Bougacha return false; 532d765a82bSAhmed Bougacha // fallthrough 533d765a82bSAhmed Bougacha case LibFunc::strcpy: 534d765a82bSAhmed Bougacha case LibFunc::stpcpy: 535d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && 536d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 537d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy); 538d765a82bSAhmed Bougacha 539d765a82bSAhmed Bougacha case LibFunc::strncpy_chk: 540d765a82bSAhmed Bougacha case LibFunc::stpncpy_chk: 541d765a82bSAhmed Bougacha --NumParams; 542d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 543d765a82bSAhmed Bougacha return false; 544d765a82bSAhmed Bougacha // fallthrough 545d765a82bSAhmed Bougacha case LibFunc::strncpy: 546d765a82bSAhmed Bougacha case LibFunc::stpncpy: 547d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 548d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 549d765a82bSAhmed Bougacha FTy.getParamType(0) == PCharTy && 550d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 551d765a82bSAhmed Bougacha 552d765a82bSAhmed Bougacha case LibFunc::strxfrm: 553d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 554d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 555d765a82bSAhmed Bougacha 556d765a82bSAhmed Bougacha case LibFunc::strcmp: 557d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && 558d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 559d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 560d765a82bSAhmed Bougacha 561d765a82bSAhmed Bougacha case LibFunc::strncmp: 562d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && 563d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 564d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 565d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy()); 566d765a82bSAhmed Bougacha 567d765a82bSAhmed Bougacha case LibFunc::strspn: 568d765a82bSAhmed Bougacha case LibFunc::strcspn: 569d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 570d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1) && 571d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy()); 572d765a82bSAhmed Bougacha 573d765a82bSAhmed Bougacha case LibFunc::strcoll: 574d765a82bSAhmed Bougacha case LibFunc::strcasecmp: 575d765a82bSAhmed Bougacha case LibFunc::strncasecmp: 576d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 577d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 578d765a82bSAhmed Bougacha 579d765a82bSAhmed Bougacha case LibFunc::strstr: 580d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 581d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 582d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 583d765a82bSAhmed Bougacha 584d765a82bSAhmed Bougacha case LibFunc::strpbrk: 585d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 586d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 587d765a82bSAhmed Bougacha FTy.getParamType(0) == FTy.getParamType(1)); 588d765a82bSAhmed Bougacha 589d765a82bSAhmed Bougacha case LibFunc::strtok: 590d765a82bSAhmed Bougacha case LibFunc::strtok_r: 591d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 592d765a82bSAhmed Bougacha case LibFunc::scanf: 593d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 594d765a82bSAhmed Bougacha case LibFunc::setbuf: 595d765a82bSAhmed Bougacha case LibFunc::setvbuf: 596d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 597d765a82bSAhmed Bougacha case LibFunc::strdup: 598d765a82bSAhmed Bougacha case LibFunc::strndup: 599d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 600d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 601d765a82bSAhmed Bougacha case LibFunc::stat: 602d765a82bSAhmed Bougacha case LibFunc::statvfs: 603d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 604d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 605d765a82bSAhmed Bougacha case LibFunc::sscanf: 606d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 607d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 608d765a82bSAhmed Bougacha case LibFunc::sprintf: 609d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 610d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 611d765a82bSAhmed Bougacha case LibFunc::snprintf: 612d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 613d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 614d765a82bSAhmed Bougacha case LibFunc::setitimer: 615d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 616d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 617d765a82bSAhmed Bougacha case LibFunc::system: 618d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 619d765a82bSAhmed Bougacha case LibFunc::malloc: 620d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); 621d765a82bSAhmed Bougacha case LibFunc::memcmp: 622d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 623d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 624d765a82bSAhmed Bougacha FTy.getReturnType()->isIntegerTy(32)); 625d765a82bSAhmed Bougacha 626d765a82bSAhmed Bougacha case LibFunc::memchr: 627d765a82bSAhmed Bougacha case LibFunc::memrchr: 628d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 629d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy(32) && 630d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 631d765a82bSAhmed Bougacha FTy.getReturnType()->isPointerTy()); 632d765a82bSAhmed Bougacha case LibFunc::modf: 633d765a82bSAhmed Bougacha case LibFunc::modff: 634d765a82bSAhmed Bougacha case LibFunc::modfl: 635d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 636d765a82bSAhmed Bougacha 637d765a82bSAhmed Bougacha case LibFunc::memcpy_chk: 638d765a82bSAhmed Bougacha case LibFunc::memmove_chk: 639d765a82bSAhmed Bougacha --NumParams; 640d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 641d765a82bSAhmed Bougacha return false; 642d765a82bSAhmed Bougacha // fallthrough 643d765a82bSAhmed Bougacha case LibFunc::memcpy: 644d765a82bSAhmed Bougacha case LibFunc::memmove: 645d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 646d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 647d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 648d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 649d765a82bSAhmed Bougacha 650d765a82bSAhmed Bougacha case LibFunc::memset_chk: 651d765a82bSAhmed Bougacha --NumParams; 652d765a82bSAhmed Bougacha if (!IsSizeTTy(FTy.getParamType(NumParams))) 653d765a82bSAhmed Bougacha return false; 654d765a82bSAhmed Bougacha // fallthrough 655d765a82bSAhmed Bougacha case LibFunc::memset: 656d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && 657d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 658d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 659d765a82bSAhmed Bougacha IsSizeTTy(FTy.getParamType(2))); 660d765a82bSAhmed Bougacha 661d765a82bSAhmed Bougacha case LibFunc::memccpy: 662d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); 663d765a82bSAhmed Bougacha case LibFunc::memalign: 664d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 665d765a82bSAhmed Bougacha case LibFunc::mkdir: 666d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 667d765a82bSAhmed Bougacha case LibFunc::mktime: 668d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->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 return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 676d765a82bSAhmed Bougacha case LibFunc::rmdir: 677d765a82bSAhmed Bougacha case LibFunc::remove: 678d765a82bSAhmed Bougacha case LibFunc::realpath: 679d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 680d765a82bSAhmed Bougacha case LibFunc::rename: 681d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 682d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 683d765a82bSAhmed Bougacha case LibFunc::readlink: 684d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 685d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 686d765a82bSAhmed Bougacha case LibFunc::write: 687d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 688d765a82bSAhmed Bougacha case LibFunc::bcopy: 689d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 690d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 691d765a82bSAhmed Bougacha case LibFunc::bcmp: 692d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 693d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 694d765a82bSAhmed Bougacha case LibFunc::bzero: 695d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 696d765a82bSAhmed Bougacha case LibFunc::calloc: 697d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); 698d765a82bSAhmed Bougacha case LibFunc::chmod: 699d765a82bSAhmed Bougacha case LibFunc::chown: 700d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 701d765a82bSAhmed Bougacha case LibFunc::ctermid: 702d765a82bSAhmed Bougacha case LibFunc::clearerr: 703d765a82bSAhmed Bougacha case LibFunc::closedir: 704d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 705d765a82bSAhmed Bougacha case LibFunc::atoi: 706d765a82bSAhmed Bougacha case LibFunc::atol: 707d765a82bSAhmed Bougacha case LibFunc::atof: 708d765a82bSAhmed Bougacha case LibFunc::atoll: 709d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 710d765a82bSAhmed Bougacha case LibFunc::access: 711d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 712d765a82bSAhmed Bougacha case LibFunc::fopen: 713d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 714d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 715d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 716d765a82bSAhmed Bougacha case LibFunc::fdopen: 717d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 718d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 719d765a82bSAhmed Bougacha case LibFunc::feof: 720d765a82bSAhmed Bougacha case LibFunc::free: 721d765a82bSAhmed Bougacha case LibFunc::fseek: 722d765a82bSAhmed Bougacha case LibFunc::ftell: 723d765a82bSAhmed Bougacha case LibFunc::fgetc: 724d765a82bSAhmed Bougacha case LibFunc::fseeko: 725d765a82bSAhmed Bougacha case LibFunc::ftello: 726d765a82bSAhmed Bougacha case LibFunc::fileno: 727d765a82bSAhmed Bougacha case LibFunc::fflush: 728d765a82bSAhmed Bougacha case LibFunc::fclose: 729d765a82bSAhmed Bougacha case LibFunc::fsetpos: 730d765a82bSAhmed Bougacha case LibFunc::flockfile: 731d765a82bSAhmed Bougacha case LibFunc::funlockfile: 732d765a82bSAhmed Bougacha case LibFunc::ftrylockfile: 733d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 734d765a82bSAhmed Bougacha case LibFunc::ferror: 735d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 736d765a82bSAhmed Bougacha case LibFunc::fputc: 737d765a82bSAhmed Bougacha case LibFunc::fstat: 738d765a82bSAhmed Bougacha case LibFunc::frexp: 739d765a82bSAhmed Bougacha case LibFunc::frexpf: 740d765a82bSAhmed Bougacha case LibFunc::frexpl: 741d765a82bSAhmed Bougacha case LibFunc::fstatvfs: 742d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 743d765a82bSAhmed Bougacha case LibFunc::fgets: 744d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 745d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 746d765a82bSAhmed Bougacha case LibFunc::fread: 747d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 748d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 749d765a82bSAhmed Bougacha case LibFunc::fwrite: 750d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && 751d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 752d765a82bSAhmed Bougacha FTy.getParamType(1)->isIntegerTy() && 753d765a82bSAhmed Bougacha FTy.getParamType(2)->isIntegerTy() && 754d765a82bSAhmed Bougacha FTy.getParamType(3)->isPointerTy()); 755d765a82bSAhmed Bougacha case LibFunc::fputs: 756d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 757d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 758d765a82bSAhmed Bougacha case LibFunc::fscanf: 759d765a82bSAhmed Bougacha case LibFunc::fprintf: 760d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 761d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 762d765a82bSAhmed Bougacha case LibFunc::fgetpos: 763d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && 764d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 765d765a82bSAhmed Bougacha case LibFunc::getc: 766d765a82bSAhmed Bougacha case LibFunc::getlogin_r: 767d765a82bSAhmed Bougacha case LibFunc::getc_unlocked: 768d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 769d765a82bSAhmed Bougacha case LibFunc::getenv: 770d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 771d765a82bSAhmed Bougacha case LibFunc::gets: 772d765a82bSAhmed Bougacha case LibFunc::getchar: 773d765a82bSAhmed Bougacha case LibFunc::getitimer: 774d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 775d765a82bSAhmed Bougacha case LibFunc::getpwnam: 776d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 777d765a82bSAhmed Bougacha case LibFunc::ungetc: 778d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 779d765a82bSAhmed Bougacha case LibFunc::uname: 780d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 781d765a82bSAhmed Bougacha case LibFunc::unlink: 782d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 783d765a82bSAhmed Bougacha case LibFunc::unsetenv: 784d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 785d765a82bSAhmed Bougacha case LibFunc::utime: 786d765a82bSAhmed Bougacha case LibFunc::utimes: 787d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 788d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 789d765a82bSAhmed Bougacha case LibFunc::putc: 790d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 791d765a82bSAhmed Bougacha case LibFunc::puts: 792d765a82bSAhmed Bougacha case LibFunc::printf: 793d765a82bSAhmed Bougacha case LibFunc::perror: 794d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 795d765a82bSAhmed Bougacha case LibFunc::pread: 796d765a82bSAhmed Bougacha case LibFunc::pwrite: 797d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); 798d765a82bSAhmed Bougacha case LibFunc::putchar: 799d765a82bSAhmed Bougacha case LibFunc::popen: 800d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 801d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 802d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 803d765a82bSAhmed Bougacha case LibFunc::pclose: 804d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 805d765a82bSAhmed Bougacha case LibFunc::vscanf: 806d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 807d765a82bSAhmed Bougacha case LibFunc::vsscanf: 808d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 809d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 810d765a82bSAhmed Bougacha case LibFunc::vfscanf: 811d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && 812d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 813d765a82bSAhmed Bougacha case LibFunc::valloc: 814d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 815d765a82bSAhmed Bougacha case LibFunc::vprintf: 816d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); 817d765a82bSAhmed Bougacha case LibFunc::vfprintf: 818d765a82bSAhmed Bougacha case LibFunc::vsprintf: 819d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && 820d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 821d765a82bSAhmed Bougacha case LibFunc::vsnprintf: 822d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && 823d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 824d765a82bSAhmed Bougacha case LibFunc::open: 825d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 826d765a82bSAhmed Bougacha case LibFunc::opendir: 827d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && 828d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 829d765a82bSAhmed Bougacha case LibFunc::tmpfile: 830d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 831d765a82bSAhmed Bougacha case LibFunc::times: 832d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 833d765a82bSAhmed Bougacha case LibFunc::htonl: 834d765a82bSAhmed Bougacha case LibFunc::htons: 835d765a82bSAhmed Bougacha case LibFunc::ntohl: 836d765a82bSAhmed Bougacha case LibFunc::ntohs: 837d765a82bSAhmed Bougacha case LibFunc::lstat: 838d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 839d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 840d765a82bSAhmed Bougacha case LibFunc::lchown: 841d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); 842d765a82bSAhmed Bougacha case LibFunc::qsort: 843d765a82bSAhmed Bougacha return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); 844d765a82bSAhmed Bougacha case LibFunc::dunder_strdup: 845d765a82bSAhmed Bougacha case LibFunc::dunder_strndup: 846d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && 847d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy()); 848d765a82bSAhmed Bougacha case LibFunc::dunder_strtok_r: 849d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); 850d765a82bSAhmed Bougacha case LibFunc::under_IO_getc: 851d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); 852d765a82bSAhmed Bougacha case LibFunc::under_IO_putc: 853d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 854d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_scanf: 855d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); 856d765a82bSAhmed Bougacha case LibFunc::stat64: 857d765a82bSAhmed Bougacha case LibFunc::lstat64: 858d765a82bSAhmed Bougacha case LibFunc::statvfs64: 859d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && 860d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 861d765a82bSAhmed Bougacha case LibFunc::dunder_isoc99_sscanf: 862d765a82bSAhmed Bougacha return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && 863d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 864d765a82bSAhmed Bougacha case LibFunc::fopen64: 865d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && 866d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 867d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 868d765a82bSAhmed Bougacha case LibFunc::fseeko64: 869d765a82bSAhmed Bougacha case LibFunc::ftello64: 870d765a82bSAhmed Bougacha return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); 871d765a82bSAhmed Bougacha case LibFunc::tmpfile64: 872d765a82bSAhmed Bougacha return (FTy.getReturnType()->isPointerTy()); 873d765a82bSAhmed Bougacha case LibFunc::fstat64: 874d765a82bSAhmed Bougacha case LibFunc::fstatvfs64: 875d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); 876d765a82bSAhmed Bougacha case LibFunc::open64: 877d765a82bSAhmed Bougacha return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); 878d765a82bSAhmed Bougacha case LibFunc::gettimeofday: 879d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && 880d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy()); 881d765a82bSAhmed Bougacha 882d765a82bSAhmed Bougacha case LibFunc::Znwj: // new(unsigned int); 883d765a82bSAhmed Bougacha case LibFunc::Znwm: // new(unsigned long); 884d765a82bSAhmed Bougacha case LibFunc::Znaj: // new[](unsigned int); 885d765a82bSAhmed Bougacha case LibFunc::Znam: // new[](unsigned long); 886d765a82bSAhmed Bougacha case LibFunc::msvc_new_int: // new(unsigned int); 887d765a82bSAhmed Bougacha case LibFunc::msvc_new_longlong: // new(unsigned long long); 888d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_int: // new[](unsigned int); 889d765a82bSAhmed Bougacha case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); 890d765a82bSAhmed Bougacha return (NumParams == 1); 891d765a82bSAhmed Bougacha 892d765a82bSAhmed Bougacha case LibFunc::memset_pattern16: 893d765a82bSAhmed Bougacha return (!FTy.isVarArg() && NumParams == 3 && 894d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(0)) && 895d765a82bSAhmed Bougacha isa<PointerType>(FTy.getParamType(1)) && 896d765a82bSAhmed Bougacha isa<IntegerType>(FTy.getParamType(2))); 897d765a82bSAhmed Bougacha 898d765a82bSAhmed Bougacha // int __nvvm_reflect(const char *); 899d765a82bSAhmed Bougacha case LibFunc::nvvm_reflect: 900d765a82bSAhmed Bougacha return (NumParams == 1 && isa<PointerType>(FTy.getParamType(0))); 901d765a82bSAhmed Bougacha 902d765a82bSAhmed Bougacha case LibFunc::sin: 903d765a82bSAhmed Bougacha case LibFunc::sinf: 904d765a82bSAhmed Bougacha case LibFunc::sinl: 905d765a82bSAhmed Bougacha case LibFunc::cos: 906d765a82bSAhmed Bougacha case LibFunc::cosf: 907d765a82bSAhmed Bougacha case LibFunc::cosl: 908d765a82bSAhmed Bougacha case LibFunc::exp: 909d765a82bSAhmed Bougacha case LibFunc::expf: 910d765a82bSAhmed Bougacha case LibFunc::expl: 911d765a82bSAhmed Bougacha case LibFunc::exp2: 912d765a82bSAhmed Bougacha case LibFunc::exp2f: 913d765a82bSAhmed Bougacha case LibFunc::exp2l: 914d765a82bSAhmed Bougacha case LibFunc::log: 915d765a82bSAhmed Bougacha case LibFunc::logf: 916d765a82bSAhmed Bougacha case LibFunc::logl: 917d765a82bSAhmed Bougacha case LibFunc::log10: 918d765a82bSAhmed Bougacha case LibFunc::log10f: 919d765a82bSAhmed Bougacha case LibFunc::log10l: 920d765a82bSAhmed Bougacha case LibFunc::log2: 921d765a82bSAhmed Bougacha case LibFunc::log2f: 922d765a82bSAhmed Bougacha case LibFunc::log2l: 923d765a82bSAhmed Bougacha case LibFunc::fabs: 924d765a82bSAhmed Bougacha case LibFunc::fabsf: 925d765a82bSAhmed Bougacha case LibFunc::fabsl: 926d765a82bSAhmed Bougacha case LibFunc::floor: 927d765a82bSAhmed Bougacha case LibFunc::floorf: 928d765a82bSAhmed Bougacha case LibFunc::floorl: 929d765a82bSAhmed Bougacha case LibFunc::ceil: 930d765a82bSAhmed Bougacha case LibFunc::ceilf: 931d765a82bSAhmed Bougacha case LibFunc::ceill: 932d765a82bSAhmed Bougacha case LibFunc::trunc: 933d765a82bSAhmed Bougacha case LibFunc::truncf: 934d765a82bSAhmed Bougacha case LibFunc::truncl: 935d765a82bSAhmed Bougacha case LibFunc::rint: 936d765a82bSAhmed Bougacha case LibFunc::rintf: 937d765a82bSAhmed Bougacha case LibFunc::rintl: 938d765a82bSAhmed Bougacha case LibFunc::nearbyint: 939d765a82bSAhmed Bougacha case LibFunc::nearbyintf: 940d765a82bSAhmed Bougacha case LibFunc::nearbyintl: 941d765a82bSAhmed Bougacha case LibFunc::round: 942d765a82bSAhmed Bougacha case LibFunc::roundf: 943d765a82bSAhmed Bougacha case LibFunc::roundl: 944d765a82bSAhmed Bougacha case LibFunc::sqrt: 945d765a82bSAhmed Bougacha case LibFunc::sqrtf: 946d765a82bSAhmed Bougacha case LibFunc::sqrtl: 947d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && 948d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 949d765a82bSAhmed Bougacha 950d765a82bSAhmed Bougacha case LibFunc::fmin: 951d765a82bSAhmed Bougacha case LibFunc::fminf: 952d765a82bSAhmed Bougacha case LibFunc::fminl: 953d765a82bSAhmed Bougacha case LibFunc::fmax: 954d765a82bSAhmed Bougacha case LibFunc::fmaxf: 955d765a82bSAhmed Bougacha case LibFunc::fmaxl: 956d765a82bSAhmed Bougacha case LibFunc::copysign: 957d765a82bSAhmed Bougacha case LibFunc::copysignf: 958d765a82bSAhmed Bougacha case LibFunc::copysignl: 959d765a82bSAhmed Bougacha case LibFunc::pow: 960d765a82bSAhmed Bougacha case LibFunc::powf: 961d765a82bSAhmed Bougacha case LibFunc::powl: 962d765a82bSAhmed Bougacha return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && 963d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0) && 964d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(1)); 965d765a82bSAhmed Bougacha 966d765a82bSAhmed Bougacha case LibFunc::ffs: 967d765a82bSAhmed Bougacha case LibFunc::ffsl: 968d765a82bSAhmed Bougacha case LibFunc::ffsll: 969d765a82bSAhmed Bougacha case LibFunc::isdigit: 970d765a82bSAhmed Bougacha case LibFunc::isascii: 971d765a82bSAhmed Bougacha case LibFunc::toascii: 972d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && 973d765a82bSAhmed Bougacha FTy.getParamType(0)->isIntegerTy()); 974d765a82bSAhmed Bougacha 975d765a82bSAhmed Bougacha case LibFunc::fls: 976d765a82bSAhmed Bougacha case LibFunc::flsl: 977d765a82bSAhmed Bougacha case LibFunc::flsll: 978d765a82bSAhmed Bougacha case LibFunc::abs: 979d765a82bSAhmed Bougacha case LibFunc::labs: 980d765a82bSAhmed Bougacha case LibFunc::llabs: 981d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && 982d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 983d765a82bSAhmed Bougacha 984d765a82bSAhmed Bougacha case LibFunc::cxa_atexit: 985d765a82bSAhmed Bougacha return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && 986d765a82bSAhmed Bougacha FTy.getParamType(0)->isPointerTy() && 987d765a82bSAhmed Bougacha FTy.getParamType(1)->isPointerTy() && 988d765a82bSAhmed Bougacha FTy.getParamType(2)->isPointerTy()); 989d765a82bSAhmed Bougacha 990d765a82bSAhmed Bougacha case LibFunc::sinpi: 991d765a82bSAhmed Bougacha case LibFunc::cospi: 992d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && 993d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 994d765a82bSAhmed Bougacha 995d765a82bSAhmed Bougacha case LibFunc::sinpif: 996d765a82bSAhmed Bougacha case LibFunc::cospif: 997d765a82bSAhmed Bougacha return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && 998d765a82bSAhmed Bougacha FTy.getReturnType() == FTy.getParamType(0)); 999d765a82bSAhmed Bougacha 1000d765a82bSAhmed Bougacha default: 1001d765a82bSAhmed Bougacha // Assume the other functions are correct. 1002d765a82bSAhmed Bougacha // FIXME: It'd be really nice to cover them all. 1003d765a82bSAhmed Bougacha return true; 1004d765a82bSAhmed Bougacha } 1005d765a82bSAhmed Bougacha } 1006d765a82bSAhmed Bougacha 1007d765a82bSAhmed Bougacha bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, 1008d765a82bSAhmed Bougacha LibFunc::Func &F) const { 1009d765a82bSAhmed Bougacha const DataLayout *DL = 1010d765a82bSAhmed Bougacha FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; 1011d765a82bSAhmed Bougacha return getLibFunc(FDecl.getName(), F) && 1012d765a82bSAhmed Bougacha isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL); 1013d765a82bSAhmed Bougacha } 1014d765a82bSAhmed Bougacha 1015c0291865SChandler Carruth void TargetLibraryInfoImpl::disableAllFunctions() { 101662d4215bSChandler Carruth memset(AvailableArray, 0, sizeof(AvailableArray)); 101762d4215bSChandler Carruth } 1018b98f63dbSChandler Carruth 1019e8f2551fSMichael Zolotukhin static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) { 1020e8f2551fSMichael Zolotukhin return std::strncmp(LHS.ScalarFnName, RHS.ScalarFnName, 1021e8f2551fSMichael Zolotukhin std::strlen(RHS.ScalarFnName)) < 0; 1022e8f2551fSMichael Zolotukhin } 1023e8f2551fSMichael Zolotukhin 1024e8f2551fSMichael Zolotukhin static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) { 1025e8f2551fSMichael Zolotukhin return std::strncmp(LHS.VectorFnName, RHS.VectorFnName, 1026e8f2551fSMichael Zolotukhin std::strlen(RHS.VectorFnName)) < 0; 1027e8f2551fSMichael Zolotukhin } 1028e8f2551fSMichael Zolotukhin 1029e8f2551fSMichael Zolotukhin static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) { 1030e8f2551fSMichael Zolotukhin return std::strncmp(LHS.ScalarFnName, S.data(), S.size()) < 0; 1031e8f2551fSMichael Zolotukhin } 1032e8f2551fSMichael Zolotukhin 1033e8f2551fSMichael Zolotukhin static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) { 1034e8f2551fSMichael Zolotukhin return std::strncmp(LHS.VectorFnName, S.data(), S.size()) < 0; 1035e8f2551fSMichael Zolotukhin } 1036e8f2551fSMichael Zolotukhin 1037e8f2551fSMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) { 1038e8f2551fSMichael Zolotukhin VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end()); 1039e8f2551fSMichael Zolotukhin std::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName); 1040e8f2551fSMichael Zolotukhin 1041e8f2551fSMichael Zolotukhin ScalarDescs.insert(ScalarDescs.end(), Fns.begin(), Fns.end()); 1042e8f2551fSMichael Zolotukhin std::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName); 1043e8f2551fSMichael Zolotukhin } 1044e8f2551fSMichael Zolotukhin 10456d8a2aa9SMichael Zolotukhin void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( 10466d8a2aa9SMichael Zolotukhin enum VectorLibrary VecLib) { 10476d8a2aa9SMichael Zolotukhin switch (VecLib) { 10486d8a2aa9SMichael Zolotukhin case Accelerate: { 10496d8a2aa9SMichael Zolotukhin const VecDesc VecFuncs[] = { 1050de63aaceSMichael Zolotukhin // Floating-Point Arithmetic and Auxiliary Functions 1051de63aaceSMichael Zolotukhin {"ceilf", "vceilf", 4}, 10526d8a2aa9SMichael Zolotukhin {"fabsf", "vfabsf", 4}, 10536d8a2aa9SMichael Zolotukhin {"llvm.fabs.f32", "vfabsf", 4}, 1054de63aaceSMichael Zolotukhin {"floorf", "vfloorf", 4}, 1055de63aaceSMichael Zolotukhin {"sqrtf", "vsqrtf", 4}, 1056de63aaceSMichael Zolotukhin {"llvm.sqrt.f32", "vsqrtf", 4}, 1057de63aaceSMichael Zolotukhin 1058de63aaceSMichael Zolotukhin // Exponential and Logarithmic Functions 1059de63aaceSMichael Zolotukhin {"expf", "vexpf", 4}, 1060de63aaceSMichael Zolotukhin {"llvm.exp.f32", "vexpf", 4}, 1061de63aaceSMichael Zolotukhin {"expm1f", "vexpm1f", 4}, 1062de63aaceSMichael Zolotukhin {"logf", "vlogf", 4}, 1063de63aaceSMichael Zolotukhin {"llvm.log.f32", "vlogf", 4}, 1064de63aaceSMichael Zolotukhin {"log1pf", "vlog1pf", 4}, 1065de63aaceSMichael Zolotukhin {"log10f", "vlog10f", 4}, 1066de63aaceSMichael Zolotukhin {"llvm.log10.f32", "vlog10f", 4}, 1067de63aaceSMichael Zolotukhin {"logbf", "vlogbf", 4}, 1068de63aaceSMichael Zolotukhin 1069de63aaceSMichael Zolotukhin // Trigonometric Functions 1070de63aaceSMichael Zolotukhin {"sinf", "vsinf", 4}, 1071de63aaceSMichael Zolotukhin {"llvm.sin.f32", "vsinf", 4}, 1072de63aaceSMichael Zolotukhin {"cosf", "vcosf", 4}, 1073de63aaceSMichael Zolotukhin {"llvm.cos.f32", "vcosf", 4}, 1074de63aaceSMichael Zolotukhin {"tanf", "vtanf", 4}, 1075de63aaceSMichael Zolotukhin {"asinf", "vasinf", 4}, 1076de63aaceSMichael Zolotukhin {"acosf", "vacosf", 4}, 1077de63aaceSMichael Zolotukhin {"atanf", "vatanf", 4}, 1078de63aaceSMichael Zolotukhin 1079de63aaceSMichael Zolotukhin // Hyperbolic Functions 1080de63aaceSMichael Zolotukhin {"sinhf", "vsinhf", 4}, 1081de63aaceSMichael Zolotukhin {"coshf", "vcoshf", 4}, 1082de63aaceSMichael Zolotukhin {"tanhf", "vtanhf", 4}, 1083de63aaceSMichael Zolotukhin {"asinhf", "vasinhf", 4}, 1084de63aaceSMichael Zolotukhin {"acoshf", "vacoshf", 4}, 1085de63aaceSMichael Zolotukhin {"atanhf", "vatanhf", 4}, 10866d8a2aa9SMichael Zolotukhin }; 10876d8a2aa9SMichael Zolotukhin addVectorizableFunctions(VecFuncs); 10886d8a2aa9SMichael Zolotukhin break; 10896d8a2aa9SMichael Zolotukhin } 10906d8a2aa9SMichael Zolotukhin case NoLibrary: 10916d8a2aa9SMichael Zolotukhin break; 10926d8a2aa9SMichael Zolotukhin } 10936d8a2aa9SMichael Zolotukhin } 10946d8a2aa9SMichael Zolotukhin 1095e8f2551fSMichael Zolotukhin bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const { 1096e8f2551fSMichael Zolotukhin funcName = sanitizeFunctionName(funcName); 1097e8f2551fSMichael Zolotukhin if (funcName.empty()) 1098e8f2551fSMichael Zolotukhin return false; 1099e8f2551fSMichael Zolotukhin 1100e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1101e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), funcName, 1102e8f2551fSMichael Zolotukhin compareWithScalarFnName); 1103e8f2551fSMichael Zolotukhin return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName; 1104e8f2551fSMichael Zolotukhin } 1105e8f2551fSMichael Zolotukhin 1106e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F, 1107e8f2551fSMichael Zolotukhin unsigned VF) const { 1108e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1109e8f2551fSMichael Zolotukhin if (F.empty()) 1110e8f2551fSMichael Zolotukhin return F; 1111e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1112e8f2551fSMichael Zolotukhin VectorDescs.begin(), VectorDescs.end(), F, compareWithScalarFnName); 1113e8f2551fSMichael Zolotukhin while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) { 1114e8f2551fSMichael Zolotukhin if (I->VectorizationFactor == VF) 1115e8f2551fSMichael Zolotukhin return I->VectorFnName; 1116e8f2551fSMichael Zolotukhin ++I; 1117e8f2551fSMichael Zolotukhin } 1118e8f2551fSMichael Zolotukhin return StringRef(); 1119e8f2551fSMichael Zolotukhin } 1120e8f2551fSMichael Zolotukhin 1121e8f2551fSMichael Zolotukhin StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F, 1122e8f2551fSMichael Zolotukhin unsigned &VF) const { 1123e8f2551fSMichael Zolotukhin F = sanitizeFunctionName(F); 1124e8f2551fSMichael Zolotukhin if (F.empty()) 1125e8f2551fSMichael Zolotukhin return F; 1126e8f2551fSMichael Zolotukhin 1127e8f2551fSMichael Zolotukhin std::vector<VecDesc>::const_iterator I = std::lower_bound( 1128e8f2551fSMichael Zolotukhin ScalarDescs.begin(), ScalarDescs.end(), F, compareWithVectorFnName); 1129e8f2551fSMichael Zolotukhin if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F) 1130e8f2551fSMichael Zolotukhin return StringRef(); 1131e8f2551fSMichael Zolotukhin VF = I->VectorizationFactor; 1132e8f2551fSMichael Zolotukhin return I->ScalarFnName; 1133e8f2551fSMichael Zolotukhin } 1134e8f2551fSMichael Zolotukhin 1135c0291865SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Module &M) { 1136c0291865SChandler Carruth if (PresetInfoImpl) 1137c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1138c0291865SChandler Carruth 1139c0291865SChandler Carruth return TargetLibraryInfo(lookupInfoImpl(Triple(M.getTargetTriple()))); 1140c0291865SChandler Carruth } 1141c0291865SChandler Carruth 1142c0291865SChandler Carruth TargetLibraryInfo TargetLibraryAnalysis::run(Function &F) { 1143c0291865SChandler Carruth if (PresetInfoImpl) 1144c0291865SChandler Carruth return TargetLibraryInfo(*PresetInfoImpl); 1145c0291865SChandler Carruth 1146c0291865SChandler Carruth return TargetLibraryInfo( 1147c0291865SChandler Carruth lookupInfoImpl(Triple(F.getParent()->getTargetTriple()))); 1148c0291865SChandler Carruth } 1149c0291865SChandler Carruth 1150c0291865SChandler Carruth TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(Triple T) { 1151c0291865SChandler Carruth std::unique_ptr<TargetLibraryInfoImpl> &Impl = 1152c0291865SChandler Carruth Impls[T.normalize()]; 1153c0291865SChandler Carruth if (!Impl) 1154c0291865SChandler Carruth Impl.reset(new TargetLibraryInfoImpl(T)); 1155c0291865SChandler Carruth 1156c0291865SChandler Carruth return *Impl; 1157c0291865SChandler Carruth } 1158c0291865SChandler Carruth 1159c0291865SChandler Carruth 1160b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() 1161c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) { 1162b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1163b98f63dbSChandler Carruth } 1164b98f63dbSChandler Carruth 1165b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T) 1166c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) { 1167b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1168b98f63dbSChandler Carruth } 1169b98f63dbSChandler Carruth 1170b98f63dbSChandler Carruth TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass( 1171c0291865SChandler Carruth const TargetLibraryInfoImpl &TLIImpl) 1172c0291865SChandler Carruth : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) { 1173b98f63dbSChandler Carruth initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 1174b98f63dbSChandler Carruth } 1175b98f63dbSChandler Carruth 1176b4faf13cSChandler Carruth char TargetLibraryAnalysis::PassID; 1177df0cd726SNAKAMURA Takumi 1178b98f63dbSChandler Carruth // Register the basic pass. 1179b98f63dbSChandler Carruth INITIALIZE_PASS(TargetLibraryInfoWrapperPass, "targetlibinfo", 1180b98f63dbSChandler Carruth "Target Library Information", false, true) 1181b98f63dbSChandler Carruth char TargetLibraryInfoWrapperPass::ID = 0; 1182b98f63dbSChandler Carruth 1183b98f63dbSChandler Carruth void TargetLibraryInfoWrapperPass::anchor() {} 1184