@@ -386,33 +386,54 @@ std::unique_ptr<VPlan> VPlanTransforms::buildPlainCFG(
386
386
// / Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
387
387
// / has exactly 2 predecessors (preheader and latch), where the block
388
388
// / dominates the latch and the preheader dominates the block. If it is a
389
- // / header block return true, making sure the preheader appears first and
390
- // / the latch second. Otherwise return false.
391
- static bool canonicalHeader (VPBlockBase *HeaderVPB,
392
- const VPDominatorTree &VPDT) {
389
+ // / header block return true and canonicalize the predecessors of the header
390
+ // / (making sure the preheader appears first and the latch second) and the
391
+ // / successors of the latch (making sure the loop exit comes first). Otherwise
392
+ // / return false.
393
+ static bool canonicalHeaderAndLatch (VPBlockBase *HeaderVPB,
394
+ const VPDominatorTree &VPDT) {
393
395
ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors ();
394
396
if (Preds.size () != 2 )
395
397
return false ;
396
398
397
399
auto *PreheaderVPBB = Preds[0 ];
398
400
auto *LatchVPBB = Preds[1 ];
399
- if (VPDT.dominates (PreheaderVPBB, HeaderVPB) &&
400
- VPDT.dominates (HeaderVPB, LatchVPBB))
401
- return true ;
401
+ if (! VPDT.dominates (PreheaderVPBB, HeaderVPB) ||
402
+ ! VPDT.dominates (HeaderVPB, LatchVPBB)) {
403
+ std::swap (PreheaderVPBB, LatchVPBB) ;
402
404
403
- std::swap (PreheaderVPBB, LatchVPBB);
405
+ if (!VPDT.dominates (PreheaderVPBB, HeaderVPB) ||
406
+ !VPDT.dominates (HeaderVPB, LatchVPBB))
407
+ return false ;
404
408
405
- if (VPDT.dominates (PreheaderVPBB, HeaderVPB) &&
406
- VPDT.dominates (HeaderVPB, LatchVPBB)) {
407
- // Canonicalize predecessors of header so that preheader is first and latch
408
- // second.
409
+ // Canonicalize predecessors of header so that preheader is first and
410
+ // latch second.
409
411
HeaderVPB->swapPredecessors ();
410
412
for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis ())
411
413
R.swapOperands ();
412
- return true ;
413
414
}
414
415
415
- return false ;
416
+ // The two successors of conditional branch match the condition, with the
417
+ // first successor corresponding to true and the second to false. We
418
+ // canonicalize the successors of the latch when introducing the region, such
419
+ // that the latch exits the region when its condition is true; invert the
420
+ // original condition if the original CFG branches to the header on true.
421
+ // Note that the exit edge is not yet connected for top-level loops.
422
+ if (LatchVPBB->getSingleSuccessor () ||
423
+ LatchVPBB->getSuccessors ()[0 ] != HeaderVPB)
424
+ return true ;
425
+
426
+ assert (LatchVPBB->getNumSuccessors () == 2 && " Must have 2 successors" );
427
+ auto *Term = cast<VPBasicBlock>(LatchVPBB)->getTerminator ();
428
+ assert (cast<VPInstruction>(Term)->getOpcode () ==
429
+ VPInstruction::BranchOnCond &&
430
+ " terminator must be a BranchOnCond" );
431
+ auto *Not = new VPInstruction (VPInstruction::Not, {Term->getOperand (0 )});
432
+ Not->insertBefore (Term);
433
+ Term->setOperand (0 , Not);
434
+ LatchVPBB->swapSuccessors ();
435
+
436
+ return true ;
416
437
}
417
438
418
439
// / Create a new VPRegionBlock for the loop starting at \p HeaderVPB.
@@ -447,7 +468,7 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan, Type *InductionTy,
447
468
VPDominatorTree VPDT;
448
469
VPDT.recalculate (Plan);
449
470
for (VPBlockBase *HeaderVPB : vp_depth_first_shallow (Plan.getEntry ()))
450
- if (canonicalHeader (HeaderVPB, VPDT))
471
+ if (canonicalHeaderAndLatch (HeaderVPB, VPDT))
451
472
createLoopRegion (Plan, HeaderVPB);
452
473
453
474
VPRegionBlock *TopRegion = Plan.getVectorLoopRegion ();
0 commit comments