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
This commit is contained in:
Artur Pilipenko 2016-05-11 14:43:28 +00:00
parent 610a4e916e
commit 7a26326442
3 changed files with 34 additions and 12 deletions

View File

@ -511,6 +511,12 @@ public:
/// dereferenceable up to the returned number of bytes. /// dereferenceable up to the returned number of bytes.
unsigned getPointerDereferenceableBytes(bool &CanBeNull) const; 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. /// \brief Returns an alignment of the pointer value.
/// ///
/// Returns an alignment which is either specified explicitly, e.g. via /// Returns an alignment which is either specified explicitly, e.g. via

View File

@ -91,9 +91,12 @@ static bool isDereferenceableAndAlignedPointer(
// Note that it is not safe to speculate into a malloc'd region because // Note that it is not safe to speculate into a malloc'd region because
// malloc may return null. // malloc may return null.
// These are obviously ok if aligned. bool CheckForNonNull;
if (isa<AllocaInst>(V)) if (V->isPointerDereferenceable(CheckForNonNull)) {
if (CheckForNonNull && !isKnownNonNullAt(V, CtxI, DT, TLI))
return false;
return isAligned(V, Align, DL); return isAligned(V, Align, DL);
}
// It's not always safe to follow a bitcast, for example: // It's not always safe to follow a bitcast, for example:
// bitcast i8* (alloca i8) to i32* // bitcast i8* (alloca i8) to i32*
@ -112,16 +115,6 @@ static bool isDereferenceableAndAlignedPointer(
CtxI, DT, TLI, Visited); 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)) if (isDereferenceableFromAttribute(V, DL, CtxI, DT, TLI))
return isAligned(V, Align, DL); return isAligned(V, Align, DL);

View File

@ -559,6 +559,29 @@ unsigned Value::getPointerDereferenceableBytes(bool &CanBeNull) const {
return DerefBytes; 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 { unsigned Value::getPointerAlignment(const DataLayout &DL) const {
assert(getType()->isPointerTy() && "must be pointer"); assert(getType()->isPointerTy() && "must be pointer");