[llvm] [NFC][VPlan] Split `makeMemOpWideningDecisions` into subpasses (PR #182593)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 13:00:57 PDT 2026
================
@@ -6473,38 +6473,79 @@ void VPlanTransforms::makeMemOpWideningDecisions(
}
}
- VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
+ // Few helpers to process different kinds of memory operations.
+
+ // To be used as argument to `VPlanTransforms::runPass` which explicitly
+ // specified pass name, hence `VPlan &` parameter.
+ auto ProcessSubset = [&](VPlan &, auto ProcessVPInst) {
+ SmallVector<VPInstruction *> RemainingMemOps;
+ for (VPInstruction *VPI : MemOps) {
+ if (!ProcessVPInst(VPI))
+ RemainingMemOps.push_back(VPI);
+ }
+
+ MemOps.clear();
+ std::swap(MemOps, RemainingMemOps);
+ };
+
+ auto ReplaceWith = [&](VPInstruction *VPI, VPRecipeBase *New) {
+ New->insertBefore(VPI);
+ if (VPI->getOpcode() == Instruction::Load)
+ VPI->replaceAllUsesWith(New->getVPSingleValue());
+ VPI->eraseFromParent();
+
+ // VPI has been processed.
+ return true;
+ };
+
+ auto Scalarize = [&](VPInstruction *VPI) {
+ return ReplaceWith(VPI, RecipeBuilder.handleReplication(VPI, Range));
+ };
+
+ auto *MiddleVPBB = Plan.getMiddleBlock();
VPBuilder FinalRedStoresBuilder(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
+ VPlanTransforms::runPass(
+ "lowerMemoryIdioms", ProcessSubset, Plan, [&](VPInstruction *VPI) {
+ if (RecipeBuilder.replaceWithFinalIfReductionStore(
+ VPI, FinalRedStoresBuilder))
+ return true;
- for (VPInstruction *VPI : MemOps) {
- auto ReplaceWith = [&](VPRecipeBase *New) {
- New->insertBefore(VPI);
- if (VPI->getOpcode() == Instruction::Load)
- VPI->replaceAllUsesWith(New->getVPSingleValue());
- VPI->eraseFromParent();
- };
+ // Filter out scalar VPlan for the remaining idioms.
+ if (LoopVectorizationPlanner::getDecisionAndClampRange(
+ [](ElementCount VF) { return VF.isScalar(); }, Range))
+ return false;
- // Note: we must do that for scalar VPlan as well.
- if (RecipeBuilder.replaceWithFinalIfReductionStore(VPI,
- FinalRedStoresBuilder))
- continue;
+ if (VPHistogramRecipe *Histogram = RecipeBuilder.widenIfHistogram(VPI))
+ return ReplaceWith(VPI, Histogram);
- // Filter out scalar VPlan for the remaining memory operations.
- if (LoopVectorizationPlanner::getDecisionAndClampRange(
- [](ElementCount VF) { return VF.isScalar(); }, Range))
- continue;
+ return false;
+ });
- if (VPHistogramRecipe *Histogram = RecipeBuilder.widenIfHistogram(VPI)) {
- ReplaceWith(Histogram);
- continue;
- }
+ // Filter out scalar VPlan for the remaining memory operations.
+ if (LoopVectorizationPlanner::getDecisionAndClampRange(
+ [](ElementCount VF) { return VF.isScalar(); }, Range))
+ return;
- VPRecipeBase *Recipe = RecipeBuilder.tryToWidenMemory(VPI, Range);
- if (!Recipe)
- Recipe = RecipeBuilder.handleReplication(VPI, Range);
+ // If the instruction's allocated size doesn't equal it's type size, it
+ // requires padding and will be scalarized.
+ VPlanTransforms::runPass(
+ "scalarizeMemOpsWithIrregularTypes", ProcessSubset, Plan,
+ [&](VPInstruction *VPI) {
+ Instruction *I = VPI->getUnderlyingInstr();
+ if (hasIrregularType(getLoadStoreType(I), I->getDataLayout()))
+ return Scalarize(VPI);
----------------
fhahn wrote:
Just checking if you had a chance to think about the above? Either is fine with me.
https://github.com/llvm/llvm-project/pull/182593
More information about the llvm-commits
mailing list