https://github.com/kasuga-fj updated 
https://github.com/llvm/llvm-project/pull/169902

>From 285364b1989e6c9b603cbb505380cde77ea7beda Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <[email protected]>
Date: Fri, 28 Nov 2025 11:12:41 +0000
Subject: [PATCH 1/2] [Delinearization] Add validation for large size arrays

---
 llvm/lib/Analysis/Delinearization.cpp         | 51 +++++++++++++++++++
 .../constant_functions_multi_dim.ll           |  2 +-
 .../Delinearization/multidim_only_ivs_2d.ll   |  4 +-
 .../Delinearization/multidim_only_ivs_3d.ll   |  2 +-
 ..._two_accesses_different_delinearization.ll |  4 +-
 .../Delinearization/validation_large_size.ll  | 13 ++---
 .../Analysis/DependenceAnalysis/DADelin.ll    | 32 ++++++------
 .../DependenceAnalysis/DifferentOffsets.ll    |  2 +-
 .../Analysis/DependenceAnalysis/StrongSIV.ll  | 10 ++--
 llvm/test/Transforms/LICM/lnicm.ll            |  3 ++
 10 files changed, 89 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/Analysis/Delinearization.cpp 
b/llvm/lib/Analysis/Delinearization.cpp
index 0c3b02ae09f47..d847de0edca12 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -747,6 +747,20 @@ bool llvm::validateDelinearizationResult(ScalarEvolution 
&SE,
                                          ArrayRef<const SCEV *> Sizes,
                                          ArrayRef<const SCEV *> Subscripts,
                                          const Value *Ptr) {
+  // Sizes and Subscripts are as follows:
+  //
+  //   Sizes:      [UNK][S_2]...[S_n]
+  //   Subscripts: [I_1][I_2]...[I_n]
+  //
+  // where the size of the outermost dimension is unknown (UNK).
+
+  auto MulOverflow = [&](const SCEV *A, const SCEV *B) -> const SCEV * {
+    if (!SE.willNotOverflow(Instruction::Mul, /*IsSigned=*/true, A, B))
+      return nullptr;
+    return SE.getMulExpr(A, B);
+  };
+
+  // Range check: 0 <= I_k < S_k for k = 2..n.
   for (size_t I = 1; I < Sizes.size(); ++I) {
     const SCEV *Size = Sizes[I - 1];
     const SCEV *Subscript = Subscripts[I];
@@ -755,6 +769,43 @@ bool llvm::validateDelinearizationResult(ScalarEvolution 
&SE,
     if (!isKnownLessThan(&SE, Subscript, Size))
       return false;
   }
+
+  // The offset computation is as follows:
+  //
+  //   Offset = I_n +
+  //            S_n * I_{n-1} +
+  //            ... +
+  //            (S_2 * ... * S_n) * I_1
+  //
+  // Regarding this as a function from (I_1, I_2, ..., I_n) to integers, it
+  // must be injective. To guarantee it, the above calculation must not
+  // overflow. Since we have already checked that 0 <= I_k < S_k for k = 2..n,
+  // the minimum and maximum values occur in the following cases:
+  //
+  //   Min = [I_1][0]...[0] = S_2 * ... * S_n * I_1
+  //   Max = [I_1][S_2-1]...[S_n-1]
+  //       = (S_2 * ... * S_n) * I_1 +
+  //         (S_2 * ... * S_{n-1}) * (S_2 - 1) +
+  //         ... +
+  //         (S_n - 1)
+  //       = (S_2 * ... * S_n) * I_1 +
+  //         (S_2 * ... * S_n) - 1  (can be proved by induction)
+  //
+  const SCEV *Prod = SE.getOne(Sizes[0]->getType());
+  for (const SCEV *Size : drop_end(Sizes)) {
+    Prod = MulOverflow(Prod, Size);
+    if (!Prod)
+      return false;
+  }
+  const SCEV *Min = MulOverflow(Prod, Subscripts[0]);
+  if (!Min)
+    return false;
+
+  // Over-approximate Max as Prod * I_1 + Prod (ignoring the -1).
+  if (!SE.willNotOverflow(Instruction::Add, /*IsSigned=*/true, Min,
+                          Subscripts[0]))
+    return false;
+
   return true;
 }
 
diff --git a/llvm/test/Analysis/Delinearization/constant_functions_multi_dim.ll 
b/llvm/test/Analysis/Delinearization/constant_functions_multi_dim.ll
index 9e6a4221f8eda..7e5c5142dccbc 100644
--- a/llvm/test/Analysis/Delinearization/constant_functions_multi_dim.ll
+++ b/llvm/test/Analysis/Delinearization/constant_functions_multi_dim.ll
@@ -11,7 +11,7 @@ define void @mat_mul(ptr %C, ptr %A, ptr %B, i64 %N) 
!kernel_arg_addr_space !2 !
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%N] with elements of 4 bytes.
 ; CHECK-NEXT:  ArrayRef[%call][{0,+,1}<nuw><nsw><%for.inc>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  Inst: %tmp5 = load float, ptr %arrayidx4, align 4
 ; CHECK-NEXT:  AccessFunction: {(4 * %call1),+,(4 * %N)}<%for.inc>
diff --git a/llvm/test/Analysis/Delinearization/multidim_only_ivs_2d.ll 
b/llvm/test/Analysis/Delinearization/multidim_only_ivs_2d.ll
index e1ad1c55313a4..e5d2806101926 100644
--- a/llvm/test/Analysis/Delinearization/multidim_only_ivs_2d.ll
+++ b/llvm/test/Analysis/Delinearization/multidim_only_ivs_2d.ll
@@ -16,14 +16,14 @@ define void @foo(i64 %n, i64 %m, ptr %A) {
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%m] with elements of 8 bytes.
 ; CHECK-NEXT:  ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  Inst: store double %val, ptr %arrayidx, align 8
 ; CHECK-NEXT:  AccessFunction: {{\{\{}}0,+,(8 * %m)}<%for.i>,+,8}<%for.j>
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%m] with elements of 8 bytes.
 ; CHECK-NEXT:  ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ;
 entry:
   br label %for.i
diff --git a/llvm/test/Analysis/Delinearization/multidim_only_ivs_3d.ll 
b/llvm/test/Analysis/Delinearization/multidim_only_ivs_3d.ll
index d5213e5afb33c..f5f0628ede937 100644
--- a/llvm/test/Analysis/Delinearization/multidim_only_ivs_3d.ll
+++ b/llvm/test/Analysis/Delinearization/multidim_only_ivs_3d.ll
@@ -16,7 +16,7 @@ define void @foo(i64 %n, i64 %m, i64 %o, ptr %A) {
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%m][%o] with elements of 8 bytes.
 ; CHECK-NEXT:  
ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>][{0,+,1}<nuw><nsw><%for.k>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ;
 entry:
   br label %for.i
diff --git 
a/llvm/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
 
b/llvm/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
index 011dc40697cb5..f768002dd9e41 100644
--- 
a/llvm/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
+++ 
b/llvm/test/Analysis/Delinearization/multidim_two_accesses_different_delinearization.ll
@@ -19,14 +19,14 @@ define void @foo(i64 %n, i64 %m, ptr %A) {
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%m] with elements of 8 bytes.
 ; CHECK-NEXT:  ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  Inst: store double 1.000000e+00, ptr %arrayidx1, align 8
 ; CHECK-NEXT:  AccessFunction: {{\{\{}}0,+,8}<%for.i>,+,(8 * %n)}<%for.j>
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%n] with elements of 8 bytes.
 ; CHECK-NEXT:  ArrayRef[{0,+,1}<nuw><nsw><%for.j>][{0,+,1}<nuw><nsw><%for.i>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ;
 entry:
   br label %for.i
diff --git a/llvm/test/Analysis/Delinearization/validation_large_size.ll 
b/llvm/test/Analysis/Delinearization/validation_large_size.ll
index f78e68f60569a..1117399a47364 100644
--- a/llvm/test/Analysis/Delinearization/validation_large_size.ll
+++ b/llvm/test/Analysis/Delinearization/validation_large_size.ll
@@ -1,12 +1,9 @@
 ; NOTE: Assertions have been autogenerated by 
utils/update_analyze_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes='print<delinearization>' 
--delinearize-use-fixed-size-array-heuristic -disable-output 2>&1 | FileCheck %s
 
-; FIXME: When considering an array as a function from subcripts to addresses,
-; it should be injective. That is, different subscript tuples should map to
-; different addresses. Currently, delinearization doesn't guarantee this
-; property, especially when the inferred array size is very large so that the
-; product of dimensions may overflow. The delinearization validation should
-; consider such cases as invalid.
+; When considering an array as a function from subcripts to addresses, it
+; should be injective. That is, different subscript tuples should map to
+; different addresses.
 
 ; for (i = 0; i < (1ULL << 60); i++)
 ;   for (j = 0; j < 256; j++)
@@ -23,7 +20,7 @@ define void @large_size_fixed(ptr %A) {
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][256] with elements of 1 bytes.
 ; CHECK-NEXT:  
ArrayRef[{0,+,1}<nuw><nsw><%for.i.header>][{0,+,1}<nuw><nsw><%for.j>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ;
 entry:
   br label %for.i.header
@@ -75,7 +72,7 @@ define void @large_size_parametric(i64 %n, i64 %m, i64 %o, 
ptr %A) {
 ; CHECK-NEXT:  Base offset: %A
 ; CHECK-NEXT:  ArrayDecl[UnknownSize][%m][%o] with elements of 1 bytes.
 ; CHECK-NEXT:  
ArrayRef[{0,+,1}<nuw><nsw><%for.i.header>][{0,+,1}<nuw><nsw><%for.j.header>][{0,+,1}<nuw><nsw><%for.k.header>]
-; CHECK-NEXT:  Delinearization validation: Succeeded
+; CHECK-NEXT:  Delinearization validation: Failed
 ;
 entry:
   %guard.i = icmp sgt i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll 
b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
index 8f94a455d3724..130b9930cfdf5 100644
--- a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
@@ -13,11 +13,11 @@ target triple = "thumbv8m.main-arm-none-eabi"
 define void @t1(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't1'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - consistent anti [0 0 0|<]!
+; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - output [* * *]!
 ;
 entry:
   %cmp49 = icmp sgt i32 %n, 0
@@ -78,7 +78,7 @@ for.cond.cleanup:                                 ; preds = 
%for.cond.cleanup3,
 define void @t2(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't2'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
 ; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
@@ -145,7 +145,7 @@ for.cond.cleanup:                                 ; preds = 
%for.cond.cleanup3,
 define void @t3(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't3'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
 ; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
@@ -212,7 +212,7 @@ for.cond.cleanup:                                 ; preds = 
%for.cond.cleanup3,
 define void @t4(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't4'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
 ; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
@@ -279,7 +279,7 @@ for.cond.cleanup:                                 ; preds = 
%for.cond.cleanup3,
 define void @t5(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't5'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
 ; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
@@ -346,11 +346,11 @@ for.cond.cleanup:                                 ; preds 
= %for.cond.cleanup3,
 define void @t6(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't6'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - consistent anti [-1 0 0]!
+; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - output [* * *]!
 ;
 entry:
   %cmp49 = icmp sgt i32 %n, 0
@@ -414,11 +414,11 @@ for.cond.cleanup:                                 ; preds 
= %for.cond.cleanup3,
 define void @t7(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't7'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - consistent anti [1 0 0]!
+; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - output [* * *]!
 ;
 entry:
   %cmp49 = icmp sgt i32 %n, 0
@@ -482,11 +482,11 @@ for.cond.cleanup:                                 ; preds 
= %for.cond.cleanup3,
 define void @t8(i32 %n, i32 %m, i32 %o, ptr nocapture %A) {
 ; CHECK-LABEL: 't8'
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: %0 = load 
i32, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - input [* * *]!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx, align 4 --> Dst: store i32 
%add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - consistent anti [0 0 1]!
+; CHECK-NEXT:    da analyze - anti [* * *|<]!
 ; CHECK-NEXT:  Src: store i32 %add12, ptr %arrayidx2, align 4 --> Dst: store 
i32 %add12, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - output [* * *]!
 ;
 entry:
   %cmp49 = icmp sgt i32 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll 
b/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
index 069a540ea0295..0ff9c05c884ff 100644
--- a/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll
@@ -100,7 +100,7 @@ define void @linearized_accesses(i64 %n, i64 %m, i64 %o, 
ptr %A) {
 ; CHECK-NEXT:  Src: store i32 1, ptr %idx0, align 4 --> Dst: store i32 1, ptr 
%idx1, align 4
 ; 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!
+; CHECK-NEXT:    da analyze - output [* * *]!
 ;
 entry:
   br label %for.i
diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll 
b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
index 19cef4537a769..16e0e7bccaaf5 100644
--- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
@@ -536,9 +536,13 @@ for.end:                                          ; preds 
= %for.body
 ;;        A[i] = 0;
 
 define void @strong11(ptr %A) nounwind uwtable ssp {
-; 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]!
+; 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]!
 ;
 entry:
   br label %for.cond1.preheader
diff --git a/llvm/test/Transforms/LICM/lnicm.ll 
b/llvm/test/Transforms/LICM/lnicm.ll
index 814f964666305..e331ab7d39e83 100644
--- a/llvm/test/Transforms/LICM/lnicm.ll
+++ b/llvm/test/Transforms/LICM/lnicm.ll
@@ -3,6 +3,9 @@
 ; RUN: opt -aa-pipeline=basic-aa 
-passes='loop-mssa(lnicm),loop(loop-interchange)' -cache-line-size=64 -S %s | 
FileCheck %s --check-prefixes LNICM
 ; RUN: opt -aa-pipeline=basic-aa 
-passes='loop-mssa(licm),loop(loop-interchange)' -cache-line-size=64 -S %s | 
FileCheck %s --check-prefixes LICM
 
+; XFAIL: *
+; Loop interchange currently fails due to a failure in dependence analysis.
+
 ; This test represents the following function:
 ; void test(int n, int m, int x[m][n], int y[n], int *z) {
 ;   for (int k = 0; k < n; k++) {

>From 6960ecedb0f253a398c0184d3a66f56538ef5c9b Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <[email protected]>
Date: Sat, 29 Nov 2025 01:49:55 +0900
Subject: [PATCH 2/2] fix spell

---
 llvm/lib/Analysis/Delinearization.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/Delinearization.cpp 
b/llvm/lib/Analysis/Delinearization.cpp
index d847de0edca12..8563eee06c994 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -789,7 +789,7 @@ bool llvm::validateDelinearizationResult(ScalarEvolution 
&SE,
   //         ... +
   //         (S_n - 1)
   //       = (S_2 * ... * S_n) * I_1 +
-  //         (S_2 * ... * S_n) - 1  (can be proved by induction)
+  //         (S_2 * ... * S_n) - 1  (can be proven by induction)
   //
   const SCEV *Prod = SE.getOne(Sizes[0]->getType());
   for (const SCEV *Size : drop_end(Sizes)) {

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to