[PATCH] D50644: [LAA] Allow runtime checks when strides different but address space does not wrap around

Anna Thomas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 13 10:02:22 PDT 2018


anna created this revision.
anna added reviewers: sbaranga, anemet.

Currently we allow runtime checks when the distance between source and sink is
not a constant in the loop, but the strides for two memory accesses are the same
(and are addrecs).

This change handles the reverse case: the distance between the source and the
sink is a constant in the loop, but the strides for the memory accesses are not
the same.

I have not added any test cases yet. There may even be changes needed to the
runtime check generation to teach this case. However, this first patch is to 
see if I missed some obvious legality constraint.

Given the strides are addrecs, we are guaranteed they do not wrap around, so
wide loads in vectorization is still legal.

If we have 2 memory accesses: load of array A and store into arrayB, where
distance = sink - source is a loop invariant computation.
Stride of ArrayA = z. Stride of ArrayB = y.

The runtime check needed is ArrayA + (z * trip count) - { ArrayB + (y * trip
count) } > Vectorization factor.


Repository:
  rL LLVM

https://reviews.llvm.org/D50644

Files:
  lib/Analysis/LoopAccessAnalysis.cpp


Index: lib/Analysis/LoopAccessAnalysis.cpp
===================================================================
--- lib/Analysis/LoopAccessAnalysis.cpp
+++ lib/Analysis/LoopAccessAnalysis.cpp
@@ -1463,20 +1463,27 @@
   LLVM_DEBUG(dbgs() << "LAA: Distance for " << *InstMap[AIdx] << " to "
                     << *InstMap[BIdx] << ": " << *Dist << "\n");
 
+  const SCEVConstant *C = dyn_cast<SCEVConstant>(Dist);
   // Need accesses with constant stride. We don't want to vectorize
   // "A[B[i]] += ..." and similar code or pointer arithmetic that could wrap in
   // the address space.
   if (!StrideAPtr || !StrideBPtr || StrideAPtr != StrideBPtr){
     LLVM_DEBUG(dbgs() << "Pointer access with non-constant stride\n");
+    // Given StrideAPtr and StrideBPtr exists, we know the pointer arithmetic
+    // does not wrap. Even if they are not the same stride, if the distance
+    // between source and sink is constant wrt the loop, then let us try with
+    // runtime checks.
+    if (StrideAPtr && StrideBPtr &&
+        (C || PSE.getSE()->isLoopInvariant(Dist, InnermostLoop)))
+      ShouldRetryWithRuntimeCheck = true;
     return Dependence::Unknown;
   }
 
   Type *ATy = APtr->getType()->getPointerElementType();
   Type *BTy = BPtr->getType()->getPointerElementType();
   auto &DL = InnermostLoop->getHeader()->getModule()->getDataLayout();
   uint64_t TypeByteSize = DL.getTypeAllocSize(ATy);
   uint64_t Stride = std::abs(StrideAPtr);
-  const SCEVConstant *C = dyn_cast<SCEVConstant>(Dist);
   if (!C) {
     if (TypeByteSize == DL.getTypeAllocSize(BTy) &&
         isSafeDependenceDistance(DL, *(PSE.getSE()),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50644.160381.patch
Type: text/x-patch
Size: 1629 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180813/addab78e/attachment.bin>


More information about the llvm-commits mailing list