@@ -2236,7 +2236,14 @@ void VPlanTransforms::materializeBroadcasts(VPlan &Plan) {
2236
2236
}
2237
2237
}
2238
2238
2239
- static bool supportedLoad (VPWidenRecipe *R0, VPValue *V, unsigned Idx) {
2239
+ // / Returns true if \p V used at \p Idx of a wide recipe is defined by a
2240
+ // / VPWidenLoadRecipe or VPInterleaveRecipe that can be converted to a narrower
2241
+ // / recipe. A VPWidenLoadRecipe can be narrowed to an index independent load if
2242
+ // / it feeds all the wide ops at all indices (checked by via the operands of the
2243
+ // / wide recipe at lane0, \p R0). A VPInterleaveRecipe can be narrowed to a wide
2244
+ // / load, if \p V used at index \p Idx are defined at \p Idx of the interleave
2245
+ // / group.
2246
+ static bool canNarrowLoad (VPWidenRecipe *R0, VPValue *V, unsigned Idx) {
2240
2247
auto *DefR = V->getDefiningRecipe ();
2241
2248
if (!DefR)
2242
2249
return false ;
@@ -2312,6 +2319,8 @@ void VPlanTransforms::narrowInterleaveGroups(VPlan &Plan, ElementCount VF,
2312
2319
if (R.mayWriteToMemory () && !InterleaveR)
2313
2320
return ;
2314
2321
2322
+ // All other ops are allowed, but we reject uses that cannot be converted
2323
+ // when checking all allowed consumers (store interleave groups) below.
2315
2324
if (!InterleaveR)
2316
2325
continue ;
2317
2326
@@ -2340,20 +2349,22 @@ void VPlanTransforms::narrowInterleaveGroups(VPlan &Plan, ElementCount VF,
2340
2349
continue ;
2341
2350
}
2342
2351
2343
- auto *Lane0 = dyn_cast_or_null<VPWidenRecipe>(
2352
+ // Check if all values feeding InterleaveR are matching wide recipes, which
2353
+ // operands that can be narrowed.
2354
+ auto *WideMember0 = dyn_cast_or_null<VPWidenRecipe>(
2344
2355
InterleaveR->getStoredValues ()[0 ]->getDefiningRecipe ());
2345
- if (!Lane0 )
2356
+ if (!WideMember0 )
2346
2357
return ;
2347
2358
for (const auto &[I, V] : enumerate(InterleaveR->getStoredValues ())) {
2348
2359
auto *R = dyn_cast<VPWidenRecipe>(V->getDefiningRecipe ());
2349
- if (!R || R->getOpcode () != Lane0->getOpcode () || R->getNumOperands () > 2 )
2360
+ if (!R || R->getOpcode () != WideMember0->getOpcode () ||
2361
+ R->getNumOperands () > 2 )
2350
2362
return ;
2351
- if (any_of (R->operands (), [Lane0 , Idx = I](VPValue *V) {
2352
- return !supportedLoad (Lane0 , V, Idx);
2363
+ if (any_of (R->operands (), [WideMember0 , Idx = I](VPValue *V) {
2364
+ return !canNarrowLoad (WideMember0 , V, Idx);
2353
2365
}))
2354
2366
return ;
2355
2367
}
2356
-
2357
2368
StoreGroups.push_back (InterleaveR);
2358
2369
}
2359
2370
@@ -2386,12 +2397,12 @@ void VPlanTransforms::narrowInterleaveGroups(VPlan &Plan, ElementCount VF,
2386
2397
// Narrow operation tree rooted at store groups.
2387
2398
for (auto *StoreGroup : StoreGroups) {
2388
2399
VPValue *Res = nullptr ;
2389
- if (auto *Lane0 = dyn_cast<VPWidenRecipe>(
2400
+ if (auto *WideMember0 = dyn_cast<VPWidenRecipe>(
2390
2401
StoreGroup->getStoredValues ()[0 ]->getDefiningRecipe ())) {
2391
- for (unsigned Idx = 0 , E = Lane0 ->getNumOperands (); Idx != E; ++Idx)
2392
- Lane0 ->setOperand (
2393
- Idx, NarrowOp (Lane0 ->getOperand (Idx)->getDefiningRecipe ()));
2394
- Res = Lane0 ;
2402
+ for (unsigned Idx = 0 , E = WideMember0 ->getNumOperands (); Idx != E; ++Idx)
2403
+ WideMember0 ->setOperand (
2404
+ Idx, NarrowOp (WideMember0 ->getOperand (Idx)->getDefiningRecipe ()));
2405
+ Res = WideMember0 ;
2395
2406
} else {
2396
2407
Res = NarrowOp (StoreGroup->getStoredValues ()[0 ]->getDefiningRecipe ());
2397
2408
}
0 commit comments