[llvm] r270893 - [BasicAA] Extend inbound GEP negative offset logic to GlobalVariables

Michael Kuperstein via llvm-commits llvm-commits at lists.llvm.org
Thu May 26 12:30:49 PDT 2016


Author: mkuper
Date: Thu May 26 14:30:49 2016
New Revision: 270893

URL: http://llvm.org/viewvc/llvm-project?rev=270893&view=rev
Log:
[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

Modified:
    llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h
    llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/trunk/test/Analysis/BasicAA/negoffset.ll

Modified: llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h?rev=270893&r1=270892&r2=270893&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/BasicAliasAnalysis.h Thu May 26 14:30:49 2016
@@ -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.

Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=270893&r1=270892&r2=270893&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Thu May 26 14:30:49 2016
@@ -955,6 +955,11 @@ static AliasResult aliasSameBasePointerG
 // 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 aliasSameBasePointerG
 // 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::isGEPBaseAtNegativeO
   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

Modified: llvm/trunk/test/Analysis/BasicAA/negoffset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/negoffset.ll?rev=270893&r1=270892&r2=270893&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/negoffset.ll (original)
+++ llvm/trunk/test/Analysis/BasicAA/negoffset.ll Thu May 26 14:30:49 2016
@@ -26,6 +26,17 @@ define void @arg(i32* %arg) {
   ret void
 }
 
+ at 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




More information about the llvm-commits mailing list