Skip to content

Commit 54a94b7

Browse files
committed
[LAA] Pass maximum stride to isSafeDependenceDistance.
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.
1 parent fcec466 commit 54a94b7

File tree

2 files changed

+20
-30
lines changed

2 files changed

+20
-30
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: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,8 @@ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
66
define void @forward_dep_known_safe_due_to_backedge_taken_count(ptr %A) {
77
; CHECK-LABEL: 'forward_dep_known_safe_due_to_backedge_taken_count'
88
; CHECK-NEXT: loop:
9-
; 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
10-
; CHECK-NEXT: Unknown data dependence.
9+
; CHECK-NEXT: Memory dependences are safe
1110
; CHECK-NEXT: Dependences:
12-
; CHECK-NEXT: Unknown:
13-
; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 ->
14-
; CHECK-NEXT: store i32 %add, ptr %gep, align 4
15-
; CHECK-EMPTY:
1611
; CHECK-NEXT: Run-time memory checks:
1712
; CHECK-NEXT: Grouped accesses:
1813
; CHECK-EMPTY:
@@ -44,10 +39,9 @@ exit:
4439
define void @forward_dep_not_known_safe_due_to_backedge_taken_count(ptr %A) {
4540
; CHECK-LABEL: 'forward_dep_not_known_safe_due_to_backedge_taken_count'
4641
; CHECK-NEXT: loop:
47-
; 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
48-
; CHECK-NEXT: Unknown data dependence.
42+
; CHECK-NEXT: Memory dependences are safe
4943
; CHECK-NEXT: Dependences:
50-
; CHECK-NEXT: Unknown:
44+
; CHECK-NEXT: Forward:
5145
; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 ->
5246
; CHECK-NEXT: store i32 %add, ptr %gep, align 4
5347
; CHECK-EMPTY:
@@ -82,13 +76,8 @@ exit:
8276
define void @unknown_dep_known_safe_due_to_backedge_taken_count(ptr %A) {
8377
; CHECK-LABEL: 'unknown_dep_known_safe_due_to_backedge_taken_count'
8478
; CHECK-NEXT: loop:
85-
; 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
86-
; CHECK-NEXT: Unknown data dependence.
79+
; CHECK-NEXT: Memory dependences are safe
8780
; CHECK-NEXT: Dependences:
88-
; CHECK-NEXT: Unknown:
89-
; CHECK-NEXT: %l = load i32, ptr %gep, align 4 ->
90-
; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4
91-
; CHECK-EMPTY:
9281
; CHECK-NEXT: Run-time memory checks:
9382
; CHECK-NEXT: Grouped accesses:
9483
; CHECK-EMPTY:

0 commit comments

Comments
 (0)