diff options
| author | Max Kazantsev <max.kazantsev@azul.com> | 2018-02-07 11:16:29 +0000 |
|---|---|---|
| committer | Max Kazantsev <max.kazantsev@azul.com> | 2018-02-07 11:16:29 +0000 |
| commit | b299ade2c5fe57a9f56849a412d1e39907c94dbb (patch) | |
| tree | 4e807de022bb552d691ffad73d7460c91cd02362 /llvm/lib | |
| parent | 986b39b61f804b4783774a9024fab0bcc124af86 (diff) | |
| download | bcm5719-llvm-b299ade2c5fe57a9f56849a412d1e39907c94dbb.tar.gz bcm5719-llvm-b299ade2c5fe57a9f56849a412d1e39907c94dbb.zip | |
Re-enable "[SCEV] Make isLoopEntryGuardedByCond a bit smarter"
The failures happened because of assert which was overconfident about
SCEV's proving capabilities and is generally not valid.
Differential Revision: https://reviews.llvm.org/D42835
llvm-svn: 324473
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 62 | ||||
| -rw-r--r-- | llvm/lib/IR/Instructions.cpp | 14 |
2 files changed, 71 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index f44bb8d447e..b6fb8484906 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -9073,6 +9073,59 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, if (isKnownPredicateViaConstantRanges(Pred, LHS, RHS)) return true; + // If we cannot prove strict comparison (e.g. a > b), maybe we can prove + // the facts (a >= b && a != b) separately. A typical situation is when the + // non-strict comparison is known from ranges and non-equality is known from + // dominating predicates. If we are proving strict comparison, we always try + // to prove non-equality and non-strict comparison separately. + auto NonStrictPredicate = ICmpInst::getNonStrictPredicate(Pred); + const bool ProvingStrictComparison = (Pred != NonStrictPredicate); + bool ProvedNonStrictComparison = false; + bool ProvedNonEquality = false; + + if (ProvingStrictComparison) { + ProvedNonStrictComparison = + isKnownPredicateViaConstantRanges(NonStrictPredicate, LHS, RHS); + ProvedNonEquality = + isKnownPredicateViaConstantRanges(ICmpInst::ICMP_NE, LHS, RHS); + if (ProvedNonStrictComparison && ProvedNonEquality) + return true; + } + + // Try to prove (Pred, LHS, RHS) using isImpliedViaGuard. + auto ProveViaGuard = [&](BasicBlock *Block) { + if (isImpliedViaGuard(Block, Pred, LHS, RHS)) + return true; + if (ProvingStrictComparison) { + if (!ProvedNonStrictComparison) + ProvedNonStrictComparison = + isImpliedViaGuard(Block, NonStrictPredicate, LHS, RHS); + if (!ProvedNonEquality) + ProvedNonEquality = + isImpliedViaGuard(Block, ICmpInst::ICMP_NE, LHS, RHS); + if (ProvedNonStrictComparison && ProvedNonEquality) + return true; + } + return false; + }; + + // Try to prove (Pred, LHS, RHS) using isImpliedCond. + auto ProveViaCond = [&](Value *Condition, bool Inverse) { + if (isImpliedCond(Pred, LHS, RHS, Condition, Inverse)) + return true; + if (ProvingStrictComparison) { + if (!ProvedNonStrictComparison) + ProvedNonStrictComparison = + isImpliedCond(NonStrictPredicate, LHS, RHS, Condition, Inverse); + if (!ProvedNonEquality) + ProvedNonEquality = + isImpliedCond(ICmpInst::ICMP_NE, LHS, RHS, Condition, Inverse); + if (ProvedNonStrictComparison && ProvedNonEquality) + return true; + } + return false; + }; + // Starting at the loop predecessor, climb up the predecessor chain, as long // as there are predecessors that can be found that have unique successors // leading to the original header. @@ -9081,7 +9134,7 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) { - if (isImpliedViaGuard(Pair.first, Pred, LHS, RHS)) + if (ProveViaGuard(Pair.first)) return true; BranchInst *LoopEntryPredicate = @@ -9090,9 +9143,8 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, LoopEntryPredicate->isUnconditional()) continue; - if (isImpliedCond(Pred, LHS, RHS, - LoopEntryPredicate->getCondition(), - LoopEntryPredicate->getSuccessor(0) != Pair.second)) + if (ProveViaCond(LoopEntryPredicate->getCondition(), + LoopEntryPredicate->getSuccessor(0) != Pair.second)) return true; } @@ -9104,7 +9156,7 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L, if (!DT.dominates(CI, L->getHeader())) continue; - if (isImpliedCond(Pred, LHS, RHS, CI->getArgOperand(0), false)) + if (ProveViaCond(CI->getArgOperand(0), false)) return true; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 490fcbce743..7fa4b06c566 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -3467,6 +3467,20 @@ CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { } } +CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) { + switch (pred) { + case ICMP_SGT: return ICMP_SGE; + case ICMP_SLT: return ICMP_SLE; + case ICMP_UGT: return ICMP_UGE; + case ICMP_ULT: return ICMP_ULE; + case FCMP_OGT: return FCMP_OGE; + case FCMP_OLT: return FCMP_OLE; + case FCMP_UGT: return FCMP_UGE; + case FCMP_ULT: return FCMP_ULE; + default: return pred; + } +} + CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) { assert(CmpInst::isUnsigned(pred) && "Call only with signed predicates!"); |

