@@ -3036,9 +3036,8 @@ PHINode *InnerLoopVectorizer::createInductionResumeValue(
3036
3036
}
3037
3037
3038
3038
// Create phi nodes to merge from the backedge-taken check block.
3039
- PHINode *BCResumeVal =
3040
- PHINode::Create (OrigPhi->getType (), 3 , " bc.resume.val" ,
3041
- LoopScalarPreHeader->getTerminator ()->getIterator ());
3039
+ PHINode *BCResumeVal = PHINode::Create (OrigPhi->getType (), 3 , " bc.resume.val" ,
3040
+ LoopScalarPreHeader->getFirstNonPHI ());
3042
3041
// Copy original phi DL over to the new one.
3043
3042
BCResumeVal->setDebugLoc (OrigPhi->getDebugLoc ());
3044
3043
@@ -7453,11 +7452,17 @@ static void createAndCollectMergePhiForReduction(
7453
7452
auto *PhiR = cast<VPReductionPHIRecipe>(RedResult->getOperand (0 ));
7454
7453
const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
7455
7454
7456
- TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue ();
7457
7455
Value *FinalValue =
7458
7456
State.get (RedResult, VPIteration (State.UF - 1 , VPLane::getFirstLane ()));
7459
7457
auto *ResumePhi =
7460
7458
dyn_cast<PHINode>(PhiR->getStartValue ()->getUnderlyingValue ());
7459
+ if (VectorizingEpilogue && RecurrenceDescriptor::isAnyOfRecurrenceKind (
7460
+ RdxDesc.getRecurrenceKind ())) {
7461
+ auto *Cmp = cast<ICmpInst>(PhiR->getStartValue ()->getUnderlyingValue ());
7462
+ assert (Cmp->getPredicate () == CmpInst::ICMP_NE);
7463
+ assert (Cmp->getOperand (1 ) == RdxDesc.getRecurrenceStartValue ());
7464
+ ResumePhi = cast<PHINode>(Cmp->getOperand (0 ));
7465
+ }
7461
7466
assert ((!VectorizingEpilogue || ResumePhi) &&
7462
7467
" when vectorizing the epilogue loop, we need a resume phi from main "
7463
7468
" vector loop" );
@@ -7481,7 +7486,7 @@ static void createAndCollectMergePhiForReduction(
7481
7486
BCBlockPhi->addIncoming (ResumePhi->getIncomingValueForBlock (Incoming),
7482
7487
Incoming);
7483
7488
else
7484
- BCBlockPhi->addIncoming (ReductionStartValue , Incoming);
7489
+ BCBlockPhi->addIncoming (RdxDesc. getRecurrenceStartValue () , Incoming);
7485
7490
}
7486
7491
7487
7492
auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue ());
@@ -7774,11 +7779,10 @@ EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton(
7774
7779
7775
7780
// Now, compare the remaining count and if there aren't enough iterations to
7776
7781
// execute the vectorized epilogue skip to the scalar part.
7777
- BasicBlock *VecEpilogueIterationCountCheck = LoopVectorPreHeader;
7778
- VecEpilogueIterationCountCheck->setName (" vec.epilog.iter.check" );
7779
- LoopVectorPreHeader =
7780
- SplitBlock (LoopVectorPreHeader, LoopVectorPreHeader->getTerminator (), DT,
7781
- LI, nullptr , " vec.epilog.ph" );
7782
+ LoopVectorPreHeader->setName (" vec.epilog.ph" );
7783
+ BasicBlock *VecEpilogueIterationCountCheck =
7784
+ SplitBlock (LoopVectorPreHeader, LoopVectorPreHeader->begin (), DT, LI,
7785
+ nullptr , " vec.epilog.iter.check" , true );
7782
7786
emitMinimumVectorEpilogueIterCountCheck (LoopScalarPreHeader,
7783
7787
VecEpilogueIterationCountCheck);
7784
7788
@@ -8913,6 +8917,10 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
8913
8917
// A ComputeReductionResult recipe is added to the middle block, also for
8914
8918
// in-loop reductions which compute their result in-loop, because generating
8915
8919
// the subsequent bc.merge.rdx phi is driven by ComputeReductionResult recipes.
8920
+ //
8921
+ // Adjust AnyOf reductions; replace the reduction phi for the selected value
8922
+ // with a boolean reduction phi node to check if the condition is true in any
8923
+ // iteration. The final value is selected by the final ComputeReductionResult.
8916
8924
void LoopVectorizationPlanner::adjustRecipesForReductions (
8917
8925
VPBasicBlock *LatchVPBB, VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder,
8918
8926
ElementCount MinVF) {
@@ -9087,6 +9095,41 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9087
9095
continue ;
9088
9096
9089
9097
const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
9098
+ // Adjust AnyOf reductions; replace the reduction phi for the selected value
9099
+ // with a boolean reduction phi node to check if the condition is true in
9100
+ // any iteration. The final value is selected by the final
9101
+ // ComputeReductionResult.
9102
+ if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
9103
+ RdxDesc.getRecurrenceKind ())) {
9104
+ auto *Select = cast<VPRecipeBase>(*find_if (PhiR->users (), [](VPUser *U) {
9105
+ return isa<VPWidenSelectRecipe>(U) ||
9106
+ (isa<VPReplicateRecipe>(U) &&
9107
+ cast<VPReplicateRecipe>(U)->getUnderlyingInstr ()->getOpcode () ==
9108
+ Instruction::Select);
9109
+ }));
9110
+ VPValue *Cmp = Select->getOperand (0 );
9111
+ // If the compare is checking the reduction PHI node, adjust it to check
9112
+ // the start value.
9113
+ if (VPRecipeBase *CmpR = Cmp->getDefiningRecipe ()) {
9114
+ for (unsigned I = 0 ; I != CmpR->getNumOperands (); ++I)
9115
+ if (CmpR->getOperand (I) == PhiR)
9116
+ CmpR->setOperand (I, PhiR->getStartValue ());
9117
+ }
9118
+ VPBuilder::InsertPointGuard Guard (Builder);
9119
+ Builder.setInsertPoint (Select);
9120
+
9121
+ // If the true value of the select is the reduction phi, the new value is
9122
+ // selected if the negated condition is true in any iteration.
9123
+ if (Select->getOperand (1 ) == PhiR)
9124
+ Cmp = Builder.createNot (Cmp);
9125
+ VPValue *Or = Builder.createOr (PhiR, Cmp);
9126
+ Select->getVPSingleValue ()->replaceAllUsesWith (Or);
9127
+
9128
+ // Convert the reduction phi to operate on bools.
9129
+ PhiR->setOperand (0 , Plan->getOrAddLiveIn (ConstantInt::getFalse (
9130
+ OrigLoop->getHeader ()->getContext ())));
9131
+ }
9132
+
9090
9133
// If tail is folded by masking, introduce selects between the phi
9091
9134
// and the live-out instruction of each reduction, at the beginning of the
9092
9135
// dedicated latch block.
@@ -9119,7 +9162,9 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9119
9162
// then extend the loop exit value to enable InstCombine to evaluate the
9120
9163
// entire expression in the smaller type.
9121
9164
Type *PhiTy = PhiR->getStartValue ()->getLiveInIRValue ()->getType ();
9122
- if (MinVF.isVector () && PhiTy != RdxDesc.getRecurrenceType ()) {
9165
+ if (MinVF.isVector () && PhiTy != RdxDesc.getRecurrenceType () &&
9166
+ !RecurrenceDescriptor::isAnyOfRecurrenceKind (
9167
+ RdxDesc.getRecurrenceKind ())) {
9123
9168
assert (!PhiR->isInLoop () && " Unexpected truncated inloop reduction!" );
9124
9169
Type *RdxTy = RdxDesc.getRecurrenceType ();
9125
9170
auto *Trunc =
@@ -10164,9 +10209,19 @@ bool LoopVectorizePass::processLoop(Loop *L) {
10164
10209
Value *ResumeV = nullptr ;
10165
10210
// TODO: Move setting of resume values to prepareToExecute.
10166
10211
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
10167
- ResumeV = ReductionResumeValues
10168
- .find (&ReductionPhi->getRecurrenceDescriptor ())
10169
- ->second ;
10212
+ const RecurrenceDescriptor &RdxDesc =
10213
+ ReductionPhi->getRecurrenceDescriptor ();
10214
+ RecurKind RK = RdxDesc.getRecurrenceKind ();
10215
+ ResumeV = ReductionResumeValues.find (&RdxDesc)->second ;
10216
+ if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) {
10217
+ // VPReductionPHIRecipes for AnyOf reductions expect a boolean as
10218
+ // start value; compare the final value from the main vector loop
10219
+ // to the start value.
10220
+ IRBuilder<> Builder (
10221
+ cast<Instruction>(ResumeV)->getParent ()->getFirstNonPHI ());
10222
+ ResumeV = Builder.CreateICmpNE (ResumeV,
10223
+ RdxDesc.getRecurrenceStartValue ());
10224
+ }
10170
10225
} else {
10171
10226
// Create induction resume values for both widened pointer and
10172
10227
// integer/fp inductions and update the start value of the induction
0 commit comments