summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@codeaurora.org>2017-07-28 18:47:43 +0000
committerChad Rosier <mcrosier@codeaurora.org>2017-07-28 18:47:43 +0000
commit2f49803c1f9de7e7974acefcfe710f0ba382a454 (patch)
tree661e7f9361dd6715f03850e169b2bf47925cac75 /llvm/lib/Analysis/ValueTracking.cpp
parentc06574ffc0053cd9bf54d174cc9467e8a8edd94d (diff)
downloadbcm5719-llvm-2f49803c1f9de7e7974acefcfe710f0ba382a454.tar.gz
bcm5719-llvm-2f49803c1f9de7e7974acefcfe710f0ba382a454.zip
[Value Tracking] Refactor icmp comparison logic into helper. NFC.
llvm-svn: 309417
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp103
1 files changed, 62 insertions, 41 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9fbc09cb71e..a274f413c69 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4384,6 +4384,51 @@ isImpliedCondMatchingImmOperands(CmpInst::Predicate APred, const Value *ALHS,
return None;
}
+/// Return true if LHS implies RHS is true. Return false if LHS implies RHS is
+/// false. Otherwise, return None if we can't infer anything.
+static Optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
+ const ICmpInst *RHS,
+ const DataLayout &DL, bool LHSIsFalse,
+ unsigned Depth) {
+ Value *ALHS = LHS->getOperand(0);
+ Value *ARHS = LHS->getOperand(1);
+ // The rest of the logic assumes the LHS condition is true. If that's not the
+ // case, invert the predicate to make it so.
+ ICmpInst::Predicate APred =
+ LHSIsFalse ? LHS->getInversePredicate() : LHS->getPredicate();
+
+ Value *BLHS = RHS->getOperand(0);
+ Value *BRHS = RHS->getOperand(1);
+ ICmpInst::Predicate BPred = RHS->getPredicate();
+
+ // Can we infer anything when the two compares have matching operands?
+ bool IsSwappedOps;
+ if (isMatchingOps(ALHS, ARHS, BLHS, BRHS, IsSwappedOps)) {
+ if (Optional<bool> Implication = isImpliedCondMatchingOperands(
+ APred, ALHS, ARHS, BPred, BLHS, BRHS, IsSwappedOps))
+ return Implication;
+ // No amount of additional analysis will infer the second condition, so
+ // early exit.
+ return None;
+ }
+
+ // Can we infer anything when the LHS operands match and the RHS operands are
+ // constants (not necessarily matching)?
+ if (ALHS == BLHS && isa<ConstantInt>(ARHS) && isa<ConstantInt>(BRHS)) {
+ if (Optional<bool> Implication = isImpliedCondMatchingImmOperands(
+ APred, ALHS, cast<ConstantInt>(ARHS), BPred, BLHS,
+ cast<ConstantInt>(BRHS)))
+ return Implication;
+ // No amount of additional analysis will infer the second condition, so
+ // early exit.
+ return None;
+ }
+
+ if (APred == BPred)
+ return isImpliedCondOperands(APred, ALHS, ARHS, BLHS, BRHS, DL, Depth);
+ return None;
+}
+
Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
const DataLayout &DL, bool LHSIsFalse,
unsigned Depth) {
@@ -4403,22 +4448,32 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
return None;
assert(OpTy->isIntegerTy(1) && "implied by above");
- 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))))
+ if (!isa<ICmpInst>(RHS))
+ return None;
+
+ // Both LHS and RHS are icmps.
+ if (isa<ICmpInst>(LHS))
+ return isImpliedCondICmps(cast<ICmpInst>(LHS), cast<ICmpInst>(RHS), DL,
+ LHSIsFalse, Depth);
+
+ // The LHS can be an 'or' or an 'and' instruction.
+ const Instruction *LHSInst = dyn_cast<Instruction>(LHS);
+ if (!LHSInst)
return None;
- 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)))) {
+ switch (LHSInst->getOpcode()) {
+ default:
+ return None;
+ case Instruction::Or:
+ case Instruction::And: {
// 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.
+ Value *ALHS, *ARHS;
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 =
@@ -4431,39 +4486,5 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
}
return None;
}
- // All of the below logic assumes both LHS and RHS are icmps.
- assert(isa<ICmpInst>(LHS) && isa<ICmpInst>(RHS) && "Expected icmps.");
-
- // 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?
- bool IsSwappedOps;
- if (isMatchingOps(ALHS, ARHS, BLHS, BRHS, IsSwappedOps)) {
- if (Optional<bool> Implication = isImpliedCondMatchingOperands(
- APred, ALHS, ARHS, BPred, BLHS, BRHS, IsSwappedOps))
- return Implication;
- // No amount of additional analysis will infer the second condition, so
- // early exit.
- return None;
- }
-
- // Can we infer anything when the LHS operands match and the RHS operands are
- // constants (not necessarily matching)?
- if (ALHS == BLHS && isa<ConstantInt>(ARHS) && isa<ConstantInt>(BRHS)) {
- if (Optional<bool> Implication = isImpliedCondMatchingImmOperands(
- APred, ALHS, cast<ConstantInt>(ARHS), BPred, BLHS,
- cast<ConstantInt>(BRHS)))
- return Implication;
- // No amount of additional analysis will infer the second condition, so
- // early exit.
- return None;
}
-
- if (APred == BPred)
- return isImpliedCondOperands(APred, ALHS, ARHS, BLHS, BRHS, DL, Depth);
-
- return None;
}
OpenPOWER on IntegriCloud