[llvm] [DA] Replace delinearization for fixed size array (PR #161822)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 18 04:46:19 PST 2025
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/161822
>From aa3e203b09bff73104564bef97a443604c319c72 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 3 Oct 2025 10:34:08 +0000
Subject: [PATCH 1/6] [DA] Replace delinearization for fixed size array
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 34 +++++++++++-------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 1f0da8d1830d3..56f29d469b2cd 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3504,12 +3504,13 @@ bool DependenceInfo::tryDelinearizeFixedSize(
"expected src and dst scev unknowns to be equal");
});
- SmallVector<int, 4> SrcSizes;
- SmallVector<int, 4> DstSizes;
- if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
- SrcSizes) ||
- !tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
- DstSizes))
+ const SCEV *ElemSize = SE->getElementSize(Src);
+ assert(ElemSize == SE->getElementSize(Dst) && "Different element sizes");
+ SmallVector<const SCEV *, 4> SrcSizes, DstSizes;
+ if (!delinearizeFixedSizeArray(*SE, SE->removePointerBase(SrcAccessFn),
+ SrcSubscripts, SrcSizes, ElemSize) ||
+ !delinearizeFixedSizeArray(*SE, SE->removePointerBase(DstAccessFn),
+ DstSubscripts, DstSizes, ElemSize))
return false;
// Check that the two size arrays are non-empty and equal in length and
@@ -3535,7 +3536,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
// iff the subscripts are positive and are less than the range of the
// dimension.
if (!DisableDelinearizationChecks) {
- auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
+ auto AllIndicesInRange = [&](ArrayRef<const SCEV *> DimensionSizes,
SmallVectorImpl<const SCEV *> &Subscripts,
Value *Ptr) {
size_t SSize = Subscripts.size();
@@ -3548,17 +3549,14 @@ bool DependenceInfo::tryDelinearizeFixedSize(
});
return false;
}
- if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
- const SCEV *Range = SE->getConstant(
- ConstantInt::get(SType, DimensionSizes[I - 1], false));
- if (!isKnownLessThan(S, Range)) {
- LLVM_DEBUG({
- dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
- dbgs() << " S: " << *S << "\n"
- << " Range: " << *Range << "\n";
- });
- return false;
- }
+ const SCEV *Range = DimensionSizes[I - 1];
+ if (!isKnownLessThan(S, Range)) {
+ LLVM_DEBUG({
+ dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
+ dbgs() << " S: " << *S << "\n"
+ << " Range: " << *Range << "\n";
+ });
+ return false;
}
}
return true;
>From e89cb447c6d5db6d1afde6be7ae7b8081aca6977 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 14 Oct 2025 11:51:59 +0000
Subject: [PATCH 2/6] update tests
---
.../Analysis/DependenceAnalysis/Banerjee.ll | 4 +-
.../Analysis/DependenceAnalysis/Coupled.ll | 6 +--
.../DependenceAnalysis/DifferentOffsets.ll | 3 +-
.../Analysis/DependenceAnalysis/Invariant.ll | 3 ++
.../NonCanonicalizedSubscript.ll | 4 +-
.../Analysis/DependenceAnalysis/PR51512.ll | 2 +-
.../DependenceAnalysis/Propagating.ll | 3 +-
.../DependenceAnalysis/SameSDLoops.ll | 2 +-
.../DependenceAnalysis/Separability.ll | 6 +--
.../LoopInterchange/legality-check.ll | 4 +-
.../LoopInterchange/outer-dependency-lte.ll | 54 +++++++++++++++----
.../dependencies_multidims.ll | 3 ++
12 files changed, 66 insertions(+), 28 deletions(-)
diff --git a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
index e0def901d1759..6dde8844c6040 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
@@ -660,7 +660,7 @@ define void @banerjee7(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 %arrayidx7, align 8
-; DELIN-NEXT: da analyze - flow [> <=]!
+; DELIN-NEXT: da analyze - consistent flow [-1 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 %arrayidx7, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, 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 [<> 0]!
+; DELIN-NEXT: da analyze - flow [-11 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
diff --git a/llvm/test/Analysis/DependenceAnalysis/Coupled.ll b/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
index 1d4513429a83c..01c84c77393bc 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Coupled.ll
@@ -503,8 +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 [0|<] splitable!
-; CHECK-NEXT: da analyze - split level = 1, iteration = 9!
+; CHECK-NEXT: da analyze - flow [0|<]!
; 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!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
@@ -548,8 +547,7 @@ define void @couple12(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 - split level = 1, iteration = 11!
+; CHECK-NEXT: da analyze - flow [<]!
; 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!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll b/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
index d9ccea55dd478..069a540ea0295 100644
--- a/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
@@ -149,11 +149,10 @@ define void @multidim_accesses(ptr %A) {
; CHECK-NEXT: Src: store i32 1, ptr %idx0, align 4 --> Dst: store i32 1, ptr %idx0, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 1, ptr %idx0, align 4 --> Dst: store i32 1, ptr %idx1, align 4
-; CHECK-NEXT: da analyze - consistent output [0 0 0|<]!
+; CHECK-NEXT: da analyze - output [<= * *|<]!
; CHECK-NEXT: Src: store i32 1, ptr %idx1, align 4 --> Dst: store i32 1, ptr %idx1, align 4
; CHECK-NEXT: da analyze - none!
;
-; FIXME: the dependence distance is not constant. Distance vector should be [* * *|<]!
; for (i = 0; i < 256; i++)
; for (j = 0; j < 256; j++)
; for (k = 0; k < 256; k++) {
diff --git a/llvm/test/Analysis/DependenceAnalysis/Invariant.ll b/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
index 1d8c51e475ae8..8a9d0a82eb27b 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
@@ -2,6 +2,9 @@
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
; RUN: | FileCheck %s
+; XFAIL: *
+; Currently fails since delinearization doesn't work as expected.
+
; Test for a bug, which caused an assert when an invalid
; SCEVAddRecExpr is created in addToCoefficient.
diff --git a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
index e5d5d21e365a1..eb832747e366e 100644
--- a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
@@ -47,6 +47,8 @@ for.end:
; }
; }
; Extends the previous example to coupled MIV subscripts.
+;
+; FIXME: Currently delinearization does not work as expected.
@a = global [10004 x [10004 x i32]] zeroinitializer, align 16
@@ -57,7 +59,7 @@ define void @coupled_miv_type_mismatch(i32 %n) #0 {
; CHECK-NEXT: Src: %2 = load i32, ptr %arrayidx5, align 4 --> Dst: %2 = load i32, ptr %arrayidx5, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: %2 = load i32, ptr %arrayidx5, align 4 --> Dst: store i32 %add6, ptr %arrayidx10, align 4
-; CHECK-NEXT: da analyze - consistent anti [1 -2]!
+; CHECK-NEXT: da analyze - anti [< >]!
; CHECK-NEXT: Src: store i32 %add6, ptr %arrayidx10, align 4 --> Dst: store i32 %add6, ptr %arrayidx10, align 4
; CHECK-NEXT: da analyze - none!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/PR51512.ll b/llvm/test/Analysis/DependenceAnalysis/PR51512.ll
index 9bee38c6c00ef..2d1638d145ffe 100644
--- a/llvm/test/Analysis/DependenceAnalysis/PR51512.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/PR51512.ll
@@ -10,7 +10,7 @@ define void @foo() {
; CHECK-NEXT: Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 42, ptr %getelementptr, align 1
; CHECK-NEXT: da analyze - consistent output [0 S]!
; CHECK-NEXT: Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
-; CHECK-NEXT: da analyze - output [0 *|<]!
+; CHECK-NEXT: da analyze - output [0 <=|<]!
; CHECK-NEXT: Src: store i32 0, ptr %getelementptr5, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
; CHECK-NEXT: da analyze - none!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/Propagating.ll b/llvm/test/Analysis/DependenceAnalysis/Propagating.ll
index 866f515baeafb..09598f43c7c7d 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Propagating.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Propagating.ll
@@ -437,7 +437,8 @@ define void @prop7(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: store i32 %conv, ptr %arrayidx7, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: %0 = load i32, ptr %arrayidx13, align 4
-; CHECK-NEXT: da analyze - flow [* <>]!
+; CHECK-NEXT: da analyze - flow [* -38] splitable!
+; CHECK-NEXT: da analyze - split level = 1, iteration = 4!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx7, align 4 --> Dst: store i32 %0, ptr %B.addr.11, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx13, align 4 --> Dst: %0 = load i32, ptr %arrayidx13, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/SameSDLoops.ll b/llvm/test/Analysis/DependenceAnalysis/SameSDLoops.ll
index 57962e01de2b4..5a51c748a344e 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SameSDLoops.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SameSDLoops.ll
@@ -148,7 +148,7 @@ define void @non_samebd0(ptr %A) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i64 %i.013, ptr %arrayidx12, align 8 --> Dst: store i64 %i.013, ptr %arrayidx12, align 8
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i64 %i.013, ptr %arrayidx12, align 8 --> Dst: store i64 %l17.04, ptr %arrayidx24, align 8
-; CHECK-NEXT: da analyze - output [-4 -3]!
+; CHECK-NEXT: da analyze - output [> *]!
; CHECK-NEXT: Src: store i64 %l17.04, ptr %arrayidx24, align 8 --> Dst: store i64 %l17.04, ptr %arrayidx24, align 8
; CHECK-NEXT: da analyze - none!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/Separability.ll b/llvm/test/Analysis/DependenceAnalysis/Separability.ll
index 2ed9cca4d1fc0..18e5da407e1aa 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Separability.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Separability.ll
@@ -182,7 +182,7 @@ define void @sep2(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx12, align 4 --> Dst: store i32 %conv, ptr %arrayidx12, align 4
; CHECK-NEXT: da analyze - consistent output [0 S 0 0]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx12, align 4 --> Dst: %0 = load i32, ptr %arrayidx19, align 4
-; CHECK-NEXT: da analyze - flow [> * * -10]!
+; CHECK-NEXT: da analyze - flow [* * * <>]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx12, align 4 --> Dst: store i32 %0, ptr %B.addr.31, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx19, align 4 --> Dst: %0 = load i32, ptr %arrayidx19, align 4
@@ -262,9 +262,9 @@ for.end28: ; preds = %for.inc26
define void @sep3(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'sep3'
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx13, align 4 --> Dst: store i32 %conv, ptr %arrayidx13, align 4
-; CHECK-NEXT: da analyze - consistent output [0 S 0 0]!
+; CHECK-NEXT: da analyze - output [0 S 0 0]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx13, align 4 --> Dst: %0 = load i32, ptr %arrayidx20, align 4
-; CHECK-NEXT: da analyze - flow [> * * *]!
+; CHECK-NEXT: da analyze - flow [* * * *|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx13, align 4 --> Dst: store i32 %0, ptr %B.addr.31, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx20, align 4 --> Dst: %0 = load i32, ptr %arrayidx20, align 4
diff --git a/llvm/test/Transforms/LoopInterchange/legality-check.ll b/llvm/test/Transforms/LoopInterchange/legality-check.ll
index c7f63d5968e62..fd0e08d3fae24 100644
--- a/llvm/test/Transforms/LoopInterchange/legality-check.ll
+++ b/llvm/test/Transforms/LoopInterchange/legality-check.ll
@@ -149,10 +149,10 @@ exit:
;; for (int k = 0; k < 19; k++)
;; b[i][j][k] = b[i][5][k + 1];
;;
-;; The direction vector of `b` is [= * <]. We cannot interchange all the loops.
+;; The direction vector of `b` is [= * *]. We cannot interchange all the loops.
; CHECK: Dependency matrix before interchange:
-; CHECK-NEXT: = * <
+; CHECK-NEXT: = * *
; CHECK-NEXT: Processing InnerLoopId = 2 and OuterLoopId = 1
; CHECK-NEXT: Failed interchange InnerLoopId = 2 and OuterLoopId = 1 due to dependence
; CHECK-NEXT: Not interchanging loops. Cannot prove legality.
diff --git a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
index c17d78f7cfce6..85b616f2abba0 100644
--- a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
+++ b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
@@ -1,6 +1,6 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
-; RUN: FileCheck --input-file=%t %s
+; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -S 2>&1 | FileCheck %s
;; The original code:
;;
@@ -15,19 +15,51 @@
;;
;; The entry of the direction vector for the outermost loop is `DVEntry::LE`.
;; We need to treat this as `*`, not `<`. See issue #123920 for details.
-
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: f
-; CHECK: --- !Missed
-; CHECK-NEXT: Pass: loop-interchange
-; CHECK-NEXT: Name: Dependence
-; CHECK-NEXT: Function: f
+;; In conclusion, we must not interchange the loops.
@a = dso_local global [16 x [16 x [16 x i32]]] zeroinitializer, align 4
define dso_local void @f() {
+; CHECK-LABEL: define dso_local void @f() {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
+; CHECK: [[FOR_COND1_PREHEADER]]:
+; CHECK-NEXT: [[I_039:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC26:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
+; CHECK-NEXT: [[SUB:%.*]] = add nuw nsw i32 [[I_039]], 3
+; CHECK-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[SUB]] to i64
+; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i32 [[I_039]], 1
+; CHECK-NEXT: [[IDXPROM13:%.*]] = zext nneg i32 [[MUL]] to i64
+; CHECK-NEXT: br label %[[FOR_COND5_PREHEADER:.*]]
+; CHECK: [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT: ret void
+; CHECK: [[FOR_COND5_PREHEADER]]:
+; CHECK-NEXT: [[J_038:%.*]] = phi i32 [ 1, %[[FOR_COND1_PREHEADER]] ], [ [[INC23:%.*]], %[[FOR_COND_CLEANUP7:.*]] ]
+; CHECK-NEXT: [[IDXPROM11:%.*]] = zext nneg i32 [[J_038]] to i64
+; CHECK-NEXT: [[SUB18:%.*]] = add nsw i32 [[J_038]], -1
+; CHECK-NEXT: [[IDXPROM19:%.*]] = sext i32 [[SUB18]] to i64
+; CHECK-NEXT: br label %[[FOR_BODY8:.*]]
+; CHECK: [[FOR_COND_CLEANUP3]]:
+; CHECK-NEXT: [[INC26]] = add nuw nsw i32 [[I_039]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[I_039]], 3
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP]]
+; CHECK: [[FOR_COND_CLEANUP7]]:
+; CHECK-NEXT: [[INC23]] = add nuw nsw i32 [[J_038]], 1
+; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[J_038]], 7
+; CHECK-NEXT: br i1 [[CMP2]], label %[[FOR_COND5_PREHEADER]], label %[[FOR_COND_CLEANUP3]]
+; CHECK: [[FOR_BODY8]]:
+; CHECK-NEXT: [[K_037:%.*]] = phi i32 [ 1, %[[FOR_COND5_PREHEADER]] ], [ [[ADD15:%.*]], %[[FOR_BODY8]] ]
+; CHECK-NEXT: [[IDXPROM9:%.*]] = zext nneg i32 [[K_037]] to i64
+; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM]], i64 [[IDXPROM9]], i64 [[IDXPROM11]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
+; CHECK-NEXT: [[ADD15]] = add nuw nsw i32 [[K_037]], 1
+; CHECK-NEXT: [[IDXPROM16:%.*]] = zext nneg i32 [[ADD15]] to i64
+; CHECK-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM13]], i64 [[IDXPROM16]], i64 [[IDXPROM19]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[SUB21:%.*]] = sub nsw i32 [[TMP1]], [[TMP0]]
+; CHECK-NEXT: store i32 [[SUB21]], ptr [[ARRAYIDX20]], align 4
+; CHECK-NEXT: [[CMP6:%.*]] = icmp samesign ult i32 [[K_037]], 7
+; CHECK-NEXT: br i1 [[CMP6]], label %[[FOR_BODY8]], label %[[FOR_COND_CLEANUP7]]
+;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
index b95bbddf11d65..2867c6c0652e9 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
@@ -3,6 +3,9 @@
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+; XFAIL: *
+; The transformation seems to have succeeded "accidentally".
+
; CHECK-LABEL: sub_sub_less
; CHECK: %j = phi
; CHECK-NOT: %j.1 = phi
>From c7dc3afec39a4578200dc4fe3ed16feac57a59dc Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 14 Oct 2025 12:09:02 +0000
Subject: [PATCH 3/6] remove remarks outputs
---
llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
index 85b616f2abba0..a3a75ab6ec739 100644
--- a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
+++ b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t \
+; RUN: opt < %s -passes=loop-interchange \
; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -S 2>&1 | FileCheck %s
;; The original code:
>From 795f2f851e250e31089c55a4df0f44f276a3c6fb Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Thu, 16 Oct 2025 02:52:57 +0900
Subject: [PATCH 4/6] address review comments
---
.../Analysis/DependenceAnalysis/Invariant.ll | 4 +-
.../LoopInterchange/outer-dependency-lte.ll | 55 ++++---------------
2 files changed, 15 insertions(+), 44 deletions(-)
diff --git a/llvm/test/Analysis/DependenceAnalysis/Invariant.ll b/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
index 8a9d0a82eb27b..5fc9dc3e031ab 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Invariant.ll
@@ -3,7 +3,9 @@
; RUN: | FileCheck %s
; XFAIL: *
-; Currently fails since delinearization doesn't work as expected.
+; Currently fails since delinearization doesn't work as expected, due to the
+; inconsistency in the estimated array sizes between `rr[i][j]` and `rr[j][j]`.
+; The latter is now regarded as an access to a 1D array.
; Test for a bug, which caused an assert when an invalid
; SCEVAddRecExpr is created in addToCoefficient.
diff --git a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
index a3a75ab6ec739..4aba99f35678e 100644
--- a/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
+++ b/llvm/test/Transforms/LoopInterchange/outer-dependency-lte.ll
@@ -1,6 +1,6 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -passes=loop-interchange \
-; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa -S 2>&1 | FileCheck %s
+; RUN: opt < %s -passes=loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t \
+; RUN: -verify-dom-info -verify-loop-info -verify-loop-lcssa
+; RUN: FileCheck --input-file=%t %s
;; The original code:
;;
@@ -17,49 +17,18 @@
;; We need to treat this as `*`, not `<`. See issue #123920 for details.
;; In conclusion, we must not interchange the loops.
+; CHECK: --- !Missed
+; CHECK-NEXT: Pass: loop-interchange
+; CHECK-NEXT: Name: Dependence
+; CHECK-NEXT: Function: f
+; CHECK-NEXT: Args:
+; CHECK-NEXT: - String: All loops have dependencies in all directions.
+; CHECK-NEXT: ...
+
+
@a = dso_local global [16 x [16 x [16 x i32]]] zeroinitializer, align 4
define dso_local void @f() {
-; CHECK-LABEL: define dso_local void @f() {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
-; CHECK: [[FOR_COND1_PREHEADER]]:
-; CHECK-NEXT: [[I_039:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INC26:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
-; CHECK-NEXT: [[SUB:%.*]] = add nuw nsw i32 [[I_039]], 3
-; CHECK-NEXT: [[IDXPROM:%.*]] = zext nneg i32 [[SUB]] to i64
-; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i32 [[I_039]], 1
-; CHECK-NEXT: [[IDXPROM13:%.*]] = zext nneg i32 [[MUL]] to i64
-; CHECK-NEXT: br label %[[FOR_COND5_PREHEADER:.*]]
-; CHECK: [[FOR_COND_CLEANUP:.*]]:
-; CHECK-NEXT: ret void
-; CHECK: [[FOR_COND5_PREHEADER]]:
-; CHECK-NEXT: [[J_038:%.*]] = phi i32 [ 1, %[[FOR_COND1_PREHEADER]] ], [ [[INC23:%.*]], %[[FOR_COND_CLEANUP7:.*]] ]
-; CHECK-NEXT: [[IDXPROM11:%.*]] = zext nneg i32 [[J_038]] to i64
-; CHECK-NEXT: [[SUB18:%.*]] = add nsw i32 [[J_038]], -1
-; CHECK-NEXT: [[IDXPROM19:%.*]] = sext i32 [[SUB18]] to i64
-; CHECK-NEXT: br label %[[FOR_BODY8:.*]]
-; CHECK: [[FOR_COND_CLEANUP3]]:
-; CHECK-NEXT: [[INC26]] = add nuw nsw i32 [[I_039]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[I_039]], 3
-; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_COND1_PREHEADER]], label %[[FOR_COND_CLEANUP]]
-; CHECK: [[FOR_COND_CLEANUP7]]:
-; CHECK-NEXT: [[INC23]] = add nuw nsw i32 [[J_038]], 1
-; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[J_038]], 7
-; CHECK-NEXT: br i1 [[CMP2]], label %[[FOR_COND5_PREHEADER]], label %[[FOR_COND_CLEANUP3]]
-; CHECK: [[FOR_BODY8]]:
-; CHECK-NEXT: [[K_037:%.*]] = phi i32 [ 1, %[[FOR_COND5_PREHEADER]] ], [ [[ADD15:%.*]], %[[FOR_BODY8]] ]
-; CHECK-NEXT: [[IDXPROM9:%.*]] = zext nneg i32 [[K_037]] to i64
-; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds nuw [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM]], i64 [[IDXPROM9]], i64 [[IDXPROM11]]
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX12]], align 4
-; CHECK-NEXT: [[ADD15]] = add nuw nsw i32 [[K_037]], 1
-; CHECK-NEXT: [[IDXPROM16:%.*]] = zext nneg i32 [[ADD15]] to i64
-; CHECK-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [16 x [16 x [16 x i32]]], ptr @a, i64 0, i64 [[IDXPROM13]], i64 [[IDXPROM16]], i64 [[IDXPROM19]]
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX20]], align 4
-; CHECK-NEXT: [[SUB21:%.*]] = sub nsw i32 [[TMP1]], [[TMP0]]
-; CHECK-NEXT: store i32 [[SUB21]], ptr [[ARRAYIDX20]], align 4
-; CHECK-NEXT: [[CMP6:%.*]] = icmp samesign ult i32 [[K_037]], 7
-; CHECK-NEXT: br i1 [[CMP6]], label %[[FOR_BODY8]], label %[[FOR_COND_CLEANUP7]]
-;
entry:
br label %for.cond1.preheader
>From ffd0badb77ac24f0edf08336a16a925020ca4cad Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 18 Nov 2025 11:17:30 +0000
Subject: [PATCH 5/6] update comment
---
.../test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
index 2867c6c0652e9..76c8a32ce116c 100644
--- a/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
+++ b/llvm/test/Transforms/LoopUnrollAndJam/dependencies_multidims.ll
@@ -4,7 +4,8 @@
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
; XFAIL: *
-; The transformation seems to have succeeded "accidentally".
+; The transformation seems to have succeeded "accidentally". It should be fixed
+; by PR #156578.
; CHECK-LABEL: sub_sub_less
; CHECK: %j = phi
>From ca093f001e9c08399b7dbed8d481e61081dd8a9d Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 18 Nov 2025 12:45:33 +0000
Subject: [PATCH 6/6] update test
---
llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll | 14 ++++----------
llvm/test/Transforms/LoopFusion/pr164082.ll | 5 +++++
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
index 71b93826ac260..19cef4537a769 100644
--- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
@@ -534,17 +534,11 @@ for.end: ; preds = %for.body
;; for (long unsigned j = 0; j < 2147483640; j++)
;; if (i < 3000000000)
;; A[i] = 0;
-;
-; FIXME: DependenceAnalysis fails to detect the dependency between A[i] and
-; itself, and the issue is not caused by the Strong SIV.
+
define void @strong11(ptr %A) nounwind uwtable ssp {
-; CHECK-ALL-LABEL: 'strong11'
-; CHECK-ALL-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
-; CHECK-ALL-NEXT: da analyze - none!
-;
-; CHECK-STRONG-SIV-LABEL: 'strong11'
-; CHECK-STRONG-SIV-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [0 S]!
+; CHECK-LABEL: 'strong11'
+; CHECK-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
+; CHECK-NEXT: da analyze - consistent output [0 S]!
;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LoopFusion/pr164082.ll b/llvm/test/Transforms/LoopFusion/pr164082.ll
index 652557cef48f8..b097cbe6ee949 100644
--- a/llvm/test/Transforms/LoopFusion/pr164082.ll
+++ b/llvm/test/Transforms/LoopFusion/pr164082.ll
@@ -2,6 +2,11 @@
; RUN: opt -passes=loop-fusion -disable-output -stats < %s 2>&1 | FileCheck -check-prefix=STAT %s
; STAT: 1 loop-fusion - Loops fused
+; XFAIL: *
+; Currently fails since delinearization doesn't work as expected. The estimated
+; array size is different for `Array[i][i]` and `Array[i][j]`. The former is
+; now regarded as an access to a 1D array.
+
; C Code
;
;; for (int i = 0; i < 100; ++i)
More information about the llvm-commits
mailing list