@@ -1275,6 +1275,7 @@ class LoopVectorizationCostModel {
12751275 " from latch block\n " );
12761276 return true ;
12771277 }
1278+
12781279 if (IsVectorizing && InterleaveInfo.requiresScalarEpilogue ()) {
12791280 LLVM_DEBUG (dbgs () << " LV: Loop requires scalar epilogue: "
12801281 " interleaved group requires scalar epilogue\n " );
@@ -4045,6 +4046,7 @@ static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
40454046 continue ;
40464047 case VPDef::VPReductionSC:
40474048 case VPDef::VPActiveLaneMaskPHISC:
4049+ case VPDef::VPLastActiveMaskPHISC:
40484050 case VPDef::VPWidenCallSC:
40494051 case VPDef::VPWidenCanonicalIVSC:
40504052 case VPDef::VPWidenCastSC:
@@ -4265,11 +4267,15 @@ bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
42654267 ElementCount VF) const {
42664268 // Cross iteration phis such as fixed-order recurrences and FMaxNum/FMinNum
42674269 // reductions need special handling and are currently unsupported.
4270+ // FindLast reductions also require special handling for the synthesized
4271+ // mask PHI.
42684272 if (any_of (OrigLoop->getHeader ()->phis (), [&](PHINode &Phi) {
42694273 if (!Legal->isReductionVariable (&Phi))
42704274 return Legal->isFixedOrderRecurrence (&Phi);
4271- return RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind (
4272- Legal->getRecurrenceDescriptor (&Phi).getRecurrenceKind ());
4275+ RecurKind Kind =
4276+ Legal->getRecurrenceDescriptor (&Phi).getRecurrenceKind ();
4277+ return RecurrenceDescriptor::isFindLastRecurrenceKind (Kind) ||
4278+ RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind (Kind);
42734279 }))
42744280 return false ;
42754281
@@ -4559,6 +4565,12 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
45594565 any_of (Plan.getVectorLoopRegion ()->getEntryBasicBlock ()->phis (),
45604566 IsaPred<VPReductionPHIRecipe>);
45614567
4568+ // FIXME: implement interleaving for FindLast transform correctly.
4569+ for (auto &[_, RdxDesc] : Legal->getReductionVars ())
4570+ if (RecurrenceDescriptor::isFindLastRecurrenceKind (
4571+ RdxDesc.getRecurrenceKind ()))
4572+ return 1 ;
4573+
45624574 // If we did not calculate the cost for VF (because the user selected the VF)
45634575 // then we calculate the cost of VF here.
45644576 if (LoopCost == 0 ) {
@@ -8488,6 +8500,10 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
84888500 *Plan, Builder))
84898501 return nullptr ;
84908502
8503+ // Create whole-vector selects for find-last recurrences.
8504+ VPlanTransforms::runPass (VPlanTransforms::convertFindLastRecurrences, *Plan,
8505+ RecipeBuilder, Legal);
8506+
84918507 if (useActiveLaneMask (Style)) {
84928508 // TODO: Move checks to VPlanTransforms::addActiveLaneMask once
84938509 // TailFoldingStyle is visible there.
@@ -8581,10 +8597,11 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
85818597 continue ;
85828598
85838599 RecurKind Kind = PhiR->getRecurrenceKind ();
8584- assert (
8585- !RecurrenceDescriptor::isAnyOfRecurrenceKind (Kind) &&
8586- !RecurrenceDescriptor::isFindIVRecurrenceKind (Kind) &&
8587- " AnyOf and FindIV reductions are not allowed for in-loop reductions" );
8600+ assert (!RecurrenceDescriptor::isFindLastRecurrenceKind (Kind) &&
8601+ !RecurrenceDescriptor::isAnyOfRecurrenceKind (Kind) &&
8602+ !RecurrenceDescriptor::isFindIVRecurrenceKind (Kind) &&
8603+ " AnyOf, FindIV, and FindLast reductions are not allowed for in-loop "
8604+ " reductions" );
85888605
85898606 // Collect the chain of "link" recipes for the reduction starting at PhiR.
85908607 SetVector<VPSingleDefRecipe *> Worklist;
@@ -8884,7 +8901,8 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
88848901 RecurKind RK = RdxDesc.getRecurrenceKind ();
88858902 if ((!RecurrenceDescriptor::isAnyOfRecurrenceKind (RK) &&
88868903 !RecurrenceDescriptor::isFindIVRecurrenceKind (RK) &&
8887- !RecurrenceDescriptor::isMinMaxRecurrenceKind (RK))) {
8904+ !RecurrenceDescriptor::isMinMaxRecurrenceKind (RK) &&
8905+ !RecurrenceDescriptor::isFindLastRecurrenceKind (RK))) {
88888906 VPBuilder PHBuilder (Plan->getVectorPreheader ());
88898907 VPValue *Iden = Plan->getOrAddLiveIn (
88908908 getRecurrenceIdentity (RK, PhiTy, RdxDesc.getFastMathFlags ()));
@@ -9294,7 +9312,7 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
92949312 SmallPtrSet<PHINode *, 2 > EpiWidenedPhis;
92959313 for (VPRecipeBase &R :
92969314 EpiPlan.getVectorLoopRegion ()->getEntryBasicBlock ()->phis ()) {
9297- if (isa<VPCanonicalIVPHIRecipe>(&R))
9315+ if (isa<VPCanonicalIVPHIRecipe, VPLastActiveMaskPHIRecipe >(&R))
92989316 continue ;
92999317 EpiWidenedPhis.insert (
93009318 cast<PHINode>(R.getVPSingleValue ()->getUnderlyingValue ()));
@@ -9491,6 +9509,10 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
94919509 continue ;
94929510 }
94939511 }
9512+ } else if (isa<VPLastActiveMaskPHIRecipe>(R)) {
9513+ // LastActiveMasks are only used as part of FindLast reductions,
9514+ // and aren't passed to the scalar loop.
9515+ continue ;
94949516 } else {
94959517 // Retrieve the induction resume values for wide inductions from
94969518 // their original phi nodes in the scalar loop.
@@ -10006,6 +10028,21 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1000610028 // Override IC if user provided an interleave count.
1000710029 IC = UserIC > 0 ? UserIC : IC;
1000810030
10031+ // FIXME: Enable interleaving for last_active reductions.
10032+ if (any_of (make_second_range (LVL.getReductionVars ()), [&](auto &RdxDesc) {
10033+ return RecurrenceDescriptor::isFindLastRecurrenceKind (
10034+ RdxDesc.getRecurrenceKind ());
10035+ })) {
10036+ LLVM_DEBUG (dbgs () << " LV: Not interleaving without vectorization due "
10037+ << " to conditional scalar assignments.\n " );
10038+ IntDiagMsg = {
10039+ " ConditionalAssignmentPreventsScalarInterleaving" ,
10040+ " Unable to interleave without vectorization due to conditional "
10041+ " assignments" };
10042+ InterleaveLoop = false ;
10043+ IC = 1 ;
10044+ }
10045+
1000910046 // Emit diagnostic messages, if any.
1001010047 const char *VAPassName = Hints.vectorizeAnalysisPassName ();
1001110048 if (!VectorizeLoop && !InterleaveLoop) {
0 commit comments