[llvm] r309726 - [Value Tracking] Refactor and/or logic into helper. NFC.
Chad Rosier via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 12:22:36 PDT 2017
Author: mcrosier
Date: Tue Aug 1 12:22:36 2017
New Revision: 309726
URL: http://llvm.org/viewvc/llvm-project?rev=309726&view=rev
Log:
[Value Tracking] Refactor and/or logic into helper. NFC.
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=309726&r1=309725&r2=309726&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Aug 1 12:22:36 2017
@@ -4493,62 +4493,74 @@ static Optional<bool> isImpliedCondICmps
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;
}
More information about the llvm-commits
mailing list