diff options
author | Chad Rosier <mcrosier@codeaurora.org> | 2017-08-01 19:22:36 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@codeaurora.org> | 2017-08-01 19:22:36 +0000 |
commit | f73a10d2df5df39f63685aaf48e134e18cbfea6e (patch) | |
tree | bf3c4c62f3ef5e7720ffa2648ed96defd4feaad6 /llvm/lib | |
parent | bbd6108369fa773ae7103c2c681dfdbd1a4c2c20 (diff) | |
download | bcm5719-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.cpp | 92 |
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; } |