[llvm] [SandboxVec][SeedCollection] Iterate over all seeds (PR #195964)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 5 16:48:48 PDT 2026
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/195964
Even though load seeds can already be collected by the seed collector, the seed collection pass was not iterating over them. This patch fixes this, we are now iterating over both store and load seeds.
>From cf345638ed8838b49deb88b123bd9dd4ef3e11d3 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vasileios.porpodas at amd.com>
Date: Mon, 27 Apr 2026 17:53:12 +0000
Subject: [PATCH] [SandboxVec][SeedCollection] Iterate over all seeds
Even though load seeds can already be collected by the seed collector,
the seed collection pass was not iterating over them.
This patch fixes this, we are now iterating over both store and load seeds.
---
.../Passes/SeedCollection.cpp | 86 ++++++++++---------
.../seed_collection_loads.ll | 15 ++++
2 files changed, 59 insertions(+), 42 deletions(-)
create mode 100644 llvm/test/Transforms/SandboxVectorizer/seed_collection_loads.ll
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
index a3bd2dec43277..48b6af9e4a203 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
@@ -58,54 +58,56 @@ bool SeedCollection::runOnFunction(Function &F, const Analyses &A) {
for (auto &BB : F) {
SeedCollector SC(&BB, A.getScalarEvolution(), CollectStores, CollectLoads,
AllowDiffTypes);
- for (SeedBundle &Seeds : SC.getStoreSeeds()) {
- unsigned ElmBits =
- Utils::getNumBits(VecUtils::getElementType(Utils::getExpectedType(
- Seeds[Seeds.getFirstUnusedElementIdx()])),
- DL);
- unsigned AS = getLoadStoreAddressSpace(Seeds[0]);
- unsigned VecRegBits = OverrideVecRegBits != 0
- ? OverrideVecRegBits
- : A.getTTI().getLoadStoreVecRegBitWidth(AS);
+ for (auto &SeedRange : {SC.getStoreSeeds(), SC.getLoadSeeds()}) {
+ for (SeedBundle &Seeds : SeedRange) {
+ unsigned ElmBits =
+ Utils::getNumBits(VecUtils::getElementType(Utils::getExpectedType(
+ Seeds[Seeds.getFirstUnusedElementIdx()])),
+ DL);
+ unsigned AS = getLoadStoreAddressSpace(Seeds[0]);
+ unsigned VecRegBits = OverrideVecRegBits != 0
+ ? OverrideVecRegBits
+ : A.getTTI().getLoadStoreVecRegBitWidth(AS);
- auto DivideBy2 = [](unsigned Num) {
- auto Floor = VecUtils::getFloorPowerOf2(Num);
- if (Floor == Num)
- return Floor / 2;
- return Floor;
- };
- // Try to create the largest vector supported by the target. If it fails
- // reduce the vector size by half.
- for (unsigned SliceElms = std::min(VecRegBits / ElmBits,
- Seeds.getNumUnusedBits() / ElmBits);
- SliceElms >= 2u; SliceElms = DivideBy2(SliceElms)) {
- if (Seeds.allUsed())
- break;
- // Keep trying offsets after FirstUnusedElementIdx, until we vectorize
- // the slice. This could be quite expensive, so we enforce a limit.
- for (unsigned Offset = Seeds.getFirstUnusedElementIdx(),
- OE = Seeds.size();
- Offset + 1 < OE; Offset += 1) {
- // Seeds are getting used as we vectorize, so skip them.
- if (Seeds.isUsed(Offset))
- continue;
+ auto DivideBy2 = [](unsigned Num) {
+ auto Floor = VecUtils::getFloorPowerOf2(Num);
+ if (Floor == Num)
+ return Floor / 2;
+ return Floor;
+ };
+ // Try to create the largest vector supported by the target. If it fails
+ // reduce the vector size by half.
+ for (unsigned SliceElms = std::min(VecRegBits / ElmBits,
+ Seeds.getNumUnusedBits() / ElmBits);
+ SliceElms >= 2u; SliceElms = DivideBy2(SliceElms)) {
if (Seeds.allUsed())
break;
+ // Keep trying offsets after FirstUnusedElementIdx, until we vectorize
+ // the slice. This could be quite expensive, so we enforce a limit.
+ for (unsigned Offset = Seeds.getFirstUnusedElementIdx(),
+ OE = Seeds.size();
+ Offset + 1 < OE; Offset += 1) {
+ // Seeds are getting used as we vectorize, so skip them.
+ if (Seeds.isUsed(Offset))
+ continue;
+ if (Seeds.allUsed())
+ break;
- auto SeedSlice =
- Seeds.getSlice(Offset, SliceElms * ElmBits, !AllowNonPow2);
- if (SeedSlice.empty())
- continue;
+ auto SeedSlice =
+ Seeds.getSlice(Offset, SliceElms * ElmBits, !AllowNonPow2);
+ if (SeedSlice.empty())
+ continue;
- assert(SeedSlice.size() >= 2 && "Should have been rejected!");
+ assert(SeedSlice.size() >= 2 && "Should have been rejected!");
- // Create a region containing the seed slice.
- auto &Ctx = F.getContext();
- RegionWithScore Rgn(Ctx, A.getTTI());
- Rgn.setAux(SeedSlice);
- // Run the region pass pipeline.
- Change |= RPM.runOnRegion(Rgn, A);
- Rgn.clearAux();
+ // Create a region containing the seed slice.
+ auto &Ctx = F.getContext();
+ RegionWithScore Rgn(Ctx, A.getTTI());
+ Rgn.setAux(SeedSlice);
+ // Run the region pass pipeline.
+ Change |= RPM.runOnRegion(Rgn, A);
+ Rgn.clearAux();
+ }
}
}
}
diff --git a/llvm/test/Transforms/SandboxVectorizer/seed_collection_loads.ll b/llvm/test/Transforms/SandboxVectorizer/seed_collection_loads.ll
new file mode 100644
index 0000000000000..43f210f0570d9
--- /dev/null
+++ b/llvm/test/Transforms/SandboxVectorizer/seed_collection_loads.ll
@@ -0,0 +1,15 @@
+; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -disable-output -sbvec-passes="seed-collection<print-region>" -sbvec-collect-seeds=loads %s | FileCheck %s
+; REQUIRES: asserts
+
+; Check that the seed collector will form a aux region containing the loads.
+define void @load_seeds(ptr %ptrA, ptr %ptrB) {
+; CHECK-LABEL: Aux:
+; CHECK-NEXT: %ld0 = load i8, ptr %ptrA0
+; CHECK-NEXT: %ld1 = load i8, ptr %ptrA1
+
+ %ptrA0 = getelementptr i8, ptr %ptrA, i32 0
+ %ptrA1 = getelementptr i8, ptr %ptrA, i32 1
+ %ld0 = load i8, ptr %ptrA0
+ %ld1 = load i8, ptr %ptrA1
+ ret void
+}
More information about the llvm-commits
mailing list