On strtod and friends, mark 'endptr' nocapture in the function prototype, and
mark the first argument nocapture if endptr=NULL for each particular call.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64453 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index d8b923a..fed239e 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -722,6 +722,26 @@
};
//===---------------------------------------===//
+// 'strto*' Optimizations
+
+struct VISIBILITY_HIDDEN StrToOpt : public LibCallOptimization {
+ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+ const FunctionType *FT = Callee->getFunctionType();
+ if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
+ !isa<PointerType>(FT->getParamType(0)) ||
+ !isa<PointerType>(FT->getParamType(1)))
+ return 0;
+
+ Value *EndPtr = CI->getOperand(2);
+ if (isa<ConstantPointerNull>(EndPtr))
+ CI->addAttribute(1, Attribute::NoCapture);
+
+ return 0;
+ }
+};
+
+
+//===---------------------------------------===//
// 'memcmp' Optimizations
struct VISIBILITY_HIDDEN MemCmpOpt : public LibCallOptimization {
@@ -1329,8 +1349,8 @@
ExitOpt Exit;
// String and Memory LibCall Optimizations
StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
- StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt MemCpy;
- MemMoveOpt MemMove; MemSetOpt MemSet;
+ StrCpyOpt StrCpy; StrLenOpt StrLen; StrToOpt StrTo; MemCmpOpt MemCmp;
+ MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
// Math Library Optimizations
PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
// Integer Optimizations
@@ -1383,6 +1403,13 @@
Optimizations["strncmp"] = &StrNCmp;
Optimizations["strcpy"] = &StrCpy;
Optimizations["strlen"] = &StrLen;
+ Optimizations["strtol"] = &StrTo;
+ Optimizations["strtod"] = &StrTo;
+ Optimizations["strtof"] = &StrTo;
+ Optimizations["strtoul"] = &StrTo;
+ Optimizations["strtoll"] = &StrTo;
+ Optimizations["strtold"] = &StrTo;
+ Optimizations["strtoull"] = &StrTo;
Optimizations["memcmp"] = &MemCmp;
Optimizations["memcpy"] = &MemCpy;
Optimizations["memmove"] = &MemMove;
@@ -1566,8 +1593,15 @@
} else if ((NameLen == 6 && !strcmp(NameStr, "strcpy")) ||
(NameLen == 6 && !strcmp(NameStr, "stpcpy")) ||
(NameLen == 6 && !strcmp(NameStr, "strcat")) ||
+ (NameLen == 6 && !strcmp(NameStr, "strtol")) ||
+ (NameLen == 6 && !strcmp(NameStr, "strtod")) ||
+ (NameLen == 6 && !strcmp(NameStr, "strtof")) ||
+ (NameLen == 7 && !strcmp(NameStr, "strtoul")) ||
+ (NameLen == 7 && !strcmp(NameStr, "strtoll")) ||
+ (NameLen == 7 && !strcmp(NameStr, "strtold")) ||
(NameLen == 7 && !strcmp(NameStr, "strncat")) ||
- (NameLen == 7 && !strcmp(NameStr, "strncpy"))) {
+ (NameLen == 7 && !strcmp(NameStr, "strncpy")) ||
+ (NameLen == 8 && !strcmp(NameStr, "strtoull"))) {
if (FTy->getNumParams() < 2 ||
!isa<PointerType>(FTy->getParamType(1)))
continue;