[llvm] [LAA] Clean up APInt-overflow related code (NFC) (PR #140048)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon May 19 03:00:50 PDT 2025
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/140048
>From 100b7a3818480cb317841d238834a5554914ab1a Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 15 May 2025 13:10:21 +0100
Subject: [PATCH 1/8] [LAA] Clean up APInt-overflow related code (NFC)
Use APInt::{trySExtValue,tryZExtValue} instead of the asserting
variants. The change is untestable, as the test demonstrates, since
getTypeSizeInBits is not equipped to handle type-sizes over 64-bits, and
the constant distance flowing through LAA is -1 as a consequence.
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 50 ++++++++++---------
.../long-pointer-distance.ll | 37 ++++++++++++++
2 files changed, 63 insertions(+), 24 deletions(-)
create mode 100644 llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index ab407e945bc53..63eb97eaeca5b 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -827,16 +827,13 @@ getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
TypeSize AllocSize = DL.getTypeAllocSize(AccessTy);
int64_t Size = AllocSize.getFixedValue();
- // Huge step value - give up.
- if (APStepVal->getBitWidth() > 64)
+ std::optional<int64_t> StepVal = APStepVal->trySExtValue();
+ if (!StepVal)
return std::nullopt;
- int64_t StepVal = APStepVal->getSExtValue();
-
// Strided access.
- int64_t Stride = StepVal / Size;
- int64_t Rem = StepVal % Size;
- if (Rem)
+ int64_t Stride = *StepVal / Size;
+ if (*StepVal % Size)
return std::nullopt;
return Stride;
@@ -2067,14 +2064,17 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::NoDep;
// Attempt to prove strided accesses independent.
- const APInt *ConstDist = nullptr;
- if (match(Dist, m_scev_APInt(ConstDist))) {
- uint64_t Distance = ConstDist->abs().getZExtValue();
+ const APInt *APDist = nullptr;
+ std::optional<uint64_t> ConstDistance = match(Dist, m_scev_APInt(APDist))
+ ? APDist->abs().tryZExtValue()
+ : std::nullopt;
+ if (ConstDistance) {
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
- if (Distance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
- areStridedAccessesIndependent(Distance, *CommonStride, TypeByteSize)) {
+ if (ConstDistance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
+ areStridedAccessesIndependent(*ConstDistance, *CommonStride,
+ TypeByteSize)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
}
@@ -2107,7 +2107,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// forward dependency will allow vectorization using any width.
if (IsTrueDataDependence && EnableForwardingConflictDetection) {
- if (!ConstDist) {
+ if (!ConstDistance) {
// TODO: FoundNonConstantDistanceDependence is used as a necessary
// condition to consider retrying with runtime checks. Historically, we
// did not set it when strides were different but there is no inherent
@@ -2115,8 +2115,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
FoundNonConstantDistanceDependence |= ShouldRetryWithRuntimeCheck;
return Dependence::Unknown;
}
- if (!HasSameSize || couldPreventStoreLoadForward(
- ConstDist->abs().getZExtValue(), TypeByteSize)) {
+ if (!HasSameSize ||
+ couldPreventStoreLoadForward(*ConstDistance, TypeByteSize)) {
LLVM_DEBUG(
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
return Dependence::ForwardButPreventsForwarding;
@@ -2127,14 +2127,15 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::Forward;
}
- int64_t MinDistance = SE.getSignedRangeMin(Dist).getSExtValue();
+ std::optional<int64_t> MinDistance =
+ SE.getSignedRangeMin(Dist).trySExtValue();
// Below we only handle strictly positive distances.
- if (MinDistance <= 0) {
+ if (!MinDistance || MinDistance <= 0) {
FoundNonConstantDistanceDependence |= ShouldRetryWithRuntimeCheck;
return Dependence::Unknown;
}
- if (!ConstDist) {
+ if (!ConstDistance) {
// Previously this case would be treated as Unknown, possibly setting
// FoundNonConstantDistanceDependence to force re-trying with runtime
// checks. Until the TODO below is addressed, set it here to preserve
@@ -2193,8 +2194,8 @@ 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;
- if (MinDistanceNeeded > static_cast<uint64_t>(MinDistance)) {
- if (!ConstDist) {
+ if (MinDistanceNeeded > static_cast<uint64_t>(*MinDistance)) {
+ if (!ConstDistance) {
// For non-constant distances, we checked the lower bound of the
// dependence distance and the distance may be larger at runtime (and safe
// for vectorization). Classify it as Unknown, so we re-try with runtime
@@ -2231,11 +2232,12 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// is 8, which is less than 2 and forbidden vectorization, But actually
// both A and B could be vectorized by 2 iterations.
MinDepDistBytes =
- std::min(static_cast<uint64_t>(MinDistance), MinDepDistBytes);
+ std::min(static_cast<uint64_t>(*MinDistance), MinDepDistBytes);
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
- if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
- couldPreventStoreLoadForward(MinDistance, TypeByteSize, *CommonStride))
+ if (IsTrueDataDependence && EnableForwardingConflictDetection &&
+ ConstDistance &&
+ couldPreventStoreLoadForward(*MinDistance, TypeByteSize, *CommonStride))
return Dependence::BackwardVectorizableButPreventsForwarding;
uint64_t MaxVF = MinDepDistBytes / MaxStride;
@@ -2243,7 +2245,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
<< " with max VF = " << MaxVF << '\n');
uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
- if (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
+ if (!ConstDistance && 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
// vectorization). Classify it as Unknown, so we re-try with runtime checks.
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
new file mode 100644
index 0000000000000..094d2a0e7fa37
--- /dev/null
+++ b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
+
+define void @test(ptr %this, i128 %loop.limit) {
+; CHECK-LABEL: 'test'
+; CHECK-NEXT: loop:
+; CHECK-NEXT: Memory dependences are safe
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Forward:
+; CHECK-NEXT: store i64 1, ptr %c, align 8 ->
+; CHECK-NEXT: store i64 2, ptr %d, align 8
+; 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 i128 [ 0, %entry ], [ %iv.next, %loop ]
+ %iv.mul.8 = mul i128 %iv, 8
+ %c = getelementptr i8, ptr %this, i128 %iv.mul.8
+ store i64 1, ptr %c, align 8
+ %iv.off = add i128 %iv.mul.8, u0x00FFFFFFFFFFFFFFFF
+ %d = getelementptr i8, ptr %this, i128 %iv.off
+ store i64 2, ptr %d, align 8
+ %iv.next = add nuw nsw i128 %iv, 1
+ %exit.cond = icmp ult i128 %iv.next, %loop.limit
+ br i1 %exit.cond, label %loop, label %exit
+exit:
+ ret void
+}
+
>From dc234572106767ff9200d57e77b66c881b23d970 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 15 May 2025 13:59:46 +0100
Subject: [PATCH 2/8] [LAA] Add additional test
---
.../long-pointer-distance.ll | 40 ++++++++++++++++++-
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
index 094d2a0e7fa37..1e782dba25655 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
-define void @test(ptr %this, i128 %loop.limit) {
-; CHECK-LABEL: 'test'
+define void @forward_i128_offset_difference(ptr %this, i128 %loop.limit) {
+; CHECK-LABEL: 'forward_i128_offset_difference'
; CHECK-NEXT: loop:
; CHECK-NEXT: Memory dependences are safe
; CHECK-NEXT: Dependences:
@@ -35,3 +35,39 @@ exit:
ret void
}
+define void @backward_distance_offset_subtract(ptr %A) {
+; CHECK-LABEL: 'backward_distance_offset_subtract'
+; CHECK-NEXT: loop:
+; CHECK-NEXT: Memory dependences are safe
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Forward:
+; CHECK-NEXT: %l = load i32, ptr %gep.off.1, align 4 ->
+; CHECK-NEXT: store i32 %add, ptr %gep.off.2, align 4
+; 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:
+ %A.off.1 = getelementptr inbounds i8, ptr %A, i64 u0x100000018
+ %A.off.2 = getelementptr inbounds i8, ptr %A, i64 u0x100000010
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep.off.1 = getelementptr inbounds i32, ptr %A.off.1, i64 %iv
+ %l = load i32, ptr %gep.off.1, align 4
+ %add = add nsw i32 %l, 5
+ %gep.off.2 = getelementptr inbounds i32, ptr %A.off.2, i64 %iv
+ store i32 %add, ptr %gep.off.2, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond.not = icmp eq i64 %iv.next, 256
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
>From 1dc0934c89c58c96b55bde77f08cc457b2d35904 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 15 May 2025 17:24:04 +0100
Subject: [PATCH 3/8] [LAA] Address review
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 63eb97eaeca5b..7bcc37f09ce29 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2065,15 +2065,17 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Attempt to prove strided accesses independent.
const APInt *APDist = nullptr;
- std::optional<uint64_t> ConstDistance = match(Dist, m_scev_APInt(APDist))
- ? APDist->abs().tryZExtValue()
- : std::nullopt;
+
+ // The rest of this function relies on ConstantDistance being at most 64-bits,
+ // which is checked earlier. Will assert if the calling code changes.
+ uint64_t ConstDistance =
+ match(Dist, m_scev_APInt(APDist)) ? APDist->abs().getZExtValue() : 0;
if (ConstDistance) {
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
if (ConstDistance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
- areStridedAccessesIndependent(*ConstDistance, *CommonStride,
+ areStridedAccessesIndependent(ConstDistance, *CommonStride,
TypeByteSize)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
@@ -2116,7 +2118,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::Unknown;
}
if (!HasSameSize ||
- couldPreventStoreLoadForward(*ConstDistance, TypeByteSize)) {
+ couldPreventStoreLoadForward(ConstDistance, TypeByteSize)) {
LLVM_DEBUG(
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
return Dependence::ForwardButPreventsForwarding;
>From 1c5950651caae4644b7fca14e433b54655118b6c Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 15 May 2025 18:15:09 +0100
Subject: [PATCH 4/8] [LAA] Fix thinko
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 7bcc37f09ce29..24f2c8cf80511 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2071,7 +2071,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
uint64_t ConstDistance =
match(Dist, m_scev_APInt(APDist)) ? APDist->abs().getZExtValue() : 0;
- if (ConstDistance) {
+ if (APDist) {
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
if (ConstDistance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
>From 10f48ba6442dfdc462b9d938ba375333aca605d3 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Thu, 15 May 2025 22:00:21 +0100
Subject: [PATCH 5/8] [LAA] Address review
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 35 +++++++++++-------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 24f2c8cf80511..fc836eb73313f 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2066,17 +2066,16 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// Attempt to prove strided accesses independent.
const APInt *APDist = nullptr;
- // The rest of this function relies on ConstantDistance being at most 64-bits,
- // which is checked earlier. Will assert if the calling code changes.
- uint64_t ConstDistance =
+ // The rest of this function relies on ConstDist being at most 64-bits, which
+ // is checked earlier. Will assert if the calling code changes.
+ uint64_t ConstDist =
match(Dist, m_scev_APInt(APDist)) ? APDist->abs().getZExtValue() : 0;
if (APDist) {
// If the distance between accesses and their strides are known constants,
// check whether the accesses interlace each other.
- if (ConstDistance > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
- areStridedAccessesIndependent(ConstDistance, *CommonStride,
- TypeByteSize)) {
+ if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
+ areStridedAccessesIndependent(ConstDist, *CommonStride, TypeByteSize)) {
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
return Dependence::NoDep;
}
@@ -2109,7 +2108,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// forward dependency will allow vectorization using any width.
if (IsTrueDataDependence && EnableForwardingConflictDetection) {
- if (!ConstDistance) {
+ if (!ConstDist) {
// TODO: FoundNonConstantDistanceDependence is used as a necessary
// condition to consider retrying with runtime checks. Historically, we
// did not set it when strides were different but there is no inherent
@@ -2118,7 +2117,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::Unknown;
}
if (!HasSameSize ||
- couldPreventStoreLoadForward(ConstDistance, TypeByteSize)) {
+ couldPreventStoreLoadForward(ConstDist, TypeByteSize)) {
LLVM_DEBUG(
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
return Dependence::ForwardButPreventsForwarding;
@@ -2129,15 +2128,14 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
return Dependence::Forward;
}
- std::optional<int64_t> MinDistance =
- SE.getSignedRangeMin(Dist).trySExtValue();
+ int64_t MinDistance = SE.getSignedRangeMin(Dist).getSExtValue();
// Below we only handle strictly positive distances.
- if (!MinDistance || MinDistance <= 0) {
+ if (MinDistance <= 0) {
FoundNonConstantDistanceDependence |= ShouldRetryWithRuntimeCheck;
return Dependence::Unknown;
}
- if (!ConstDistance) {
+ if (!ConstDist) {
// Previously this case would be treated as Unknown, possibly setting
// FoundNonConstantDistanceDependence to force re-trying with runtime
// checks. Until the TODO below is addressed, set it here to preserve
@@ -2196,8 +2194,8 @@ 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;
- if (MinDistanceNeeded > static_cast<uint64_t>(*MinDistance)) {
- if (!ConstDistance) {
+ if (MinDistanceNeeded > static_cast<uint64_t>(MinDistance)) {
+ if (!ConstDist) {
// For non-constant distances, we checked the lower bound of the
// dependence distance and the distance may be larger at runtime (and safe
// for vectorization). Classify it as Unknown, so we re-try with runtime
@@ -2234,12 +2232,11 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
// is 8, which is less than 2 and forbidden vectorization, But actually
// both A and B could be vectorized by 2 iterations.
MinDepDistBytes =
- std::min(static_cast<uint64_t>(*MinDistance), MinDepDistBytes);
+ std::min(static_cast<uint64_t>(MinDistance), MinDepDistBytes);
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
- if (IsTrueDataDependence && EnableForwardingConflictDetection &&
- ConstDistance &&
- couldPreventStoreLoadForward(*MinDistance, TypeByteSize, *CommonStride))
+ if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
+ couldPreventStoreLoadForward(MinDistance, TypeByteSize, *CommonStride))
return Dependence::BackwardVectorizableButPreventsForwarding;
uint64_t MaxVF = MinDepDistBytes / MaxStride;
@@ -2247,7 +2244,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
<< " with max VF = " << MaxVF << '\n');
uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
- if (!ConstDistance && MaxVFInBits < MaxTargetVectorWidthInBits) {
+ 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
// vectorization). Classify it as Unknown, so we re-try with runtime checks.
>From e51dd5dfd2bd345bfa33467beee71e2604285ca3 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 16 May 2025 08:00:06 +0100
Subject: [PATCH 6/8] [LAA] Shorten some code
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index fc836eb73313f..7668d49465f52 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -832,11 +832,7 @@ getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
return std::nullopt;
// Strided access.
- int64_t Stride = *StepVal / Size;
- if (*StepVal % Size)
- return std::nullopt;
-
- return Stride;
+ return *StepVal % Size ? std::nullopt : std::make_optional(*StepVal / Size);
}
static bool isNoWrapGEP(Value *Ptr, PredicatedScalarEvolution &PSE,
>From 0aff252aced568727751aa49127df2863eeb7194 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 16 May 2025 08:01:09 +0100
Subject: [PATCH 7/8] [LAA] Move some comments
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 7668d49465f52..5f466bbe4e027 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2059,14 +2059,13 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
DL, SE, *(PSE.getSymbolicMaxBackedgeTakenCount()), *Dist, MaxStride))
return Dependence::NoDep;
- // Attempt to prove strided accesses independent.
- const APInt *APDist = nullptr;
-
// The rest of this function relies on ConstDist being at most 64-bits, which
// is checked earlier. Will assert if the calling code changes.
+ const APInt *APDist = nullptr;
uint64_t ConstDist =
match(Dist, m_scev_APInt(APDist)) ? APDist->abs().getZExtValue() : 0;
+ // 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.
>From 036655edf004fa40ba0c06dca6ad65c859955ba3 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 19 May 2025 11:00:01 +0100
Subject: [PATCH 8/8] [LAA] Address newline nit in tests
---
llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
index 1e782dba25655..da1dd4bc2cd9f 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/long-pointer-distance.ll
@@ -20,6 +20,7 @@ define void @forward_i128_offset_difference(ptr %this, i128 %loop.limit) {
;
entry:
br label %loop
+
loop:
%iv = phi i128 [ 0, %entry ], [ %iv.next, %loop ]
%iv.mul.8 = mul i128 %iv, 8
@@ -31,6 +32,7 @@ loop:
%iv.next = add nuw nsw i128 %iv, 1
%exit.cond = icmp ult i128 %iv.next, %loop.limit
br i1 %exit.cond, label %loop, label %exit
+
exit:
ret void
}
More information about the llvm-commits
mailing list