diff options
author | Michael Kuperstein <mkuper@google.com> | 2016-05-26 19:30:49 +0000 |
---|---|---|
committer | Michael Kuperstein <mkuper@google.com> | 2016-05-26 19:30:49 +0000 |
commit | ae21491819051aa41f1e51f597b03764b0093476 (patch) | |
tree | 80b6992f8a0af5a4ef378eb017faee28224f33c6 /llvm/lib/Analysis/BasicAliasAnalysis.cpp | |
parent | d99068d26db69f2cdaba0ad02a6bd92512f04b60 (diff) | |
download | llvm-ae21491819051aa41f1e51f597b03764b0093476.zip llvm-ae21491819051aa41f1e51f597b03764b0093476.tar.gz llvm-ae21491819051aa41f1e51f597b03764b0093476.tar.bz2 |
[BasicAA] Extend inbound GEP negative offset logic to GlobalVariables
r270777 improved the precision of alloca vs. inbounbds GEP alias queries: if
we have (a) an inbounds GEP and (b) a pointer based on an alloca, and the
beginning of the object the GEP points to would have a negative offset with
respect to the alloca, then the GEP can not alias pointer (b).
This makes the same logic fire when (b) is based on a GlobalVariable instead
of an alloca.
Differential Revision: http://reviews.llvm.org/D20652
llvm-svn: 270893
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index f1b60c6..cfb7354 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -955,6 +955,11 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1, // repsect to the alloca, that means the GEP can not alias pointer (b). // Note that the pointer based on the alloca may not be a GEP. For // example, it may be the alloca itself. +// The same applies if (b) is based on a GlobalVariable. Note that just being +// based on isIdentifiedObject() is not enough - we need an identified object +// that does not permit access to negative offsets. For example, a negative +// offset from a noalias argument or call can be inbounds w.r.t the actual +// underlying object. // // For example, consider: // @@ -977,19 +982,22 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1, // the highest %f1 can be is (%alloca + 3). This means %random can not be higher // than (%alloca - 1), and so is not inbounds, a contradiction. bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, - const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompAlloca, - uint64_t AllocaAccessSize) { - // If the alloca access size is unknown, or the GEP isn't inbounds, bail. - if (AllocaAccessSize == MemoryLocation::UnknownSize || !GEPOp->isInBounds()) + const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject, + uint64_t ObjectAccessSize) { + // If the object access size is unknown, or the GEP isn't inbounds, bail. + if (ObjectAccessSize == MemoryLocation::UnknownSize || !GEPOp->isInBounds()) return false; - // We need an alloca, and want to know the offset of the pointer - // from the alloca precisely, so no variable indices are allowed. - if (!isa<AllocaInst>(DecompAlloca.Base) || !DecompAlloca.VarIndices.empty()) + // We need the object to be an alloca or a globalvariable, and want to know + // the offset of the pointer from the object precisely, so no variable + // indices are allowed. + if (!(isa<AllocaInst>(DecompObject.Base) || + isa<GlobalVariable>(DecompObject.Base)) || + !DecompObject.VarIndices.empty()) return false; - int64_t AllocaBaseOffset = DecompAlloca.StructOffset + - DecompAlloca.OtherOffset; + int64_t ObjectBaseOffset = DecompObject.StructOffset + + DecompObject.OtherOffset; // If the GEP has no variable indices, we know the precise offset // from the base, then use it. If the GEP has variable indices, we're in @@ -1000,7 +1008,7 @@ bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp, if (DecompGEP.VarIndices.empty()) GEPBaseOffset += DecompGEP.OtherOffset; - return (GEPBaseOffset >= AllocaBaseOffset + (int64_t)AllocaAccessSize); + return (GEPBaseOffset >= ObjectBaseOffset + (int64_t)ObjectAccessSize); } /// Provides a bunch of ad-hoc rules to disambiguate a GEP instruction against |