@@ -1658,11 +1658,13 @@ void VPlanTransforms::addActiveLaneMask(
16581658// / \p TypeInfo VPlan-based type analysis.
16591659// / \p AllOneMask The vector mask parameter of vector-predication intrinsics.
16601660// / \p EVL The explicit vector length parameter of vector-predication
1661- // / intrinsics.
1661+ // / intrinsics.
1662+ // / \p PrevEVL The explicit vector length of the previous iteration.
16621663static VPRecipeBase *createEVLRecipe (VPValue *HeaderMask,
16631664 VPRecipeBase &CurRecipe,
16641665 VPTypeAnalysis &TypeInfo,
1665- VPValue &AllOneMask, VPValue &EVL) {
1666+ VPValue &AllOneMask, VPValue &EVL,
1667+ VPValue *PrevEVL) {
16661668 using namespace llvm ::VPlanPatternMatch;
16671669 auto GetNewMask = [&](VPValue *OrigMask) -> VPValue * {
16681670 assert (OrigMask && " Unmasked recipe when folding tail" );
@@ -1690,6 +1692,15 @@ static VPRecipeBase *createEVLRecipe(VPValue *HeaderMask,
16901692 Sel->getDebugLoc ());
16911693 })
16921694 .Case <VPInstruction>([&](VPInstruction *VPI) -> VPRecipeBase * {
1695+ if (VPI->getOpcode () == VPInstruction::FirstOrderRecurrenceSplice) {
1696+ assert (PrevEVL && " Fixed-order recurrences require previous EVL" );
1697+ SmallVector<VPValue *> Ops (VPI->operands ());
1698+ Ops.append ({&AllOneMask, PrevEVL, &EVL});
1699+ return new VPWidenIntrinsicRecipe (Intrinsic::experimental_vp_splice,
1700+ Ops, TypeInfo.inferScalarType (VPI),
1701+ VPI->getDebugLoc ());
1702+ }
1703+
16931704 VPValue *LHS, *RHS;
16941705 // Transform select with a header mask condition
16951706 // select(header_mask, LHS, RHS)
@@ -1718,6 +1729,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17181729
17191730 // Create a scalar phi to track the previous EVL if fixed-order recurrence is
17201731 // contained.
1732+ VPScalarPHIRecipe *PrevEVL = nullptr ;
17211733 bool ContainsFORs =
17221734 any_of (Header->phis (), IsaPred<VPFirstOrderRecurrencePHIRecipe>);
17231735 if (ContainsFORs) {
@@ -1733,7 +1745,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17331745 VPBasicBlock *Preheader = LoopRegion->getPreheaderVPBB ();
17341746 Preheader->appendRecipe (cast<VPScalarCastRecipe>(MaxEVL));
17351747 }
1736- auto * PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1748+ PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
17371749 PrevEVL->insertBefore (*Header, Header->getFirstNonPhi ());
17381750 }
17391751
@@ -1747,8 +1759,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
17471759 for (VPValue *HeaderMask : collectAllHeaderMasks (Plan)) {
17481760 for (VPUser *U : collectUsersRecursively (HeaderMask)) {
17491761 auto *CurRecipe = cast<VPRecipeBase>(U);
1750- VPRecipeBase *EVLRecipe =
1751- createEVLRecipe ( HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL);
1762+ VPRecipeBase *EVLRecipe = createEVLRecipe (
1763+ HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL, PrevEVL );
17521764 if (!EVLRecipe)
17531765 continue ;
17541766
0 commit comments