[llvm] 747cf24 - [LV] Rework legacy widen/replicate in tryToBuildVPlan (NFC) (#224569)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 10:48:50 PDT 2026
Author: Ramkumar Ramachandra
Date: 2026-09-22T17:48:43Z
New Revision: 747cf241988e83e9ab4aae88efc10d91e87a0b90
URL: https://github.com/llvm/llvm-project/commit/747cf241988e83e9ab4aae88efc10d91e87a0b90
DIFF: https://github.com/llvm/llvm-project/commit/747cf241988e83e9ab4aae88efc10d91e87a0b90.diff
LOG: [LV] Rework legacy widen/replicate in tryToBuildVPlan (NFC) (#224569)
The code has been rewritten for clarity:
- An RPOT traversal is unnecessary, and a depth-first will do.
- The list of recipes to be skipped continues to grow, and its utility
is in question. Replace it with a clean make_isa_range over
VPInstructions, and an assert.
- Clarify that tryToCreateWidenNonPhiRecipe is the routine that produces
VPWidenIntOrFpInductionRecipes.
- Clarify the necessity of the underling value.
Added:
Modified:
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 983eaf665839c..6e27d1e209daf 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6645,12 +6645,6 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan,
// ---------------------------------------------------------------------------
VPRecipeBuilder RecipeBuilder(*Plan, Legal, *CM, Builder);
- // Scan the body of the loop in a topological order to visit each basic block
- // after having visited its predecessor basic blocks.
- VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
- ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT(
- HeaderVPBB);
-
RUN_VPLAN_PASS(VPlanTransforms::createInLoopReductionRecipes, *Plan,
Range.Start);
@@ -6664,50 +6658,55 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan,
RUN_VPLAN_PASS(VPlanTransforms::makeCallWideningDecisions, *Plan, Range,
RecipeBuilder, CostCtx);
- // Now process all other blocks and instructions.
- for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
- // Convert input VPInstructions to widened recipes.
- for (VPRecipeBase &R : make_early_inc_range(
- make_range(VPBB->getFirstNonPhi(), VPBB->end()))) {
- // Skip recipes that do not need transforming or have already been
- // transformed.
- if (isa<VPWidenCanonicalIVRecipe, VPBlendRecipe, VPReductionRecipe,
- VPReplicateRecipe, VPWidenLoadRecipe, VPWidenStoreRecipe,
- VPWidenCallRecipe, VPWidenIntrinsicRecipe, VPVectorPointerRecipe,
- VPVectorEndPointerRecipe, VPHistogramRecipe>(&R) ||
- (Instruction::isCast(cast<VPInstruction>(R).getOpcode()) &&
- vputils::onlyFirstLaneUsed(R.getVPSingleValue())))
+ // Convert remaining VPInstructions to widen or replicate recipes.
+ // TODO: This legacy code should eventually be migrated to VPlan.
+ VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
+ vp_depth_first_shallow(HeaderVPBB))) {
+ // All types but VPInstructions are already widened and don't need extra
+ // processing. We process VPInstructions below.
+ assert(
+ all_of(
+ make_range(VPBB->getFirstNonPhi(), VPBB->end()),
+ IsaPred<VPWidenCanonicalIVRecipe, VPBlendRecipe, VPReductionRecipe,
+ VPReplicateRecipe, VPWidenLoadRecipe, VPWidenStoreRecipe,
+ VPWidenCallRecipe, VPWidenIntrinsicRecipe,
+ VPVectorPointerRecipe, VPVectorEndPointerRecipe,
+ VPHistogramRecipe, VPInstruction>) &&
+ "Unexpected recipe");
+ for (VPInstruction &VPI :
+ make_early_inc_range(make_isa_range<VPInstruction>(*VPBB))) {
+ // We represent single-scalar casts directly as VPInstructions.
+ if (Instruction::isCast(VPI.getOpcode()) &&
+ vputils::onlyFirstLaneUsed(&VPI))
continue;
- auto *VPI = cast<VPInstruction>(&R);
- if (!VPI->getUnderlyingValue())
+
+ // Only VPInstrutions with an underlying value need to be processed.
+ if (!VPI.getUnderlyingValue())
continue;
- // TODO: Gradually replace uses of underlying instruction by analyses on
- // VPlan. Migrate code relying on the underlying instruction from VPlan0
- // to construct recipes below to not use the underlying instruction.
- Instruction *Instr = cast<Instruction>(VPI->getUnderlyingValue());
- Builder.setInsertPoint(VPI);
+ Builder.setInsertPoint(&VPI);
VPRecipeBase *Recipe =
- RecipeBuilder.tryToCreateWidenNonPhiRecipe(VPI, Range);
- if (!Recipe)
- Recipe =
- RecipeBuilder.handleReplication(cast<VPInstruction>(VPI), Range);
+ RecipeBuilder.tryToCreateWidenNonPhiRecipe(&VPI, Range);
- if (isa<VPWidenIntOrFpInductionRecipe>(Recipe) && isa<TruncInst>(Instr)) {
+ if (isa_and_nonnull<VPWidenIntOrFpInductionRecipe>(Recipe) &&
+ VPI.getOpcode() == Instruction::Trunc) {
// Optimized a truncate to VPWidenIntOrFpInductionRecipe. It needs to be
// moved to the phi section in the header.
Recipe->insertBefore(*HeaderVPBB, HeaderVPBB->getFirstNonPhi());
} else {
+ if (!Recipe)
+ Recipe = RecipeBuilder.handleReplication(&VPI, Range);
Builder.insert(Recipe);
}
if (Recipe->getNumDefinedValues() == 1) {
- VPI->replaceAllUsesWith(Recipe->getVPSingleValue());
+ VPI.replaceAllUsesWith(Recipe->getVPSingleValue());
} else {
assert(Recipe->getNumDefinedValues() == 0 &&
"Unexpected multidef recipe");
}
- R.eraseFromParent();
+ VPI.eraseFromParent();
}
}
More information about the llvm-commits
mailing list