@@ -1642,11 +1642,13 @@ void VPlanTransforms::addActiveLaneMask(
1642
1642
// / \p TypeInfo VPlan-based type analysis.
1643
1643
// / \p AllOneMask The vector mask parameter of vector-predication intrinsics.
1644
1644
// / \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.
1646
1647
static VPRecipeBase *createEVLRecipe (VPValue *HeaderMask,
1647
1648
VPRecipeBase &CurRecipe,
1648
1649
VPTypeAnalysis &TypeInfo,
1649
- VPValue &AllOneMask, VPValue &EVL) {
1650
+ VPValue &AllOneMask, VPValue &EVL,
1651
+ VPValue *PrevEVL) {
1650
1652
using namespace llvm ::VPlanPatternMatch;
1651
1653
auto GetNewMask = [&](VPValue *OrigMask) -> VPValue * {
1652
1654
assert (OrigMask && " Unmasked recipe when folding tail" );
@@ -1704,6 +1706,15 @@ static VPRecipeBase *createEVLRecipe(VPValue *HeaderMask,
1704
1706
Sel->getDebugLoc ());
1705
1707
})
1706
1708
.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
+
1707
1718
VPValue *LHS, *RHS;
1708
1719
// Transform select with a header mask condition
1709
1720
// select(header_mask, LHS, RHS)
@@ -1732,6 +1743,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1732
1743
1733
1744
// Create a scalar phi to track the previous EVL if fixed-order recurrence is
1734
1745
// contained.
1746
+ VPScalarPHIRecipe *PrevEVL = nullptr ;
1735
1747
bool ContainsFORs =
1736
1748
any_of (Header->phis (), IsaPred<VPFirstOrderRecurrencePHIRecipe>);
1737
1749
if (ContainsFORs) {
@@ -1747,7 +1759,7 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1747
1759
VPBasicBlock *Preheader = LoopRegion->getPreheaderVPBB ();
1748
1760
Preheader->appendRecipe (cast<VPScalarCastRecipe>(MaxEVL));
1749
1761
}
1750
- auto * PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1762
+ PrevEVL = new VPScalarPHIRecipe (MaxEVL, &EVL, DebugLoc (), " prev.evl" );
1751
1763
PrevEVL->insertBefore (*Header, Header->getFirstNonPhi ());
1752
1764
}
1753
1765
@@ -1761,8 +1773,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
1761
1773
for (VPValue *HeaderMask : collectAllHeaderMasks (Plan)) {
1762
1774
for (VPUser *U : collectUsersRecursively (HeaderMask)) {
1763
1775
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 );
1766
1778
if (!EVLRecipe)
1767
1779
continue ;
1768
1780
0 commit comments