diff options
author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-05-11 14:43:28 +0000 |
---|---|---|
committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-05-11 14:43:28 +0000 |
commit | 7a26326442ed1feadbeef62799daba43e2912a3c (patch) | |
tree | d6b74fce250e7a1a930d6bf17da025fe8fc435a4 | |
parent | 610a4e916e5ceb01386d8602f928c7c00f362168 (diff) | |
download | bcm5719-llvm-7a26326442ed1feadbeef62799daba43e2912a3c.tar.gz bcm5719-llvm-7a26326442ed1feadbeef62799daba43e2912a3c.zip |
NFC. Introduce Value::isPointerDereferenceable
Extract a part of isDereferenceableAndAlignedPointer functionality to Value:
Reviewed By: hfinkel, sanjoy
Differential Revision: http://reviews.llvm.org/D17611
llvm-svn: 269190
-rw-r--r-- | llvm/include/llvm/IR/Value.h | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/Loads.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/IR/Value.cpp | 23 |
3 files changed, 34 insertions, 12 deletions
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h index 39ad9d8145c..fe5c33765c3 100644 --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -511,6 +511,12 @@ public: /// dereferenceable up to the returned number of bytes. unsigned getPointerDereferenceableBytes(bool &CanBeNull) const; + /// \brief Returns true if the pointer value is fully dereferenceable. + /// + /// Sets CanBeNull to true if the pointer is either null or can be fully + /// dereferenceable. + bool isPointerDereferenceable(bool &CanBeNull) const; + /// \brief Returns an alignment of the pointer value. /// /// Returns an alignment which is either specified explicitly, e.g. via diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp index 58a8723626b..b0355ccee87 100644 --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -91,9 +91,12 @@ static bool isDereferenceableAndAlignedPointer( // Note that it is not safe to speculate into a malloc'd region because // malloc may return null. - // These are obviously ok if aligned. - if (isa<AllocaInst>(V)) + bool CheckForNonNull; + if (V->isPointerDereferenceable(CheckForNonNull)) { + if (CheckForNonNull && !isKnownNonNullAt(V, CtxI, DT, TLI)) + return false; return isAligned(V, Align, DL); + } // It's not always safe to follow a bitcast, for example: // bitcast i8* (alloca i8) to i32* @@ -112,16 +115,6 @@ static bool isDereferenceableAndAlignedPointer( CtxI, DT, TLI, Visited); } - // Global variables which can't collapse to null are ok. - if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) - if (!GV->hasExternalWeakLinkage()) - return isAligned(V, Align, DL); - - // byval arguments are okay. - if (const Argument *A = dyn_cast<Argument>(V)) - if (A->hasByValAttr()) - return isAligned(V, Align, DL); - if (isDereferenceableFromAttribute(V, DL, CtxI, DT, TLI)) return isAligned(V, Align, DL); diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index fb8d00f5657..de2c5991daa 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -559,6 +559,29 @@ unsigned Value::getPointerDereferenceableBytes(bool &CanBeNull) const { return DerefBytes; } +bool Value::isPointerDereferenceable(bool &CanBeNull) const { + assert(getType()->isPointerTy() && "must be pointer"); + + CanBeNull = false; + + // These are obviously ok. + if (isa<AllocaInst>(this)) + return true; + + // Global variables which can't collapse to null are ok. + // TODO: return true for those but set CanBeNull flag + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) + if (!GV->hasExternalWeakLinkage()) + return true; + + // byval arguments are okay. + if (const Argument *A = dyn_cast<Argument>(this)) + if (A->hasByValAttr()) + return true; + + return false; +} + unsigned Value::getPointerAlignment(const DataLayout &DL) const { assert(getType()->isPointerTy() && "must be pointer"); |