aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp67
-rw-r--r--llvm/lib/Transforms/Vectorize/LoopVectorize.cpp11
2 files changed, 42 insertions, 36 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index b767372..e695902 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1473,13 +1473,13 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// Keep a record of all the exiting blocks.
SmallVector<const SCEVPredicate *, 4> Predicates;
- for (BasicBlock *BB1 : ExitingBlocks) {
+ for (BasicBlock *BB : ExitingBlocks) {
const SCEV *EC =
- PSE.getSE()->getPredicatedExitCount(TheLoop, BB1, &Predicates);
+ PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
if (isa<SCEVCouldNotCompute>(EC)) {
- UncountableExitingBlocks.push_back(BB1);
+ UncountableExitingBlocks.push_back(BB);
- SmallVector<BasicBlock *, 2> Succs(successors(BB1));
+ SmallVector<BasicBlock *, 2> Succs(successors(BB));
if (Succs.size() != 2) {
reportVectorizationFailure(
"Early exiting block does not have exactly two successors",
@@ -1488,17 +1488,21 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
- BasicBlock *BB2;
+ BasicBlock *ExitBlock;
if (!TheLoop->contains(Succs[0]))
- BB2 = Succs[0];
+ ExitBlock = Succs[0];
else {
assert(!TheLoop->contains(Succs[1]));
- BB2 = Succs[1];
+ ExitBlock = Succs[1];
}
- UncountableExitBlocks.push_back(BB2);
+ UncountableExitBlocks.push_back(ExitBlock);
} else
- CountableExitingBlocks.push_back(BB1);
+ CountableExitingBlocks.push_back(BB);
}
+ // We can safely ignore the predicates here because when vectorizing the loop
+ // the PredicatatedScalarEvolution class will keep track of all predicates
+ // for each exiting block anyway. This happens when calling
+ // PSE.getSymbolicMaxBackedgeTakenCount() below.
Predicates.clear();
// We only support one uncountable early exit.
@@ -1513,13 +1517,25 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// The only supported early exit loops so far are ones where the early
// exiting block is a unique predecessor of the latch block.
BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor();
- if (LatchPredBB != getSpeculativeEarlyExitingBlock()) {
+ if (LatchPredBB != getUncountableEarlyExitingBlock()) {
reportVectorizationFailure("Early exit is not the latch predecessor",
"Cannot vectorize early exit loop",
"EarlyExitNotLatchPredecessor", ORE, TheLoop);
return false;
}
+ // The latch block must have a countable exit.
+ if (isa<SCEVCouldNotCompute>(
+ PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
+ reportVectorizationFailure(
+ "Cannot determine exact exit count for latch block",
+ "Cannot vectorize early exit loop",
+ "UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
+ return false;
+ }
+ assert(llvm::is_contained(CountableExitingBlocks, LatchBB) &&
+ "Latch block not found in list of countable exits!");
+
// Check to see if there are instructions that could potentially generate
// exceptions or have side-effects.
auto IsSafeOperation = [](Instruction *I) -> bool {
@@ -1555,18 +1571,8 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
}
}
- // The latch block must have a countable exit.
- if (isa<SCEVCouldNotCompute>(
- PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
- reportVectorizationFailure(
- "Cannot determine exact exit count for latch block",
- "Cannot vectorize early exit loop",
- "UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
- return false;
- }
-
// The vectoriser cannot handle loads that occur after the early exit block.
- assert(LatchBB->getUniquePredecessor() == getSpeculativeEarlyExitingBlock() &&
+ assert(LatchBB->getUniquePredecessor() == getUncountableEarlyExitingBlock() &&
"Expected latch predecessor to be the early exiting block");
// TODO: Handle loops that may fault.
@@ -1580,16 +1586,15 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
- LLVM_DEBUG(
- dbgs()
- << "LV: Found an early exit. Retrying with speculative exit count.\n");
- [[maybe_unused]] const SCEV *SpecExitCount =
+ [[maybe_unused]] const SCEV *SymbolicMaxBTC =
PSE.getSymbolicMaxBackedgeTakenCount();
- assert(!isa<SCEVCouldNotCompute>(SpecExitCount) &&
+ // Since we have an exact exit count for the latch and the early exit
+ // dominates the latch, then this should guarantee a computed SCEV value.
+ assert(!isa<SCEVCouldNotCompute>(SymbolicMaxBTC) &&
"Failed to get symbolic expression for backedge taken count");
-
- LLVM_DEBUG(dbgs() << "LV: Found speculative backedge taken count: "
- << *SpecExitCount << '\n');
+ LLVM_DEBUG(dbgs() << "LV: Found an early exit loop with symbolic max "
+ "backedge taken count: "
+ << *SymbolicMaxBTC << '\n');
return true;
}
@@ -1653,7 +1658,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
return false;
}
- HasSpeculativeEarlyExit = false;
+ HasUncountableEarlyExit = false;
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
if (!isVectorizableEarlyExitLoop()) {
if (DoExtraAnalysis)
@@ -1661,7 +1666,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
else
return false;
} else
- HasSpeculativeEarlyExit = true;
+ HasUncountableEarlyExit = true;
}
// Go over each instruction and look at memory deps.
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 62aa032..0566d80 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -9794,11 +9794,12 @@ bool LoopVectorizePass::processLoop(Loop *L) {
return false;
}
- if (LVL.hasSpeculativeEarlyExit()) {
- reportVectorizationFailure(
- "Auto-vectorization of early exit loops is not yet supported.",
- "Auto-vectorization of early exit loops is not yet supported.",
- "EarlyExitLoopsUnsupported", ORE, L);
+ if (LVL.hasUncountableEarlyExit()) {
+ reportVectorizationFailure("Auto-vectorization of loops with uncountable "
+ "early exit is not yet supported",
+ "Auto-vectorization of loops with uncountable "
+ "early exit is not yet supported",
+ "UncountableEarlyExitLoopsUnsupported", ORE, L);
return false;
}