瀏覽代碼

[LibCalls] Added returned attribute to libcalls

Reviewers: efriedma

Reviewed By: efriedma

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D51092

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340512 91177308-0d34-0410-b5e6-96231b3b80d8
David Bolvansky 7 年之前
父節點
當前提交
0130b6e98a
共有 2 個文件被更改,包括 22 次插入9 次删除
  1. 16 3
      lib/Transforms/Utils/BuildLibCalls.cpp
  2. 6 6
      test/Transforms/InferFunctionAttrs/annotate.ll

+ 16 - 3
lib/Transforms/Utils/BuildLibCalls.cpp

@@ -38,6 +38,7 @@ STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
 STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
 STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
 STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
+STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
 
 static bool setDoesNotAccessMemory(Function &F) {
   if (F.doesNotAccessMemory())
@@ -105,6 +106,14 @@ static bool setRetNonNull(Function &F) {
   return true;
 }
 
+static bool setReturnedArg(Function &F, unsigned ArgNo) {
+  if (F.hasParamAttribute(ArgNo, Attribute::Returned))
+    return false;
+  F.addParamAttr(ArgNo, Attribute::Returned);
+  ++NumReturnedArg;
+  return true;
+}
+
 static bool setNonLazyBind(Function &F) {
   if (F.hasFnAttribute(Attribute::NonLazyBind))
     return false;
@@ -147,10 +156,12 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_strcpy:
-  case LibFunc_stpcpy:
+  case LibFunc_strncpy:
   case LibFunc_strcat:
   case LibFunc_strncat:
-  case LibFunc_strncpy:
+    Changed |= setReturnedArg(F, 0);
+    LLVM_FALLTHROUGH;
+  case LibFunc_stpcpy:
   case LibFunc_stpncpy:
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
@@ -262,9 +273,11 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 1);
     return Changed;
   case LibFunc_memcpy:
+  case LibFunc_memmove:
+    Changed |= setReturnedArg(F, 0);
+    LLVM_FALLTHROUGH;
   case LibFunc_mempcpy:
   case LibFunc_memccpy:
-  case LibFunc_memmove:
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 1);
     Changed |= setOnlyReadsMemory(F, 1);

+ 6 - 6
test/Transforms/InferFunctionAttrs/annotate.ll

@@ -625,13 +625,13 @@ declare i8* @memchr(i8*, i32, i64)
 ; CHECK: declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
 declare i32 @memcmp(i8*, i8*, i64)
 
-; CHECK: declare i8* @memcpy(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @memcpy(i8* returned, i8* nocapture readonly, i64) [[G0]]
 declare i8* @memcpy(i8*, i8*, i64)
 
 ; CHECK: declare i8* @mempcpy(i8*, i8* nocapture readonly, i64) [[G0]]
 declare i8* @mempcpy(i8*, i8*, i64)
 
-; CHECK: declare i8* @memmove(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @memmove(i8* returned, i8* nocapture readonly, i64) [[G0]]
 declare i8* @memmove(i8*, i8*, i64)
 
 ; CHECK: declare i8* @memset(i8*, i32, i64)
@@ -829,7 +829,7 @@ declare i8* @stpncpy(i8*, i8*, i64)
 ; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[G1]]
 declare i32 @strcasecmp(i8*, i8*)
 
-; CHECK: declare i8* @strcat(i8*, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @strcat(i8* returned, i8* nocapture readonly) [[G0]]
 declare i8* @strcat(i8*, i8*)
 
 ; CHECK: declare i8* @strchr(i8*, i32) [[G1]]
@@ -841,7 +841,7 @@ declare i32 @strcmp(i8*, i8*)
 ; CHECK: declare i32 @strcoll(i8* nocapture, i8* nocapture) [[G1]]
 declare i32 @strcoll(i8*, i8*)
 
-; CHECK: declare i8* @strcpy(i8*, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @strcpy(i8* returned, i8* nocapture readonly) [[G0]]
 declare i8* @strcpy(i8*, i8*)
 
 ; CHECK: declare i64 @strcspn(i8* nocapture, i8* nocapture) [[G1]]
@@ -856,13 +856,13 @@ declare i64 @strlen(i8*)
 ; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[G1]]
 declare i32 @strncasecmp(i8*, i8*, i64)
 
-; CHECK: declare i8* @strncat(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @strncat(i8* returned, i8* nocapture readonly, i64) [[G0]]
 declare i8* @strncat(i8*, i8*, i64)
 
 ; CHECK: declare i32 @strncmp(i8* nocapture, i8* nocapture, i64) [[G1]]
 declare i32 @strncmp(i8*, i8*, i64)
 
-; CHECK: declare i8* @strncpy(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @strncpy(i8* returned, i8* nocapture readonly, i64) [[G0]]
 declare i8* @strncpy(i8*, i8*, i64)
 
 ; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[G0]]