@@ -2242,48 +2242,50 @@ static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
2242
2242
}
2243
2243
}
2244
2244
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);
2246
2256
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);
2283
2257
HeaderMask->replaceAllUsesWith (EVLMask);
2284
2258
ToErase.push_back (HeaderMask->getDefiningRecipe ());
2285
2259
}
2286
2260
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
+
2287
2289
for (VPRecipeBase *R : reverse (ToErase)) {
2288
2290
SmallVector<VPValue *> PossiblyDead (R->operands ());
2289
2291
R->eraseFromParent ();
0 commit comments