[PATCH] D66651: Annotate return values of allocation functions with dereferenceable_or_null

Dávid Bolvanský via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 06:52:57 PDT 2019


xbolva00 created this revision.
xbolva00 added a reviewer: jdoerfert.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
xbolva00 marked an inline comment as done.
xbolva00 added a comment.

I will update/add tests after some initial code review.



================
Comment at: lib/Transforms/InstCombine/InstCombineCalls.cpp:4189
+    CI->addAttribute(AttributeList::ReturnIndex,
+                     Attribute::getWithDereferenceableBytes(
+                         CI->getContext(), Op0C->getZExtValue()));
----------------
Not a typo. OpNewLike never returns null, it just throws exception.


Example
define dso_local noalias i8* @_Z6maixxnv() local_unnamed_addr #0 {
entry:

  %call = tail call noalias dereferenceable_or_null(64) i8* @malloc(i64 64) #6
  ret i8* %call

}


Repository:
  rL LLVM

https://reviews.llvm.org/D66651

Files:
  include/llvm/Analysis/MemoryBuiltins.h
  lib/Analysis/MemoryBuiltins.cpp
  lib/Transforms/InstCombine/InstCombineCalls.cpp


Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4177,8 +4177,42 @@
   return nullptr;
 }
 
+static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
+  CallInst *CI = cast<CallInst>(&Call);
+  ConstantInt *Op0C = dyn_cast<ConstantInt>(CI->getOperand(0));
+  if (isMallocLikeFn(CI, TLI) && Op0C && !Op0C->isNullValue()) {
+    CI->addAttribute(AttributeList::ReturnIndex,
+                     Attribute::getWithDereferenceableOrNullBytes(
+                         CI->getContext(), Op0C->getZExtValue()));
+  } else if (isOpNewLikeFn(CI, TLI) && Op0C && !Op0C->isNullValue()) {
+    CI->addAttribute(AttributeList::ReturnIndex,
+                     Attribute::getWithDereferenceableBytes(
+                         CI->getContext(), Op0C->getZExtValue()));
+  } else if (isReallocLikeFn(CI, TLI)) {
+    ConstantInt *Op1C = dyn_cast<ConstantInt>(CI->getOperand(1));
+    if (Op1C && !Op1C->isNullValue())
+      CI->addAttribute(AttributeList::ReturnIndex,
+                       Attribute::getWithDereferenceableOrNullBytes(
+                           CI->getContext(), Op1C->getZExtValue()));
+  } else if (isCallocLikeFn(CI, TLI) && Op0C && !Op0C->isNullValue()) {
+    ConstantInt *Op1C = dyn_cast<ConstantInt>(CI->getOperand(1));
+    if (Op1C && !Op1C->isNullValue()) {
+      bool Overflow;
+      const APInt &N = Op0C->getValue();
+      APInt Size = N.umul_ov(Op1C->getValue(), Overflow);
+      if (!Overflow)
+        CI->addAttribute(AttributeList::ReturnIndex,
+                         Attribute::getWithDereferenceableOrNullBytes(
+                             CI->getContext(), Size.getZExtValue()));
+    }
+  }
+}
+
 /// Improvements for call, callbr and invoke instructions.
 Instruction *InstCombiner::visitCallBase(CallBase &Call) {
+  if (isAllocationFn(&Call, &TLI))
+    annotateAnyAllocSite(Call, &TLI);
+
   if (isAllocLikeFn(&Call, &TLI))
     return visitAllocSite(Call);
 
Index: lib/Analysis/MemoryBuiltins.cpp
===================================================================
--- lib/Analysis/MemoryBuiltins.cpp
+++ lib/Analysis/MemoryBuiltins.cpp
@@ -276,6 +276,13 @@
   return getAllocationDataForFunction(F, ReallocLike, TLI).hasValue();
 }
 
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., new).
+bool llvm::isOpNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                     bool LookThroughBitCast) {
+  return getAllocationData(V, OpNewLike, TLI, LookThroughBitCast).hasValue();
+}
+
 /// extractMallocCall - Returns the corresponding CallInst if the instruction
 /// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
 /// ignore InvokeInst here.
Index: include/llvm/Analysis/MemoryBuiltins.h
===================================================================
--- include/llvm/Analysis/MemoryBuiltins.h
+++ include/llvm/Analysis/MemoryBuiltins.h
@@ -93,6 +93,11 @@
 /// reallocates memory (e.g., realloc).
 bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
 
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., new).
+bool isOpNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                     bool LookThroughBitCast = false);
+
 //===----------------------------------------------------------------------===//
 //  malloc Call Utility Functions.
 //


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66651.216830.patch
Type: text/x-patch
Size: 3574 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190823/920fc4e3/attachment.bin>


More information about the llvm-commits mailing list