Skip to content

Commit 7dad4ad

Browse files
committed
[LoopVectorize] Address comments on PR llvm#107004 left post-commit
* Rename Speculative -> Uncountable and update tests. * Add comments explaining why it's safe to ignore the predicates when building up a list of exiting blocks. * Reshuffle some code to do (hopefully) cheaper checks first.
1 parent 02ee96e commit 7dad4ad

File tree

4 files changed

+54
-52
lines changed

4 files changed

+54
-52
lines changed

llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -377,19 +377,19 @@ class LoopVectorizationLegality {
377377
return LAI->getDepChecker().getMaxSafeVectorWidthInBits();
378378
}
379379

380-
/// Returns true if the loop has a speculative early exit, i.e. an
380+
/// Returns true if the loop has an uncountable early exit, i.e. an
381381
/// uncountable exit that isn't the latch block.
382-
bool hasSpeculativeEarlyExit() const { return HasSpeculativeEarlyExit; }
382+
bool hasUncountableEarlyExit() const { return HasUncountableEarlyExit; }
383383

384-
/// Returns the speculative early exiting block.
385-
BasicBlock *getSpeculativeEarlyExitingBlock() const {
384+
/// Returns the uncountable early exiting block.
385+
BasicBlock *getUncountableEarlyExitingBlock() const {
386386
assert(getUncountableExitingBlocks().size() == 1 &&
387387
"Expected only a single uncountable exiting block");
388388
return getUncountableExitingBlocks()[0];
389389
}
390390

391-
/// Returns the destination of a speculative early exiting block.
392-
BasicBlock *getSpeculativeEarlyExitBlock() const {
391+
/// Returns the destination of an uncountable early exiting block.
392+
BasicBlock *getUncountableEarlyExitBlock() const {
393393
assert(getUncountableExitBlocks().size() == 1 &&
394394
"Expected only a single uncountable exit block");
395395
return getUncountableExitBlocks()[0];
@@ -603,15 +603,17 @@ class LoopVectorizationLegality {
603603
/// the use of those function variants.
604604
bool VecCallVariantsFound = false;
605605

606-
/// Indicates whether this loop has a speculative early exit, i.e. an
606+
/// Indicates whether this loop has an uncountable early exit, i.e. an
607607
/// uncountable exiting block that is not the latch.
608-
bool HasSpeculativeEarlyExit = false;
608+
bool HasUncountableEarlyExit = false;
609609

610-
/// Keep track of all the loop exiting blocks.
610+
/// Keep track of all the countable and uncountable exiting blocks if
611+
/// the exact backedge taken count is not computable.
611612
SmallVector<BasicBlock *, 4> CountableExitingBlocks;
612613
SmallVector<BasicBlock *, 4> UncountableExitingBlocks;
613614

614-
/// Keep track of the destinations of all uncountable exits.
615+
/// Keep track of the destinations of all uncountable exits if the
616+
/// exact backedge taken count is not computable.
615617
SmallVector<BasicBlock *, 4> UncountableExitBlocks;
616618
};
617619

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,13 +1473,13 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
14731473

14741474
// Keep a record of all the exiting blocks.
14751475
SmallVector<const SCEVPredicate *, 4> Predicates;
1476-
for (BasicBlock *BB1 : ExitingBlocks) {
1476+
for (BasicBlock *BB : ExitingBlocks) {
14771477
const SCEV *EC =
1478-
PSE.getSE()->getPredicatedExitCount(TheLoop, BB1, &Predicates);
1478+
PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
14791479
if (isa<SCEVCouldNotCompute>(EC)) {
1480-
UncountableExitingBlocks.push_back(BB1);
1480+
UncountableExitingBlocks.push_back(BB);
14811481

1482-
SmallVector<BasicBlock *, 2> Succs(successors(BB1));
1482+
SmallVector<BasicBlock *, 2> Succs(successors(BB));
14831483
if (Succs.size() != 2) {
14841484
reportVectorizationFailure(
14851485
"Early exiting block does not have exactly two successors",
@@ -1488,17 +1488,21 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
14881488
return false;
14891489
}
14901490

1491-
BasicBlock *BB2;
1491+
BasicBlock *ExitBlock;
14921492
if (!TheLoop->contains(Succs[0]))
1493-
BB2 = Succs[0];
1493+
ExitBlock = Succs[0];
14941494
else {
14951495
assert(!TheLoop->contains(Succs[1]));
1496-
BB2 = Succs[1];
1496+
ExitBlock = Succs[1];
14971497
}
1498-
UncountableExitBlocks.push_back(BB2);
1498+
UncountableExitBlocks.push_back(ExitBlock);
14991499
} else
1500-
CountableExitingBlocks.push_back(BB1);
1500+
CountableExitingBlocks.push_back(BB);
15011501
}
1502+
// We can safely ignore the predicates here because when vectorizing the loop
1503+
// the PredicatatedScalarEvolution class will keep track of all predicates
1504+
// for each exiting block anyway. This happens when calling
1505+
// PSE.getSymbolicMaxBackedgeTakenCount() below.
15021506
Predicates.clear();
15031507

15041508
// We only support one uncountable early exit.
@@ -1513,13 +1517,25 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15131517
// The only supported early exit loops so far are ones where the early
15141518
// exiting block is a unique predecessor of the latch block.
15151519
BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor();
1516-
if (LatchPredBB != getSpeculativeEarlyExitingBlock()) {
1520+
if (LatchPredBB != getUncountableEarlyExitingBlock()) {
15171521
reportVectorizationFailure("Early exit is not the latch predecessor",
15181522
"Cannot vectorize early exit loop",
15191523
"EarlyExitNotLatchPredecessor", ORE, TheLoop);
15201524
return false;
15211525
}
15221526

1527+
// The latch block must have a countable exit.
1528+
if (isa<SCEVCouldNotCompute>(
1529+
PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
1530+
reportVectorizationFailure(
1531+
"Cannot determine exact exit count for latch block",
1532+
"Cannot vectorize early exit loop",
1533+
"UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
1534+
return false;
1535+
}
1536+
assert(llvm::is_contained(CountableExitingBlocks, LatchBB) &&
1537+
"Latch block not found in list of countable exits!");
1538+
15231539
// Check to see if there are instructions that could potentially generate
15241540
// exceptions or have side-effects.
15251541
auto IsSafeOperation = [](Instruction *I) -> bool {
@@ -1555,18 +1571,8 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15551571
}
15561572
}
15571573

1558-
// The latch block must have a countable exit.
1559-
if (isa<SCEVCouldNotCompute>(
1560-
PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
1561-
reportVectorizationFailure(
1562-
"Cannot determine exact exit count for latch block",
1563-
"Cannot vectorize early exit loop",
1564-
"UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
1565-
return false;
1566-
}
1567-
15681574
// The vectoriser cannot handle loads that occur after the early exit block.
1569-
assert(LatchBB->getUniquePredecessor() == getSpeculativeEarlyExitingBlock() &&
1575+
assert(LatchBB->getUniquePredecessor() == getUncountableEarlyExitingBlock() &&
15701576
"Expected latch predecessor to be the early exiting block");
15711577

15721578
// TODO: Handle loops that may fault.
@@ -1580,16 +1586,15 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15801586
return false;
15811587
}
15821588

1583-
LLVM_DEBUG(
1584-
dbgs()
1585-
<< "LV: Found an early exit. Retrying with speculative exit count.\n");
1586-
[[maybe_unused]] const SCEV *SpecExitCount =
1589+
[[maybe_unused]] const SCEV *SymbolicMaxBTC =
15871590
PSE.getSymbolicMaxBackedgeTakenCount();
1588-
assert(!isa<SCEVCouldNotCompute>(SpecExitCount) &&
1591+
// Since we have an exact exit count for the latch and the early exit
1592+
// dominates the latch, then this should guarantee a computed SCEV value.
1593+
assert(!isa<SCEVCouldNotCompute>(SymbolicMaxBTC) &&
15891594
"Failed to get symbolic expression for backedge taken count");
1590-
1591-
LLVM_DEBUG(dbgs() << "LV: Found speculative backedge taken count: "
1592-
<< *SpecExitCount << '\n');
1595+
LLVM_DEBUG(dbgs() << "LV: Found an early exit loop with symbolic max "
1596+
"backedge taken count: "
1597+
<< *SymbolicMaxBTC << '\n');
15931598
return true;
15941599
}
15951600

@@ -1653,15 +1658,15 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
16531658
return false;
16541659
}
16551660

1656-
HasSpeculativeEarlyExit = false;
1661+
HasUncountableEarlyExit = false;
16571662
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
16581663
if (!isVectorizableEarlyExitLoop()) {
16591664
if (DoExtraAnalysis)
16601665
Result = false;
16611666
else
16621667
return false;
16631668
} else
1664-
HasSpeculativeEarlyExit = true;
1669+
HasUncountableEarlyExit = true;
16651670
}
16661671

16671672
// Go over each instruction and look at memory deps.

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9792,7 +9792,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
97929792
return false;
97939793
}
97949794

9795-
if (LVL.hasSpeculativeEarlyExit()) {
9795+
if (LVL.hasUncountableEarlyExit()) {
97969796
reportVectorizationFailure(
97979797
"Auto-vectorization of early exit loops is not yet supported.",
97989798
"Auto-vectorization of early exit loops is not yet supported.",

llvm/test/Transforms/LoopVectorize/simple_early_exit.ll

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ declare void @init_mem(ptr, i64);
77

88
define i64 @same_exit_block_pre_inc_use1() {
99
; DEBUG-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1'
10-
; DEBUG: LV: Found an early exit. Retrying with speculative exit count.
11-
; DEBUG-NEXT: LV: Found speculative backedge taken count: 63
10+
; DEBUG: LV: Found an early exit loop with symbolic max backedge taken count: 63
1211
; DEBUG-NEXT: LV: We can vectorize this loop!
1312
; DEBUG-NEXT: LV: Not vectorizing: Auto-vectorization of early exit loops is not yet supported.
1413
; CHECK-LABEL: define i64 @same_exit_block_pre_inc_use1() {
@@ -1089,8 +1088,7 @@ loop.end:
10891088

10901089
define i64 @loop_contains_safe_call() {
10911090
; DEBUG-LABEL: LV: Checking a loop in 'loop_contains_safe_call'
1092-
; DEBUG: LV: Found an early exit. Retrying with speculative exit count.
1093-
; DEBUG-NEXT: LV: Found speculative backedge taken count: 63
1091+
; DEBUG: LV: Found an early exit loop with symbolic max backedge taken count: 63
10941092
; DEBUG-NEXT: LV: We can vectorize this loop!
10951093
; CHECK-LABEL: define i64 @loop_contains_safe_call() {
10961094
; CHECK-NEXT: entry:
@@ -1193,8 +1191,7 @@ loop.end:
11931191

11941192
define i64 @loop_contains_safe_div() {
11951193
; DEBUG-LABEL: LV: Checking a loop in 'loop_contains_safe_div'
1196-
; DEBUG: LV: Found an early exit. Retrying with speculative exit count.
1197-
; DEBUG-NEXT: LV: Found speculative backedge taken count: 63
1194+
; DEBUG: LV: Found an early exit loop with symbolic max backedge taken count: 63
11981195
; DEBUG-NEXT: LV: We can vectorize this loop!
11991196
; CHECK-LABEL: define i64 @loop_contains_safe_div() {
12001197
; CHECK-NEXT: entry:
@@ -1347,8 +1344,7 @@ loop.end:
13471344

13481345
define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align(8) %p2) {
13491346
; DEBUG-LABEL: LV: Checking a loop in 'loop_contains_load_after_early_exit'
1350-
; DEBUG: LV: Found an early exit. Retrying with speculative exit count.
1351-
; DEBUG-NEXT: LV: Found speculative backedge taken count: 63
1347+
; DEBUG: LV: Found an early exit loop with symbolic max backedge taken count: 63
13521348
; DEBUG-NEXT: LV: We can vectorize this loop!
13531349
; DEBUG-NEXT: LV: Not vectorizing: Auto-vectorization of early exit loops is not yet supported.
13541350
; CHECK-LABEL: define i64 @loop_contains_load_after_early_exit(
@@ -1695,8 +1691,7 @@ declare void @abort()
16951691
; early is loop invariant.
16961692
define i32 @diff_blocks_invariant_early_exit_cond(ptr %s) {
16971693
; DEBUG-LABEL: LV: Checking a loop in 'diff_blocks_invariant_early_exit_cond'
1698-
; DEBUG: LV: Found an early exit. Retrying with speculative exit count.
1699-
; DEBUG-NEXT: LV: Found speculative backedge taken count: 275
1694+
; DEBUG: LV: Found an early exit loop with symbolic max backedge taken count: 275
17001695
; DEBUG: LV: Not vectorizing: Auto-vectorization of early exit loops is not yet supported.
17011696
; CHECK-LABEL: define i32 @diff_blocks_invariant_early_exit_cond(
17021697
; CHECK-SAME: ptr [[S:%.*]]) {

0 commit comments

Comments
 (0)