[llvm] [DA] Set Distance to zero when Direction is EQ (PR #147966)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 09:02:49 PDT 2025
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/147966
>From ad3f5e94b9b6bf9c2f92ae1f50cefdc509b91c15 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Thu, 10 Jul 2025 13:20:16 +0000
Subject: [PATCH 1/5] [DA] Set Distance to zero when Direction is EQ
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 29 +++++++++++++++++++
.../Analysis/DependenceAnalysis/Banerjee.ll | 18 ++++++------
.../Analysis/DependenceAnalysis/Coupled.ll | 6 ++--
.../NonCanonicalizedSubscript.ll | 2 +-
4 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 5b85060f9caa1..df5fd0e938707 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -187,6 +187,18 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
OS << " da analyze - ";
if (auto D = DA->depends(&*SrcI, &*DstI,
/*UnderRuntimeAssumptions=*/true)) {
+
+ // Verify that the distance begin zero is equivalent to the
+ // direction being EQ.
+ for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
+ const SCEV *Distance = D->getDistance(Level);
+ bool IsDistanceZero = Distance && Distance->isZero();
+ bool IsDirectionEQ =
+ D->getDirection(Level) == Dependence::DVEntry::EQ;
+ assert(IsDistanceZero == IsDirectionEQ &&
+ "Inconsistent distance and direction.");
+ }
+
// Normalize negative direction vectors if required by clients.
if (NormalizeResults && D->normalize(&SE))
OS << "normalized - ";
@@ -3991,6 +4003,23 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
if (CompleteLoops[II])
Result.DV[II - 1].Scalar = false;
+ // Set the distance to zero if the direction is EQ.
+ // TODO: Ideally, the distance should be set to 0 immediately simultaneously
+ // with the corresponding direction being set to EQ.
+ for (unsigned II = 1; II <= Result.getLevels(); ++II) {
+ if (Result.getDirection(II) == Dependence::DVEntry::EQ)
+ Result.DV[II - 1].Distance = SE->getZero(SrcSCEV->getType());
+
+ LLVM_DEBUG({
+ // Check that the converse (i.e., if the distance is zero, then the
+ // direction is EQ) holds.
+ const SCEV *Distance = Result.getDistance(II);
+ if (Distance && Distance->isZero())
+ assert(Result.getDirection(II) == Dependence::DVEntry::EQ &&
+ "Distance is zero, but direction is not EQ");
+ });
+ }
+
if (PossiblyLoopIndependent) {
// Make sure the LoopIndependent flag is set correctly.
// All directions must include equal, otherwise no
diff --git a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
index 6768e9067dca3..d3301520fd107 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
@@ -802,7 +802,7 @@ define void @banerjee9(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; CHECK-NEXT: da analyze - output [* *]!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
-; CHECK-NEXT: da analyze - flow [<= =|<]!
+; CHECK-NEXT: da analyze - flow [<= 0|<]!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %1 = load i64, ptr %arrayidx7, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
@@ -816,7 +816,7 @@ define void @banerjee9(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; NORMALIZE-NEXT: da analyze - output [* *]!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
-; NORMALIZE-NEXT: da analyze - flow [<= =|<]!
+; NORMALIZE-NEXT: da analyze - flow [<= 0|<]!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; NORMALIZE-NEXT: da analyze - confused!
; NORMALIZE-NEXT: Src: %1 = load i64, ptr %arrayidx7, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
@@ -830,7 +830,7 @@ define void @banerjee9(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; DELIN-NEXT: da analyze - output [* *]!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT: da analyze - flow [<= =|<]!
+; DELIN-NEXT: da analyze - flow [<= 0|<]!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; DELIN-NEXT: da analyze - confused!
; DELIN-NEXT: Src: %1 = load i64, ptr %arrayidx7, align 8 --> Dst: %1 = load i64, ptr %arrayidx7, align 8
@@ -888,7 +888,7 @@ define void @banerjee10(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
-; CHECK-NEXT: da analyze - flow [<> =]!
+; CHECK-NEXT: da analyze - flow [<> 0]!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %1 = load i64, ptr %arrayidx6, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
@@ -902,7 +902,7 @@ define void @banerjee10(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; NORMALIZE-NEXT: da analyze - none!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
-; NORMALIZE-NEXT: da analyze - flow [<> =]!
+; NORMALIZE-NEXT: da analyze - flow [<> 0]!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; NORMALIZE-NEXT: da analyze - confused!
; NORMALIZE-NEXT: Src: %1 = load i64, ptr %arrayidx6, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
@@ -916,7 +916,7 @@ define void @banerjee10(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; DELIN-NEXT: da analyze - none!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
-; DELIN-NEXT: da analyze - flow [<> =]!
+; DELIN-NEXT: da analyze - flow [<> 0]!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %1, ptr %B.addr.11, align 8
; DELIN-NEXT: da analyze - confused!
; DELIN-NEXT: Src: %1 = load i64, ptr %arrayidx6, align 8 --> Dst: %1 = load i64, ptr %arrayidx6, align 8
@@ -1058,7 +1058,7 @@ define void @banerjee12(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; CHECK-NEXT: da analyze - flow [= <>]!
+; CHECK-NEXT: da analyze - flow [0 <>]!
; CHECK-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
@@ -1072,7 +1072,7 @@ define void @banerjee12(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; NORMALIZE-NEXT: da analyze - none!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; NORMALIZE-NEXT: da analyze - flow [= <>]!
+; NORMALIZE-NEXT: da analyze - flow [0 <>]!
; NORMALIZE-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
; NORMALIZE-NEXT: da analyze - confused!
; NORMALIZE-NEXT: Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
@@ -1086,7 +1086,7 @@ define void @banerjee12(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
; DELIN-NEXT: da analyze - none!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; DELIN-NEXT: da analyze - flow [= <>]!
+; DELIN-NEXT: da analyze - flow [0 <>]!
; DELIN-NEXT: Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
; DELIN-NEXT: da analyze - confused!
; DELIN-NEXT: Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
diff --git a/llvm/test/Analysis/DependenceAnalysis/Coupled.ll b/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
index ff9f393f88152..06bfc5d2e8573 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
@@ -285,7 +285,7 @@ define void @couple6(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx1, align 4 --> Dst: store i32 %conv, ptr %arrayidx1, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - flow [=|<]!
+; CHECK-NEXT: da analyze - flow [0|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
@@ -503,7 +503,7 @@ define void @couple11(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx2, align 4 --> Dst: store i32 %conv, ptr %arrayidx2, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - flow [=|<] splitable!
+; CHECK-NEXT: da analyze - flow [0|<] splitable!
; CHECK-NEXT: da analyze - split level = 1, iteration = 9!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
; CHECK-NEXT: da analyze - confused!
@@ -636,7 +636,7 @@ define void @couple14(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx3, align 4 --> Dst: store i32 %conv, ptr %arrayidx3, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
-; CHECK-NEXT: da analyze - flow [=|<]!
+; CHECK-NEXT: da analyze - flow [0|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx3, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx6, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
index f0cd2fd4cd930..e5d5d21e365a1 100644
--- a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
@@ -18,7 +18,7 @@ define void @i32_subscript(ptr %a, ptr %b) {
; CHECK-NEXT: Src: %0 = load i32, ptr %a.addr, align 4 --> Dst: %0 = load i32, ptr %a.addr, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: %0 = load i32, ptr %a.addr, align 4 --> Dst: store i32 %1, ptr %a.addr.2, align 4
-; CHECK-NEXT: da analyze - anti [=|<]!
+; CHECK-NEXT: da analyze - anti [0|<]!
; CHECK-NEXT: Src: store i32 %1, ptr %a.addr.2, align 4 --> Dst: store i32 %1, ptr %a.addr.2, align 4
; CHECK-NEXT: da analyze - none!
;
>From c3338ba51e9634c88d5dfc60d3ab0e399e212d44 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 11 Jul 2025 00:49:00 +0900
Subject: [PATCH 2/5] Apply suggestions from code review
Co-authored-by: Michael Kruse <github at meinersbur.de>
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index df5fd0e938707..65b803bffc453 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -188,6 +188,7 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
if (auto D = DA->depends(&*SrcI, &*DstI,
/*UnderRuntimeAssumptions=*/true)) {
+#ifndef NDEBUG
// Verify that the distance begin zero is equivalent to the
// direction being EQ.
for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
@@ -198,6 +199,7 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
assert(IsDistanceZero == IsDirectionEQ &&
"Inconsistent distance and direction.");
}
+#endif
// Normalize negative direction vectors if required by clients.
if (NormalizeResults && D->normalize(&SE))
@@ -4010,14 +4012,14 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
if (Result.getDirection(II) == Dependence::DVEntry::EQ)
Result.DV[II - 1].Distance = SE->getZero(SrcSCEV->getType());
- LLVM_DEBUG({
+#ifndef NDEBUG
// Check that the converse (i.e., if the distance is zero, then the
// direction is EQ) holds.
const SCEV *Distance = Result.getDistance(II);
if (Distance && Distance->isZero())
assert(Result.getDirection(II) == Dependence::DVEntry::EQ &&
"Distance is zero, but direction is not EQ");
- });
+#endif
}
if (PossiblyLoopIndependent) {
>From 20d5661982ecd143e8f713d11d3b4c0dd1fd686c Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 11 Jul 2025 00:48:47 +0900
Subject: [PATCH 3/5] Add assert for the cases where distance is non-zero and
direction is EQ
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 65b803bffc453..ff30b0122f4d3 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -4009,8 +4009,13 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
// TODO: Ideally, the distance should be set to 0 immediately simultaneously
// with the corresponding direction being set to EQ.
for (unsigned II = 1; II <= Result.getLevels(); ++II) {
- if (Result.getDirection(II) == Dependence::DVEntry::EQ)
- Result.DV[II - 1].Distance = SE->getZero(SrcSCEV->getType());
+ if (Result.getDirection(II) == Dependence::DVEntry::EQ) {
+ if (Result.DV[II - 1].Distance == nullptr)
+ Result.DV[II - 1].Distance = SE->getZero(SrcSCEV->getType());
+ else
+ assert(Result.DV[II - 1].Distance->isZero() &&
+ "Inconsistency between distance and direction");
+ }
#ifndef NDEBUG
// Check that the converse (i.e., if the distance is zero, then the
>From 2a8f9c8dc1f5a6499d84d1e681ef96e70d0c63a0 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 11 Jul 2025 00:51:50 +0900
Subject: [PATCH 4/5] Fix typo
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index ff30b0122f4d3..1aa117043f17e 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -189,7 +189,7 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
/*UnderRuntimeAssumptions=*/true)) {
#ifndef NDEBUG
- // Verify that the distance begin zero is equivalent to the
+ // Verify that the distance being zero is equivalent to the
// direction being EQ.
for (unsigned Level = 1; Level <= D->getLevels(); Level++) {
const SCEV *Distance = D->getDistance(Level);
>From dcb667956216cc1d333ca2a12d5a56fe381e655e Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 11 Jul 2025 01:02:31 +0900
Subject: [PATCH 5/5] Apply format
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 1aa117043f17e..428342f51ad2e 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -4018,12 +4018,12 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
}
#ifndef NDEBUG
- // Check that the converse (i.e., if the distance is zero, then the
- // direction is EQ) holds.
- const SCEV *Distance = Result.getDistance(II);
- if (Distance && Distance->isZero())
- assert(Result.getDirection(II) == Dependence::DVEntry::EQ &&
- "Distance is zero, but direction is not EQ");
+ // Check that the converse (i.e., if the distance is zero, then the
+ // direction is EQ) holds.
+ const SCEV *Distance = Result.getDistance(II);
+ if (Distance && Distance->isZero())
+ assert(Result.getDirection(II) == Dependence::DVEntry::EQ &&
+ "Distance is zero, but direction is not EQ");
#endif
}
More information about the llvm-commits
mailing list