@@ -386,51 +386,60 @@ std::unique_ptr<VPlan> VPlanTransforms::buildPlainCFG(
386386// / Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
387387// / has exactly 2 predecessors (preheader and latch), where the block
388388// / 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) {
393395 ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors ();
394396 if (Preds.size () != 2 )
395397 return false ;
396398
397399 auto *PreheaderVPBB = Preds[0 ];
398400 auto *LatchVPBB = Preds[1 ];
399- if (VPDT.dominates (PreheaderVPBB, HeaderVPB) &&
400- VPDT.dominates (HeaderVPB, LatchVPBB))
401- return true ;
402-
403- std::swap (PreheaderVPBB, LatchVPBB);
401+ if (!VPDT.dominates (PreheaderVPBB, HeaderVPB) ||
402+ !VPDT.dominates (HeaderVPB, LatchVPBB)) {
403+ std::swap (PreheaderVPBB, LatchVPBB);
404404
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- HeaderVPB->swapPredecessors ();
410- for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis ())
411- R.swapOperands ();
412- return true ;
405+ if (!VPDT.dominates (PreheaderVPBB, HeaderVPB) ||
406+ !VPDT.dominates (HeaderVPB, LatchVPBB)) {
407+ return false ;
408+ } else {
409+ // Canonicalize predecessors of header so that preheader is first and
410+ // latch second.
411+ HeaderVPB->swapPredecessors ();
412+ for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis ())
413+ R.swapOperands ();
414+ }
413415 }
414416
415- return false ;
416- }
417-
418- // / Create a new VPRegionBlock for the loop starting at \p HeaderVPB.
419- static void createLoopRegion (VPlan &Plan, VPBlockBase *HeaderVPB) {
420- auto *PreheaderVPBB = HeaderVPB->getPredecessors ()[0 ];
421- auto *LatchVPBB = HeaderVPB->getPredecessors ()[1 ];
422-
423- // We are canonicalizing the successors of the latch when introducing the
424- // region. We will exit the region of the latch condition is true; invert the
417+ // The two successors of conditional branch match the condition, with the
418+ // first successor corresponding to true and the second to false. We
419+ // canonicalize the successors of the latch when introducing the region, such
420+ // that the latch exits the region when its condition is true; invert the
425421 // original condition if the original CFG branches to the header on true.
426422 if (!LatchVPBB->getSingleSuccessor () &&
427423 LatchVPBB->getSuccessors ()[0 ] == HeaderVPB) {
424+ assert (LatchVPBB->getNumSuccessors () == 2 && " Must have 2 successors" );
428425 auto *Term = cast<VPBasicBlock>(LatchVPBB)->getTerminator ();
426+ assert (cast<VPInstruction>(Term)->getOpcode () ==
427+ VPInstruction::BranchOnCond &&
428+ " terminator must be a BranchOnCond" );
429429 auto *Not = new VPInstruction (VPInstruction::Not, {Term->getOperand (0 )});
430430 Not->insertBefore (Term);
431431 Term->setOperand (0 , Not);
432+ LatchVPBB->swapSuccessors ();
432433 }
433434
435+ return true ;
436+ }
437+
438+ // / Create a new VPRegionBlock for the loop starting at \p HeaderVPB.
439+ static void createLoopRegion (VPlan &Plan, VPBlockBase *HeaderVPB) {
440+ auto *PreheaderVPBB = HeaderVPB->getPredecessors ()[0 ];
441+ auto *LatchVPBB = HeaderVPB->getPredecessors ()[1 ];
442+
434443 VPBlockUtils::disconnectBlocks (PreheaderVPBB, HeaderVPB);
435444 VPBlockUtils::disconnectBlocks (LatchVPBB, HeaderVPB);
436445 VPBlockBase *Succ = LatchVPBB->getSingleSuccessor ();
@@ -458,7 +467,7 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan, Type *InductionTy,
458467 VPDominatorTree VPDT;
459468 VPDT.recalculate (Plan);
460469 for (VPBlockBase *HeaderVPB : vp_depth_first_shallow (Plan.getEntry ()))
461- if (canonicalHeader (HeaderVPB, VPDT))
470+ if (canonicalHeaderAndLatch (HeaderVPB, VPDT))
462471 createLoopRegion (Plan, HeaderVPB);
463472
464473 VPRegionBlock *TopRegion = Plan.getVectorLoopRegion ();
0 commit comments