[llvm] 5f05ff0 - [BasicAA] Improve scalable vector handling

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 14 11:24:00 PDT 2021


Author: Nikita Popov
Date: 2021-10-14T20:23:50+02:00
New Revision: 5f05ff081f391fd482e3a5c3ea9f191c6961c42e

URL: https://github.com/llvm/llvm-project/commit/5f05ff081f391fd482e3a5c3ea9f191c6961c42e
DIFF: https://github.com/llvm/llvm-project/commit/5f05ff081f391fd482e3a5c3ea9f191c6961c42e.diff

LOG: [BasicAA] Improve scalable vector handling

Currently, DecomposeGEP() bails out on the whole decomposition if
it encounters a scalable GEP type anywhere. However, it is fine to
still analyze other GEPs that we look through before hitting the
scalable GEP. This does mean that the decomposed GEP base is no
longer required to be the same as the underlying object. However,
I don't believe this property is necessary for correctness anymore.

This allows us to compute slightly more precise aliasing results
for GEP chains containing scalable vectors, though my primary
interest here is simplifying the code.

Differential Revision: https://reviews.llvm.org/D110511

Added: 
    

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp
    llvm/test/Analysis/BasicAA/vscale.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 69f5cf025135b..7d782cbec56ba 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -83,8 +83,7 @@ STATISTIC(SearchTimes, "Number of times a GEP is decomposed");
 const unsigned MaxNumPhiBBsValueReachabilityCheck = 20;
 
 // The max limit of the search depth in DecomposeGEPExpression() and
-// getUnderlyingObject(), both functions need to use the same search
-// depth otherwise the algorithm in aliasGEP will assert.
+// getUnderlyingObject().
 static const unsigned MaxLookupSearchDepth = 6;
 
 bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA,
@@ -494,8 +493,6 @@ struct BasicAAResult::DecomposedGEP {
   APInt Offset;
   // Scaled variable (non-constant) indices.
   SmallVector<VariableGEPIndex, 4> VarIndices;
-  // Is GEP index scale compile-time constant.
-  bool HasCompileTimeConstantScale;
   // Are all operations inbounds GEPs or non-indexing operations?
   // (None iff expression doesn't involve any geps)
   Optional<bool> InBounds;
@@ -513,8 +510,7 @@ struct BasicAAResult::DecomposedGEP {
         OS << ", ";
       VarIndices[i].print(OS);
     }
-    OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale
-       << ")";
+    OS << "])";
   }
 };
 
@@ -526,11 +522,6 @@ struct BasicAAResult::DecomposedGEP {
 /// in the VarIndices vector) are Value*'s that are known to be scaled by the
 /// specified amount, but which may have other unrepresented high bits. As
 /// such, the gep cannot necessarily be reconstructed from its decomposed form.
-///
-/// This function is capable of analyzing everything that getUnderlyingObject
-/// can look through. To be able to do that getUnderlyingObject and
-/// DecomposeGEPExpression must use the same search depth
-/// (MaxLookupSearchDepth).
 BasicAAResult::DecomposedGEP
 BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
                                       AssumptionCache *AC, DominatorTree *DT) {
@@ -542,7 +533,6 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
   unsigned MaxPointerSize = DL.getMaxPointerSizeInBits();
   DecomposedGEP Decomposed;
   Decomposed.Offset = APInt(MaxPointerSize, 0);
-  Decomposed.HasCompileTimeConstantScale = true;
   do {
     // See if this is a bitcast or GEP.
     const Operator *Op = dyn_cast<Operator>(V);
@@ -605,7 +595,6 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
     // constant.
     if (isa<ScalableVectorType>(GEPOp->getSourceElementType())) {
       Decomposed.Base = V;
-      Decomposed.HasCompileTimeConstantScale = false;
       return Decomposed;
     }
 
@@ -1145,16 +1134,10 @@ AliasResult BasicAAResult::aliasGEP(
   DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
   DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);
 
-  // Don't attempt to analyze the decomposed GEP if index scale is not a
-  // compile-time constant.
-  if (!DecompGEP1.HasCompileTimeConstantScale ||
-      !DecompGEP2.HasCompileTimeConstantScale)
+  // Bail if we were not able to decompose anything.
+  if (DecompGEP1.Base == GEP1 && DecompGEP2.Base == V2)
     return AliasResult::MayAlias;
 
-  assert(DecompGEP1.Base == UnderlyingV1 && DecompGEP2.Base == UnderlyingV2 &&
-         "DecomposeGEPExpression returned a result 
diff erent from "
-         "getUnderlyingObject");
-
   // Subtract the GEP2 pointer from the GEP1 pointer to find out their
   // symbolic 
diff erence.
   subtractDecomposedGEPs(DecompGEP1, DecompGEP2);

diff  --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll
index ecd3091e92fb0..42ce45dfae24b 100644
--- a/llvm/test/Analysis/BasicAA/vscale.ll
+++ b/llvm/test/Analysis/BasicAA/vscale.ll
@@ -130,7 +130,7 @@ define void @gep_bitcast_2(<vscale x 4 x i32>* %p) {
 ; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_1
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_1
-; CHECK-DAG:  MayAlias:     i32* %gep, i32* %gep_rec_1
+; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
 define void @gep_recursion_level_1(i32* %a, <vscale x 4 x i32>* %p) {
   %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
   %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
@@ -143,7 +143,7 @@ define void @gep_recursion_level_1(i32* %a, <vscale x 4 x i32>* %p) {
 ; CHECK-DAG:  MayAlias:     i32* %a, i32* %gep_rec_1
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_1
-; CHECK-DAG:  MayAlias:     i32* %gep, i32* %gep_rec_1
+; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
 define void @gep_recursion_level_1_bitcast(i32* %a) {
   %p = bitcast i32* %a to <vscale x 4 x i32>*
   %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
@@ -159,9 +159,9 @@ define void @gep_recursion_level_1_bitcast(i32* %a) {
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_1
 ; CHECK-DAG:  MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_2
-; CHECK-DAG:  MayAlias:     i32* %gep, i32* %gep_rec_1
-; CHECK-DAG:  MayAlias:     i32* %gep, i32* %gep_rec_2
-; CHECK-DAG:  MayAlias:     i32* %gep_rec_1, i32* %gep_rec_2
+; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_1
+; CHECK-DAG:  NoAlias:      i32* %gep, i32* %gep_rec_2
+; CHECK-DAG:  NoAlias:      i32* %gep_rec_1, i32* %gep_rec_2
 define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
   %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
   %gep_rec_1 = getelementptr i32, i32* %gep, i64 1
@@ -185,27 +185,27 @@ define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
 ; CHECK-DAG: MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_4
 ; CHECK-DAG: MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_5
 ; CHECK-DAG: MayAlias:     <vscale x 4 x i32>* %p, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_1
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_2
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_3
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_4
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_5
-; CHECK-DAG: MayAlias:     i32* %gep, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep_rec_1, i32* %gep_rec_2
-; CHECK-DAG: MayAlias:     i32* %gep_rec_1, i32* %gep_rec_3
-; CHECK-DAG: MayAlias:     i32* %gep_rec_1, i32* %gep_rec_4
-; CHECK-DAG: MayAlias:     i32* %gep_rec_1, i32* %gep_rec_5
-; CHECK-DAG: MayAlias:     i32* %gep_rec_1, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep_rec_2, i32* %gep_rec_3
-; CHECK-DAG: MayAlias:     i32* %gep_rec_2, i32* %gep_rec_4
-; CHECK-DAG: MayAlias:     i32* %gep_rec_2, i32* %gep_rec_5
-; CHECK-DAG: MayAlias:     i32* %gep_rec_2, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep_rec_3, i32* %gep_rec_4
-; CHECK-DAG: MayAlias:     i32* %gep_rec_3, i32* %gep_rec_5
-; CHECK-DAG: MayAlias:     i32* %gep_rec_3, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep_rec_4, i32* %gep_rec_5
-; CHECK-DAG: MayAlias:     i32* %gep_rec_4, i32* %gep_rec_6
-; CHECK-DAG: MayAlias:     i32* %gep_rec_5, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_1
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_2
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_3
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_4
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_5
+; CHECK-DAG: NoAlias:      i32* %gep, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_2
+; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_3
+; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_4
+; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_5
+; CHECK-DAG: NoAlias:      i32* %gep_rec_1, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_3
+; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_4
+; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_5
+; CHECK-DAG: NoAlias:      i32* %gep_rec_2, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_4
+; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_5
+; CHECK-DAG: NoAlias:      i32* %gep_rec_3, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep_rec_4, i32* %gep_rec_5
+; CHECK-DAG: NoAlias:      i32* %gep_rec_4, i32* %gep_rec_6
+; CHECK-DAG: NoAlias:      i32* %gep_rec_5, i32* %gep_rec_6
 ; GEP max lookup depth was set to 6.
 define void @gep_recursion_max_lookup_depth_reached(i32* %a, <vscale x 4 x i32>* %p) {
   %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2


        


More information about the llvm-commits mailing list