@@ -1293,6 +1293,7 @@ class LoopVectorizationCostModel {
12931293 " from latch block\n " );
12941294 return true ;
12951295 }
1296+
12961297 if (IsVectorizing && InterleaveInfo.requiresScalarEpilogue ()) {
12971298 LLVM_DEBUG (dbgs () << " LV: Loop requires scalar epilogue: "
12981299 " interleaved group requires scalar epilogue\n " );
@@ -4084,6 +4085,7 @@ static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
40844085 continue ;
40854086 case VPDef::VPReductionSC:
40864087 case VPDef::VPActiveLaneMaskPHISC:
4088+ case VPDef::VPLastActiveMaskPHISC:
40874089 case VPDef::VPWidenCallSC:
40884090 case VPDef::VPWidenCanonicalIVSC:
40894091 case VPDef::VPWidenCastSC:
@@ -4302,11 +4304,15 @@ bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
43024304 ElementCount VF) const {
43034305 // Cross iteration phis such as fixed-order recurrences and FMaxNum/FMinNum
43044306 // reductions need special handling and are currently unsupported.
4307+ // FindLast reductions also require special handling for the synthesized
4308+ // mask PHI.
43054309 if (any_of (OrigLoop->getHeader ()->phis (), [&](PHINode &Phi) {
43064310 if (!Legal->isReductionVariable (&Phi))
43074311 return Legal->isFixedOrderRecurrence (&Phi);
4308- return RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind (
4309- Legal->getRecurrenceDescriptor (&Phi).getRecurrenceKind ());
4312+ RecurKind Kind =
4313+ Legal->getRecurrenceDescriptor (&Phi).getRecurrenceKind ();
4314+ return RecurrenceDescriptor::isFindLastRecurrenceKind (Kind) ||
4315+ RecurrenceDescriptor::isFPMinMaxNumRecurrenceKind (Kind);
43104316 }))
43114317 return false ;
43124318
@@ -4612,6 +4618,12 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
46124618 any_of (Plan.getVectorLoopRegion ()->getEntryBasicBlock ()->phis (),
46134619 IsaPred<VPReductionPHIRecipe>);
46144620
4621+ // FIXME: implement interleaving for FindLast transform correctly.
4622+ for (auto &[_, RdxDesc] : Legal->getReductionVars ())
4623+ if (RecurrenceDescriptor::isFindLastRecurrenceKind (
4624+ RdxDesc.getRecurrenceKind ()))
4625+ return 1 ;
4626+
46154627 // If we did not calculate the cost for VF (because the user selected the VF)
46164628 // then we calculate the cost of VF here.
46174629 if (LoopCost == 0 ) {
@@ -8566,6 +8578,10 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
85668578 *Plan, Builder))
85678579 return nullptr ;
85688580
8581+ // Create whole-vector selects for find-last recurrences.
8582+ VPlanTransforms::runPass (VPlanTransforms::convertFindLastRecurrences, *Plan,
8583+ RecipeBuilder, Legal);
8584+
85698585 if (useActiveLaneMask (Style)) {
85708586 // TODO: Move checks to VPlanTransforms::addActiveLaneMask once
85718587 // TailFoldingStyle is visible there.
@@ -8660,10 +8676,11 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
86608676 continue ;
86618677
86628678 RecurKind Kind = PhiR->getRecurrenceKind ();
8663- assert (
8664- !RecurrenceDescriptor::isAnyOfRecurrenceKind (Kind) &&
8665- !RecurrenceDescriptor::isFindIVRecurrenceKind (Kind) &&
8666- " AnyOf and FindIV reductions are not allowed for in-loop reductions" );
8679+ assert (!RecurrenceDescriptor::isFindLastRecurrenceKind (Kind) &&
8680+ !RecurrenceDescriptor::isAnyOfRecurrenceKind (Kind) &&
8681+ !RecurrenceDescriptor::isFindIVRecurrenceKind (Kind) &&
8682+ " AnyOf, FindIV, and FindLast reductions are not allowed for in-loop "
8683+ " reductions" );
86678684
86688685 // Collect the chain of "link" recipes for the reduction starting at PhiR.
86698686 SetVector<VPSingleDefRecipe *> Worklist;
@@ -8960,7 +8977,8 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
89608977 RecurKind RK = RdxDesc.getRecurrenceKind ();
89618978 if ((!RecurrenceDescriptor::isAnyOfRecurrenceKind (RK) &&
89628979 !RecurrenceDescriptor::isFindIVRecurrenceKind (RK) &&
8963- !RecurrenceDescriptor::isMinMaxRecurrenceKind (RK))) {
8980+ !RecurrenceDescriptor::isMinMaxRecurrenceKind (RK) &&
8981+ !RecurrenceDescriptor::isFindLastRecurrenceKind (RK))) {
89648982 VPBuilder PHBuilder (Plan->getVectorPreheader ());
89658983 VPValue *Iden = Plan->getOrAddLiveIn (
89668984 getRecurrenceIdentity (RK, PhiTy, RdxDesc.getFastMathFlags ()));
@@ -9362,7 +9380,7 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
93629380 SmallPtrSet<PHINode *, 2 > EpiWidenedPhis;
93639381 for (VPRecipeBase &R :
93649382 EpiPlan.getVectorLoopRegion ()->getEntryBasicBlock ()->phis ()) {
9365- if (isa<VPCanonicalIVPHIRecipe>(&R))
9383+ if (isa<VPCanonicalIVPHIRecipe, VPLastActiveMaskPHIRecipe >(&R))
93669384 continue ;
93679385 EpiWidenedPhis.insert (
93689386 cast<PHINode>(R.getVPSingleValue ()->getUnderlyingValue ()));
@@ -9559,6 +9577,10 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95599577 continue ;
95609578 }
95619579 }
9580+ } else if (isa<VPLastActiveMaskPHIRecipe>(R)) {
9581+ // LastActiveMasks are only used as part of FindLast reductions,
9582+ // and aren't passed to the scalar loop.
9583+ continue ;
95629584 } else {
95639585 // Retrieve the induction resume values for wide inductions from
95649586 // their original phi nodes in the scalar loop.
@@ -10080,6 +10102,21 @@ bool LoopVectorizePass::processLoop(Loop *L) {
1008010102 // Override IC if user provided an interleave count.
1008110103 IC = UserIC > 0 ? UserIC : IC;
1008210104
10105+ // FIXME: Enable interleaving for last_active reductions.
10106+ if (any_of (make_second_range (LVL.getReductionVars ()), [&](auto &RdxDesc) {
10107+ return RecurrenceDescriptor::isFindLastRecurrenceKind (
10108+ RdxDesc.getRecurrenceKind ());
10109+ })) {
10110+ LLVM_DEBUG (dbgs () << " LV: Not interleaving without vectorization due "
10111+ << " to conditional scalar assignments.\n " );
10112+ IntDiagMsg = {
10113+ " ConditionalAssignmentPreventsScalarInterleaving" ,
10114+ " Unable to interleave without vectorization due to conditional "
10115+ " assignments" };
10116+ InterleaveLoop = false ;
10117+ IC = 1 ;
10118+ }
10119+
1008310120 // Emit diagnostic messages, if any.
1008410121 const char *VAPassName = Hints.vectorizeAnalysisPassName ();
1008510122 if (!VectorizeLoop && !InterleaveLoop) {
0 commit comments