@@ -2630,22 +2630,6 @@ 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-
26492633// / Try to optimize a \p CurRecipe masked by \p HeaderMask to a corresponding
26502634// / EVL-based recipe without the header mask. Returns nullptr if no EVL-based
26512635// / recipe could be created.
@@ -2687,12 +2671,31 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
26872671 return new VPWidenStoreEVLRecipe (cast<VPWidenStoreRecipe>(CurRecipe), Addr,
26882672 EVL, Mask);
26892673
2690- if (match (&CurRecipe, m_MaskedStore (m_VPValue (EndPtr), m_VPValue (),
2674+ VPValue *StoredVal;
2675+ if (match (&CurRecipe, m_MaskedStore (m_VPValue (EndPtr), m_VPValue (StoredVal),
26912676 m_RemoveMask (HeaderMask, Mask))) &&
26922677 match (EndPtr, m_VecEndPtr (m_VPValue (Addr), m_Specific (&Plan->getVF ()))) &&
2693- cast<VPWidenStoreRecipe>(CurRecipe).isReverse ())
2694- return new VPWidenStoreEVLRecipe (cast<VPWidenStoreRecipe>(CurRecipe),
2695- AdjustEndPtr (EndPtr), EVL, Mask);
2678+ cast<VPWidenStoreRecipe>(CurRecipe).isReverse ()) {
2679+ auto *StoreR = cast<VPWidenStoreRecipe>(&CurRecipe);
2680+ // Convert general reverse operations on stored value into vp.reverse.
2681+ // Skip if the stored value is not defined in the loop region.
2682+ if (!StoredVal->isDefinedOutsideLoopRegions ()) {
2683+ VPValue *ReversedVal;
2684+ bool IsReverse = match (StoredVal, m_VPInstruction<VPInstruction::Reverse>(
2685+ m_VPValue (ReversedVal)));
2686+ assert (IsReverse && " The stored value of reverse store must be defined "
2687+ " by a reverse operation" );
2688+ auto *Reverse = cast<VPInstruction>(StoredVal);
2689+ auto *NewReverse = new VPWidenIntrinsicRecipe (
2690+ Intrinsic::experimental_vp_reverse,
2691+ {ReversedVal, Plan->getTrue (), &EVL},
2692+ TypeInfo.inferScalarType (Reverse), {}, {}, Reverse->getDebugLoc ());
2693+ NewReverse->insertBefore (Reverse);
2694+ return new VPWidenStoreEVLRecipe (*StoreR, AdjustEndPtr (EndPtr),
2695+ NewReverse, EVL, Mask);
2696+ }
2697+ return new VPWidenStoreEVLRecipe (*StoreR, AdjustEndPtr (EndPtr), EVL, Mask);
2698+ }
26962699
26972700 if (auto *Rdx = dyn_cast<VPReductionRecipe>(&CurRecipe))
26982701 if (Rdx->isConditional () &&
@@ -2835,41 +2838,32 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
28352838 }
28362839 ToErase.push_back (CurRecipe);
28372840
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))))
2841+ // Convert general reverse operations on loaded results into vp.reverse,
2842+ // when the VPVectorEndPointerRecipe adjusting the access address uses EVL
2843+ // instead of VF.
2844+ if (auto *LoadR = dyn_cast<VPWidenLoadEVLRecipe>(EVLRecipe)) {
2845+ if (!match (LoadR->getAddr (), m_VecEndPtr (m_VPValue (), m_Specific (&EVL))))
28452846 continue ;
2846- assert (MemR ->isReverse () &&
2847+ assert (LoadR ->isReverse () &&
28472848 " 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);
2849+ // TODO: Extend conversion along the use-def chain, as reverse operations
2850+ // may be eliminated or sunk in the future.
2851+ assert (LoadR->getNumUsers () == 1 &&
2852+ " Unexpected user number of reverse load" );
2853+ auto *UserR = cast<VPRecipeBase>(*LoadR->user_begin ());
2854+ VPValue *ReversedVal;
2855+ bool IsReverse = match (UserR, m_VPInstruction<VPInstruction::Reverse>(
2856+ m_VPValue (ReversedVal)));
2857+ assert (IsReverse && " The defined value of reverse load must be used by a "
2858+ " reverse operation" );
2859+ auto *Reverse = cast<VPInstruction>(UserR);
2860+ auto *NewReverse = new VPWidenIntrinsicRecipe (
2861+ Intrinsic::experimental_vp_reverse,
2862+ {ReversedVal, Plan.getTrue (), &EVL},
2863+ TypeInfo.inferScalarType (Reverse), {}, {}, Reverse->getDebugLoc ());
2864+ NewReverse->insertBefore (Reverse);
2865+ Reverse->replaceAllUsesWith (NewReverse);
2866+ ToErase.push_back (Reverse);
28732867 }
28742868 }
28752869 // Remove dead EVL mask.
0 commit comments