@@ -8539,10 +8539,7 @@ VPWidenIntOrFpInductionRecipe *VPRecipeBuilder::tryToOptimizeInductionTruncate(
8539
8539
return nullptr;
8540
8540
}
8541
8541
8542
- VPBlendRecipe *VPRecipeBuilder::tryToBlend(PHINode *Phi,
8543
- ArrayRef<VPValue *> Operands) {
8544
- unsigned NumIncoming = Phi->getNumIncomingValues();
8545
-
8542
+ VPBlendRecipe *VPRecipeBuilder::tryToBlend(VPWidenPHIRecipe *PhiR) {
8546
8543
// We know that all PHIs in non-header blocks are converted into selects, so
8547
8544
// we don't have to worry about the insertion order and we can just use the
8548
8545
// builder. At this point we generate the predication tree. There may be
@@ -8552,17 +8549,19 @@ VPBlendRecipe *VPRecipeBuilder::tryToBlend(PHINode *Phi,
8552
8549
// Map incoming IR BasicBlocks to incoming VPValues, for lookup below.
8553
8550
// TODO: Add operands and masks in order from the VPlan predecessors.
8554
8551
DenseMap<BasicBlock *, VPValue *> VPIncomingValues;
8552
+ auto *Phi = cast<PHINode>(PhiR->getUnderlyingInstr());
8555
8553
for (const auto &[Idx, Pred] : enumerate(predecessors(Phi->getParent())))
8556
- VPIncomingValues[Pred] = Operands[ Idx] ;
8554
+ VPIncomingValues[Pred] = PhiR->getOperand( Idx) ;
8557
8555
8556
+ unsigned NumIncoming = PhiR->getNumIncoming();
8558
8557
SmallVector<VPValue *, 2> OperandsWithMask;
8559
8558
for (unsigned In = 0; In < NumIncoming; In++) {
8560
8559
BasicBlock *Pred = Phi->getIncomingBlock(In);
8561
8560
OperandsWithMask.push_back(VPIncomingValues.lookup(Pred));
8562
8561
VPValue *EdgeMask = getEdgeMask(Pred, Phi->getParent());
8563
8562
if (!EdgeMask) {
8564
8563
assert(In == 0 && "Both null and non-null edge masks found");
8565
- assert(all_equal(Operands ) &&
8564
+ assert(all_equal(PhiR->operands() ) &&
8566
8565
"Distinct incoming values with one having a full mask");
8567
8566
break;
8568
8567
}
@@ -8955,15 +8954,21 @@ bool VPRecipeBuilder::getScaledReductions(
8955
8954
return false;
8956
8955
}
8957
8956
8958
- VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(
8959
- Instruction *Instr, ArrayRef<VPValue *> Operands, VFRange &Range) {
8957
+ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(VPSingleDefRecipe *R,
8958
+ VFRange &Range) {
8960
8959
// First, check for specific widening recipes that deal with inductions, Phi
8961
8960
// nodes, calls and memory operations.
8962
8961
VPRecipeBase *Recipe;
8963
- if (auto *Phi = dyn_cast<PHINode>(Instr)) {
8964
- if (Phi->getParent() != OrigLoop->getHeader())
8965
- return tryToBlend(Phi, Operands);
8966
-
8962
+ Instruction *Instr = R->getUnderlyingInstr();
8963
+ SmallVector<VPValue *, 4> Operands(R->operands());
8964
+ if (auto *PhiR = dyn_cast<VPWidenPHIRecipe>(R)) {
8965
+ VPBasicBlock *Parent = PhiR->getParent();
8966
+ VPRegionBlock *LoopRegionOf = Parent->getEnclosingLoopRegion();
8967
+ // Handle phis in non-header blocks.
8968
+ if (!LoopRegionOf || LoopRegionOf->getEntry() != Parent)
8969
+ return tryToBlend(PhiR);
8970
+
8971
+ auto *Phi = cast<PHINode>(R->getUnderlyingInstr());
8967
8972
assert(Operands.size() == 2 && "Must have 2 operands for header phis");
8968
8973
if ((Recipe = tryToOptimizeInductionPHI(Phi, Operands, Range)))
8969
8974
return Recipe;
@@ -9528,11 +9533,12 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range,
9528
9533
continue;
9529
9534
}
9530
9535
9531
- SmallVector<VPValue *, 4> Operands(R.operands());
9532
9536
VPRecipeBase *Recipe =
9533
- RecipeBuilder.tryToCreateWidenRecipe(Instr, Operands, Range);
9534
- if (!Recipe)
9537
+ RecipeBuilder.tryToCreateWidenRecipe(SingleDef, Range);
9538
+ if (!Recipe) {
9539
+ SmallVector<VPValue *, 4> Operands(R.operands());
9535
9540
Recipe = RecipeBuilder.handleReplication(Instr, Operands, Range);
9541
+ }
9536
9542
9537
9543
RecipeBuilder.setRecipe(Instr, Recipe);
9538
9544
if (isa<VPWidenIntOrFpInductionRecipe>(Recipe) && isa<TruncInst>(Instr)) {
0 commit comments