[llvm] 67aac91 - [BuildLibCalls] Add noundef to the returned pointers of allocators and argument of free

Juneyoung Lee via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 10:14:16 PDT 2020


Author: Juneyoung Lee
Date: 2020-09-30T02:13:48+09:00
New Revision: 67aac915ba94a75cbdb3c9c5f6c8e9904829ce37

URL: https://github.com/llvm/llvm-project/commit/67aac915ba94a75cbdb3c9c5f6c8e9904829ce37
DIFF: https://github.com/llvm/llvm-project/commit/67aac915ba94a75cbdb3c9c5f6c8e9904829ce37.diff

LOG: [BuildLibCalls] Add noundef to the returned pointers of allocators and argument of free

This patch adds noundef to the returned pointers of allocators (malloc, calloc, ...)
and the pointer argument of free.
The returned pointer of allocators cannot be poison or (partially) undef.
Since the pointer that is given to free should precisely have zero offset,
it cannot be poison or (partially) undef too.

For the size arguments of allocators, noundef wasn't attached simply because
I wasn't sure whether attaching it is okay or not.

Reviewed By: jdoerfert

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

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 64e168d48da9..2a0cdf617610 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -105,14 +105,18 @@ static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
   return true;
 }
 
-static bool setRetAndArgsNoUndef(Function &F) {
-  bool Changed = false;
+static bool setRetNoUndef(Function &F) {
   if (!F.getReturnType()->isVoidTy() &&
       !F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef)) {
     F.addAttribute(AttributeList::ReturnIndex, Attribute::NoUndef);
     ++NumNoUndef;
-    Changed = true;
+    return true;
   }
+  return false;
+}
+
+static bool setArgsNoUndef(Function &F) {
+  bool Changed = false;
   for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
     if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {
       F.addParamAttr(ArgNo, Attribute::NoUndef);
@@ -123,6 +127,10 @@ static bool setRetAndArgsNoUndef(Function &F) {
   return Changed;
 }
 
+static bool setRetAndArgsNoUndef(Function &F) {
+  return setRetNoUndef(F) | setArgsNoUndef(F);
+}
+
 static bool setRetNonNull(Function &F) {
   assert(F.getReturnType()->isPointerTy() &&
          "nonnull applies only to pointers");
@@ -318,6 +326,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 0);
     return Changed;
   case LibFunc_malloc:
+    Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     return Changed;
@@ -383,10 +392,14 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_realloc:
+    Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
+  case LibFunc_reallocf:
+    Changed |= setRetNoUndef(F);
+    return Changed;
   case LibFunc_read:
     // May throw; "read" is a valid pthread cancellation point.
     Changed |= setRetAndArgsNoUndef(F);
@@ -427,6 +440,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_aligned_alloc:
+    Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     return Changed;
@@ -448,6 +462,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_calloc:
+    Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     return Changed;
@@ -501,6 +516,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
   case LibFunc_free:
+    Changed |= setArgsNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setDoesNotCapture(F, 0);
     return Changed;
@@ -723,6 +739,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
     Changed |= setOnlyReadsMemory(F, 1);
     return Changed;
   case LibFunc_valloc:
+    Changed |= setRetNoUndef(F);
     Changed |= setDoesNotThrow(F);
     Changed |= setRetDoesNotAlias(F);
     return Changed;
@@ -891,6 +908,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
   case LibFunc_msvc_new_array_int: // new[](unsigned int)
   case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
     // Operator new always returns a nonnull noalias pointer
+    Changed |= setRetNoUndef(F);
     Changed |= setRetNonNull(F);
     Changed |= setRetDoesNotAlias(F);
     return Changed;

diff  --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index d4b0f0fb679d..c374e90cc075 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 nonnull i8* @_Znwj(i64) [[G0:#[0-9]+]]
+; CHECK: declare noalias noundef nonnull i8* @_Znwj(i64) [[G0:#[0-9]+]]
 declare i8* @_Znwm(i64)
-; CHECK: declare noalias nonnull i8* @_Znwm(i64) [[G0]]
+; CHECK: declare noalias noundef nonnull i8* @_Znwm(i64) [[G0]]
 
 declare i32 @__nvvm_reflect(i8*)
 ; CHECK-NVPTX: declare noundef i32 @__nvvm_reflect(i8* noundef) [[G0:#[0-9]+]]
@@ -253,7 +253,7 @@ declare void @bcopy(i8*, i8*, i64)
 ; CHECK: declare void @bzero(i8* nocapture, i64) [[G1]]
 declare void @bzero(i8*, i64)
 
-; CHECK: declare noalias i8* @calloc(i64, i64) [[G1]]
+; CHECK: declare noalias noundef i8* @calloc(i64, i64) [[G1]]
 declare i8* @calloc(i64, i64)
 
 ; CHECK: declare double @cbrt(double) [[G0]]
@@ -451,7 +451,7 @@ declare i32 @fputs(i8*, %opaque*)
 ; CHECK: declare noundef i64 @fread(i8* nocapture noundef, i64 noundef, i64 noundef, %opaque* nocapture noundef) [[G1]]
 declare i64 @fread(i8*, i64, i64, %opaque*)
 
-; CHECK: declare void @free(i8* nocapture) [[G3:#[0-9]+]]
+; CHECK: declare void @free(i8* nocapture noundef) [[G3:#[0-9]+]]
 declare void @free(i8*)
 
 ; CHECK: declare double @frexp(double, i32* nocapture) [[G1]]
@@ -613,7 +613,7 @@ declare i32 @lstat(i8*, %opaque*)
 ; CHECK-LINUX: declare noundef i32 @lstat64(i8* nocapture noundef readonly, %opaque* nocapture noundef) [[G1]]
 declare i32 @lstat64(i8*, %opaque*)
 
-; CHECK: declare noalias i8* @malloc(i64) [[G1]]
+; CHECK: declare noalias noundef i8* @malloc(i64) [[G1]]
 declare i8* @malloc(i64)
 
 ; CHECK-LINUX: declare noalias i8* @memalign(i64, i64) [[G0]]
@@ -726,10 +726,10 @@ declare i64 @read(i32, i8*, i64)
 ; CHECK: declare noundef i64 @readlink(i8* nocapture noundef readonly, i8* nocapture noundef, i64 noundef) [[G1]]
 declare i64 @readlink(i8*, i8*, i64)
 
-; CHECK: declare noalias i8* @realloc(i8* nocapture, i64) [[G3]]
+; CHECK: declare noalias noundef i8* @realloc(i8* nocapture, i64) [[G3]]
 declare i8* @realloc(i8*, i64)
 
-; CHECK: declare i8* @reallocf(i8*, i64)
+; CHECK: declare noundef i8* @reallocf(i8*, i64)
 declare i8* @reallocf(i8*, i64)
 
 ; CHECK: declare noundef i8* @realpath(i8* nocapture noundef readonly, i8* noundef) [[G1]]
@@ -978,7 +978,7 @@ declare i32 @utime(i8*, %opaque*)
 ; CHECK: declare noundef i32 @utimes(i8* nocapture noundef readonly, %opaque* nocapture noundef readonly) [[G1]]
 declare i32 @utimes(i8*, %opaque*)
 
-; CHECK: declare noalias i8* @valloc(i64) [[G1]]
+; CHECK: declare noalias noundef i8* @valloc(i64) [[G1]]
 declare i8* @valloc(i64)
 
 ; CHECK: declare noundef i32 @vfprintf(%opaque* nocapture noundef, i8* nocapture noundef readonly, %opaque* noundef) [[G1]]


        


More information about the llvm-commits mailing list