@@ -9192,52 +9192,60 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
9192
9192
auto GetReplicateRegion = [](VPRecipeBase *R) -> VPRegionBlock * {
9193
9193
auto *Region =
9194
9194
dyn_cast_or_null<VPRegionBlock>(R->getParent ()->getParent ());
9195
- if (Region && Region->isReplicator ())
9195
+ if (Region && Region->isReplicator ()) {
9196
+ assert (Region->getNumSuccessors () == 1 &&
9197
+ Region->getNumPredecessors () == 1 && " Expected SESE region!" );
9198
+ assert (R->getParent ()->size () == 1 &&
9199
+ " A recipe in an original replicator region must be the only "
9200
+ " recipe in its block" );
9196
9201
return Region;
9202
+ }
9197
9203
return nullptr ;
9198
9204
};
9199
-
9200
- // If the target is in a replication region, make sure to move Sink to the
9201
- // block after it, not into the replication region itself.
9202
- if (auto *TargetRegion = GetReplicateRegion (Target)) {
9203
- assert (TargetRegion->getNumSuccessors () == 1 && " Expected SESE region!" );
9204
- assert (!GetReplicateRegion (Sink) &&
9205
- " cannot sink a region into another region yet" );
9206
- VPBasicBlock *NextBlock =
9207
- cast<VPBasicBlock>(TargetRegion->getSuccessors ().front ());
9208
- Sink->moveBefore (*NextBlock, NextBlock->getFirstNonPhi ());
9209
- continue ;
9210
- }
9211
-
9205
+ auto *TargetRegion = GetReplicateRegion (Target);
9212
9206
auto *SinkRegion = GetReplicateRegion (Sink);
9213
- // Unless the sink source is in a replicate region, sink the recipe
9214
- // directly.
9215
9207
if (!SinkRegion) {
9216
- Sink->moveAfter (Target);
9208
+ // If the sink source is not a replicate region, sink the recipe directly.
9209
+ if (TargetRegion) {
9210
+ // The target is in a replication region, make sure to move Sink to
9211
+ // the block after it, not into the replication region itself.
9212
+ VPBasicBlock *NextBlock =
9213
+ cast<VPBasicBlock>(TargetRegion->getSuccessors ().front ());
9214
+ Sink->moveBefore (*NextBlock, NextBlock->getFirstNonPhi ());
9215
+ } else
9216
+ Sink->moveAfter (Target);
9217
9217
continue ;
9218
9218
}
9219
9219
9220
- // If the sink source is in a replicate region, we need to move the whole
9221
- // replicate region, which should only contain a single recipe in the main
9222
- // block.
9223
- assert (Sink->getParent ()->size () == 1 &&
9224
- " parent must be a replicator with a single recipe" );
9225
- auto *SplitBlock =
9226
- Target->getParent ()->splitAt (std::next (Target->getIterator ()));
9227
-
9228
- auto *Pred = SinkRegion->getSinglePredecessor ();
9229
- auto *Succ = SinkRegion->getSingleSuccessor ();
9230
- VPBlockUtils::disconnectBlocks (Pred, SinkRegion);
9231
- VPBlockUtils::disconnectBlocks (SinkRegion, Succ);
9232
- VPBlockUtils::connectBlocks (Pred, Succ);
9233
-
9234
- auto *SplitPred = SplitBlock->getSinglePredecessor ();
9235
-
9236
- VPBlockUtils::disconnectBlocks (SplitPred, SplitBlock);
9237
- VPBlockUtils::connectBlocks (SplitPred, SinkRegion);
9238
- VPBlockUtils::connectBlocks (SinkRegion, SplitBlock);
9239
- if (VPBB == SplitPred)
9240
- VPBB = SplitBlock;
9220
+ // The sink source is in a replicate region. Unhook the region from the CFG.
9221
+ auto *SinkPred = SinkRegion->getSinglePredecessor ();
9222
+ auto *SinkSucc = SinkRegion->getSingleSuccessor ();
9223
+ VPBlockUtils::disconnectBlocks (SinkPred, SinkRegion);
9224
+ VPBlockUtils::disconnectBlocks (SinkRegion, SinkSucc);
9225
+ VPBlockUtils::connectBlocks (SinkPred, SinkSucc);
9226
+
9227
+ if (TargetRegion) {
9228
+ // The target recipe is also in a replicate region, move the sink region
9229
+ // after the target region.
9230
+ auto *TargetSucc = TargetRegion->getSingleSuccessor ();
9231
+ VPBlockUtils::disconnectBlocks (TargetRegion, TargetSucc);
9232
+ VPBlockUtils::connectBlocks (TargetRegion, SinkRegion);
9233
+ VPBlockUtils::connectBlocks (SinkRegion, TargetSucc);
9234
+ } else {
9235
+ // The sink source is in a replicate region, we need to move the whole
9236
+ // replicate region, which should only contain a single recipe in the main
9237
+ // block.
9238
+ auto *SplitBlock =
9239
+ Target->getParent ()->splitAt (std::next (Target->getIterator ()));
9240
+
9241
+ auto *SplitPred = SplitBlock->getSinglePredecessor ();
9242
+
9243
+ VPBlockUtils::disconnectBlocks (SplitPred, SplitBlock);
9244
+ VPBlockUtils::connectBlocks (SplitPred, SinkRegion);
9245
+ VPBlockUtils::connectBlocks (SinkRegion, SplitBlock);
9246
+ if (VPBB == SplitPred)
9247
+ VPBB = SplitBlock;
9248
+ }
9241
9249
}
9242
9250
9243
9251
// Interleave memory: for each Interleave Group we marked earlier as relevant
0 commit comments