@@ -2766,22 +2766,6 @@ static inline RemoveMask_match<Op0_t, Op1_t> m_RemoveMask(const Op0_t &In,
27662766 return RemoveMask_match<Op0_t, Op1_t>(In, Out);
27672767}
27682768
2769- // / If \p R is a VPInstruction::Reverse, return a VPWidenIntrinsicRecipe
2770- // / for the vp.reverse intrinsic using \p EVL. Returns nullptr otherwise.
2771- static VPWidenIntrinsicRecipe *
2772- getEVLReverse (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPValue &EVL) {
2773- VPValue *ReversedVal;
2774- if (!match (&R,
2775- m_VPInstruction<VPInstruction::Reverse>(m_VPValue (ReversedVal))))
2776- return nullptr ;
2777-
2778- auto *Reverse = cast<VPInstruction>(&R);
2779- VPlan *Plan = Reverse->getParent ()->getPlan ();
2780- return new VPWidenIntrinsicRecipe (
2781- Intrinsic::experimental_vp_reverse, {ReversedVal, Plan->getTrue (), &EVL},
2782- TypeInfo.inferScalarType (Reverse), {}, {}, Reverse->getDebugLoc ());
2783- }
2784-
27852769// / Try to optimize a \p CurRecipe masked by \p HeaderMask to a corresponding
27862770// / EVL-based recipe without the header mask. Returns nullptr if no EVL-based
27872771// / recipe could be created.
@@ -2865,6 +2849,32 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
28652849 return nullptr ;
28662850}
28672851
2852+ static void convertToEVLReverse (VPlan &Plan, VPTypeAnalysis &TypeInfo,
2853+ VPValue &EVL) {
2854+ SmallVector<VPRecipeBase *> ToRemove;
2855+
2856+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2857+ vp_depth_first_shallow (Plan.getVectorLoopRegion ()->getEntry ()))) {
2858+ for (VPRecipeBase &R : make_early_inc_range (reverse (*VPBB))) {
2859+ auto *VPI = dyn_cast<VPInstruction>(&R);
2860+ if (!VPI || VPI->getOpcode () != VPInstruction::Reverse)
2861+ continue ;
2862+
2863+ SmallVector<VPValue *> Ops (VPI->operands ());
2864+ Ops.append ({Plan.getTrue (), &EVL});
2865+ auto *NewReverse = new VPWidenIntrinsicRecipe (
2866+ Intrinsic::experimental_vp_reverse, Ops,
2867+ TypeInfo.inferScalarType (VPI), {}, {}, VPI->getDebugLoc ());
2868+ NewReverse->insertBefore (VPI);
2869+ VPI->replaceAllUsesWith (NewReverse);
2870+ ToRemove.push_back (VPI);
2871+ }
2872+ }
2873+
2874+ for (VPRecipeBase *R : ToRemove)
2875+ R->eraseFromParent ();
2876+ }
2877+
28682878// / Replace recipes with their EVL variants.
28692879static void transformRecipestoEVLRecipes (VPlan &Plan, VPValue &EVL) {
28702880 VPTypeAnalysis TypeInfo (Plan);
@@ -2979,44 +2989,8 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
29792989 }
29802990 }
29812991 ToErase.push_back (CurRecipe);
2982-
2983- // Convert general reverse operations on loaded values and stored values
2984- // into vp.reverse, when the VPVectorEndPointerRecipe adjusting the access
2985- // address uses EVL instead of VF.
2986- // TODO: Extend conversion along the def-use/use-def chain, as reverse
2987- // operations may be eliminated or moved in the future.
2988- if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(EVLRecipe)) {
2989- if (!match (MemR->getAddr (), m_VecEndPtr (m_VPValue (), m_Specific (&EVL))))
2990- continue ;
2991- assert (MemR->isReverse () &&
2992- " Only reverse access uses VPVectorEndPointerRecipe as address" );
2993-
2994- VPRecipeBase *Candidate = nullptr ;
2995- if (auto *LoadR = dyn_cast<VPWidenLoadEVLRecipe>(MemR)) {
2996- assert (LoadR->getNumUsers () == 1 &&
2997- " Unexpected user number of reverse load" );
2998- Candidate = cast<VPRecipeBase>(*LoadR->user_begin ());
2999- } else if (auto *StoreR = dyn_cast<VPWidenStoreEVLRecipe>(MemR)) {
3000- VPValue *StoredVal = StoreR->getStoredValue ();
3001- // Skip if the stored value is not defined in the loop region.
3002- if (StoredVal->isDefinedOutsideLoopRegions ())
3003- continue ;
3004- Candidate = StoredVal->getDefiningRecipe ();
3005- }
3006- assert (Candidate && " Must have one reverse operation for reverse access" );
3007-
3008- if (match (Candidate, m_Intrinsic<Intrinsic::experimental_vp_reverse>()))
3009- continue ;
3010-
3011- VPWidenIntrinsicRecipe *NewReverse =
3012- getEVLReverse (*Candidate, TypeInfo, EVL);
3013- assert (NewReverse &&
3014- " Unable to get an EVL reverse when tail folding by EVL" );
3015- NewReverse->insertBefore (Candidate);
3016- cast<VPInstruction>(Candidate)->replaceAllUsesWith (NewReverse);
3017- ToErase.push_back (Candidate);
3018- }
30192992 }
2993+ convertToEVLReverse (Plan, TypeInfo, EVL);
30202994 // Remove dead EVL mask.
30212995 if (EVLMask->getNumUsers () == 0 )
30222996 ToErase.push_back (EVLMask->getDefiningRecipe ());
0 commit comments