[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