[llvm] [LAA] Prepare to handle diff type sizes v2 (NFC) (PR #161238)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 02:34:56 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/161238
>From d908bee40c535d49773db3cb9d9106a20135de6a Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 29 Sep 2025 12:39:13 +0100
Subject: [PATCH 1/4] [LAA] Prepare to handle diff type sizes v2
The change was originally landed as 1aded51 ([LAA] Prepare to handle
diff type sizes (NFC)), but resulted in regressions, and a subsequent
crash when 56a1cbb ([LAA] Fix non-NFC parts 1aded51) was landed. This
iteration includes tests from reports, corresponding fixes, and is not
a NFC. In particular, it fixes the case of loop-guards not being applied
before checking isSafeDependenceDistance.
As depend_diff_types shows, there are several places where the
HasSameSize check can be relaxed for higher analysis precision. As a
first step, return both the source size and the sink size from
getDependenceDistanceStrideAndSize, along with a HasSameSize boolean for
the moment.
---
.../llvm/Analysis/LoopAccessAnalysis.h | 27 ++++-----
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 56 +++++++++++--------
.../LoopAccessAnalysis/depend_diff_types.ll | 39 +++++++++++++
3 files changed, 87 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 392321448c895..38ca537bb19db 100644
--- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -419,29 +419,30 @@ class MemoryDepChecker {
uint64_t MaxStride;
std::optional<uint64_t> CommonStride;
- /// TypeByteSize is either the common store size of both accesses, or 0 when
- /// store sizes mismatch.
- uint64_t TypeByteSize;
+ /// TypeByteSize is a pair of alloc sizes of the source and sink.
+ std::pair<uint64_t, uint64_t> TypeByteSize;
+
+ // HasSameSize is a boolean indicating whether the store sizes of the source
+ // and sink are equal.
+ // TODO: Remove this.
+ bool HasSameSize;
bool AIsWrite;
bool BIsWrite;
DepDistanceStrideAndSizeInfo(const SCEV *Dist, uint64_t MaxStride,
std::optional<uint64_t> CommonStride,
- uint64_t TypeByteSize, bool AIsWrite,
- bool BIsWrite)
+ std::pair<uint64_t, uint64_t> TypeByteSize,
+ bool HasSameSize, bool AIsWrite, bool BIsWrite)
: Dist(Dist), MaxStride(MaxStride), CommonStride(CommonStride),
- TypeByteSize(TypeByteSize), AIsWrite(AIsWrite), BIsWrite(BIsWrite) {}
+ TypeByteSize(TypeByteSize), HasSameSize(HasSameSize),
+ AIsWrite(AIsWrite), BIsWrite(BIsWrite) {}
};
/// Get the dependence distance, strides, type size and whether it is a write
- /// for the dependence between A and B. Returns a DepType, if we can prove
- /// there's no dependence or the analysis fails. Outlined to lambda to limit
- /// he scope of various temporary variables, like A/BPtr, StrideA/BPtr and
- /// others. Returns either the dependence result, if it could already be
- /// determined, or a DepDistanceStrideAndSizeInfo struct, noting that
- /// TypeByteSize could be 0 when store sizes mismatch, and this should be
- /// checked in the caller.
+ /// for the dependence between A and B. Returns either a DepType, the
+ /// dependence result, if it could already be determined, or a
+ /// DepDistanceStrideAndSizeInfo struct.
std::variant<Dependence::DepType, DepDistanceStrideAndSizeInfo>
getDependenceDistanceStrideAndSize(const MemAccessInfo &A, Instruction *AInst,
const MemAccessInfo &B,
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index c99d43dd1ccc2..e09e7523baf71 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2194,14 +2194,12 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
return MemoryDepChecker::Dependence::Unknown;
}
- TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
- TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
-
- // If store sizes are not the same, set TypeByteSize to zero, so we can check
- // it in the caller isDependent.
uint64_t ASz = DL.getTypeAllocSize(ATy);
uint64_t BSz = DL.getTypeAllocSize(BTy);
- uint64_t TypeByteSize = (AStoreSz == BStoreSz) ? BSz : 0;
+
+ // Both the source and sink sizes are neeeded in dependence checks, depending
+ // on the use.
+ std::pair<uint64_t, uint64_t> TypeByteSize(ASz, BSz);
uint64_t StrideAScaled = std::abs(StrideAPtrInt) * ASz;
uint64_t StrideBScaled = std::abs(StrideBPtrInt) * BSz;
@@ -2223,8 +2221,24 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
return Dependence::Unknown;
}
+ // When the distance is possibly zero, we're reading/writing the same memory
+ // location: if the store sizes are not equal, fail with an unknown
+ // dependence.
+ TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
+ TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
+ if (AStoreSz != BStoreSz && SE.isKnownNonPositive(Dist) &&
+ SE.isKnownNonNegative(Dist)) {
+ LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence distance with "
+ "different type sizes\n");
+ return Dependence::Unknown;
+ }
+
+ // TODO: Remove this.
+ bool HasSameSize = AStoreSz == BStoreSz;
+
return DepDistanceStrideAndSizeInfo(Dist, MaxStride, CommonStride,
- TypeByteSize, AIsWrite, BIsWrite);
+ TypeByteSize, HasSameSize, AIsWrite,
+ BIsWrite);
}
MemoryDepChecker::Dependence::DepType
@@ -2256,9 +2270,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return std::get<Dependence::DepType>(Res);
}
- auto &[Dist, MaxStride, CommonStride, TypeByteSize, AIsWrite, BIsWrite] =
- std::get<DepDistanceStrideAndSizeInfo>(Res);
- bool HasSameSize = TypeByteSize > 0;
+ auto &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameSize, AIsWrite,
+ BIsWrite] = std::get<DepDistanceStrideAndSizeInfo>(Res);
ScalarEvolution &SE = *PSE.getSE();
auto &DL = InnermostLoop->getHeader()->getDataLayout();
@@ -2289,7 +2302,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
- areStridedAccessesIndependent(ConstDist, *CommonStride, TypeByteSize)) {
+ areStridedAccessesIndependent(ConstDist, *CommonStride,
+ TypeByteSize.first)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
}
@@ -2303,13 +2317,9 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Negative distances are not plausible dependencies.
if (SE.isKnownNonPositive(Dist)) {
if (SE.isKnownNonNegative(Dist)) {
- if (HasSameSize) {
- // Write to the same location with the same size.
- return Dependence::Forward;
- }
- LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence difference but "
- "different type sizes\n");
- return Dependence::Unknown;
+ // Write to the same location with the same size.
+ assert(HasSameSize && "Accesses must have the same size");
+ return Dependence::Forward;
}
bool IsTrueDataDependence = (AIsWrite && !BIsWrite);
@@ -2327,7 +2337,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
: Dependence::Unknown;
}
if (!HasSameSize ||
- couldPreventStoreLoadForward(ConstDist, TypeByteSize)) {
+ couldPreventStoreLoadForward(ConstDist, TypeByteSize.first)) {
LLVM_DEBUG(
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
return Dependence::ForwardButPreventsForwarding;
@@ -2399,7 +2409,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// We know that Dist is positive, but it may not be constant. Use the signed
// minimum for computations below, as this ensures we compute the closest
// possible dependence distance.
- uint64_t MinDistanceNeeded = MaxStride * (MinNumIter - 1) + TypeByteSize;
+ uint64_t MinDistanceNeeded =
+ MaxStride * (MinNumIter - 1) + TypeByteSize.first;
if (MinDistanceNeeded > static_cast<uint64_t>(MinDistance)) {
if (!ConstDist) {
// For non-constant distances, we checked the lower bound of the
@@ -2427,14 +2438,15 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
- couldPreventStoreLoadForward(MinDistance, TypeByteSize, *CommonStride))
+ couldPreventStoreLoadForward(MinDistance, TypeByteSize.first,
+ *CommonStride))
return Dependence::BackwardVectorizableButPreventsForwarding;
uint64_t MaxVF = MinDepDistBytes / MaxStride;
LLVM_DEBUG(dbgs() << "LAA: Positive min distance " << MinDistance
<< " with max VF = " << MaxVF << '\n');
- uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
+ uint64_t MaxVFInBits = MaxVF * TypeByteSize.first * 8;
if (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
// For non-constant distances, we checked the lower bound of the dependence
// distance and the distance may be larger at runtime (and safe for
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll
index 5d59660a68e90..4e200111d9e39 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll
@@ -187,6 +187,45 @@ exit:
ret void
}
+; In the following test, dependence distance is possibly zero,
+; but this is not equivalent to the condition known-non-positive
+; and known-non-negative.
+
+define void @possibly_zero_dist_diff_typesz(ptr %p) {
+; CHECK-LABEL: 'possibly_zero_dist_diff_typesz'
+; CHECK-NEXT: loop:
+; CHECK-NEXT: Memory dependences are safe
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Forward:
+; CHECK-NEXT: %ld.p = load i32, ptr %gep.p.iv.i32, align 1 ->
+; CHECK-NEXT: store i16 %trunc, ptr %gep.p.iv.i16, align 1
+; CHECK-EMPTY:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep.p.iv.i32 = getelementptr inbounds nuw i32, ptr %p, i16 %iv
+ %ld.p = load i32, ptr %gep.p.iv.i32, align 1
+ %trunc = trunc i32 %ld.p to i16
+ %gep.p.iv.i16 = getelementptr inbounds nuw i16, ptr %p, i16 %iv
+ store i16 %trunc, ptr %gep.p.iv.i16, align 1
+ %iv.next = add nuw nsw i16 %iv, 1
+ %exit.cond = icmp eq i16 %iv.next, 32
+ br i1 %exit.cond, label %exit, label %loop
+
+exit:
+ ret void
+}
+
; In the following test, the sink is loop-invariant.
define void @type_size_equivalence_sink_loopinv(ptr nocapture %vec, i64 %n) {
>From b1afbfd2d7aeb9d269392f8c0534d595036ff0a5 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 29 Sep 2025 13:53:04 +0100
Subject: [PATCH 2/4] [LAA] Pre-commit crash test
---
.../unknown-dependence-with-loop-guards.ll | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll b/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
new file mode 100644
index 0000000000000..6995550811f41
--- /dev/null
+++ b/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
@@ -0,0 +1,26 @@
+; REQUIRES: asserts
+; RUN: not --crash opt -passes='print<access-info>' -disable-output %s
+
+define void @unknown_dep_loopguards(ptr %a, ptr %b, ptr %c) {
+entry:
+ %ld.b = load i32, ptr %b
+ %guard.cond = icmp slt i32 0, %ld.b
+ br i1 %guard.cond, label %exit, label %loop
+
+loop:
+ %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
+ %offset = add i32 %ld.b, %iv
+ %gep.a.offset = getelementptr i32, ptr %a, i32 %offset
+ %gep.a.offset.2 = getelementptr i32, ptr %gep.a.offset, i32 4
+ %ld.a = load [4 x i32], ptr %gep.a.offset.2
+ store [4 x i32] %ld.a, ptr %c
+ %offset.4 = add i32 %offset, 4
+ %gep.a.offset.4 = getelementptr i32, ptr %a, i32 %offset.4
+ store i32 0, ptr %gep.a.offset.4
+ %iv.next = add i32 %iv, 8
+ %exit.cond = icmp eq i32 %iv.next, 16
+ br i1 %exit.cond, label %exit, label %loop
+
+exit:
+ ret void
+}
>From 135a9f956d376d8445083253b3763fa82c6a8136 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 13 Jul 2026 12:01:56 +0100
Subject: [PATCH 3/4] [LAAA] New NFC patch with reduced scope
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 30 ++++-------
.../unknown-dependence-with-loop-guards.ll | 50 +++++++++++++++++--
2 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index e09e7523baf71..e067e5d09b2a1 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2194,10 +2194,12 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
return MemoryDepChecker::Dependence::Unknown;
}
+ TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
+ TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
uint64_t ASz = DL.getTypeAllocSize(ATy);
uint64_t BSz = DL.getTypeAllocSize(BTy);
- // Both the source and sink sizes are neeeded in dependence checks, depending
+ // Both the source and sink sizes are needed in dependence checks, depending
// on the use.
std::pair<uint64_t, uint64_t> TypeByteSize(ASz, BSz);
@@ -2221,18 +2223,6 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
return Dependence::Unknown;
}
- // When the distance is possibly zero, we're reading/writing the same memory
- // location: if the store sizes are not equal, fail with an unknown
- // dependence.
- TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
- TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
- if (AStoreSz != BStoreSz && SE.isKnownNonPositive(Dist) &&
- SE.isKnownNonNegative(Dist)) {
- LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence distance with "
- "different type sizes\n");
- return Dependence::Unknown;
- }
-
// TODO: Remove this.
bool HasSameSize = AStoreSz == BStoreSz;
@@ -2299,9 +2289,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Attempt to prove strided accesses independent.
if (APDist) {
- // If the distance between accesses and their strides are known constants,
- // check whether the accesses interlace each other.
- if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
+ if (ConstDist && CommonStride && CommonStride > 1 && HasSameSize &&
areStridedAccessesIndependent(ConstDist, *CommonStride,
TypeByteSize.first)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
@@ -2317,9 +2305,13 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Negative distances are not plausible dependencies.
if (SE.isKnownNonPositive(Dist)) {
if (SE.isKnownNonNegative(Dist)) {
- // Write to the same location with the same size.
- assert(HasSameSize && "Accesses must have the same size");
- return Dependence::Forward;
+ if (HasSameSize) {
+ // Write to the same location with the same size.
+ return Dependence::Forward;
+ }
+ LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence difference but "
+ "different type sizes\n");
+ return Dependence::Unknown;
}
bool IsTrueDataDependence = (AIsWrite && !BIsWrite);
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll b/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
index 6995550811f41..c57a2600a6c2a 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/unknown-dependence-with-loop-guards.ll
@@ -1,7 +1,51 @@
-; REQUIRES: asserts
-; RUN: not --crash opt -passes='print<access-info>' -disable-output %s
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
-define void @unknown_dep_loopguards(ptr %a, ptr %b, ptr %c) {
+define void @unsafe_dep_loopguards(ptr %a, ptr %b, ptr %c) {
+; CHECK-LABEL: 'unsafe_dep_loopguards'
+; 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: Dependences:
+; CHECK-NEXT: Unknown:
+; CHECK-NEXT: %ld.a = load [4 x i32], ptr %gep.a.offset.2, align 4 ->
+; CHECK-NEXT: store i32 0, ptr %gep.a.offset.4, align 4
+; CHECK-EMPTY:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Check 0:
+; CHECK-NEXT: Comparing group GRP0:
+; CHECK-NEXT: ptr %c
+; CHECK-NEXT: Against group GRP1:
+; CHECK-NEXT: %gep.a.offset.2 = getelementptr i32, ptr %gep.a.offset, i32 4
+; CHECK-NEXT: Check 1:
+; CHECK-NEXT: Comparing group GRP0:
+; CHECK-NEXT: ptr %c
+; CHECK-NEXT: Against group GRP2:
+; CHECK-NEXT: %gep.a.offset.4 = getelementptr i32, ptr %a, i32 %offset.4
+; CHECK-NEXT: Grouped accesses:
+; CHECK-NEXT: Group GRP0:
+; CHECK-NEXT: (Low: %c High: (16 + %c))
+; CHECK-NEXT: Member: %c
+; CHECK-NEXT: Group GRP1:
+; CHECK-NEXT: (Low: (16 + (4 * (sext i32 %ld.b to i64))<nsw> + %a) High: (64 + (4 * (sext i32 %ld.b to i64))<nsw> + %a))
+; CHECK-NEXT: Member: {(16 + (4 * (sext i32 %ld.b to i64))<nsw> + %a),+,32}<nw><%loop>
+; CHECK-NEXT: Group GRP2:
+; CHECK-NEXT: (Low: ((4 * (sext i32 (4 + %ld.b) to i64))<nsw> + %a) High: (36 + (4 * (sext i32 (4 + %ld.b) to i64))<nsw> + %a))
+; CHECK-NEXT: Member: {((4 * (sext i32 (4 + %ld.b) to i64))<nsw> + %a),+,32}<nw><%loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-NEXT: {(4 + %ld.b),+,8}<nw><%loop> Added Flags: <nssw>
+; CHECK-NEXT: {%ld.b,+,8}<nw><%loop> Added Flags: <nssw>
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+; CHECK-NEXT: [PSE] %gep.a.offset.2 = getelementptr i32, ptr %gep.a.offset, i32 4:
+; CHECK-NEXT: (16 + (4 * (sext i32 {%ld.b,+,8}<nw><%loop> to i64))<nsw> + %a)
+; CHECK-NEXT: --> {(16 + (4 * (sext i32 %ld.b to i64))<nsw> + %a),+,32}<nw><%loop>
+; CHECK-NEXT: [PSE] %gep.a.offset.4 = getelementptr i32, ptr %a, i32 %offset.4:
+; CHECK-NEXT: ((4 * (sext i32 {(4 + %ld.b),+,8}<nw><%loop> to i64))<nsw> + %a)
+; CHECK-NEXT: --> {((4 * (sext i32 (4 + %ld.b) to i64))<nsw> + %a),+,32}<nw><%loop>
+;
entry:
%ld.b = load i32, ptr %b
%guard.cond = icmp slt i32 0, %ld.b
>From 651931c2396b47c54368454a155e4c365be2300b Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 3 Aug 2026 10:16:07 +0100
Subject: [PATCH 4/4] [LAA] TypeByteSize.second, rename HasSameSize; thanks
David!
---
.../llvm/Analysis/LoopAccessAnalysis.h | 14 +++++----
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 29 ++++++++++---------
2 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 38ca537bb19db..8d73ac5c14aca 100644
--- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -422,10 +422,11 @@ class MemoryDepChecker {
/// TypeByteSize is a pair of alloc sizes of the source and sink.
std::pair<uint64_t, uint64_t> TypeByteSize;
- // HasSameSize is a boolean indicating whether the store sizes of the source
- // and sink are equal.
- // TODO: Remove this.
- bool HasSameSize;
+ // HasSameStoreSz is a boolean indicating whether the store sizes of the
+ // source and sink are equal.
+ // TODO: This is unnecessary, and the code in isDependent should only depend
+ // on the type alloc sizes.
+ bool HasSameStoreSz;
bool AIsWrite;
bool BIsWrite;
@@ -433,9 +434,10 @@ class MemoryDepChecker {
DepDistanceStrideAndSizeInfo(const SCEV *Dist, uint64_t MaxStride,
std::optional<uint64_t> CommonStride,
std::pair<uint64_t, uint64_t> TypeByteSize,
- bool HasSameSize, bool AIsWrite, bool BIsWrite)
+ bool HasSameStoreSz, bool AIsWrite,
+ bool BIsWrite)
: Dist(Dist), MaxStride(MaxStride), CommonStride(CommonStride),
- TypeByteSize(TypeByteSize), HasSameSize(HasSameSize),
+ TypeByteSize(TypeByteSize), HasSameStoreSz(HasSameStoreSz),
AIsWrite(AIsWrite), BIsWrite(BIsWrite) {}
};
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index e067e5d09b2a1..5e334f08476d5 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2223,11 +2223,12 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
return Dependence::Unknown;
}
- // TODO: Remove this.
- bool HasSameSize = AStoreSz == BStoreSz;
+ // TODO: This is unnecessary, and the code in isDependent should only depend
+ // on the type alloc sizes.
+ bool HasSameStoreSz = AStoreSz == BStoreSz;
return DepDistanceStrideAndSizeInfo(Dist, MaxStride, CommonStride,
- TypeByteSize, HasSameSize, AIsWrite,
+ TypeByteSize, HasSameStoreSz, AIsWrite,
BIsWrite);
}
@@ -2260,7 +2261,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return std::get<Dependence::DepType>(Res);
}
- auto &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameSize, AIsWrite,
+ auto &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameStoreSz, AIsWrite,
BIsWrite] = std::get<DepDistanceStrideAndSizeInfo>(Res);
ScalarEvolution &SE = *PSE.getSE();
@@ -2271,7 +2272,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// upper bound of the number of iterations), 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 &&
+ if (HasSameStoreSz &&
isSafeDependenceDistance(
DL, SE, *(PSE.getSymbolicMaxBackedgeTakenCount()), *Dist, MaxStride))
return Dependence::NoDep;
@@ -2289,9 +2290,9 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Attempt to prove strided accesses independent.
if (APDist) {
- if (ConstDist && CommonStride && CommonStride > 1 && HasSameSize &&
+ if (ConstDist && CommonStride && CommonStride > 1 && HasSameStoreSz &&
areStridedAccessesIndependent(ConstDist, *CommonStride,
- TypeByteSize.first)) {
+ TypeByteSize.second)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
}
@@ -2305,7 +2306,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Negative distances are not plausible dependencies.
if (SE.isKnownNonPositive(Dist)) {
if (SE.isKnownNonNegative(Dist)) {
- if (HasSameSize) {
+ if (HasSameStoreSz) {
// Write to the same location with the same size.
return Dependence::Forward;
}
@@ -2328,8 +2329,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return CheckCompletelyBeforeOrAfter() ? Dependence::NoDep
: Dependence::Unknown;
}
- if (!HasSameSize ||
- couldPreventStoreLoadForward(ConstDist, TypeByteSize.first)) {
+ if (!HasSameStoreSz ||
+ couldPreventStoreLoadForward(ConstDist, TypeByteSize.second)) {
LLVM_DEBUG(
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
return Dependence::ForwardButPreventsForwarding;
@@ -2353,7 +2354,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
: Dependence::Unknown;
}
- if (!HasSameSize) {
+ if (!HasSameStoreSz) {
if (CheckCompletelyBeforeOrAfter())
return Dependence::NoDep;
LLVM_DEBUG(dbgs() << "LAA: ReadWrite-Write positive dependency with "
@@ -2402,7 +2403,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// minimum for computations below, as this ensures we compute the closest
// possible dependence distance.
uint64_t MinDistanceNeeded =
- MaxStride * (MinNumIter - 1) + TypeByteSize.first;
+ MaxStride * (MinNumIter - 1) + TypeByteSize.second;
if (MinDistanceNeeded > static_cast<uint64_t>(MinDistance)) {
if (!ConstDist) {
// For non-constant distances, we checked the lower bound of the
@@ -2430,7 +2431,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
- couldPreventStoreLoadForward(MinDistance, TypeByteSize.first,
+ couldPreventStoreLoadForward(MinDistance, TypeByteSize.second,
*CommonStride))
return Dependence::BackwardVectorizableButPreventsForwarding;
@@ -2438,7 +2439,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
LLVM_DEBUG(dbgs() << "LAA: Positive min distance " << MinDistance
<< " with max VF = " << MaxVF << '\n');
- uint64_t MaxVFInBits = MaxVF * TypeByteSize.first * 8;
+ uint64_t MaxVFInBits = MaxVF * TypeByteSize.second * 8;
if (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
// For non-constant distances, we checked the lower bound of the dependence
// distance and the distance may be larger at runtime (and safe for
More information about the llvm-commits
mailing list