@@ -2736,22 +2736,6 @@ static inline RemoveMask_match<Op0_t, Op1_t> m_RemoveMask(const Op0_t &In,
27362736 return RemoveMask_match<Op0_t, Op1_t>(In, Out);
27372737}
27382738
2739- // / If \p R is a VPInstruction::Reverse, return a VPWidenIntrinsicRecipe
2740- // / for the vp.reverse intrinsic using \p EVL. Returns nullptr otherwise.
2741- static VPWidenIntrinsicRecipe *
2742- getEVLReverse (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPValue &EVL) {
2743- VPValue *ReversedVal;
2744- if (!match (&R,
2745- m_VPInstruction<VPInstruction::Reverse>(m_VPValue (ReversedVal))))
2746- return nullptr ;
2747-
2748- auto *Reverse = cast<VPInstruction>(&R);
2749- VPlan *Plan = Reverse->getParent ()->getPlan ();
2750- return new VPWidenIntrinsicRecipe (
2751- Intrinsic::experimental_vp_reverse, {ReversedVal, Plan->getTrue (), &EVL},
2752- TypeInfo.inferScalarType (Reverse), {}, {}, Reverse->getDebugLoc ());
2753- }
2754-
27552739// / Try to optimize a \p CurRecipe masked by \p HeaderMask to a corresponding
27562740// / EVL-based recipe without the header mask. Returns nullptr if no EVL-based
27572741// / recipe could be created.
@@ -2835,6 +2819,32 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
28352819 return nullptr ;
28362820}
28372821
2822+ static void convertToEVLReverse (VPlan &Plan, VPTypeAnalysis &TypeInfo,
2823+ VPValue &EVL) {
2824+ SmallVector<VPRecipeBase *> ToRemove;
2825+
2826+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2827+ vp_depth_first_shallow (Plan.getVectorLoopRegion ()->getEntry ()))) {
2828+ for (VPRecipeBase &R : make_early_inc_range (reverse (*VPBB))) {
2829+ auto *VPI = dyn_cast<VPInstruction>(&R);
2830+ if (!VPI || VPI->getOpcode () != VPInstruction::Reverse)
2831+ continue ;
2832+
2833+ SmallVector<VPValue *> Ops (VPI->operands ());
2834+ Ops.append ({Plan.getTrue (), &EVL});
2835+ auto *NewReverse = new VPWidenIntrinsicRecipe (
2836+ Intrinsic::experimental_vp_reverse, Ops,
2837+ TypeInfo.inferScalarType (VPI), {}, {}, VPI->getDebugLoc ());
2838+ NewReverse->insertBefore (VPI);
2839+ VPI->replaceAllUsesWith (NewReverse);
2840+ ToRemove.push_back (VPI);
2841+ }
2842+ }
2843+
2844+ for (VPRecipeBase *R : ToRemove)
2845+ R->eraseFromParent ();
2846+ }
2847+
28382848// / Replace recipes with their EVL variants.
28392849static void transformRecipestoEVLRecipes (VPlan &Plan, VPValue &EVL) {
28402850 VPTypeAnalysis TypeInfo (Plan);
@@ -2949,44 +2959,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
29492959 }
29502960 }
29512961 ToErase.push_back (CurRecipe);
2952-
2953- // Convert general reverse operations on loaded values and stored values
2954- // into vp.reverse, when the VPVectorEndPointerRecipe adjusting the access
2955- // address uses EVL instead of VF.
2956- // TODO: Extend conversion along the def-use/use-def chain, as reverse
2957- // operations may be eliminated or moved in the future.
2958- if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(EVLRecipe)) {
2959- if (!match (MemR->getAddr (), m_VecEndPtr (m_VPValue (), m_Specific (&EVL))))
2960- continue ;
2961- assert (MemR->isReverse () &&
2962- " Only reverse access uses VPVectorEndPointerRecipe as address" );
2963-
2964- VPRecipeBase *Candidate = nullptr ;
2965- if (auto *LoadR = dyn_cast<VPWidenLoadEVLRecipe>(MemR)) {
2966- assert (LoadR->getNumUsers () == 1 &&
2967- " Unexpected user number of reverse load" );
2968- Candidate = cast<VPRecipeBase>(*LoadR->user_begin ());
2969- } else if (auto *StoreR = dyn_cast<VPWidenStoreEVLRecipe>(MemR)) {
2970- VPValue *StoredVal = StoreR->getStoredValue ();
2971- // Skip if the stored value is not defined in the loop region.
2972- if (StoredVal->isDefinedOutsideLoopRegions ())
2973- continue ;
2974- Candidate = StoredVal->getDefiningRecipe ();
2975- }
2976- assert (Candidate && " Must have one reverse operation for reverse access" );
2977-
2978- if (match (Candidate, m_Intrinsic<Intrinsic::experimental_vp_reverse>()))
2979- continue ;
2980-
2981- VPWidenIntrinsicRecipe *NewReverse =
2982- getEVLReverse (*Candidate, TypeInfo, EVL);
2983- assert (NewReverse &&
2984- " Unable to get an EVL reverse when tail folding by EVL" );
2985- NewReverse->insertBefore (Candidate);
2986- cast<VPInstruction>(Candidate)->replaceAllUsesWith (NewReverse);
2987- ToErase.push_back (Candidate);
2988- }
29892962 }
2963+ convertToEVLReverse (Plan, TypeInfo, EVL);
29902964 // Remove dead EVL mask.
29912965 if (EVLMask->getNumUsers () == 0 )
29922966 ToErase.push_back (EVLMask->getDefiningRecipe ());
0 commit comments