@@ -2242,48 +2242,50 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
22422242 }
22432243 }
22442244
2245- // Try to optimize header mask recipes away to their EVL variants.
2245+ // Replace header masks with a mask equivalent to predicating by EVL:
2246+ //
2247+ // icmp ule widen-canonical-iv backedge-taken-count
2248+ // ->
2249+ // icmp ult step-vector, EVL
2250+ VPRecipeBase *EVLR = EVL.getDefiningRecipe ();
2251+ VPBuilder Builder (EVLR->getParent (), std::next (EVLR->getIterator ()));
2252+ Type *EVLType = TypeInfo.inferScalarType (&EVL);
2253+ VPValue *EVLMask = Builder.createICmp (
2254+ CmpInst::ICMP_ULT,
2255+ Builder.createNaryOp (VPInstruction::StepVector, {}, EVLType), &EVL);
22462256 for (VPValue *HeaderMask : collectAllHeaderMasks (Plan)) {
2247- // TODO: Split optimizeMaskToEVL out and move into
2248- // VPlanTransforms::optimize. transformRecipestoEVLRecipes should be run in
2249- // tryToBuildVPlanWithVPRecipes beforehand.
2250- for (VPUser *U : collectUsersRecursively (HeaderMask)) {
2251- auto *CurRecipe = cast<VPRecipeBase>(U);
2252- VPRecipeBase *EVLRecipe =
2253- optimizeMaskToEVL (HeaderMask, *CurRecipe, TypeInfo, *AllOneMask, EVL);
2254- if (!EVLRecipe)
2255- continue ;
2256-
2257- [[maybe_unused]] unsigned NumDefVal = EVLRecipe->getNumDefinedValues ();
2258- assert (NumDefVal == CurRecipe->getNumDefinedValues () &&
2259- " New recipe must define the same number of values as the "
2260- " original." );
2261- assert (
2262- NumDefVal <= 1 &&
2263- " Only supports recipes with a single definition or without users." );
2264- EVLRecipe->insertBefore (CurRecipe);
2265- if (isa<VPSingleDefRecipe, VPWidenLoadEVLRecipe>(EVLRecipe)) {
2266- VPValue *CurVPV = CurRecipe->getVPSingleValue ();
2267- CurVPV->replaceAllUsesWith (EVLRecipe->getVPSingleValue ());
2268- }
2269- ToErase.push_back (CurRecipe);
2270- }
2271-
2272- // Replace header masks with a mask equivalent to predicating by EVL:
2273- //
2274- // icmp ule widen-canonical-iv backedge-taken-count
2275- // ->
2276- // icmp ult step-vector, EVL
2277- VPRecipeBase *EVLR = EVL.getDefiningRecipe ();
2278- VPBuilder Builder (EVLR->getParent (), std::next (EVLR->getIterator ()));
2279- Type *EVLType = TypeInfo.inferScalarType (&EVL);
2280- VPValue *EVLMask = Builder.createICmp (
2281- CmpInst::ICMP_ULT,
2282- Builder.createNaryOp (VPInstruction::StepVector, {}, EVLType), &EVL);
22832257 HeaderMask->replaceAllUsesWith (EVLMask);
22842258 ToErase.push_back (HeaderMask->getDefiningRecipe ());
22852259 }
22862260
2261+ // Try to optimize header mask recipes away to their EVL variants.
2262+ // TODO: Split optimizeMaskToEVL out and move into
2263+ // VPlanTransforms::optimize. transformRecipestoEVLRecipes should be run in
2264+ // tryToBuildVPlanWithVPRecipes beforehand.
2265+ for (VPUser *U : collectUsersRecursively (EVLMask)) {
2266+ auto *CurRecipe = cast<VPRecipeBase>(U);
2267+ VPRecipeBase *EVLRecipe =
2268+ optimizeMaskToEVL (EVLMask, *CurRecipe, TypeInfo, *AllOneMask, EVL);
2269+ if (!EVLRecipe)
2270+ continue ;
2271+
2272+ [[maybe_unused]] unsigned NumDefVal = EVLRecipe->getNumDefinedValues ();
2273+ assert (NumDefVal == CurRecipe->getNumDefinedValues () &&
2274+ " New recipe must define the same number of values as the "
2275+ " original." );
2276+ assert (NumDefVal <= 1 &&
2277+ " Only supports recipes with a single definition or without users." );
2278+ EVLRecipe->insertBefore (CurRecipe);
2279+ if (isa<VPSingleDefRecipe, VPWidenLoadEVLRecipe>(EVLRecipe)) {
2280+ VPValue *CurVPV = CurRecipe->getVPSingleValue ();
2281+ CurVPV->replaceAllUsesWith (EVLRecipe->getVPSingleValue ());
2282+ }
2283+ ToErase.push_back (CurRecipe);
2284+ }
2285+ // Remove dead EVL mask.
2286+ if (EVLMask->getNumUsers () == 0 )
2287+ EVLMask->getDefiningRecipe ()->eraseFromParent ();
2288+
22872289 for (VPRecipeBase *R : reverse (ToErase)) {
22882290 SmallVector<VPValue *> PossiblyDead (R->operands ());
22892291 R->eraseFromParent ();
0 commit comments