summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorAhmed Bougacha <ahmed.bougacha@gmail.com>2016-04-27 19:04:35 +0000
committerAhmed Bougacha <ahmed.bougacha@gmail.com>2016-04-27 19:04:35 +0000
commitd765a82b54c63c4d4d1c98ca55c189366f50043a (patch)
treeba4ca0354cc5816a8260e4b4cacf373a51baebc6 /llvm/lib/Analysis
parent220c4010bfc7c6417039d8a8010be1d6cdf20b33 (diff)
downloadbcm5719-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.cpp20
-rw-r--r--llvm/lib/Analysis/MemoryLocation.cpp22
-rw-r--r--llvm/lib/Analysis/TargetLibraryInfo.cpp531
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp83
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;
}
OpenPOWER on IntegriCloud