[llvm] [LAA] Avoid duplicate runtime-check group members (PR #226829)
Dávid Bolvanský via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 06:49:42 PDT 2026
https://github.com/davidbolvansky updated https://github.com/llvm/llvm-project/pull/226829
>From 47a562eacff7414d976d463a2288a65aac232288 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= <david.bolvansky at gmail.com>
Date: Sun, 27 Sep 2026 21:16:48 +0200
Subject: [PATCH 1/3] [LAA] Avoid duplicate runtime-check group members
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 28 ++++++++++---------
.../bounded-access-pattern.ll | 2 --
.../LoopAccessAnalysis/forked-pointers.ll | 4 ---
.../invariant-dep-same-ptr.ll | 7 -----
.../non-affine-monotonic-bounds.ll | 8 ------
.../LoopAccessAnalysis/pointer-phis.ll | 9 ------
...ter-dependence-analysis-forked-pointers.ll | 2 --
.../Inputs/loop-access-analysis.ll.expected | 3 --
.../Inputs/loop-distribute.ll.expected | 4 ---
9 files changed, 15 insertions(+), 52 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 804ffe5bb2edd..10da96c504851 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -736,13 +736,13 @@ void RuntimePointerChecking::groupChecks(
unsigned TotalComparisons = 0;
- DenseMap<Value *, SmallVector<unsigned>> PositionMap;
- for (unsigned Index = 0; Index < Pointers.size(); ++Index)
- PositionMap[Pointers[Index].PointerValue].push_back(Index);
+ DenseMap<Value *, SmallVector<unsigned>> PointerToIndices;
+ for (unsigned I = 0; I < Pointers.size(); ++I)
+ PointerToIndices[Pointers[I].PointerValue].push_back(I);
// We need to keep track of what pointers we've already seen so we
// don't process them twice.
- SmallSet<unsigned, 2> Seen;
+ SmallSet<unsigned, 2> SeenIndices;
// Go through all equivalence classes, get the "pointer check groups"
// and add them to the overall solution. We use the order in which accesses
@@ -750,7 +750,7 @@ void RuntimePointerChecking::groupChecks(
for (unsigned I = 0; I < Pointers.size(); ++I) {
// We've seen this pointer before, and therefore already processed
// its equivalence class.
- if (Seen.contains(I))
+ if (SeenIndices.contains(I))
continue;
MemoryDepChecker::MemAccessInfo Access(Pointers[I].PointerValue,
@@ -764,6 +764,7 @@ void RuntimePointerChecking::groupChecks(
}
SmallVector<RuntimeCheckingPtrGroup, 2> Groups;
+ SmallPtrSet<Value *, 2> SeenPointers;
// Because DepCands is constructed by visiting accesses in the order in
// which they appear in alias sets (which is deterministic) and the
@@ -771,15 +772,16 @@ void RuntimePointerChecking::groupChecks(
// the order in which unions and insertions are performed on the
// equivalence class, the iteration order is deterministic.
for (auto M : DepCands.members(Access)) {
- auto PointerI = PositionMap.find(M.getPointer());
- // If we can't find the pointer in PositionMap that means we can't
- // generate a memcheck for it.
- if (PointerI == PositionMap.end())
+ Value *Pointer = M.getPointer();
+ // A read-modify-write access appears in DepCands in both access modes.
+ if (!SeenPointers.insert(Pointer).second)
continue;
- for (unsigned Pointer : PointerI->second) {
+
+ for (unsigned PointerIndex : PointerToIndices.lookup(Pointer)) {
bool Merged = false;
+
// Mark this pointer as seen.
- Seen.insert(Pointer);
+ SeenIndices.insert(PointerIndex);
// Go through all the existing sets and see if we can find one
// which can include this pointer.
@@ -793,7 +795,7 @@ void RuntimePointerChecking::groupChecks(
TotalComparisons++;
- if (Group.addPointer(Pointer, *this)) {
+ if (Group.addPointer(PointerIndex, *this)) {
Merged = true;
break;
}
@@ -803,7 +805,7 @@ void RuntimePointerChecking::groupChecks(
// We couldn't add this pointer to any existing set or the threshold
// for the number of comparisons has been reached. Create a new group
// to hold the current pointer.
- Groups.emplace_back(Pointer, *this);
+ Groups.emplace_back(PointerIndex, *this);
}
}
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
>From 8866b5146399067d75ed61134cc40365bcb3c8e7 Mon Sep 17 00:00:00 2001
From: David Bolvansky <david.bolvansky at gmail.com>
Date: Tue, 29 Sep 2026 11:26:31 +0200
Subject: [PATCH 2/3] Address review comments
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 10da96c504851..ed7e1f0729c1d 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -764,7 +764,6 @@ void RuntimePointerChecking::groupChecks(
}
SmallVector<RuntimeCheckingPtrGroup, 2> Groups;
- SmallPtrSet<Value *, 2> SeenPointers;
// Because DepCands is constructed by visiting accesses in the order in
// which they appear in alias sets (which is deterministic) and the
@@ -773,15 +772,12 @@ void RuntimePointerChecking::groupChecks(
// equivalence class, the iteration order is deterministic.
for (auto M : DepCands.members(Access)) {
Value *Pointer = M.getPointer();
- // A read-modify-write access appears in DepCands in both access modes.
- if (!SeenPointers.insert(Pointer).second)
- continue;
-
for (unsigned PointerIndex : PointerToIndices.lookup(Pointer)) {
- bool Merged = false;
+ // A read-modify-write access appears in DepCands in both access modes.
+ if (!SeenIndices.insert(PointerIndex).second)
+ continue;
- // Mark this pointer as seen.
- SeenIndices.insert(PointerIndex);
+ bool Merged = false;
// Go through all the existing sets and see if we can find one
// which can include this pointer.
>From 62921fcb9d635ed81f0ec103c9ace23cece01106 Mon Sep 17 00:00:00 2001
From: David Bolvansky <david.bolvansky at gmail.com>
Date: Wed, 30 Sep 2026 15:49:09 +0200
Subject: [PATCH 3/3] Address review comments
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 23c04fa6704c5..c668d86b2e552 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -736,13 +736,14 @@ void RuntimePointerChecking::groupChecks(
unsigned TotalComparisons = 0;
- DenseMap<Value *, SmallVector<unsigned>> PointerToIndices;
- for (unsigned I = 0; I < Pointers.size(); ++I)
- PointerToIndices[Pointers[I].PointerValue].push_back(I);
+ DenseMap<MemoryDepChecker::MemAccessInfo, SmallVector<unsigned>> PositionMap;
+ for (unsigned Index = 0; Index < Pointers.size(); ++Index)
+ PositionMap[{Pointers[Index].PointerValue, Pointers[Index].IsWritePtr}]
+ .push_back(Index);
// We need to keep track of what pointers we've already seen so we
// don't process them twice.
- SmallSet<unsigned, 2> SeenIndices;
+ SmallSet<unsigned, 2> Seen;
// Go through all equivalence classes, get the "pointer check groups"
// and add them to the overall solution. We use the order in which accesses
@@ -750,7 +751,7 @@ void RuntimePointerChecking::groupChecks(
for (unsigned I = 0; I < Pointers.size(); ++I) {
// We've seen this pointer before, and therefore already processed
// its equivalence class.
- if (SeenIndices.contains(I))
+ if (Seen.contains(I))
continue;
MemoryDepChecker::MemAccessInfo Access(Pointers[I].PointerValue,
@@ -771,12 +772,8 @@ void RuntimePointerChecking::groupChecks(
// the order in which unions and insertions are performed on the
// equivalence class, the iteration order is deterministic.
for (auto M : DepCands.members(Access)) {
- Value *Pointer = M.getPointer();
- for (unsigned PointerIndex : PointerToIndices.lookup(Pointer)) {
- // A read-modify-write access appears in DepCands in both access modes.
- if (!SeenIndices.insert(PointerIndex).second)
- continue;
-
+ for (unsigned Pointer : PositionMap.lookup(M)) {
+ assert(Seen.insert(Pointer).second && "pointer already processed");
bool Merged = false;
// Go through all the existing sets and see if we can find one
@@ -791,7 +788,7 @@ void RuntimePointerChecking::groupChecks(
TotalComparisons++;
- if (Group.addPointer(PointerIndex, *this)) {
+ if (Group.addPointer(Pointer, *this)) {
Merged = true;
break;
}
@@ -801,7 +798,7 @@ void RuntimePointerChecking::groupChecks(
// We couldn't add this pointer to any existing set or the threshold
// for the number of comparisons has been reached. Create a new group
// to hold the current pointer.
- Groups.emplace_back(PointerIndex, *this);
+ Groups.emplace_back(Pointer, *this);
}
}
More information about the llvm-commits
mailing list