@@ -1643,11 +1643,13 @@ void VPlanTransforms::addActiveLaneMask(
1643
1643
// / \p TypeInfo VPlan-based type analysis.
1644
1644
// / \p AllOneMask The vector mask parameter of vector-predication intrinsics.
1645
1645
// / \p EVL The explicit vector length parameter of vector-predication
1646
+ // / \p PrevEVL The explicit vector length of the previous iteration.
1646
1647
// / intrinsics.
1647
1648
static VPRecipeBase *createEVLRecipe (VPValue *HeaderMask,
1648
1649
VPRecipeBase &CurRecipe,
1649
1650
VPTypeAnalysis &TypeInfo,
1650
- VPValue &AllOneMask, VPValue &EVL) {
1651
+ VPValue &AllOneMask, VPValue &EVL,
1652
+ VPValue *PrevEVL) {
1651
1653
using namespace llvm ::VPlanPatternMatch;
1652
1654
auto GetNewMask = [&](VPValue *OrigMask) -> VPValue * {
1653
1655
assert (OrigMask && " Unmasked recipe when folding tail" );
@@ -1705,6 +1707,15 @@ static VPRecipeBase *createEVLRecipe(VPValue *HeaderMask,
1705
1707
Sel->getDebugLoc ());
1706
1708
})
1707
1709
.Case <VPInstruction>([&](VPInstruction *VPI) -> VPRecipeBase * {
1710
+ if (VPI->getOpcode () == VPInstruction::FirstOrderRecurrenceSplice) {
1711
+ assert (PrevEVL && " Fixed-order recurrences require previous EVL" );
1712
+ SmallVector<VPValue *> Ops (VPI->operands ());
1713
+ Ops.append ({&AllOneMask, PrevEVL, &EVL});
1714
+ return new VPWidenIntrinsicRecipe (Intrinsic::experimental_vp_splice,
1715
+ Ops, TypeInfo.inferScalarType (VPI),
1716
+ VPI->getDebugLoc ());
1717
+ }
1718
+
1708
1719
VPValue *LHS, *RHS;
1709
1720
// Transform select with a header mask condition
1710
1721
// select(header_mask, LHS, RHS)
@@ -1733,6 +1744,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1733
1744
1734
1745
// Create a scalar phi to track the previous EVL if fixed-order recurrence is
1735
1746
// contained.
1747
+ VPScalarPHIRecipe *PrevEVL = nullptr ;
1736
1748
bool ContainsFORs =
1737
1749
any_of (Header->phis (), IsaPred<VPFirstOrderRecurrencePHIRecipe>);
1738
1750
if (ContainsFORs) {
@@ -1748,7 +1760,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1748
1760
VPBasicBlock *Preheader = LoopRegion->getPreheaderVPBB ();
1749
1761
Preheader->appendRecipe (cast<VPScalarCastRecipe>(MaxEVL));
1750
1762
}
1751
- auto * PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1763
+ PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1752
1764
PrevEVL->insertBefore (*Header, Header->getFirstNonPhi ());
1753
1765
}
1754
1766
@@ -1762,8 +1774,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1762
1774
for (VPValue *HeaderMask : collectAllHeaderMasks (Plan)) {
1763
1775
for (VPUser *U : collectUsersRecursively (HeaderMask)) {
1764
1776
auto *CurRecipe = cast<VPRecipeBase>(U);
1765
- VPRecipeBase *EVLRecipe =
1766
- createEVLRecipe ( HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL);
1777
+ VPRecipeBase *EVLRecipe = createEVLRecipe (
1778
+ HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL, PrevEVL );
1767
1779
if (!EVLRecipe)
1768
1780
continue ;
1769
1781
0 commit comments