[PATCH] D29488: [DA] Fix for PR31848: Treat AddRec subscripts containing extra loops as NonLinear

Philip Pfaffe via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 3 05:06:10 PST 2017


philip.pfaffe created this revision.

The SCEVAddRecExpr nest describing a Subscript may contain loops in which the corresponding memory access is not contained in. This causes errors in DependenceAnalysis. An example is this (see PR31848 for details):

void foo(int *A, int n) {

  for (int j = 0; j < n; ++j) {
    for (int i = 0; i < n; ++i) {
      for (int di = -1; di <= 1; ++di) {
        for (int dj = -1; dj <= 1; ++dj) {
          int x = i + di;
          int y = j + dj;
          while (x < 0)
            x += n;
          while (y < 0)
            y += n;
  
          A[y * n + x] = 7;
        }
      }
    }
  }

}

This patch detects that, and classifies the subscripts as NonLinear. This solution is possibly a bit over-pessimistic. For instance, subscripts might well be legal, if its extraneous loops are loop invariant wrt. there respective relevant parents in the loop nest. I haven't been able to produce this situation however, so I'm not sure whether that can actually happen, or whether it triggers entirely different paths of DA.


Repository:
  rL LLVM

https://reviews.llvm.org/D29488

Files:
  lib/Analysis/DependenceAnalysis.cpp


Index: lib/Analysis/DependenceAnalysis.cpp
===================================================================
--- lib/Analysis/DependenceAnalysis.cpp
+++ lib/Analysis/DependenceAnalysis.cpp
@@ -848,14 +848,24 @@
   }
 }
 
+static const Loop *getLowestCommonAncestor(const Loop *A, const Loop *B) {
+  if (!A || !B)
+    return nullptr;
+  if (A == B)
+    return A;
+  if (A->getLoopDepth() > B->getLoopDepth())
+    return getLowestCommonAncestor(A->getParentLoop(), B);
+  return getLowestCommonAncestor(A, B->getParentLoop());
+}
 
 // Examine the scev and return true iff it's linear.
 // Collect any loops mentioned in the set of "Loops".
 bool DependenceInfo::checkSrcSubscript(const SCEV *Src, const Loop *LoopNest,
                                        SmallBitVector &Loops) {
   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Src);
   if (!AddRec)
     return isLoopInvariant(Src, LoopNest);
+  const auto *Loop = AddRec->getLoop();
   const SCEV *Start = AddRec->getStart();
   const SCEV *Step = AddRec->getStepRecurrence(*SE);
   const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop());
@@ -866,6 +876,12 @@
         return false;
     }
   }
+
+  // Test if the Loop this AddRec refers to is an ancestor of LoopNest
+  auto *LCA = getLowestCommonAncestor(Loop, LoopNest);
+  if (LCA && LCA != Loop) // Loop is a sibling or uncle of LoopNest.
+    return false;
+
   if (!isLoopInvariant(Step, LoopNest))
     return false;
   Loops.set(mapSrcLoop(AddRec->getLoop()));
@@ -881,19 +897,25 @@
   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Dst);
   if (!AddRec)
     return isLoopInvariant(Dst, LoopNest);
+  const auto *Loop = AddRec->getLoop();
   const SCEV *Start = AddRec->getStart();
   const SCEV *Step = AddRec->getStepRecurrence(*SE);
-  const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop());
+  const SCEV *UB = SE->getBackedgeTakenCount(Loop);
   if (!isa<SCEVCouldNotCompute>(UB)) {
     if (SE->getTypeSizeInBits(Start->getType()) <
         SE->getTypeSizeInBits(UB->getType())) {
       if (!AddRec->getNoWrapFlags())
         return false;
     }
   }
+  // Test if the Loop this AddRec refers to is an ancestor of LoopNest
+  auto *LCA = getLowestCommonAncestor(Loop, LoopNest);
+  if (LCA && LCA != Loop) // Loop is a sibling or uncle of LoopNest.
+    return false;
+
   if (!isLoopInvariant(Step, LoopNest))
     return false;
-  Loops.set(mapDstLoop(AddRec->getLoop()));
+  Loops.set(mapDstLoop(Loop));
   return checkDstSubscript(Start, LoopNest, Loops);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29488.86950.patch
Type: text/x-patch
Size: 2531 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170203/a7bbd872/attachment.bin>


More information about the llvm-commits mailing list