[llvm-branch-commits] [llvm] 16d6e85 - [BuildLibcalls] Mark some libcalls with inaccessiblememonly and inaccessiblemem_or_argmemonly

Dávid Bolvanský via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 20 10:50:30 PST 2021


Author: Dávid Bolvanský
Date: 2021-01-20T19:45:23+01:00
New Revision: 16d6e8527189298c75bf5690c771e8ab6dc3628d

URL: https://github.com/llvm/llvm-project/commit/16d6e8527189298c75bf5690c771e8ab6dc3628d
DIFF: https://github.com/llvm/llvm-project/commit/16d6e8527189298c75bf5690c771e8ab6dc3628d.diff

LOG: [BuildLibcalls] Mark some libcalls with inaccessiblememonly and inaccessiblemem_or_argmemonly

Reviewed By: jdoerfert

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/BuildLibCalls.cpp
    llvm/test/Transforms/InferFunctionAttrs/annotate.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index d2ffb99274e3..857c3d915e8c 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -31,8 +31,12 @@ using namespace llvm;
 //- Infer Attributes ---------------------------------------------------------//
 
 STATISTIC(NumReadNone, "Number of functions inferred as readnone");
+STATISTIC(NumInaccessibleMemOnly,
+          "Number of functions inferred as inaccessiblememonly");
 STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
 STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
+STATISTIC(NumInaccessibleMemOrArgMemOnly,
+          "Number of functions inferred as inaccessiblemem_or_argmemonly");
 STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
 STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
@@ -52,6 +56,14 @@ static bool setDoesNotAccessMemory(Function &F) {
   return true;
 }
 
+static bool setOnlyAccessesInaccessibleMemory(Function &F) {
+  if (F.onlyAccessesInaccessibleMemory())
+    return false;
+  F.setOnlyAccessesInaccessibleMemory();
+  ++NumInaccessibleMemOnly;
+  return true;
+}
+
 static bool setOnlyReadsMemory(Function &F) {
   if (F.onlyReadsMemory())
     return false;
@@ -68,6 +80,14 @@ static bool setOnlyAccessesArgMemory(Function &F) {
   return true;
 }
 
+static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
+  if (F.onlyAccessesInaccessibleMemOrArgMem())
+    return false;
+  F.setOnlyAccessesInaccessibleMemOrArgMem();
+  ++NumInaccessibleMemOrArgMemOnly;
+  return true;
+}
+
 static bool setDoesNotThrow(Function &F) {
   if (F.doesNotThrow())
     return false;
@@ -315,6 +335,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     return Changed;
   case LibFunc_strdup:
   case LibFunc_strndup:
+    Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setWillReturn(F);
@@ -370,6 +391,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_malloc:
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
     Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
@@ -432,6 +454,9 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotThrow(F);
     return Changed;
   case LibFunc_memalign:
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
+    Changed |= setRetNoUndef(F);
+    Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setWillReturn(F);
     return Changed;
@@ -448,6 +473,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_realloc:
+    Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
     Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
@@ -498,6 +524,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_aligned_alloc:
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
     Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
@@ -528,6 +555,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyWritesMemory(F, 0);
     return Changed;
   case LibFunc_calloc:
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
     Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
@@ -584,6 +612,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_free:
+    Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
     Changed |= setArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setWillReturn(F);
@@ -809,9 +838,11 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_valloc:
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
     Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
+    Changed |= setWillReturn(F);
     return Changed;
   case LibFunc_vprintf:
     Changed |= setRetAndArgsNoUndef(F);
@@ -978,6 +1009,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
   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)
+    Changed |= setOnlyAccessesInaccessibleMemory(F);
     // Operator new always returns a nonnull noalias pointer
     Changed |= setRetNoUndef(F);
     Changed |= setRetNonNull(F);

diff  --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index eaf9bac09d69..0af18151d6f6 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -6,9 +6,9 @@
 
 ; operator new routines
 declare i8* @_Znwj(i64 )
-; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) [[NOFREE_WILLRETURN:#[0-9]+]]
+; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) [[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN:#[0-9]+]]
 declare i8* @_Znwm(i64)
-; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) [[NOFREE_WILLRETURN]]
+; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) [[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]]
 
 declare i32 @__nvvm_reflect(i8*)
 ; CHECK-NVPTX: declare noundef i32 @__nvvm_reflect(i8* noundef) [[NOFREE_NOUNWIND_READNONE:#[0-9]+]]
@@ -184,6 +184,9 @@ declare x86_fp80 @acoshl(x86_fp80)
 ; CHECK: declare x86_fp80 @acosl(x86_fp80) [[NOFREE_NOUNWIND_WILLRETURN]]
 declare x86_fp80 @acosl(x86_fp80)
 
+; CHECK: declare noalias noundef i8* @aligned_alloc(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
+declare i8* @aligned_alloc(i64, i64)
+
 ; CHECK: declare double @asin(double) [[NOFREE_NOUNWIND_WILLRETURN]]
 declare double @asin(double)
 
@@ -253,7 +256,7 @@ declare void @bcopy(i8*, i8*, i64)
 ; CHECK: declare void @bzero(i8* nocapture writeonly, i64)  [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
 declare void @bzero(i8*, i64)
 
-; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
+; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
 declare i8* @calloc(i64, i64)
 
 ; CHECK: declare double @cbrt(double) [[NOFREE_NOUNWIND_WILLRETURN]]
@@ -550,7 +553,7 @@ declare i64 @labs(i64)
 ; CHECK: declare noundef i32 @lchown(i8* nocapture noundef readonly, i32 noundef, i32 noundef) [[NOFREE_NOUNWIND]]
 declare i32 @lchown(i8*, i32, i32)
 
-; CHECK: declare double @ldexp(double, i32 signext) [[NOFREE_WILLRETURN]]
+; CHECK: declare double @ldexp(double, i32 signext) [[NOFREE_WILLRETURN:#[0-9]+]]
 declare double @ldexp(double, i32)
 
 ; CHECK: declare float @ldexpf(float, i32 signext) [[NOFREE_WILLRETURN]]
@@ -613,10 +616,10 @@ declare i32 @lstat(i8*, %opaque*)
 ; CHECK-LINUX: declare noundef i32 @lstat64(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[NOFREE_NOUNWIND]]
 declare i32 @lstat64(i8*, %opaque*)
 
-; CHECK: declare noalias noundef i8* @malloc(i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare noalias noundef i8* @malloc(i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
 declare i8* @malloc(i64)
 
-; CHECK-LINUX: declare noalias i8* @memalign(i64, i64) [[NOFREE_WILLRETURN]]
+; CHECK-LINUX: declare noalias noundef i8* @memalign(i64, i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
 declare i8* @memalign(i64, i64)
 
 ; CHECK: declare i8* @memccpy(i8* noalias writeonly, i8* noalias nocapture readonly, i32, i64) [[ARGMEMONLY_NOFREE_NOUNWIND:#[0-9]+]]
@@ -856,7 +859,7 @@ declare i8* @strcpy(i8*, i8*)
 ; CHECK: declare i64 @strcspn(i8* nocapture, i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]]
 declare i64 @strcspn(i8*, i8*)
 
-; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
 declare i8* @strdup(i8*)
 
 ; CHECK: declare i64 @strlen(i8* nocapture) [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]]
@@ -874,7 +877,7 @@ declare i32 @strncmp(i8*, i8*, i64)
 ; CHECK: declare i8* @strncpy(i8* noalias returned writeonly, i8* noalias nocapture readonly, i64) [[ARGMEMONLY_NOFREE_NOUNWIND]]
 declare i8* @strncpy(i8*, i8*, i64)
 
-; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN]]
 declare i8* @strndup(i8*, i64)
 
 ; CHECK: declare i64 @strnlen(i8*, i64) [[NOFREE_NOUNWIND_WILLRETURN]]
@@ -982,7 +985,7 @@ declare i32 @utime(i8*, %opaque*)
 ; CHECK: declare noundef i32 @utimes(i8* nocapture noundef readonly, %opaque* nocapture noundef readonly) [[NOFREE_NOUNWIND]]
 declare i32 @utimes(i8*, %opaque*)
 
-; CHECK: declare noalias noundef i8* @valloc(i64) [[NOFREE_NOUNWIND]]
+; CHECK: declare noalias noundef i8* @valloc(i64) [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
 declare i8* @valloc(i64)
 
 ; CHECK: declare noundef i32 @vfprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[NOFREE_NOUNWIND]]
@@ -1014,23 +1017,31 @@ declare i64 @write(i32, i8*, i64)
 ; CHECK-DARWIN: declare void @memset_pattern16(i8* nocapture writeonly, i8* nocapture readonly, i64) [[ARGMEMONLY_NOFREE:#[0-9]+]]
 declare void @memset_pattern16(i8*, i8*, i64)
 
-; CHECK-DAG: attributes [[NOFREE_WILLRETURN]] = { nofree willreturn }
-; CHECK-DAG: attributes [[NOFREE]] = { nofree }
-; CHECK-DAG: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn }
-; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { argmemonly nofree nounwind willreturn }
-; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly }
-; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { nofree nounwind readonly willreturn }
-
-; CHECK-DAG-UNKNOWN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { argmemonly nofree nounwind }
-; CHECK-DAG-UNKNOWN: attributes [[NOUNWIND]] = { nounwind }
-; CHECK-DAG-UNKNOWN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] = { argmemonly nofree nounwind readonly }
-
-; CHECK-DAG-LINUX: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] = { argmemonly nofree nounwind readonly }
-; CHECK-DAG-LINUX: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { argmemonly nofree nounwind }
-; CHECK-DAG-LINUX: attributes [[NOUNWIND]] = { nounwind }
-
-; CHECK-DAG-DARWIN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { argmemonly nofree nounwind }
-; CHECK-DAG-DARWIN: attributes [[NOUNWIND]] = { nounwind }
-; CHECK-DAG-DARWIN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY]] = { argmemonly nofree nounwind readonly }
-; CHECK-DAG-DARWIN: attributes [[ARGMEMONLY_NOFREE]] = { argmemonly nofree }
-
+; CHECK-DAG-UNKNOWN: attributes [[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]] = { inaccessiblememonly nofree willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind }
+; CHECK-DAG-UNKNOWN: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { inaccessiblememonly nofree nounwind willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]]  = { nofree nounwind readonly willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly nofree nounwind willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly }
+; CHECK-DAG-UNKNOWN: attributes [[INACCESSIBLEMEMORARGONLY_NOUNWIND_WILLRETURN]]  = { inaccessiblemem_or_argmemonly nounwind willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE_WILLRETURN]] = { nofree willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly nofree nounwind readonly willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[NOFREE]] = { nofree }
+; CHECK-DAG-UNKNOWN: attributes [[WILLRETURN]]= { willreturn }
+; CHECK-DAG-UNKNOWN: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN]]  = { inaccessiblemem_or_argmemonly nofree nounwind willreturn }
+
+; CHECK-DAG-LINUX: attributes [[INACCESSIBLEMEMONLY_NOFREE_WILLRETURN]] = { inaccessiblememonly nofree willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE]] = { nofree }
+; CHECK-DAG-LINUX: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE_NOUNWIND]] = { nofree nounwind }
+; CHECK-DAG-LINUX: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { inaccessiblememonly nofree nounwind willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]]  = { nofree nounwind readonly willreturn }
+; CHECK-DAG-LINUX: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly nofree nounwind readonly willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { argmemonly nofree nounwind willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind readonly }
+; CHECK-DAG-LINUX: attributes [[INACCESSIBLEMEMORARGONLY_NOUNWIND_WILLRETURN]]  = { inaccessiblemem_or_argmemonly nounwind willreturn }
+; CHECK-DAG-LINUX: attributes [[NOFREE_WILLRETURN]] = { nofree willreturn }
+; CHECK-DAG-LINUX: attributes [[WILLRETURN]]= { willreturn }
+; CHECK-DAG-LINUX: attributes [[INACCESSIBLEMEMORARGONLY_NOFREE_NOUNWIND_WILLRETURN]]  = { inaccessiblemem_or_argmemonly nofree nounwind willreturn }
+; CHECK-DAG-LINUX: attributes [[ARGMEMONLY_NOFREE_NOUNWIND]] = { inaccessiblememonly nofree nounwind }


        


More information about the llvm-branch-commits mailing list