summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp39
1 files changed, 32 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c9a6485afad..514b8f29f84 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4393,7 +4393,7 @@ isImpliedCondMatchingImmOperands(CmpInst::Predicate APred, const Value *ALHS,
}
Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
- const DataLayout &DL, bool InvertAPred,
+ const DataLayout &DL, bool LHSIsFalse,
unsigned Depth, AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT) {
@@ -4405,7 +4405,7 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
assert(OpTy->getScalarType()->isIntegerTy(1));
// LHS ==> RHS by definition
- if (!InvertAPred && LHS == RHS)
+ if (!LHSIsFalse && LHS == RHS)
return true;
if (OpTy->isVectorTy())
@@ -4413,15 +4413,40 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
return None;
assert(OpTy->isIntegerTy(1) && "implied by above");
- ICmpInst::Predicate APred, BPred;
- Value *ALHS, *ARHS;
Value *BLHS, *BRHS;
+ ICmpInst::Predicate BPred;
+ // We expect the RHS to be an icmp.
+ if (!match(RHS, m_ICmp(BPred, m_Value(BLHS), m_Value(BRHS))))
+ return None;
- if (!match(LHS, m_ICmp(APred, m_Value(ALHS), m_Value(ARHS))) ||
- !match(RHS, m_ICmp(BPred, m_Value(BLHS), m_Value(BRHS))))
+ Value *ALHS, *ARHS;
+ ICmpInst::Predicate APred;
+ // The LHS can be an 'or', 'and', or 'icmp'.
+ if (!match(LHS, m_ICmp(APred, m_Value(ALHS), m_Value(ARHS)))) {
+ // The remaining tests are all recursive, so bail out if we hit the limit.
+ if (Depth == MaxDepth)
+ return None;
+ // If the result of an 'or' is false, then we know both legs of the 'or' are
+ // false. Similarly, if the result of an 'and' is true, then we know both
+ // legs of the 'and' are true.
+ if ((LHSIsFalse && match(LHS, m_Or(m_Value(ALHS), m_Value(ARHS)))) ||
+ (!LHSIsFalse && match(LHS, m_And(m_Value(ALHS), m_Value(ARHS))))) {
+ if (Optional<bool> Implication = isImpliedCondition(
+ ALHS, RHS, DL, LHSIsFalse, Depth + 1, AC, CxtI, DT))
+ return Implication;
+ if (Optional<bool> Implication = isImpliedCondition(
+ ARHS, RHS, DL, LHSIsFalse, Depth + 1, AC, CxtI, DT))
+ return Implication;
+ return None;
+ }
return None;
+ }
+ // All of the below logic assumes both LHS and RHS are icmps.
+ assert(isa<ICmpInst>(LHS) && isa<ICmpInst>(RHS) && "Expected icmps.");
- if (InvertAPred)
+ // The rest of the logic assumes the LHS condition is true. If that's not the
+ // case, invert the predicate to make it so.
+ if (LHSIsFalse)
APred = CmpInst::getInversePredicate(APred);
// Can we infer anything when the two compares have matching operands?
OpenPOWER on IntegriCloud