diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index d8a72c9f7b989..8c29c242215d6 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -186,47 +186,30 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts, SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo)); } -bool llvm::haveNoCommonBitsSet(const WithCache &LHSCache, - const WithCache &RHSCache, - const SimplifyQuery &SQ) { - const Value *LHS = LHSCache.getValue(); - const Value *RHS = RHSCache.getValue(); - - assert(LHS->getType() == RHS->getType() && - "LHS and RHS should have the same type"); - assert(LHS->getType()->isIntOrIntVectorTy() && - "LHS and RHS should be integers"); +static bool haveNoCommonBitsSetSpecialCases(const Value *LHS, + const Value *RHS) { // Look for an inverted mask: (X & ~M) op (Y & M). { Value *M; if (match(LHS, m_c_And(m_Not(m_Value(M)), m_Value())) && match(RHS, m_c_And(m_Specific(M), m_Value()))) return true; - if (match(RHS, m_c_And(m_Not(m_Value(M)), m_Value())) && - match(LHS, m_c_And(m_Specific(M), m_Value()))) - return true; } // X op (Y & ~X) - if (match(RHS, m_c_And(m_Not(m_Specific(LHS)), m_Value())) || - match(LHS, m_c_And(m_Not(m_Specific(RHS)), m_Value()))) + if (match(RHS, m_c_And(m_Not(m_Specific(LHS)), m_Value()))) return true; // X op ((X & Y) ^ Y) -- this is the canonical form of the previous pattern // for constant Y. Value *Y; - if (match(RHS, - m_c_Xor(m_c_And(m_Specific(LHS), m_Value(Y)), m_Deferred(Y))) || - match(LHS, m_c_Xor(m_c_And(m_Specific(RHS), m_Value(Y)), m_Deferred(Y)))) + if (match(RHS, m_c_Xor(m_c_And(m_Specific(LHS), m_Value(Y)), m_Deferred(Y)))) return true; // Peek through extends to find a 'not' of the other side: // (ext Y) op ext(~Y) - // (ext ~Y) op ext(Y) - if ((match(LHS, m_ZExtOrSExt(m_Value(Y))) && - match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))) || - (match(RHS, m_ZExtOrSExt(m_Value(Y))) && - match(LHS, m_ZExtOrSExt(m_Not(m_Specific(Y)))))) + if (match(LHS, m_ZExtOrSExt(m_Value(Y))) && + match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))) return true; // Look for: (A & B) op ~(A | B) @@ -235,11 +218,26 @@ bool llvm::haveNoCommonBitsSet(const WithCache &LHSCache, if (match(LHS, m_And(m_Value(A), m_Value(B))) && match(RHS, m_Not(m_c_Or(m_Specific(A), m_Specific(B))))) return true; - if (match(RHS, m_And(m_Value(A), m_Value(B))) && - match(LHS, m_Not(m_c_Or(m_Specific(A), m_Specific(B))))) - return true; } + return false; +} + +bool llvm::haveNoCommonBitsSet(const WithCache &LHSCache, + const WithCache &RHSCache, + const SimplifyQuery &SQ) { + const Value *LHS = LHSCache.getValue(); + const Value *RHS = RHSCache.getValue(); + + assert(LHS->getType() == RHS->getType() && + "LHS and RHS should have the same type"); + assert(LHS->getType()->isIntOrIntVectorTy() && + "LHS and RHS should be integers"); + + if (haveNoCommonBitsSetSpecialCases(LHS, RHS) || + haveNoCommonBitsSetSpecialCases(RHS, LHS)) + return true; + return KnownBits::haveNoCommonBitsSet(LHSCache.getKnownBits(SQ), RHSCache.getKnownBits(SQ)); }