summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChad Rosier <mcrosier@codeaurora.org>2017-08-01 19:22:36 +0000
committerChad Rosier <mcrosier@codeaurora.org>2017-08-01 19:22:36 +0000
commitf73a10d2df5df39f63685aaf48e134e18cbfea6e (patch)
treebf3c4c62f3ef5e7720ffa2648ed96defd4feaad6 /llvm/lib
parentbbd6108369fa773ae7103c2c681dfdbd1a4c2c20 (diff)
downloadbcm5719-llvm-f73a10d2df5df39f63685aaf48e134e18cbfea6e.tar.gz
bcm5719-llvm-f73a10d2df5df39f63685aaf48e134e18cbfea6e.zip
[Value Tracking] Refactor and/or logic into helper. NFC.
llvm-svn: 309726
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp92
1 files changed, 52 insertions, 40 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f5557b5881d..fd73f25660f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4493,62 +4493,74 @@ static Optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
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. We expect the
+/// RHS to be an icmp and the LHS to be an 'and' or an 'or' instruction.
+static Optional<bool> isImpliedCondAndOr(const BinaryOperator *LHS,
+ const ICmpInst *RHS,
+ const DataLayout &DL, bool LHSIsFalse,
+ unsigned Depth) {
+ // The LHS must be an 'or' or an 'and' instruction.
+ assert((LHS->getOpcode() == Instruction::And ||
+ LHS->getOpcode() == Instruction::Or) &&
+ "Expected LHS to be 'and' or 'or'.");
+
+ // 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))))) {
+ // FIXME: Make this non-recursion.
+ if (Optional<bool> Implication =
+ isImpliedCondition(ALHS, RHS, DL, LHSIsFalse, Depth + 1))
+ return Implication;
+ if (Optional<bool> Implication =
+ isImpliedCondition(ARHS, RHS, DL, LHSIsFalse, Depth + 1))
+ return Implication;
+ return None;
+ }
+ return None;
+}
+
Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
const DataLayout &DL, bool LHSIsFalse,
unsigned Depth) {
- // A mismatch occurs when we compare a scalar cmp to a vector cmp, for example.
+ // A mismatch occurs when we compare a scalar cmp to a vector cmp, for
+ // example.
if (LHS->getType() != RHS->getType())
return None;
Type *OpTy = LHS->getType();
- assert(OpTy->isIntOrIntVectorTy(1));
+ assert(OpTy->isIntOrIntVectorTy(1) && "Expected integer type only!");
// LHS ==> RHS by definition
if (LHS == RHS)
return !LHSIsFalse;
+ // FIXME: Extending the code below to handle vectors.
if (OpTy->isVectorTy())
- // TODO: extending the code below to handle vectors
return None;
- assert(OpTy->isIntegerTy(1) && "implied by above");
- // We expect the RHS to be an icmp.
- if (!isa<ICmpInst>(RHS))
- return None;
+ assert(OpTy->isIntegerTy(1) && "implied by above");
// 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;
-
- 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 =
- isImpliedCondition(ALHS, RHS, DL, LHSIsFalse, Depth + 1))
- return Implication;
- if (Optional<bool> Implication =
- isImpliedCondition(ARHS, RHS, DL, LHSIsFalse, Depth + 1))
- return Implication;
- return None;
- }
- return None;
- }
+ const ICmpInst *LHSCmp = dyn_cast<ICmpInst>(LHS);
+ const ICmpInst *RHSCmp = dyn_cast<ICmpInst>(RHS);
+ if (LHSCmp && RHSCmp)
+ return isImpliedCondICmps(LHSCmp, RHSCmp, DL, LHSIsFalse, Depth);
+
+ // The LHS should be an 'or' or an 'and' instruction. We expect the RHS to be
+ // an icmp. FIXME: Add support for and/or on the RHS.
+ const BinaryOperator *LHSBO = dyn_cast<BinaryOperator>(LHS);
+ if (LHSBO && RHSCmp) {
+ if ((LHSBO->getOpcode() == Instruction::And ||
+ LHSBO->getOpcode() == Instruction::Or))
+ return isImpliedCondAndOr(LHSBO, RHSCmp, DL, LHSIsFalse, Depth);
}
+ return None;
}
OpenPOWER on IntegriCloud