[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