From c1d5445ac57af624fea9636741584a8f629b5611 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Fri, 28 Jul 2017 18:47:43 +0000 Subject: [PATCH] [Value Tracking] Refactor icmp comparison logic into helper. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309417 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ValueTracking.cpp | 103 ++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 9fbc09cb71e..a274f413c69 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/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 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 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(ARHS) && isa(BRHS)) { + if (Optional Implication = isImpliedCondMatchingImmOperands( + APred, ALHS, cast(ARHS), BPred, BLHS, + cast(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 llvm::isImpliedCondition(const Value *LHS, const Value *RHS, const DataLayout &DL, bool LHSIsFalse, unsigned Depth) { @@ -4403,22 +4448,32 @@ Optional 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(RHS)) + return None; + + // Both LHS and RHS are icmps. + if (isa(LHS)) + return isImpliedCondICmps(cast(LHS), cast(RHS), DL, + LHSIsFalse, Depth); + + // The LHS can be an 'or' or an 'and' instruction. + const Instruction *LHSInst = dyn_cast(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 Implication = @@ -4431,39 +4486,5 @@ Optional llvm::isImpliedCondition(const Value *LHS, const Value *RHS, } return None; } - // All of the below logic assumes both LHS and RHS are icmps. - assert(isa(LHS) && isa(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 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(ARHS) && isa(BRHS)) { - if (Optional Implication = isImpliedCondMatchingImmOperands( - APred, ALHS, cast(ARHS), BPred, BLHS, - cast(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; } -- 2.40.0