Skip to content

Commit b7591e9

Browse files
committed
Change the way to convert reverse operation When EVL lowering.
1 parent 9df99d4 commit b7591e9

File tree

1 file changed

+53
-27
lines changed

1 file changed

+53
-27
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,6 +2630,22 @@ static inline RemoveMask_match<Op0_t, Op1_t> m_RemoveMask(const Op0_t &In,
26302630
return RemoveMask_match<Op0_t, Op1_t>(In, Out);
26312631
}
26322632

2633+
/// If \p R is a VPInstruction::Reverse, return a VPWidenIntrinsicRecipe
2634+
/// for the vp.reverse intrinsic using \p EVL. Returns nullptr otherwise.
2635+
static VPWidenIntrinsicRecipe *
2636+
getEVLReverse(VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPValue &EVL) {
2637+
VPValue *ReversedVal;
2638+
if (!match(&R,
2639+
m_VPInstruction<VPInstruction::Reverse>(m_VPValue(ReversedVal))))
2640+
return nullptr;
2641+
2642+
auto *Reverse = cast<VPInstruction>(&R);
2643+
VPlan *Plan = Reverse->getParent()->getPlan();
2644+
return new VPWidenIntrinsicRecipe(
2645+
Intrinsic::experimental_vp_reverse, {ReversedVal, Plan->getTrue(), &EVL},
2646+
TypeInfo.inferScalarType(Reverse), {}, {}, Reverse->getDebugLoc());
2647+
}
2648+
26332649
/// Try to optimize a \p CurRecipe masked by \p HeaderMask to a corresponding
26342650
/// EVL-based recipe without the header mask. Returns nullptr if no EVL-based
26352651
/// recipe could be created.
@@ -2704,32 +2720,6 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
27042720
return nullptr;
27052721
}
27062722

2707-
static void convertToEVLReverse(VPlan &Plan, VPTypeAnalysis &TypeInfo,
2708-
VPValue &EVL) {
2709-
SmallVector<VPRecipeBase *> ToRemove;
2710-
2711-
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2712-
vp_depth_first_shallow(Plan.getVectorLoopRegion()->getEntry()))) {
2713-
for (VPRecipeBase &R : make_early_inc_range(reverse(*VPBB))) {
2714-
auto *VPI = dyn_cast<VPInstruction>(&R);
2715-
if (!VPI || VPI->getOpcode() != VPInstruction::Reverse)
2716-
continue;
2717-
2718-
SmallVector<VPValue *> Ops(VPI->operands());
2719-
Ops.append({Plan.getTrue(), &EVL});
2720-
auto *NewReverse = new VPWidenIntrinsicRecipe(
2721-
Intrinsic::experimental_vp_reverse, Ops,
2722-
TypeInfo.inferScalarType(VPI), {}, {}, VPI->getDebugLoc());
2723-
NewReverse->insertBefore(VPI);
2724-
VPI->replaceAllUsesWith(NewReverse);
2725-
ToRemove.push_back(VPI);
2726-
}
2727-
}
2728-
2729-
for (VPRecipeBase *R : ToRemove)
2730-
R->eraseFromParent();
2731-
}
2732-
27332723
/// Replace recipes with their EVL variants.
27342724
static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
27352725
VPTypeAnalysis TypeInfo(Plan);
@@ -2844,8 +2834,44 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
28442834
}
28452835
}
28462836
ToErase.push_back(CurRecipe);
2837+
2838+
// Convert general reverse operations on loaded values and stored values
2839+
// into vp.reverse, when the VPVectorEndPointerRecipe adjusting the access
2840+
// address uses EVL instead of VF.
2841+
// TODO: Extend conversion along the def-use/use-def chain, as reverse
2842+
// operations may be eliminated or moved in the future.
2843+
if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(EVLRecipe)) {
2844+
if (!match(MemR->getAddr(), m_VecEndPtr(m_VPValue(), m_Specific(&EVL))))
2845+
continue;
2846+
assert(MemR->isReverse() &&
2847+
"Only reverse access uses VPVectorEndPointerRecipe as address");
2848+
2849+
VPRecipeBase *Candidate = nullptr;
2850+
if (auto *LoadR = dyn_cast<VPWidenLoadEVLRecipe>(MemR)) {
2851+
assert(LoadR->getNumUsers() == 1 &&
2852+
"Unexpected user number of reverse load");
2853+
Candidate = cast<VPRecipeBase>(*LoadR->user_begin());
2854+
} else if (auto *StoreR = dyn_cast<VPWidenStoreEVLRecipe>(MemR)) {
2855+
VPValue *StoredVal = StoreR->getStoredValue();
2856+
// Skip if the stored value is not defined in the loop region.
2857+
if (StoredVal->isDefinedOutsideLoopRegions())
2858+
continue;
2859+
Candidate = StoredVal->getDefiningRecipe();
2860+
}
2861+
assert(Candidate && "Must have one reverse operation for reverse access");
2862+
2863+
if (match(Candidate, m_Intrinsic<Intrinsic::experimental_vp_reverse>()))
2864+
continue;
2865+
2866+
VPWidenIntrinsicRecipe *NewReverse =
2867+
getEVLReverse(*Candidate, TypeInfo, EVL);
2868+
assert(NewReverse &&
2869+
"Unable to get an EVL reverse when tail folding by EVL");
2870+
NewReverse->insertBefore(Candidate);
2871+
cast<VPInstruction>(Candidate)->replaceAllUsesWith(NewReverse);
2872+
ToErase.push_back(Candidate);
2873+
}
28472874
}
2848-
convertToEVLReverse(Plan, TypeInfo, EVL);
28492875
// Remove dead EVL mask.
28502876
if (EVLMask->getNumUsers() == 0)
28512877
ToErase.push_back(EVLMask->getDefiningRecipe());

0 commit comments

Comments
 (0)