diff --git a/llvm/lib/Transforms/Vectorize/VPlanCFG.h b/llvm/lib/Transforms/Vectorize/VPlanCFG.h --- a/llvm/lib/Transforms/Vectorize/VPlanCFG.h +++ b/llvm/lib/Transforms/Vectorize/VPlanCFG.h @@ -144,7 +144,9 @@ /// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their /// parent region's successors. This ensures all blocks in a region are visited /// before any blocks in a successor region when doing a reverse post-order -// traversal of the graph. +// traversal of the graph. Region blocks themselves traverse only their entries +// directly and not their successors. Those will be traversed when a region's +// exiting block is traversed template class VPAllSuccessorsIterator : public iterator_facade_base, @@ -166,9 +168,8 @@ /// both the const and non-const operator* implementations. template static T1 deref(T1 Block, unsigned SuccIdx) { if (auto *R = dyn_cast(Block)) { - if (SuccIdx == 0) - return R->getEntry(); - SuccIdx--; + assert(SuccIdx == 0); + return R->getEntry(); } // For exit blocks, use the next parent region with successors. @@ -188,12 +189,13 @@ } static VPAllSuccessorsIterator end(BlockPtrTy Block) { + if (auto *R = dyn_cast(Block)) { + // Traverse through the region's entry node. + return {R, 1}; + } BlockPtrTy ParentWithSuccs = getBlockWithSuccs(Block); unsigned NumSuccessors = ParentWithSuccs ? ParentWithSuccs->getNumSuccessors() : 0; - - if (auto *R = dyn_cast(Block)) - return {R, NumSuccessors + 1}; return {Block, NumSuccessors}; } diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -398,9 +398,8 @@ SmallVector FromIterator( VPAllSuccessorsIterator(R1), VPAllSuccessorsIterator::end(R1)); - EXPECT_EQ(2u, FromIterator.size()); + EXPECT_EQ(1u, FromIterator.size()); EXPECT_EQ(R1BB1, FromIterator[0]); - EXPECT_EQ(R2, FromIterator[1]); // Depth-first. VPBlockRecursiveTraversalWrapper Start(R1);