Skip to content

Commit b3db33b

Browse files
committed
[LoopVectorize] Use new getUniqueLatchExitBlock routine
With PR #88385 I am introducing support for vectorising more loops with early exits that don't require a scalar epilogue. As such, if a loop doesn't have a unique exit block it will not automatically imply we require a scalar epilogue. Also, in the only place in the code today where we use the variable LoopExitBlock we actually mean the exit block from the latch. Therefore, it seemed reasonable to add a new getUniqueLatchExitBlock helper that allows the caller to determine the exit block taken from the latch and use this instead of getUniqueExitBlock. I also removed LoopExitBlock since it was only used in one place. While doing this I also noticed that one of the comments in requiresScalarEpilogue is wrong when we require a scalar epilogue, i.e. when we're not exiting from the latch block. This doesn't always imply we have multiple exits, e.g. see the test in Transforms/LoopVectorize/unroll_nonlatch.ll where the latch unconditionally branches back to the only exiting block.
1 parent 66b2820 commit b3db33b

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

llvm/include/llvm/Support/GenericLoopInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ template <class BlockT, class LoopT> class LoopBase {
294294
/// Otherwise return null.
295295
BlockT *getUniqueExitBlock() const;
296296

297+
/// Return the unique exit block for the latch, or null if there are multiple
298+
/// different exit blocks.
299+
BlockT *getUniqueLatchExitBlock() const;
300+
297301
/// Return true if this loop does not have any exit blocks.
298302
bool hasNoExitBlocks() const;
299303

llvm/include/llvm/Support/GenericLoopInfoImpl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,16 @@ BlockT *LoopBase<BlockT, LoopT>::getUniqueExitBlock() const {
159159
return getExitBlockHelper(this, true).first;
160160
}
161161

162+
template <class BlockT, class LoopT>
163+
BlockT *LoopBase<BlockT, LoopT>::getUniqueLatchExitBlock() const {
164+
const BlockT *Latch = getLoopLatch();
165+
assert(Latch && "Latch block must exists");
166+
SmallVector<BlockT *, 4> ExitBlocks;
167+
getUniqueExitBlocksHelper(this, ExitBlocks,
168+
[Latch](const BlockT *BB) { return BB == Latch; });
169+
return ExitBlocks.size() == 1 ? ExitBlocks[0] : nullptr;
170+
}
171+
162172
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
163173
template <class BlockT, class LoopT>
164174
void LoopBase<BlockT, LoopT>::getExitEdges(

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,6 @@ class InnerLoopVectorizer {
637637
/// Middle Block between the vector and the scalar.
638638
BasicBlock *LoopMiddleBlock;
639639

640-
/// The unique ExitBlock of the scalar loop if one exists. Note that
641-
/// there can be multiple exiting edges reaching this block.
642-
BasicBlock *LoopExitBlock;
643-
644640
/// The scalar loop body.
645641
BasicBlock *LoopScalarBody;
646642

@@ -1363,8 +1359,8 @@ class LoopVectorizationCostModel {
13631359
// If we might exit from anywhere but the latch, must run the exiting
13641360
// iteration in scalar form.
13651361
if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) {
1366-
LLVM_DEBUG(
1367-
dbgs() << "LV: Loop requires scalar epilogue: multiple exits\n");
1362+
LLVM_DEBUG(dbgs() << "LV: Loop requires scalar epilogue: not exiting "
1363+
"from latch block\n");
13681364
return true;
13691365
}
13701366
if (IsVectorizing && InterleaveInfo.requiresScalarEpilogue()) {
@@ -2004,8 +2000,7 @@ class GeneratedRTChecks {
20042000
/// adjusts the branches to branch to the vector preheader or \p Bypass,
20052001
/// depending on the generated condition.
20062002
BasicBlock *emitSCEVChecks(BasicBlock *Bypass,
2007-
BasicBlock *LoopVectorPreHeader,
2008-
BasicBlock *LoopExitBlock) {
2003+
BasicBlock *LoopVectorPreHeader) {
20092004
if (!SCEVCheckCond)
20102005
return nullptr;
20112006

@@ -2478,7 +2473,7 @@ void InnerLoopVectorizer::emitIterationCountCheck(BasicBlock *Bypass) {
24782473

24792474
BasicBlock *InnerLoopVectorizer::emitSCEVChecks(BasicBlock *Bypass) {
24802475
BasicBlock *const SCEVCheckBlock =
2481-
RTChecks.emitSCEVChecks(Bypass, LoopVectorPreHeader, LoopExitBlock);
2476+
RTChecks.emitSCEVChecks(Bypass, LoopVectorPreHeader);
24822477
if (!SCEVCheckBlock)
24832478
return nullptr;
24842479

@@ -2533,8 +2528,8 @@ void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) {
25332528
LoopScalarBody = OrigLoop->getHeader();
25342529
LoopVectorPreHeader = OrigLoop->getLoopPreheader();
25352530
assert(LoopVectorPreHeader && "Invalid loop structure");
2536-
LoopExitBlock = OrigLoop->getUniqueExitBlock(); // may be nullptr
2537-
assert((LoopExitBlock || Cost->requiresScalarEpilogue(VF.isVector())) &&
2531+
assert((OrigLoop->getUniqueExitBlock() ||
2532+
Cost->requiresScalarEpilogue(VF.isVector())) &&
25382533
"multiple exit loop without required epilogue?");
25392534

25402535
LoopMiddleBlock =
@@ -7807,7 +7802,7 @@ EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton(
78077802
// If there is an epilogue which must run, there's no edge from the
78087803
// middle block to exit blocks and thus no need to update the immediate
78097804
// dominator of the exit blocks.
7810-
DT->changeImmediateDominator(LoopExitBlock,
7805+
DT->changeImmediateDominator(OrigLoop->getUniqueLatchExitBlock(),
78117806
EPI.EpilogueIterationCountCheck);
78127807

78137808
// Keep track of bypass blocks, as they feed start values to the induction and

0 commit comments

Comments
 (0)