diff options
author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-04-27 19:04:35 +0000 |
---|---|---|
committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-04-27 19:04:35 +0000 |
commit | d765a82b54c63c4d4d1c98ca55c189366f50043a (patch) | |
tree | ba4ca0354cc5816a8260e4b4cacf373a51baebc6 /llvm/lib/Analysis | |
parent | 220c4010bfc7c6417039d8a8010be1d6cdf20b33 (diff) | |
download | bcm5719-llvm-d765a82b54c63c4d4d1c98ca55c189366f50043a.tar.gz bcm5719-llvm-d765a82b54c63c4d4d1c98ca55c189366f50043a.zip |
[TLI] Unify LibFunc signature checking. NFCI.
I tried to be as close as possible to the strongest check that
existed before; cleaning these up properly is left for future work.
Differential Revision: http://reviews.llvm.org/D19469
llvm-svn: 267758
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Analysis/MemoryLocation.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/Analysis/TargetLibraryInfo.cpp | 531 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 83 |
4 files changed, 560 insertions, 96 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index ee7d1497c57..4c6f00132dc 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -541,22 +541,6 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc, return Worklist.empty(); } -// FIXME: This code is duplicated with MemoryLocation and should be hoisted to -// some common utility location. -static bool isMemsetPattern16(const Function *MS, - const TargetLibraryInfo &TLI) { - if (TLI.has(LibFunc::memset_pattern16) && - MS->getName() == "memset_pattern16") { - FunctionType *MemsetType = MS->getFunctionType(); - if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 && - isa<PointerType>(MemsetType->getParamType(0)) && - isa<PointerType>(MemsetType->getParamType(1)) && - isa<IntegerType>(MemsetType->getParamType(2))) - return true; - } - return false; -} - /// Returns the behavior when calling the given call site. FunctionModRefBehavior BasicAAResult::getModRefBehavior(ImmutableCallSite CS) { if (CS.doesNotAccessMemory()) @@ -629,7 +613,9 @@ static bool isWriteOnlyParam(ImmutableCallSite CS, unsigned ArgIdx, // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. Note that all but the missing writeonly attribute are // handled via InferFunctionAttr. - if (CS.getCalledFunction() && isMemsetPattern16(CS.getCalledFunction(), TLI)) + LibFunc::Func F; + if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && + F == LibFunc::memset_pattern16 && TLI.has(F)) if (ArgIdx == 0) return true; diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index e4491261e05..a0ae72f1415 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -90,23 +90,6 @@ MemoryLocation MemoryLocation::getForDest(const MemIntrinsic *MTI) { return MemoryLocation(MTI->getRawDest(), Size, AATags); } -// FIXME: This code is duplicated with BasicAliasAnalysis and should be hoisted -// to some common utility location. -static bool isMemsetPattern16(const Function *MS, - const TargetLibraryInfo &TLI) { - if (TLI.has(LibFunc::memset_pattern16) && - MS->getName() == "memset_pattern16") { - FunctionType *MemsetType = MS->getFunctionType(); - if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 && - isa<PointerType>(MemsetType->getParamType(0)) && - isa<PointerType>(MemsetType->getParamType(1)) && - isa<IntegerType>(MemsetType->getParamType(2))) - return true; - } - - return false; -} - MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, unsigned ArgIdx, const TargetLibraryInfo &TLI) { @@ -159,8 +142,9 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, // for memcpy/memset. This is particularly important because the // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. - if (CS.getCalledFunction() && - isMemsetPattern16(CS.getCalledFunction(), TLI)) { + LibFunc::Func F; + if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && + F == LibFunc::memset_pattern16 && TLI.has(F)) { assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memset_pattern16"); if (ArgIdx == 1) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 2d34ac2bd5c..36f83adeaa1 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -479,6 +479,537 @@ bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName, return false; } +bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy, + LibFunc::Func F, + const DataLayout *DL) const { + LLVMContext &Ctx = FTy.getContext(); + Type *PCharTy = Type::getInt8PtrTy(Ctx); + Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AS=*/0) : nullptr; + auto IsSizeTTy = [SizeTTy](Type *Ty) { + return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy(); + }; + unsigned NumParams = FTy.getNumParams(); + + switch (F) { + case LibFunc::strlen: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && + FTy.getReturnType()->isIntegerTy()); + + case LibFunc::strchr: + case LibFunc::strrchr: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0) == FTy.getReturnType() && + FTy.getParamType(1)->isIntegerTy()); + + case LibFunc::strtol: + case LibFunc::strtod: + case LibFunc::strtof: + case LibFunc::strtoul: + case LibFunc::strtoll: + case LibFunc::strtold: + case LibFunc::strtoull: + return ((NumParams == 2 || NumParams == 3) && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::strcat: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0) == FTy.getReturnType() && + FTy.getParamType(1) == FTy.getReturnType()); + + case LibFunc::strncat: + return (NumParams == 3 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0) == FTy.getReturnType() && + FTy.getParamType(1) == FTy.getReturnType() && + FTy.getParamType(2)->isIntegerTy()); + + case LibFunc::strcpy_chk: + case LibFunc::stpcpy_chk: + --NumParams; + if (!IsSizeTTy(FTy.getParamType(NumParams))) + return false; + // fallthrough + case LibFunc::strcpy: + case LibFunc::stpcpy: + return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && + FTy.getParamType(0) == FTy.getParamType(1) && + FTy.getParamType(0) == PCharTy); + + case LibFunc::strncpy_chk: + case LibFunc::stpncpy_chk: + --NumParams; + if (!IsSizeTTy(FTy.getParamType(NumParams))) + return false; + // fallthrough + case LibFunc::strncpy: + case LibFunc::stpncpy: + return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && + FTy.getParamType(0) == FTy.getParamType(1) && + FTy.getParamType(0) == PCharTy && + FTy.getParamType(2)->isIntegerTy()); + + case LibFunc::strxfrm: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + + case LibFunc::strcmp: + return (NumParams == 2 && FTy.getReturnType()->isIntegerTy(32) && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(0) == FTy.getParamType(1)); + + case LibFunc::strncmp: + return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(0) == FTy.getParamType(1) && + FTy.getParamType(2)->isIntegerTy()); + + case LibFunc::strspn: + case LibFunc::strcspn: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(0) == FTy.getParamType(1) && + FTy.getReturnType()->isIntegerTy()); + + case LibFunc::strcoll: + case LibFunc::strcasecmp: + case LibFunc::strncasecmp: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + + case LibFunc::strstr: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + + case LibFunc::strpbrk: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getReturnType() == FTy.getParamType(0) && + FTy.getParamType(0) == FTy.getParamType(1)); + + case LibFunc::strtok: + case LibFunc::strtok_r: + return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::scanf: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::setbuf: + case LibFunc::setvbuf: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::strdup: + case LibFunc::strndup: + return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy()); + case LibFunc::stat: + case LibFunc::statvfs: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::sscanf: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::sprintf: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::snprintf: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::setitimer: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::system: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::malloc: + return (NumParams == 1 && FTy.getReturnType()->isPointerTy()); + case LibFunc::memcmp: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy() && + FTy.getReturnType()->isIntegerTy(32)); + + case LibFunc::memchr: + case LibFunc::memrchr: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isIntegerTy(32) && + FTy.getParamType(2)->isIntegerTy() && + FTy.getReturnType()->isPointerTy()); + case LibFunc::modf: + case LibFunc::modff: + case LibFunc::modfl: + return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); + + case LibFunc::memcpy_chk: + case LibFunc::memmove_chk: + --NumParams; + if (!IsSizeTTy(FTy.getParamType(NumParams))) + return false; + // fallthrough + case LibFunc::memcpy: + case LibFunc::memmove: + return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy() && + IsSizeTTy(FTy.getParamType(2))); + + case LibFunc::memset_chk: + --NumParams; + if (!IsSizeTTy(FTy.getParamType(NumParams))) + return false; + // fallthrough + case LibFunc::memset: + return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isIntegerTy() && + IsSizeTTy(FTy.getParamType(2))); + + case LibFunc::memccpy: + return (NumParams >= 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::memalign: + return (FTy.getReturnType()->isPointerTy()); + case LibFunc::mkdir: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::mktime: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::realloc: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getReturnType()->isPointerTy()); + case LibFunc::read: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::rewind: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::rmdir: + case LibFunc::remove: + case LibFunc::realpath: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::rename: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::readlink: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::write: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::bcopy: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::bcmp: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::bzero: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::calloc: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy()); + case LibFunc::chmod: + case LibFunc::chown: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::ctermid: + case LibFunc::clearerr: + case LibFunc::closedir: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::atoi: + case LibFunc::atol: + case LibFunc::atof: + case LibFunc::atoll: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::access: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::fopen: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::fdopen: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::feof: + case LibFunc::free: + case LibFunc::fseek: + case LibFunc::ftell: + case LibFunc::fgetc: + case LibFunc::fseeko: + case LibFunc::ftello: + case LibFunc::fileno: + case LibFunc::fflush: + case LibFunc::fclose: + case LibFunc::fsetpos: + case LibFunc::flockfile: + case LibFunc::funlockfile: + case LibFunc::ftrylockfile: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::ferror: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::fputc: + case LibFunc::fstat: + case LibFunc::frexp: + case LibFunc::frexpf: + case LibFunc::frexpl: + case LibFunc::fstatvfs: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::fgets: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::fread: + return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(3)->isPointerTy()); + case LibFunc::fwrite: + return (NumParams == 4 && FTy.getReturnType()->isIntegerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isIntegerTy() && + FTy.getParamType(2)->isIntegerTy() && + FTy.getParamType(3)->isPointerTy()); + case LibFunc::fputs: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::fscanf: + case LibFunc::fprintf: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::fgetpos: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::getc: + case LibFunc::getlogin_r: + case LibFunc::getc_unlocked: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::getenv: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::gets: + case LibFunc::getchar: + case LibFunc::getitimer: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::getpwnam: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::ungetc: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::uname: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::unlink: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::unsetenv: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::utime: + case LibFunc::utimes: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::putc: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::puts: + case LibFunc::printf: + case LibFunc::perror: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::pread: + case LibFunc::pwrite: + return (NumParams == 4 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::putchar: + case LibFunc::popen: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::pclose: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::vscanf: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::vsscanf: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::vfscanf: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::valloc: + return (FTy.getReturnType()->isPointerTy()); + case LibFunc::vprintf: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::vfprintf: + case LibFunc::vsprintf: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::vsnprintf: + return (NumParams == 4 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + case LibFunc::open: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::opendir: + return (NumParams == 1 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy()); + case LibFunc::tmpfile: + return (FTy.getReturnType()->isPointerTy()); + case LibFunc::times: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::htonl: + case LibFunc::htons: + case LibFunc::ntohl: + case LibFunc::ntohs: + case LibFunc::lstat: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::lchown: + return (NumParams == 3 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::qsort: + return (NumParams == 4 && FTy.getParamType(3)->isPointerTy()); + case LibFunc::dunder_strdup: + case LibFunc::dunder_strndup: + return (NumParams >= 1 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy()); + case LibFunc::dunder_strtok_r: + return (NumParams == 3 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::under_IO_getc: + return (NumParams == 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::under_IO_putc: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::dunder_isoc99_scanf: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::stat64: + case LibFunc::lstat64: + case LibFunc::statvfs64: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::dunder_isoc99_sscanf: + return (NumParams >= 1 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::fopen64: + return (NumParams == 2 && FTy.getReturnType()->isPointerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + case LibFunc::fseeko64: + case LibFunc::ftello64: + return (NumParams == 0 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::tmpfile64: + return (FTy.getReturnType()->isPointerTy()); + case LibFunc::fstat64: + case LibFunc::fstatvfs64: + return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); + case LibFunc::open64: + return (NumParams >= 2 && FTy.getParamType(0)->isPointerTy()); + case LibFunc::gettimeofday: + return (NumParams == 2 && FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy()); + + case LibFunc::Znwj: // new(unsigned int); + case LibFunc::Znwm: // new(unsigned long); + case LibFunc::Znaj: // new[](unsigned int); + case LibFunc::Znam: // new[](unsigned long); + case LibFunc::msvc_new_int: // new(unsigned int); + case LibFunc::msvc_new_longlong: // new(unsigned long long); + case LibFunc::msvc_new_array_int: // new[](unsigned int); + case LibFunc::msvc_new_array_longlong: // new[](unsigned long long); + return (NumParams == 1); + + case LibFunc::memset_pattern16: + return (!FTy.isVarArg() && NumParams == 3 && + isa<PointerType>(FTy.getParamType(0)) && + isa<PointerType>(FTy.getParamType(1)) && + isa<IntegerType>(FTy.getParamType(2))); + + // int __nvvm_reflect(const char *); + case LibFunc::nvvm_reflect: + return (NumParams == 1 && isa<PointerType>(FTy.getParamType(0))); + + case LibFunc::sin: + case LibFunc::sinf: + case LibFunc::sinl: + case LibFunc::cos: + case LibFunc::cosf: + case LibFunc::cosl: + case LibFunc::exp: + case LibFunc::expf: + case LibFunc::expl: + case LibFunc::exp2: + case LibFunc::exp2f: + case LibFunc::exp2l: + case LibFunc::log: + case LibFunc::logf: + case LibFunc::logl: + case LibFunc::log10: + case LibFunc::log10f: + case LibFunc::log10l: + case LibFunc::log2: + case LibFunc::log2f: + case LibFunc::log2l: + case LibFunc::fabs: + case LibFunc::fabsf: + case LibFunc::fabsl: + case LibFunc::floor: + case LibFunc::floorf: + case LibFunc::floorl: + case LibFunc::ceil: + case LibFunc::ceilf: + case LibFunc::ceill: + case LibFunc::trunc: + case LibFunc::truncf: + case LibFunc::truncl: + case LibFunc::rint: + case LibFunc::rintf: + case LibFunc::rintl: + case LibFunc::nearbyint: + case LibFunc::nearbyintf: + case LibFunc::nearbyintl: + case LibFunc::round: + case LibFunc::roundf: + case LibFunc::roundl: + case LibFunc::sqrt: + case LibFunc::sqrtf: + case LibFunc::sqrtl: + return (NumParams == 1 && FTy.getReturnType()->isFloatingPointTy() && + FTy.getReturnType() == FTy.getParamType(0)); + + case LibFunc::fmin: + case LibFunc::fminf: + case LibFunc::fminl: + case LibFunc::fmax: + case LibFunc::fmaxf: + case LibFunc::fmaxl: + case LibFunc::copysign: + case LibFunc::copysignf: + case LibFunc::copysignl: + case LibFunc::pow: + case LibFunc::powf: + case LibFunc::powl: + return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() && + FTy.getReturnType() == FTy.getParamType(0) && + FTy.getReturnType() == FTy.getParamType(1)); + + case LibFunc::ffs: + case LibFunc::ffsl: + case LibFunc::ffsll: + case LibFunc::isdigit: + case LibFunc::isascii: + case LibFunc::toascii: + return (NumParams == 1 && FTy.getReturnType()->isIntegerTy(32) && + FTy.getParamType(0)->isIntegerTy()); + + case LibFunc::fls: + case LibFunc::flsl: + case LibFunc::flsll: + case LibFunc::abs: + case LibFunc::labs: + case LibFunc::llabs: + return (NumParams == 1 && FTy.getReturnType()->isIntegerTy() && + FTy.getReturnType() == FTy.getParamType(0)); + + case LibFunc::cxa_atexit: + return (NumParams == 3 && FTy.getReturnType()->isIntegerTy() && + FTy.getParamType(0)->isPointerTy() && + FTy.getParamType(1)->isPointerTy() && + FTy.getParamType(2)->isPointerTy()); + + case LibFunc::sinpi: + case LibFunc::cospi: + return (NumParams == 1 && FTy.getReturnType()->isDoubleTy() && + FTy.getReturnType() == FTy.getParamType(0)); + + case LibFunc::sinpif: + case LibFunc::cospif: + return (NumParams == 1 && FTy.getReturnType()->isFloatTy() && + FTy.getReturnType() == FTy.getParamType(0)); + + default: + // Assume the other functions are correct. + // FIXME: It'd be really nice to cover them all. + return true; + } +} + +bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl, + LibFunc::Func &F) const { + const DataLayout *DL = + FDecl.getParent() ? &FDecl.getParent()->getDataLayout() : nullptr; + return getLibFunc(FDecl.getName(), F) && + isValidProtoForLibFunc(*FDecl.getFunctionType(), F, DL); +} + void TargetLibraryInfoImpl::disableAllFunctions() { memset(AvailableArray, 0, sizeof(AvailableArray)); } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index a9b8af1017c..c616e091290 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2242,46 +2242,6 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, return false; } -/// \brief Check call has a unary float signature -/// It checks following: -/// a) call should have a single argument -/// b) argument type should be floating point type -/// c) call instruction type and argument type should be same -/// d) call should only reads memory. -/// If all these condition is met then return ValidIntrinsicID -/// else return not_intrinsic. -static Intrinsic::ID checkUnaryFloatSignature(ImmutableCallSite ICS, - Intrinsic::ID ValidIntrinsicID) { - if (ICS.getNumArgOperands() != 1 || - !ICS.getArgOperand(0)->getType()->isFloatingPointTy() || - ICS.getType() != ICS.getArgOperand(0)->getType() || - !ICS.onlyReadsMemory()) - return Intrinsic::not_intrinsic; - - return ValidIntrinsicID; -} - -/// \brief Check call has a binary float signature -/// It checks following: -/// a) call should have 2 arguments. -/// b) arguments type should be floating point type -/// c) call instruction type and arguments type should be same -/// d) call should only reads memory. -/// If all these condition is met then return ValidIntrinsicID -/// else return not_intrinsic. -static Intrinsic::ID checkBinaryFloatSignature(ImmutableCallSite ICS, - Intrinsic::ID ValidIntrinsicID) { - if (ICS.getNumArgOperands() != 2 || - !ICS.getArgOperand(0)->getType()->isFloatingPointTy() || - !ICS.getArgOperand(1)->getType()->isFloatingPointTy() || - ICS.getType() != ICS.getArgOperand(0)->getType() || - ICS.getType() != ICS.getArgOperand(1)->getType() || - !ICS.onlyReadsMemory()) - return Intrinsic::not_intrinsic; - - return ValidIntrinsicID; -} - Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, const TargetLibraryInfo *TLI) { const Function *F = ICS.getCalledFunction(); @@ -2298,7 +2258,10 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, // We're going to make assumptions on the semantics of the functions, check // that the target knows that it's available in this environment and it does // not have local linkage. - if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func)) + if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(*F, Func)) + return Intrinsic::not_intrinsic; + + if (!ICS.onlyReadsMemory()) return Intrinsic::not_intrinsic; // Otherwise check if we have a call to a function that can be turned into a @@ -2309,80 +2272,80 @@ Intrinsic::ID llvm::getIntrinsicForCallSite(ImmutableCallSite ICS, case LibFunc::sin: case LibFunc::sinf: case LibFunc::sinl: - return checkUnaryFloatSignature(ICS, Intrinsic::sin); + return Intrinsic::sin; case LibFunc::cos: case LibFunc::cosf: case LibFunc::cosl: - return checkUnaryFloatSignature(ICS, Intrinsic::cos); + return Intrinsic::cos; case LibFunc::exp: case LibFunc::expf: case LibFunc::expl: - return checkUnaryFloatSignature(ICS, Intrinsic::exp); + return Intrinsic::exp; case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l: - return checkUnaryFloatSignature(ICS, Intrinsic::exp2); + return Intrinsic::exp2; case LibFunc::log: case LibFunc::logf: case LibFunc::logl: - return checkUnaryFloatSignature(ICS, Intrinsic::log); + return Intrinsic::log; case LibFunc::log10: case LibFunc::log10f: case LibFunc::log10l: - return checkUnaryFloatSignature(ICS, Intrinsic::log10); + return Intrinsic::log10; case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l: - return checkUnaryFloatSignature(ICS, Intrinsic::log2); + return Intrinsic::log2; case LibFunc::fabs: case LibFunc::fabsf: case LibFunc::fabsl: - return checkUnaryFloatSignature(ICS, Intrinsic::fabs); + return Intrinsic::fabs; case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl: - return checkBinaryFloatSignature(ICS, Intrinsic::minnum); + return Intrinsic::minnum; case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl: - return checkBinaryFloatSignature(ICS, Intrinsic::maxnum); + return Intrinsic::maxnum; case LibFunc::copysign: case LibFunc::copysignf: case LibFunc::copysignl: - return checkBinaryFloatSignature(ICS, Intrinsic::copysign); + return Intrinsic::copysign; case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl: - return checkUnaryFloatSignature(ICS, Intrinsic::floor); + return Intrinsic::floor; case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: - return checkUnaryFloatSignature(ICS, Intrinsic::ceil); + return Intrinsic::ceil; case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl: - return checkUnaryFloatSignature(ICS, Intrinsic::trunc); + return Intrinsic::trunc; case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl: - return checkUnaryFloatSignature(ICS, Intrinsic::rint); + return Intrinsic::rint; case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: - return checkUnaryFloatSignature(ICS, Intrinsic::nearbyint); + return Intrinsic::nearbyint; case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl: - return checkUnaryFloatSignature(ICS, Intrinsic::round); + return Intrinsic::round; case LibFunc::pow: case LibFunc::powf: case LibFunc::powl: - return checkBinaryFloatSignature(ICS, Intrinsic::pow); + return Intrinsic::pow; case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl: if (ICS->hasNoNaNs()) - return checkUnaryFloatSignature(ICS, Intrinsic::sqrt); + return Intrinsic::sqrt; return Intrinsic::not_intrinsic; } |