Skip to content

Commit 82219e5

Browse files
authored
[LAA] Pass maximum stride to isSafeDependenceDistance. (#90036)
As discussed in #88039, support different strides with isSafeDependenceDistance by passing the maximum of both strides. isSafeDependenceDistance tries to prove that |Dist| > BackedgeTakenCount * Step holds. Chosing the maximum stride computes the maximum range accesed by the loop for all strides. PR: #90036
1 parent 5cd074f commit 82219e5

File tree

2 files changed

+17
-25
lines changed

2 files changed

+17
-25
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,20 +1805,20 @@ void MemoryDepChecker::mergeInStatus(VectorizationSafetyStatus S) {
18051805
}
18061806

18071807
/// Given a dependence-distance \p Dist between two
1808-
/// memory accesses, that have the same stride whose absolute value is given
1809-
/// in \p Stride, and that have the same type size \p TypeByteSize,
1810-
/// in a loop whose takenCount is \p BackedgeTakenCount, check if it is
1811-
/// possible to prove statically that the dependence distance is larger
1812-
/// than the range that the accesses will travel through the execution of
1813-
/// the loop. If so, return true; false otherwise. This is useful for
1814-
/// example in loops such as the following (PR31098):
1808+
/// memory accesses, that have strides in the same direction whose absolute
1809+
/// value of the maximum stride is given in \p MaxStride, and that have the same
1810+
/// type size \p TypeByteSize, in a loop whose takenCount is \p
1811+
/// BackedgeTakenCount, check if it is possible to prove statically that the
1812+
/// dependence distance is larger than the range that the accesses will travel
1813+
/// through the execution of the loop. If so, return true; false otherwise. This
1814+
/// is useful for example in loops such as the following (PR31098):
18151815
/// for (i = 0; i < D; ++i) {
18161816
/// = out[i];
18171817
/// out[i+D] =
18181818
/// }
18191819
static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE,
18201820
const SCEV &BackedgeTakenCount,
1821-
const SCEV &Dist, uint64_t Stride,
1821+
const SCEV &Dist, uint64_t MaxStride,
18221822
uint64_t TypeByteSize) {
18231823

18241824
// If we can prove that
@@ -1838,7 +1838,7 @@ static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE,
18381838
// will be executed only if LoopCount >= VF, proving distance >= LoopCount
18391839
// also guarantees that distance >= VF.
18401840
//
1841-
const uint64_t ByteStride = Stride * TypeByteSize;
1841+
const uint64_t ByteStride = MaxStride * TypeByteSize;
18421842
const SCEV *Step = SE.getConstant(BackedgeTakenCount.getType(), ByteStride);
18431843
const SCEV *Product = SE.getMulExpr(&BackedgeTakenCount, Step);
18441844

@@ -2046,14 +2046,15 @@ MemoryDepChecker::Dependence::DepType MemoryDepChecker::isDependent(
20462046

20472047
ScalarEvolution &SE = *PSE.getSE();
20482048
auto &DL = InnermostLoop->getHeader()->getModule()->getDataLayout();
2049+
uint64_t MaxStride = std::max(StrideA, StrideB);
20492050

2050-
// If the distance between the acecsses is larger than their absolute stride
2051-
// multiplied by the backedge taken count, the accesses are independet, i.e.
2052-
// they are far enough appart that accesses won't access the same location
2053-
// across all loop ierations.
2054-
if (HasSameSize && CommonStride &&
2051+
// If the distance between the acecsses is larger than their maximum absolute
2052+
// stride multiplied by the backedge taken count, the accesses are independet,
2053+
// i.e. they are far enough appart that accesses won't access the same
2054+
// location across all loop ierations.
2055+
if (HasSameSize &&
20552056
isSafeDependenceDistance(DL, SE, *(PSE.getBackedgeTakenCount()), *Dist,
2056-
*CommonStride, TypeByteSize))
2057+
MaxStride, TypeByteSize))
20572058
return Dependence::NoDep;
20582059

20592060
const SCEVConstant *C = dyn_cast<SCEVConstant>(Dist);

llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ define void @forward_dep_known_safe_due_to_backedge_taken_count(ptr %A) {
88
; CHECK-NEXT: loop:
99
; CHECK-NEXT: Memory dependences are safe
1010
; CHECK-NEXT: Dependences:
11-
; CHECK-NEXT: Forward:
12-
; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 ->
13-
; CHECK-NEXT: store i32 %add, ptr %gep, align 4
14-
; CHECK-EMPTY:
1511
; CHECK-NEXT: Run-time memory checks:
1612
; CHECK-NEXT: Grouped accesses:
1713
; CHECK-EMPTY:
@@ -80,13 +76,8 @@ exit:
8076
define void @unknown_dep_known_safe_due_to_backedge_taken_count(ptr %A) {
8177
; CHECK-LABEL: 'unknown_dep_known_safe_due_to_backedge_taken_count'
8278
; CHECK-NEXT: loop:
83-
; 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
84-
; CHECK-NEXT: Unknown data dependence.
79+
; CHECK-NEXT: Memory dependences are safe
8580
; CHECK-NEXT: Dependences:
86-
; CHECK-NEXT: Unknown:
87-
; CHECK-NEXT: %l = load i32, ptr %gep, align 4 ->
88-
; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4
89-
; CHECK-EMPTY:
9081
; CHECK-NEXT: Run-time memory checks:
9182
; CHECK-NEXT: Grouped accesses:
9283
; CHECK-EMPTY:

0 commit comments

Comments
 (0)