@@ -3055,9 +3055,8 @@ PHINode *InnerLoopVectorizer::createInductionResumeValue(
3055
3055
}
3056
3056
3057
3057
// 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 ());
3061
3060
// Copy original phi DL over to the new one.
3062
3061
BCResumeVal->setDebugLoc (OrigPhi->getDebugLoc ());
3063
3062
@@ -7460,7 +7459,6 @@ static void createAndCollectMergePhiForReduction(
7460
7459
auto *PhiR = cast<VPReductionPHIRecipe>(RedResult->getOperand (0 ));
7461
7460
const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
7462
7461
7463
- TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue ();
7464
7462
Value *FinalValue =
7465
7463
State.get (RedResult, VPIteration (State.UF - 1 , VPLane::getFirstLane ()));
7466
7464
auto *ResumePhi =
@@ -7485,7 +7483,7 @@ static void createAndCollectMergePhiForReduction(
7485
7483
BCBlockPhi->addIncoming (ResumePhi->getIncomingValueForBlock (Incoming),
7486
7484
Incoming);
7487
7485
else
7488
- BCBlockPhi->addIncoming (ReductionStartValue , Incoming);
7486
+ BCBlockPhi->addIncoming (RdxDesc. getRecurrenceStartValue () , Incoming);
7489
7487
}
7490
7488
7491
7489
auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue ());
@@ -7778,11 +7776,10 @@ EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton(
7778
7776
7779
7777
// Now, compare the remaining count and if there aren't enough iterations to
7780
7778
// 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 );
7786
7783
emitMinimumVectorEpilogueIterCountCheck (LoopScalarPreHeader,
7787
7784
VecEpilogueIterationCountCheck);
7788
7785
@@ -8901,6 +8898,10 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
8901
8898
// A ComputeReductionResult recipe is added to the middle block, also for
8902
8899
// in-loop reductions which compute their result in-loop, because generating
8903
8900
// 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.
8904
8905
void LoopVectorizationPlanner::adjustRecipesForReductions (
8905
8906
VPBasicBlock *LatchVPBB, VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder,
8906
8907
ElementCount MinVF) {
@@ -9074,6 +9075,41 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9074
9075
continue ;
9075
9076
9076
9077
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
+
9077
9113
// If tail is folded by masking, introduce selects between the phi
9078
9114
// and the live-out instruction of each reduction, at the beginning of the
9079
9115
// dedicated latch block.
@@ -9106,7 +9142,9 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9106
9142
// then extend the loop exit value to enable InstCombine to evaluate the
9107
9143
// entire expression in the smaller type.
9108
9144
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 ())) {
9110
9148
assert (!PhiR->isInLoop () && " Unexpected truncated inloop reduction!" );
9111
9149
Type *RdxTy = RdxDesc.getRecurrenceType ();
9112
9150
auto *Trunc =
@@ -10198,9 +10236,19 @@ bool LoopVectorizePass::processLoop(Loop *L) {
10198
10236
Value *ResumeV = nullptr ;
10199
10237
// TODO: Move setting of resume values to prepareToExecute.
10200
10238
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
+ }
10204
10252
} else {
10205
10253
// Create induction resume values for both widened pointer and
10206
10254
// integer/fp inductions and update the start value of the induction
0 commit comments