aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopPredication.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2019-06-01 00:31:58 +0000
committerPhilip Reames <listmail@philipreames.com>2019-06-01 00:31:58 +0000
commit099eca832e7ef22c7229bc707789bc680ea228bd (patch)
tree0e17a7b8f7b0673af6a3c344f7f700dde4edade0 /llvm/lib/Transforms/Scalar/LoopPredication.cpp
parentd8e8722791e4ce6694673d450fdcaf99e5edcbf9 (diff)
downloadllvm-099eca832e7ef22c7229bc707789bc680ea228bd.zip
llvm-099eca832e7ef22c7229bc707789bc680ea228bd.tar.gz
llvm-099eca832e7ef22c7229bc707789bc680ea228bd.tar.bz2
[LoopPred] Handle a subset of NE comparison based latches
At the moment, LoopPredication completely bails out if it sees a latch of the form: %cmp = icmp ne %iv, %N br i1 %cmp, label %loop, label %exit OR %cmp = icmp ne %iv.next, %NPlus1 br i1 %cmp, label %loop, label %exit This is unfortunate since this is exactly the form that LFTR likes to produce. So, go ahead and recognize simple cases where we can. For pre-increment loops, we leverage the fact that LFTR likes canonical counters (i.e. those starting at zero) and a (presumed) range fact on RHS to discharge the check trivially. For post-increment forms, the key insight is in remembering that LFTR had to insert a (N+1) for the RHS. CVP can hopefully prove that add nsw/nuw (if there's appropriate range on N to start with). This leaves us both with the post-inc IV and the RHS involving an nsw/nuw add, and SCEV can discharge that with no problem. This does still need to be extended to handle non-one steps, or other harder patterns of variable (but range restricted) starting values. That'll come later. Differential Revision: https://reviews.llvm.org/D62748 llvm-svn: 362282
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopPredication.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopPredication.cpp54
1 files changed, 33 insertions, 21 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
index 15e5b64..1503b50 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -230,23 +230,23 @@ static cl::opt<bool> PredicateWidenableBranchGuards(
cl::init(true));
namespace {
-class LoopPredication {
- /// Represents an induction variable check:
- /// icmp Pred, <induction variable>, <loop invariant limit>
- struct LoopICmp {
- ICmpInst::Predicate Pred;
- const SCEVAddRecExpr *IV;
- const SCEV *Limit;
- LoopICmp(ICmpInst::Predicate Pred, const SCEVAddRecExpr *IV,
- const SCEV *Limit)
- : Pred(Pred), IV(IV), Limit(Limit) {}
- LoopICmp() {}
- void dump() {
- dbgs() << "LoopICmp Pred = " << Pred << ", IV = " << *IV
- << ", Limit = " << *Limit << "\n";
- }
- };
+/// Represents an induction variable check:
+/// icmp Pred, <induction variable>, <loop invariant limit>
+struct LoopICmp {
+ ICmpInst::Predicate Pred;
+ const SCEVAddRecExpr *IV;
+ const SCEV *Limit;
+ LoopICmp(ICmpInst::Predicate Pred, const SCEVAddRecExpr *IV,
+ const SCEV *Limit)
+ : Pred(Pred), IV(IV), Limit(Limit) {}
+ LoopICmp() {}
+ void dump() {
+ dbgs() << "LoopICmp Pred = " << Pred << ", IV = " << *IV
+ << ", Limit = " << *Limit << "\n";
+ }
+};
+class LoopPredication {
AliasAnalysis *AA;
ScalarEvolution *SE;
BranchProbabilityInfo *BPI;
@@ -382,7 +382,7 @@ PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM,
return getLoopPassPreservedAnalyses();
}
-Optional<LoopPredication::LoopICmp>
+Optional<LoopICmp>
LoopPredication::parseLoopICmp(ICmpInst::Predicate Pred, Value *LHS,
Value *RHS) {
const SCEV *LHSS = SE->getSCEV(LHS);
@@ -428,7 +428,7 @@ Value *LoopPredication::expandCheck(SCEVExpander &Expander,
return Builder.CreateICmp(Pred, LHSV, RHSV);
}
-Optional<LoopPredication::LoopICmp>
+Optional<LoopICmp>
LoopPredication::generateLoopLatchCheck(Type *RangeCheckType) {
auto *LatchType = LatchCheck.IV->getType();
@@ -518,7 +518,7 @@ bool LoopPredication::isLoopInvariantValue(const SCEV* S) {
}
Optional<Value *> LoopPredication::widenICmpRangeCheckIncrementingLoop(
- LoopPredication::LoopICmp LatchCheck, LoopPredication::LoopICmp RangeCheck,
+ LoopICmp LatchCheck, LoopICmp RangeCheck,
SCEVExpander &Expander, Instruction *Guard) {
auto *Ty = RangeCheck.IV->getType();
// Generate the widened condition for the forward loop:
@@ -567,7 +567,7 @@ Optional<Value *> LoopPredication::widenICmpRangeCheckIncrementingLoop(
}
Optional<Value *> LoopPredication::widenICmpRangeCheckDecrementingLoop(
- LoopPredication::LoopICmp LatchCheck, LoopPredication::LoopICmp RangeCheck,
+ LoopICmp LatchCheck, LoopICmp RangeCheck,
SCEVExpander &Expander, Instruction *Guard) {
auto *Ty = RangeCheck.IV->getType();
const SCEV *GuardStart = RangeCheck.IV->getStart();
@@ -614,6 +614,17 @@ Optional<Value *> LoopPredication::widenICmpRangeCheckDecrementingLoop(
return Builder.CreateAnd(FirstIterationCheck, LimitCheck);
}
+static void normalizePredicate(ScalarEvolution *SE, Loop *L,
+ LoopICmp& RC) {
+ // LFTR canonicalizes checks to the ICMP_NE form instead of an ULT/SLT form.
+ // Normalize back to the ULT/SLT form for ease of handling.
+ if (RC.Pred == ICmpInst::ICMP_NE &&
+ RC.IV->getStepRecurrence(*SE)->isOne() &&
+ SE->isKnownPredicate(ICmpInst::ICMP_ULE, RC.IV->getStart(), RC.Limit))
+ RC.Pred = ICmpInst::ICMP_ULT;
+}
+
+
/// If ICI can be widened to a loop invariant condition emits the loop
/// invariant condition in the loop preheader and return it, otherwise
/// returns None.
@@ -798,7 +809,7 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
return true;
}
-Optional<LoopPredication::LoopICmp> LoopPredication::parseLoopLatchICmp() {
+Optional<LoopICmp> LoopPredication::parseLoopLatchICmp() {
using namespace PatternMatch;
BasicBlock *LoopLatch = L->getLoopLatch();
@@ -852,6 +863,7 @@ Optional<LoopPredication::LoopICmp> LoopPredication::parseLoopLatchICmp() {
}
};
+ normalizePredicate(SE, L, *Result);
if (IsUnsupportedPredicate(Step, Result->Pred)) {
LLVM_DEBUG(dbgs() << "Unsupported loop latch predicate(" << Result->Pred
<< ")!\n");