[llvm] [SandboxVec][SeedCollection] Iterate over all seeds (PR #195964)
via llvm-commits
llvm-commits at lists.llvm.org
Tue May 5 16:49:31 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-vectorizers
Author: vporpo (vporpo)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/195964.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp (+44-42)
- (added) llvm/test/Transforms/SandboxVectorizer/seed_collection_loads.ll (+15)
``````````diff
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/195964
More information about the llvm-commits
mailing list