@@ -1642,11 +1642,13 @@ void VPlanTransforms::addActiveLaneMask(
16421642// / \p TypeInfo VPlan-based type analysis.
16431643// / \p AllOneMask The vector mask parameter of vector-predication intrinsics.
16441644// / \p EVL The explicit vector length parameter of vector-predication
1645- // / intrinsics.
1645+ // / intrinsics.
1646+ // / \p PrevEVL The explicit vector length of the previous iteration.
16461647static VPRecipeBase *createEVLRecipe (VPValue *HeaderMask,
16471648 VPRecipeBase &CurRecipe,
16481649 VPTypeAnalysis &TypeInfo,
1649- VPValue &AllOneMask, VPValue &EVL) {
1650+ VPValue &AllOneMask, VPValue &EVL,
1651+ VPValue *PrevEVL) {
16501652 using namespace llvm ::VPlanPatternMatch;
16511653 auto GetNewMask = [&](VPValue *OrigMask) -> VPValue * {
16521654 assert (OrigMask && " Unmasked recipe when folding tail" );
@@ -1704,6 +1706,15 @@ static VPRecipeBase *createEVLRecipe(VPValue *HeaderMask,
17041706 Sel->getDebugLoc ());
17051707 })
17061708 .Case <VPInstruction>([&](VPInstruction *VPI) -> VPRecipeBase * {
1709+ if (VPI->getOpcode () == VPInstruction::FirstOrderRecurrenceSplice) {
1710+ assert (PrevEVL && " Fixed-order recurrences require previous EVL" );
1711+ SmallVector<VPValue *> Ops (VPI->operands ());
1712+ Ops.append ({&AllOneMask, PrevEVL, &EVL});
1713+ return new VPWidenIntrinsicRecipe (Intrinsic::experimental_vp_splice,
1714+ Ops, TypeInfo.inferScalarType (VPI),
1715+ VPI->getDebugLoc ());
1716+ }
1717+
17071718 VPValue *LHS, *RHS;
17081719 // Transform select with a header mask condition
17091720 // select(header_mask, LHS, RHS)
@@ -1732,6 +1743,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17321743
17331744 // Create a scalar phi to track the previous EVL if fixed-order recurrence is
17341745 // contained.
1746+ VPScalarPHIRecipe *PrevEVL = nullptr ;
17351747 bool ContainsFORs =
17361748 any_of (Header->phis (), IsaPred<VPFirstOrderRecurrencePHIRecipe>);
17371749 if (ContainsFORs) {
@@ -1747,7 +1759,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17471759 VPBasicBlock *Preheader = LoopRegion->getPreheaderVPBB ();
17481760 Preheader->appendRecipe (cast<VPScalarCastRecipe>(MaxEVL));
17491761 }
1750- auto * PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1762+ PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
17511763 PrevEVL->insertBefore (*Header, Header->getFirstNonPhi ());
17521764 }
17531765
@@ -1761,8 +1773,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17611773 for (VPValue *HeaderMask : collectAllHeaderMasks (Plan)) {
17621774 for (VPUser *U : collectUsersRecursively (HeaderMask)) {
17631775 auto *CurRecipe = cast<VPRecipeBase>(U);
1764- VPRecipeBase *EVLRecipe =
1765- createEVLRecipe ( HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL);
1776+ VPRecipeBase *EVLRecipe = createEVLRecipe (
1777+ HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL, PrevEVL );
17661778 if (!EVLRecipe)
17671779 continue ;
17681780
0 commit comments