[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