diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index f65515ca38722..b0d29e2409f76 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1805,20 +1805,20 @@ void MemoryDepChecker::mergeInStatus(VectorizationSafetyStatus S) { } /// Given a dependence-distance \p Dist between two -/// memory accesses, that have the same stride whose absolute value is given -/// in \p Stride, and that have the same type size \p TypeByteSize, -/// in a loop whose takenCount is \p BackedgeTakenCount, check if it is -/// possible to prove statically that the dependence distance is larger -/// than the range that the accesses will travel through the execution of -/// the loop. If so, return true; false otherwise. This is useful for -/// example in loops such as the following (PR31098): +/// memory accesses, that have strides in the same direction whose absolute +/// value of the maximum stride is given in \p MaxStride, and that have the same +/// type size \p TypeByteSize, in a loop whose takenCount is \p +/// BackedgeTakenCount, check if it is possible to prove statically that the +/// dependence distance is larger than the range that the accesses will travel +/// through the execution of the loop. If so, return true; false otherwise. This +/// is useful for example in loops such as the following (PR31098): /// for (i = 0; i < D; ++i) { /// = out[i]; /// out[i+D] = /// } static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE, const SCEV &BackedgeTakenCount, - const SCEV &Dist, uint64_t Stride, + const SCEV &Dist, uint64_t MaxStride, uint64_t TypeByteSize) { // If we can prove that @@ -1838,7 +1838,7 @@ static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE, // will be executed only if LoopCount >= VF, proving distance >= LoopCount // also guarantees that distance >= VF. // - const uint64_t ByteStride = Stride * TypeByteSize; + const uint64_t ByteStride = MaxStride * TypeByteSize; const SCEV *Step = SE.getConstant(BackedgeTakenCount.getType(), ByteStride); const SCEV *Product = SE.getMulExpr(&BackedgeTakenCount, Step); @@ -2046,14 +2046,15 @@ MemoryDepChecker::Dependence::DepType MemoryDepChecker::isDependent( ScalarEvolution &SE = *PSE.getSE(); auto &DL = InnermostLoop->getHeader()->getModule()->getDataLayout(); + uint64_t MaxStride = std::max(StrideA, StrideB); - // If the distance between the acecsses is larger than their absolute stride - // multiplied by the backedge taken count, the accesses are independet, i.e. - // they are far enough appart that accesses won't access the same location - // across all loop ierations. - if (HasSameSize && CommonStride && + // If the distance between the acecsses is larger than their maximum absolute + // stride multiplied by the backedge taken count, the accesses are independet, + // i.e. they are far enough appart that accesses won't access the same + // location across all loop ierations. + if (HasSameSize && isSafeDependenceDistance(DL, SE, *(PSE.getBackedgeTakenCount()), *Dist, - *CommonStride, TypeByteSize)) + MaxStride, TypeByteSize)) return Dependence::NoDep; const SCEVConstant *C = dyn_cast(Dist); diff --git a/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll b/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll index 5312c36e436a2..8c7df4bdf5a5a 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll @@ -8,10 +8,6 @@ define void @forward_dep_known_safe_due_to_backedge_taken_count(ptr %A) { ; CHECK-NEXT: loop: ; CHECK-NEXT: Memory dependences are safe ; CHECK-NEXT: Dependences: -; CHECK-NEXT: Forward: -; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 -> -; CHECK-NEXT: store i32 %add, ptr %gep, align 4 -; CHECK-EMPTY: ; CHECK-NEXT: Run-time memory checks: ; CHECK-NEXT: Grouped accesses: ; CHECK-EMPTY: @@ -80,13 +76,8 @@ exit: define void @unknown_dep_known_safe_due_to_backedge_taken_count(ptr %A) { ; CHECK-LABEL: 'unknown_dep_known_safe_due_to_backedge_taken_count' ; CHECK-NEXT: loop: -; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop -; CHECK-NEXT: Unknown data dependence. +; CHECK-NEXT: Memory dependences are safe ; CHECK-NEXT: Dependences: -; CHECK-NEXT: Unknown: -; CHECK-NEXT: %l = load i32, ptr %gep, align 4 -> -; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4 -; CHECK-EMPTY: ; CHECK-NEXT: Run-time memory checks: ; CHECK-NEXT: Grouped accesses: ; CHECK-EMPTY: