@@ -3055,9 +3055,8 @@ PHINode *InnerLoopVectorizer::createInductionResumeValue(
30553055 }
30563056
30573057 // Create phi nodes to merge from the backedge-taken check block.
3058- PHINode *BCResumeVal =
3059- PHINode::Create (OrigPhi->getType (), 3 , " bc.resume.val" ,
3060- LoopScalarPreHeader->getTerminator ()->getIterator ());
3058+ PHINode *BCResumeVal = PHINode::Create (OrigPhi->getType (), 3 , " bc.resume.val" ,
3059+ LoopScalarPreHeader->getFirstNonPHI ());
30613060 // Copy original phi DL over to the new one.
30623061 BCResumeVal->setDebugLoc (OrigPhi->getDebugLoc ());
30633062
@@ -7460,7 +7459,6 @@ static void createAndCollectMergePhiForReduction(
74607459 auto *PhiR = cast<VPReductionPHIRecipe>(RedResult->getOperand (0 ));
74617460 const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
74627461
7463- TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue ();
74647462 Value *FinalValue =
74657463 State.get (RedResult, VPIteration (State.UF - 1 , VPLane::getFirstLane ()));
74667464 auto *ResumePhi =
@@ -7485,7 +7483,7 @@ static void createAndCollectMergePhiForReduction(
74857483 BCBlockPhi->addIncoming (ResumePhi->getIncomingValueForBlock (Incoming),
74867484 Incoming);
74877485 else
7488- BCBlockPhi->addIncoming (ReductionStartValue , Incoming);
7486+ BCBlockPhi->addIncoming (RdxDesc. getRecurrenceStartValue () , Incoming);
74897487 }
74907488
74917489 auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue ());
@@ -7778,11 +7776,10 @@ EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton(
77787776
77797777 // Now, compare the remaining count and if there aren't enough iterations to
77807778 // execute the vectorized epilogue skip to the scalar part.
7781- BasicBlock *VecEpilogueIterationCountCheck = LoopVectorPreHeader;
7782- VecEpilogueIterationCountCheck->setName (" vec.epilog.iter.check" );
7783- LoopVectorPreHeader =
7784- SplitBlock (LoopVectorPreHeader, LoopVectorPreHeader->getTerminator (), DT,
7785- LI, nullptr , " vec.epilog.ph" );
7779+ LoopVectorPreHeader->setName (" vec.epilog.ph" );
7780+ BasicBlock *VecEpilogueIterationCountCheck =
7781+ SplitBlock (LoopVectorPreHeader, LoopVectorPreHeader->begin (), DT, LI,
7782+ nullptr , " vec.epilog.iter.check" , true );
77867783 emitMinimumVectorEpilogueIterCountCheck (LoopScalarPreHeader,
77877784 VecEpilogueIterationCountCheck);
77887785
@@ -8901,6 +8898,10 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
89018898// A ComputeReductionResult recipe is added to the middle block, also for
89028899// in-loop reductions which compute their result in-loop, because generating
89038900// the subsequent bc.merge.rdx phi is driven by ComputeReductionResult recipes.
8901+ //
8902+ // Adjust AnyOf reductions; replace the reduction phi for the selected value
8903+ // with a boolean reduction phi node to check if the condition is true in any
8904+ // iteration. The final value is selected by the final ComputeReductionResult.
89048905void LoopVectorizationPlanner::adjustRecipesForReductions (
89058906 VPBasicBlock *LatchVPBB, VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder,
89068907 ElementCount MinVF) {
@@ -9074,6 +9075,41 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
90749075 continue ;
90759076
90769077 const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
9078+ // Adjust AnyOf reductions; replace the reduction phi for the selected value
9079+ // with a boolean reduction phi node to check if the condition is true in
9080+ // any iteration. The final value is selected by the final
9081+ // ComputeReductionResult.
9082+ if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
9083+ RdxDesc.getRecurrenceKind ())) {
9084+ auto *Select = cast<VPRecipeBase>(*find_if (PhiR->users (), [](VPUser *U) {
9085+ return isa<VPWidenSelectRecipe>(U) ||
9086+ (isa<VPReplicateRecipe>(U) &&
9087+ cast<VPReplicateRecipe>(U)->getUnderlyingInstr ()->getOpcode () ==
9088+ Instruction::Select);
9089+ }));
9090+ VPValue *Cmp = Select->getOperand (0 );
9091+ // If the compare is checking the reduction PHI node, adjust it to check
9092+ // the start value.
9093+ if (VPRecipeBase *CmpR = Cmp->getDefiningRecipe ()) {
9094+ for (unsigned I = 0 ; I != CmpR->getNumOperands (); ++I)
9095+ if (CmpR->getOperand (I) == PhiR)
9096+ CmpR->setOperand (I, PhiR->getStartValue ());
9097+ }
9098+ VPBuilder::InsertPointGuard Guard (Builder);
9099+ Builder.setInsertPoint (Select);
9100+
9101+ // If the true value of the select is the reduction phi, the new value is
9102+ // selected if the negated condition is true in any iteration.
9103+ if (Select->getOperand (1 ) == PhiR)
9104+ Cmp = Builder.createNot (Cmp);
9105+ VPValue *Or = Builder.createOr (PhiR, Cmp);
9106+ Select->getVPSingleValue ()->replaceAllUsesWith (Or);
9107+
9108+ // Convert the reduction phi to operate on bools.
9109+ PhiR->setOperand (0 , Plan->getOrAddLiveIn (ConstantInt::getFalse (
9110+ OrigLoop->getHeader ()->getContext ())));
9111+ }
9112+
90779113 // If tail is folded by masking, introduce selects between the phi
90789114 // and the live-out instruction of each reduction, at the beginning of the
90799115 // dedicated latch block.
@@ -9106,7 +9142,9 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
91069142 // then extend the loop exit value to enable InstCombine to evaluate the
91079143 // entire expression in the smaller type.
91089144 Type *PhiTy = PhiR->getStartValue ()->getLiveInIRValue ()->getType ();
9109- if (MinVF.isVector () && PhiTy != RdxDesc.getRecurrenceType ()) {
9145+ if (MinVF.isVector () && PhiTy != RdxDesc.getRecurrenceType () &&
9146+ !RecurrenceDescriptor::isAnyOfRecurrenceKind (
9147+ RdxDesc.getRecurrenceKind ())) {
91109148 assert (!PhiR->isInLoop () && " Unexpected truncated inloop reduction!" );
91119149 Type *RdxTy = RdxDesc.getRecurrenceType ();
91129150 auto *Trunc =
@@ -10198,9 +10236,19 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1019810236 Value *ResumeV = nullptr ;
1019910237 // TODO: Move setting of resume values to prepareToExecute.
1020010238 if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
10201- ResumeV = ReductionResumeValues
10202- .find (&ReductionPhi->getRecurrenceDescriptor ())
10203- ->second ;
10239+ const RecurrenceDescriptor &RdxDesc =
10240+ ReductionPhi->getRecurrenceDescriptor ();
10241+ RecurKind RK = RdxDesc.getRecurrenceKind ();
10242+ ResumeV = ReductionResumeValues.find (&RdxDesc)->second ;
10243+ if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) {
10244+ // VPReductionPHIRecipes for AnyOf reductions expect a boolean as
10245+ // start value; compare the final value from the main vector loop
10246+ // to the start value.
10247+ IRBuilder<> Builder (
10248+ cast<Instruction>(ResumeV)->getParent ()->getFirstNonPHI ());
10249+ ResumeV = Builder.CreateICmpNE (ResumeV,
10250+ RdxDesc.getRecurrenceStartValue ());
10251+ }
1020410252 } else {
1020510253 // Create induction resume values for both widened pointer and
1020610254 // integer/fp inductions and update the start value of the induction
0 commit comments