[llvm] [LAA][NFC] Add a test for #191867 (PR #213722)

Andrei Elovikov via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 10:57:33 PDT 2026


https://github.com/eas updated https://github.com/llvm/llvm-project/pull/213722

>From e74255f7e3b13ed3506f7cd8c1c79d2dc18aa971 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 3 Aug 2026 10:20:00 -0700
Subject: [PATCH 1/2] [LAA][NFC] Add a test for #191867

---
 .../num-iters-for-store-load-conflict.ll      | 100 ++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll b/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
index 71eaa0ed2341e..4f76f07fe63ec 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
@@ -348,6 +348,106 @@ exit:
   ret void
 }
 
+; Same as above but with an unrelated store-to-load forwarding deps that do have
+; a safe VF. Make sure those aren't reported as ;
+; `BackwardVectorizableButPreventsForwarding`. We provide two of those (%B and
+; %C) becase the order of processing matters, so we have one lexically before %A
+; and another after ti.
+define void @fwd_conflict_dep_should_not_affect_another_dep(ptr %A, ptr %B, ptr %C) {
+; CHECK-LABEL: 'fwd_conflict_dep_should_not_affect_another_dep'
+; 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:  Backward loop carried data dependence that prevents store-to-load forwarding.
+; CHECK-NEXT:      Dependences:
+; CHECK-NEXT:        BackwardVectorizableButPreventsForwarding:
+; CHECK-NEXT:            %ld = load i32, ptr %gep.ld, align 4 ->
+; CHECK-NEXT:            store i32 %ld, ptr %gep.st, align 4
+; CHECK-EMPTY:
+; CHECK-NEXT:        BackwardVectorizable:
+; CHECK-NEXT:            %ld.C = load i32, ptr %gep.C.ld, align 4 ->
+; CHECK-NEXT:            store i32 %ld.C, ptr %gep.C.st, align 4
+; CHECK-EMPTY:
+; CHECK-NEXT:        BackwardVectorizable:
+; CHECK-NEXT:            %ld.B = load i32, ptr %gep.B.ld, align 4 ->
+; CHECK-NEXT:            store i32 %ld.B, ptr %gep.B.st, align 4
+; CHECK-EMPTY:
+; CHECK-NEXT:      Run-time memory checks:
+; CHECK-NEXT:      Check 0:
+; CHECK-NEXT:        Comparing group GRP0:
+; CHECK-NEXT:          %gep.B.ld = getelementptr i32, ptr %B, i64 %iv
+; CHECK-NEXT:          %gep.B.st = getelementptr i32, ptr %B.offset, i64 %iv
+; CHECK-NEXT:        Against group GRP1:
+; CHECK-NEXT:          %gep.ld = getelementptr i32, ptr %A, i64 %iv.x2
+; CHECK-NEXT:          %gep.st = getelementptr i32, ptr %A.offset, i64 %iv.x2
+; CHECK-NEXT:      Check 1:
+; CHECK-NEXT:        Comparing group GRP0:
+; CHECK-NEXT:          %gep.B.ld = getelementptr i32, ptr %B, i64 %iv
+; CHECK-NEXT:          %gep.B.st = getelementptr i32, ptr %B.offset, i64 %iv
+; CHECK-NEXT:        Against group GRP2:
+; CHECK-NEXT:          %gep.C.ld = getelementptr i32, ptr %C, i64 %iv
+; CHECK-NEXT:          %gep.C.st = getelementptr i32, ptr %C.offset, i64 %iv
+; CHECK-NEXT:      Check 2:
+; CHECK-NEXT:        Comparing group GRP1:
+; CHECK-NEXT:          %gep.ld = getelementptr i32, ptr %A, i64 %iv.x2
+; CHECK-NEXT:          %gep.st = getelementptr i32, ptr %A.offset, i64 %iv.x2
+; CHECK-NEXT:        Against group GRP2:
+; CHECK-NEXT:          %gep.C.ld = getelementptr i32, ptr %C, i64 %iv
+; CHECK-NEXT:          %gep.C.st = getelementptr i32, ptr %C.offset, i64 %iv
+; CHECK-NEXT:      Grouped accesses:
+; CHECK-NEXT:        Group GRP0:
+; CHECK-NEXT:          (Low: %B High: (4132 + %B))
+; CHECK-NEXT:            Member: {%B,+,4}<nw><%loop>
+; CHECK-NEXT:            Member: {(32 + %B),+,4}<nw><%loop>
+; CHECK-NEXT:        Group GRP1:
+; CHECK-NEXT:          (Low: %A High: (8220 + %A))
+; CHECK-NEXT:            Member: {%A,+,8}<nw><%loop>
+; CHECK-NEXT:            Member: {(24 + %A),+,8}<nw><%loop>
+; CHECK-NEXT:        Group GRP2:
+; CHECK-NEXT:          (Low: %C High: (4132 + %C))
+; CHECK-NEXT:            Member: {%C,+,4}<nw><%loop>
+; CHECK-NEXT:            Member: {(32 + %C),+,4}<nw><%loop>
+; 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.offset = getelementptr i32, ptr %A, i64 6
+  %B.offset = getelementptr i32, ptr %B, i64 8
+  %C.offset = getelementptr i32, ptr %C, i64 8
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+
+  ; VF <= 8 is safe for this dependency:
+  %gep.B.ld = getelementptr i32, ptr %B, i64 %iv
+  %ld.B = load i32, ptr %gep.B.ld, align 4
+  %gep.B.st = getelementptr i32, ptr %B.offset, i64 %iv
+  store i32 %ld.B, ptr %gep.B.st
+
+  ; Same as in `@stride2_store_load_preventing_forwarding`.
+  %iv.x2 = mul i64 %iv, 2
+  %gep.ld = getelementptr i32, ptr %A, i64 %iv.x2
+  %ld = load i32, ptr %gep.ld, align 4
+  %gep.st = getelementptr i32, ptr %A.offset, i64 %iv.x2
+  store i32 %ld, ptr %gep.st, align 4
+
+  ; VF <= 8 is safe for this dependency:
+  %gep.C.ld = getelementptr i32, ptr %C, i64 %iv
+  %ld.C = load i32, ptr %gep.C.ld, align 4
+  %gep.C.st = getelementptr i32, ptr %C.offset, i64 %iv
+  store i32 %ld.C, ptr %gep.C.st
+
+  %iv.next = add i64 %iv, 1
+  %cmp = icmp ne i64 %iv, 1024
+  br i1 %cmp, label %loop, label %exit
+
+exit:
+  ret void
+}
+
 ; FIXME: VF 2 is safe for store-load forwarding:
 ;                 idx |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
 ; v/iter 0 load  lane |  0 |    |    |  1 |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |

>From f355e21d25632a50e24b4b8540550ad8a7021c76 Mon Sep 17 00:00:00 2001
From: Andrei Elovikov <andrei.elovikov at sifive.com>
Date: Mon, 3 Aug 2026 10:57:08 -0700
Subject: [PATCH 2/2] Fix comment

---
 .../LoopAccessAnalysis/num-iters-for-store-load-conflict.ll   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll b/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
index 4f76f07fe63ec..e1b9ebb41a4b9 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/num-iters-for-store-load-conflict.ll
@@ -349,10 +349,10 @@ exit:
 }
 
 ; Same as above but with an unrelated store-to-load forwarding deps that do have
-; a safe VF. Make sure those aren't reported as ;
+; a safe VF. Make sure those aren't reported as
 ; `BackwardVectorizableButPreventsForwarding`. We provide two of those (%B and
 ; %C) becase the order of processing matters, so we have one lexically before %A
-; and another after ti.
+; and another after it.
 define void @fwd_conflict_dep_should_not_affect_another_dep(ptr %A, ptr %B, ptr %C) {
 ; CHECK-LABEL: 'fwd_conflict_dep_should_not_affect_another_dep'
 ; CHECK-NEXT:    loop:



More information about the llvm-commits mailing list