[llvm] [LAA] Avoid duplicate runtime-check group members (PR #226829)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 27 12:47:01 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Dávid Bolvanský (davidbolvansky)
<details>
<summary>Changes</summary>
Found while working on #<!-- -->226816 and extracted into a separate PR for easier review.
A read-modify-write pointer has separate read and write entries in the dependence candidates. Both entries can map back to the same runtime-check pointer index, causing the index to be added to a checking group twice.
Check `Seen` when consuming each index so an exact runtime-pointer entry is only grouped once. This removes duplicate group members and avoids overcounting runtime-check costs without changing pointer bounds or dependence legality.
---
Full diff: https://github.com/llvm/llvm-project/pull/226829.diff
9 Files Affected:
- (modified) llvm/lib/Analysis/LoopAccessAnalysis.cpp (+5-2)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/bounded-access-pattern.ll (-2)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll (-4)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/invariant-dep-same-ptr.ll (-7)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/non-affine-monotonic-bounds.ll (-8)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll (-9)
- (modified) llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll (-2)
- (modified) llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected (-3)
- (modified) llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected (-4)
``````````diff
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 804ffe5bb2edd..e739a6d7ea65b 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -777,9 +777,12 @@ void RuntimePointerChecking::groupChecks(
if (PointerI == PositionMap.end())
continue;
for (unsigned Pointer : PointerI->second) {
+ // A read-modify-write access appears in DepCands in both access modes,
+ // but both entries can map to the same runtime-check pointer.
+ if (!Seen.insert(Pointer).second)
+ continue;
+
bool Merged = false;
- // Mark this pointer as seen.
- Seen.insert(Pointer);
// Go through all the existing sets and see if we can find one
// which can include this pointer.
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/bounded-access-pattern.ll b/llvm/test/Analysis/LoopAccessAnalysis/bounded-access-pattern.ll
index 020d808f7b503..40d82b910a313 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/bounded-access-pattern.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/bounded-access-pattern.ll
@@ -936,7 +936,6 @@ define void @bounded_i24_store_size(ptr %a, ptr %b) {
; CHECK-NEXT: %gep.b = getelementptr inbounds i24, ptr %b, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep.a = getelementptr inbounds i24, ptr %a, i64 %idx
-; CHECK-NEXT: %gep.a = getelementptr inbounds i24, ptr %a, i64 %idx
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %b High: (4095 + %b))
@@ -944,7 +943,6 @@ define void @bounded_i24_store_size(ptr %a, ptr %b) {
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %a High: (4095 + %a))
; CHECK-NEXT: Member: {%a,+,4}<nw><%loop>
-; CHECK-NEXT: Member: {%a,+,4}<nw><%loop>
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
; CHECK-NEXT: SCEV assumptions:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
index fa72ae910cbbb..28e0871d123c5 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
@@ -13,20 +13,17 @@ define void @forked_ptrs_simple(ptr nocapture readonly %Base1, ptr nocapture rea
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))
; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
-; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1))
; CHECK-NEXT: Member: {%Base1,+,4}<nw><%loop>
@@ -906,7 +903,6 @@ define void @forked_ptrs_two_select(ptr nocapture readonly %Base1, ptr nocapture
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))
; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
-; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
; CHECK-NEXT: Generated run-time checks are incomplete
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/invariant-dep-same-ptr.ll b/llvm/test/Analysis/LoopAccessAnalysis/invariant-dep-same-ptr.ll
index 777a247dd90d3..d7db75aff7a9a 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/invariant-dep-same-ptr.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/invariant-dep-same-ptr.ll
@@ -20,20 +20,17 @@ define void @conditional_store_load_same_invariant_via_phi(ptr %p0, ptr %p1, ptr
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %p2
-; CHECK-NEXT: ptr %p2
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep0 = getelementptr i32, ptr %p0, i64 %iv
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %p2
-; CHECK-NEXT: ptr %p2
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: %gep1 = getelementptr i32, ptr %phip, i64 %iv
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %p2 High: (4 + %p2))
; CHECK-NEXT: Member: %p2
-; CHECK-NEXT: Member: %p2
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %p0 High: ((4 * %n) + %p0))
; CHECK-NEXT: Member: {%p0,+,4}<%loop>
@@ -160,19 +157,16 @@ define void @phi_with_loads_from_same_addr(ptr %p0, ptr %p1, ptr %x, i64 %n, i1
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
-; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep0 = getelementptr i32, ptr %p0, i64 %iv
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
-; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: %gep1 = getelementptr i32, ptr %phip, i64 %iv
; CHECK-NEXT: Check 2:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
-; CHECK-NEXT: %ld1 = load ptr, ptr %x, align 8
; CHECK-NEXT: Against group GRP3:
; CHECK-NEXT: %ld2 = load ptr, ptr %x, align 8
; CHECK-NEXT: Check 3:
@@ -184,7 +178,6 @@ define void @phi_with_loads_from_same_addr(ptr %p0, ptr %p1, ptr %x, i64 %n, i1
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %ld1 High: (4 + %ld1))
; CHECK-NEXT: Member: %ld1
-; CHECK-NEXT: Member: %ld1
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %p0 High: ((4 * %n) + %p0))
; CHECK-NEXT: Member: {%p0,+,4}<%loop>
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/non-affine-monotonic-bounds.ll b/llvm/test/Analysis/LoopAccessAnalysis/non-affine-monotonic-bounds.ll
index e008eb011fadb..d721d1fe7a2db 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/non-affine-monotonic-bounds.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/non-affine-monotonic-bounds.ll
@@ -11,14 +11,12 @@ define void @bitset_udiv64_const_tc(ptr %words, ptr %out) {
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
-; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep.words = getelementptr inbounds i8, ptr %words, i64 %div
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %out High: (441 + %out))
; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
-; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %words High: (7 + %words))
; CHECK-NEXT: Member: (({0,+,1}<nuw><nsw><%loop> /u 64) + %words)<nuw>
@@ -58,14 +56,12 @@ define void @bitset_udiv64_symbolic_tc(ptr %words, ptr %out, i64 %N) {
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
-; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep.words = getelementptr inbounds i8, ptr %words, i64 %div
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %out High: (%N + %out))
; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
-; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %words High: (1 + ((-1 + %N) /u 64) + %words))
; CHECK-NEXT: Member: (({0,+,1}<nuw><nsw><%loop> /u 64) + %words)<nuw>
@@ -591,14 +587,12 @@ define void @bitset_udiv_neg_4_symbolic_tc(ptr %words, ptr %out, i64 %N) {
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
-; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep.words = getelementptr inbounds i8, ptr %words, i64 %div
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %out High: (%N + %out))
; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
-; CHECK-NEXT: Member: {%out,+,1}<nuw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %words High: (1 + ((-1 + %N) /u -4) + %words))
; CHECK-NEXT: Member: (({0,+,1}<nuw><nsw><%loop> /u -4) + %words)<nuw>
@@ -640,14 +634,12 @@ define void @bitset_udiv64_symbolic_start_and_tc(ptr %words, ptr %out, i64 %N, i
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
-; CHECK-NEXT: %gep.out = getelementptr inbounds i8, ptr %out, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %gep.words = getelementptr inbounds i8, ptr %words, i64 %div
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: (%start + %out) High: (%N + %out))
; CHECK-NEXT: Member: {(%start + %out),+,1}<nw><%loop>
-; CHECK-NEXT: Member: {(%start + %out),+,1}<nw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: ((%start /u 64) + %words) High: (1 + ((-1 + %N) /u 64) + %words))
; CHECK-NEXT: Member: (({%start,+,1}<nuw><nsw><%loop> /u 64) + %words)<nuw>
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll b/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
index db6013a69bf6d..6bfaec8af22a8 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll
@@ -509,37 +509,28 @@ define void @phi_load_store_memdep_check(i1 %c, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %A
-; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: ptr %C
-; CHECK-NEXT: ptr %C
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %A
-; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: ptr %B
-; CHECK-NEXT: ptr %B
; CHECK-NEXT: Check 2:
; CHECK-NEXT: Comparing group GRP1:
; CHECK-NEXT: ptr %C
-; CHECK-NEXT: ptr %C
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: ptr %B
-; CHECK-NEXT: ptr %B
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %A High: (2 + %A))
; CHECK-NEXT: Member: %A
-; CHECK-NEXT: Member: %A
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %C High: (2 + %C))
; CHECK-NEXT: Member: %C
-; CHECK-NEXT: Member: %C
; CHECK-NEXT: Group GRP2:
; CHECK-NEXT: (Low: %B High: (2 + %B))
; CHECK-NEXT: Member: %B
-; CHECK-NEXT: Member: %B
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were found in loop.
; CHECK-NEXT: SCEV assumptions:
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll
index 19c52c7dfa88b..0e81226d5212e 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/retry-runtime-checks-after-dependence-analysis-forked-pointers.ll
@@ -163,7 +163,6 @@ define void @dependency_check_and_runtime_checks_needed_select_of_ptr_add_recs_m
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %a High: ((4 * %n) + %a))
; CHECK-NEXT: Member: {%a,+,4}<nuw><%loop>
-; CHECK-NEXT: Member: {%a,+,4}<nuw><%loop>
; CHECK-NEXT: Generated run-time checks are incomplete
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
@@ -212,7 +211,6 @@ define void @dependency_check_and_runtime_checks_needed_select_of_ptr_add_recs_m
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %a High: ((4 * %n) + %a))
; CHECK-NEXT: Member: {%a,+,4}<nuw><%loop>
-; CHECK-NEXT: Member: {%a,+,4}<nuw><%loop>
; CHECK-NEXT: Generated run-time checks are incomplete
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
index 6d7b0655acdce..052c12488267a 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-access-analysis.ll.expected
@@ -10,20 +10,17 @@ define void @laa(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, p
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))
; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
-; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%loop>
; CHECK-NEXT: Group GRP1:
; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1))
; CHECK-NEXT: Member: {%Base1,+,4}<nw><%loop>
diff --git a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
index e3e62c44f6ce4..1901747ed1b07 100644
--- a/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
+++ b/llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected
@@ -57,17 +57,13 @@ define void @ldist(i1 %cond, ptr %A, ptr %B, ptr %C) {
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %A
-; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group GRP1:
; CHECK-NEXT: ptr %C
-; CHECK-NEXT: ptr %C
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group GRP0:
; CHECK-NEXT: ptr %A
-; CHECK-NEXT: ptr %A
; CHECK-NEXT: Against group GRP2:
; CHECK-NEXT: ptr %B
-; CHECK-NEXT: ptr %B
; CHECK-NEXT: LDist: After removing unused Instrs:
; CHECK-NEXT: LDist: Partition 0:
; CHECK-NEXT: for.body.ldist1: ; preds = %if.end.ldist1, %for.body.ph.ldist1
``````````
</details>
https://github.com/llvm/llvm-project/pull/226829
More information about the llvm-commits
mailing list