Skip to content

Commit 244c92c

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 d4536bf commit 244c92c

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
@@ -1467,13 +1467,13 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
14671467

14681468
// Keep a record of all the exiting blocks.
14691469
SmallVector<const SCEVPredicate *, 4> Predicates;
1470-
for (BasicBlock *BB1 : ExitingBlocks) {
1470+
for (BasicBlock *BB : ExitingBlocks) {
14711471
const SCEV *EC =
1472-
PSE.getSE()->getPredicatedExitCount(TheLoop, BB1, &Predicates);
1472+
PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
14731473
if (isa<SCEVCouldNotCompute>(EC)) {
1474-
UncountableExitingBlocks.push_back(BB1);
1474+
UncountableExitingBlocks.push_back(BB);
14751475

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

1485-
BasicBlock *BB2;
1485+
BasicBlock *ExitBlock;
14861486
if (!TheLoop->contains(Succs[0]))
1487-
BB2 = Succs[0];
1487+
ExitBlock = Succs[0];
14881488
else {
14891489
assert(!TheLoop->contains(Succs[1]));
1490-
BB2 = Succs[1];
1490+
ExitBlock = Succs[1];
14911491
}
1492-
UncountableExitBlocks.push_back(BB2);
1492+
UncountableExitBlocks.push_back(ExitBlock);
14931493
} else
1494-
CountableExitingBlocks.push_back(BB1);
1494+
CountableExitingBlocks.push_back(BB);
14951495
}
1496+
// We can safely ignore the predicates here because when vectorizing the loop
1497+
// the PredicatatedScalarEvolution class will keep track of all predicates
1498+
// for each exiting block anyway. This happens when calling
1499+
// PSE.getSymbolicMaxBackedgeTakenCount() below.
14961500
Predicates.clear();
14971501

14981502
// We only support one uncountable early exit.
@@ -1507,13 +1511,25 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15071511
// The only supported early exit loops so far are ones where the early
15081512
// exiting block is a unique predecessor of the latch block.
15091513
BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor();
1510-
if (LatchPredBB != getSpeculativeEarlyExitingBlock()) {
1514+
if (LatchPredBB != getUncountableEarlyExitingBlock()) {
15111515
reportVectorizationFailure("Early exit is not the latch predecessor",
15121516
"Cannot vectorize early exit loop",
15131517
"EarlyExitNotLatchPredecessor", ORE, TheLoop);
15141518
return false;
15151519
}
15161520

1521+
// The latch block must have a countable exit.
1522+
if (isa<SCEVCouldNotCompute>(
1523+
PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
1524+
reportVectorizationFailure(
1525+
"Cannot determine exact exit count for latch block",
1526+
"Cannot vectorize early exit loop",
1527+
"UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
1528+
return false;
1529+
}
1530+
assert(llvm::is_contained(CountableExitingBlocks, LatchBB) &&
1531+
"Latch block not found in list of countable exits!");
1532+
15171533
// Check to see if there are instructions that could potentially generate
15181534
// exceptions or have side-effects.
15191535
auto IsSafeOperation = [](Instruction *I) -> bool {
@@ -1549,18 +1565,8 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15491565
}
15501566
}
15511567

1552-
// The latch block must have a countable exit.
1553-
if (isa<SCEVCouldNotCompute>(
1554-
PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
1555-
reportVectorizationFailure(
1556-
"Cannot determine exact exit count for latch block",
1557-
"Cannot vectorize early exit loop",
1558-
"UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
1559-
return false;
1560-
}
1561-
15621568
// The vectoriser cannot handle loads that occur after the early exit block.
1563-
assert(LatchBB->getUniquePredecessor() == getSpeculativeEarlyExitingBlock() &&
1569+
assert(LatchBB->getUniquePredecessor() == getUncountableEarlyExitingBlock() &&
15641570
"Expected latch predecessor to be the early exiting block");
15651571

15661572
// TODO: Handle loops that may fault.
@@ -1572,16 +1578,15 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
15721578
return false;
15731579
}
15741580

1575-
LLVM_DEBUG(
1576-
dbgs()
1577-
<< "LV: Found an early exit. Retrying with speculative exit count.\n");
1578-
[[maybe_unused]] const SCEV *SpecExitCount =
1581+
[[maybe_unused]] const SCEV *SymbolicMaxBTC =
15791582
PSE.getSymbolicMaxBackedgeTakenCount();
1580-
assert(!isa<SCEVCouldNotCompute>(SpecExitCount) &&
1583+
// Since we have an exact exit count for the latch and the early exit
1584+
// dominates the latch, then this should guarantee a computed SCEV value.
1585+
assert(!isa<SCEVCouldNotCompute>(SymbolicMaxBTC) &&
15811586
"Failed to get symbolic expression for backedge taken count");
1582-
1583-
LLVM_DEBUG(dbgs() << "LV: Found speculative backedge taken count: "
1584-
<< *SpecExitCount << '\n');
1587+
LLVM_DEBUG(dbgs() << "LV: Found an early exit loop with symbolic max "
1588+
"backedge taken count: "
1589+
<< *SymbolicMaxBTC << '\n');
15851590
return true;
15861591
}
15871592

@@ -1645,15 +1650,15 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
16451650
return false;
16461651
}
16471652

1648-
HasSpeculativeEarlyExit = false;
1653+
HasUncountableEarlyExit = false;
16491654
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
16501655
if (!isVectorizableEarlyExitLoop()) {
16511656
if (DoExtraAnalysis)
16521657
Result = false;
16531658
else
16541659
return false;
16551660
} else
1656-
HasSpeculativeEarlyExit = true;
1661+
HasUncountableEarlyExit = true;
16571662
}
16581663

16591664
// 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
@@ -9807,7 +9807,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
98079807
return false;
98089808
}
98099809

9810-
if (LVL.hasSpeculativeEarlyExit()) {
9810+
if (LVL.hasUncountableEarlyExit()) {
98119811
reportVectorizationFailure(
98129812
"Auto-vectorization of early exit loops is not yet supported.",
98139813
"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)