summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kuperstein <mkuper@google.com>2016-05-26 19:30:49 +0000
committerMichael Kuperstein <mkuper@google.com>2016-05-26 19:30:49 +0000
commitae21491819051aa41f1e51f597b03764b0093476 (patch)
tree80b6992f8a0af5a4ef378eb017faee28224f33c6
parentd99068d26db69f2cdaba0ad02a6bd92512f04b60 (diff)
downloadbcm5719-llvm-ae21491819051aa41f1e51f597b03764b0093476.tar.gz
bcm5719-llvm-ae21491819051aa41f1e51f597b03764b0093476.zip
[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
-rw-r--r--llvm/include/llvm/Analysis/BasicAliasAnalysis.h4
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp28
-rw-r--r--llvm/test/Analysis/BasicAA/negoffset.ll11
3 files changed, 31 insertions, 12 deletions
diff --git a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
index c1b0902e7d1..a3195d17b02 100644
--- a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -157,8 +157,8 @@ private:
const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT);
static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
- const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompAlloca,
- uint64_t AllocaAccessSize);
+ const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
+ uint64_t ObjectAccessSize);
/// \brief A Heuristic for aliasGEP that searches for a constant offset
/// between the variables.
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index f1b60c6432b..cfb73541820 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
diff --git a/llvm/test/Analysis/BasicAA/negoffset.ll b/llvm/test/Analysis/BasicAA/negoffset.ll
index 9b9af787692..e8550948dc1 100644
--- a/llvm/test/Analysis/BasicAA/negoffset.ll
+++ b/llvm/test/Analysis/BasicAA/negoffset.ll
@@ -26,6 +26,17 @@ define void @arg(i32* %arg) {
ret void
}
+@gv = global i32 1
+; CHECK-LABEL: Function: global:
+; CHECK-DAG: MayAlias: i32* %p0, i32* @gv
+; CHECK-DAG: NoAlias: i32* %p1, i32* @gv
+define void @global() {
+ %random = call i32* @random.i32(i32* @gv)
+ %p0 = getelementptr inbounds i32, i32* %random, i32 0
+ %p1 = getelementptr inbounds i32, i32* %random, i32 1
+ ret void
+}
+
; CHECK-LABEL: Function: struct:
; CHECK-DAG: MayAlias: i32* %f0, i32* %p0
; CHECK-DAG: MayAlias: i32* %f1, i32* %p0
OpenPOWER on IntegriCloud