diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 134 |
1 files changed, 61 insertions, 73 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index baf9f488..cda9c12 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -633,101 +633,89 @@ static bool isKnownNonZeroFromAssume(const Value *V, const SimplifyQuery &Q) { static void computeKnownBitsFromCmp(const Value *V, const ICmpInst *Cmp, KnownBits &Known, unsigned Depth, const SimplifyQuery &Q) { + if (Cmp->getOperand(1)->getType()->isPointerTy()) { + // Handle comparison of pointer to null explicitly, as it will not be + // covered by the m_APInt() logic below. + if (match(Cmp->getOperand(1), m_Zero())) { + switch (Cmp->getPredicate()) { + case ICmpInst::ICMP_EQ: + Known.setAllZero(); + break; + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_SGT: + Known.makeNonNegative(); + break; + case ICmpInst::ICMP_SLT: + Known.makeNegative(); + break; + default: + break; + } + } + return; + } + unsigned BitWidth = Known.getBitWidth(); - // We are attempting to compute known bits for the operands of an assume. - // Do not try to use other assumptions for those recursive calls because - // that can lead to mutual recursion and a compile-time explosion. - // An example of the mutual recursion: computeKnownBits can call - // isKnownNonZero which calls computeKnownBitsFromAssume (this function) - // and so on. - SimplifyQuery QueryNoAC = Q; - QueryNoAC.AC = nullptr; - - // Note that ptrtoint may change the bitwidth. - Value *A, *B; auto m_V = m_CombineOr(m_Specific(V), m_PtrToIntSameSize(Q.DL, m_Specific(V))); CmpInst::Predicate Pred; - uint64_t C; + const APInt *Mask, *C; + uint64_t ShAmt; switch (Cmp->getPredicate()) { case ICmpInst::ICMP_EQ: - // assume(v = a) - if (match(Cmp, m_c_ICmp(Pred, m_V, m_Value(A)))) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - Known = Known.unionWith(RHSKnown); - // assume(v & b = a) - } else if (match(Cmp, - m_c_ICmp(Pred, m_c_And(m_V, m_Value(B)), m_Value(A)))) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - KnownBits MaskKnown = computeKnownBits(B, Depth + 1, QueryNoAC); - - // For those bits in the mask that are known to be one, we can propagate - // known bits from the RHS to V. - Known.Zero |= RHSKnown.Zero & MaskKnown.One; - Known.One |= RHSKnown.One & MaskKnown.One; - // assume(v | b = a) + // assume(V = C) + if (match(Cmp, m_ICmp(Pred, m_V, m_APInt(C)))) { + Known = Known.unionWith(KnownBits::makeConstant(*C)); + // assume(V & Mask = C) } else if (match(Cmp, - m_c_ICmp(Pred, m_c_Or(m_V, m_Value(B)), m_Value(A)))) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - KnownBits BKnown = computeKnownBits(B, Depth + 1, QueryNoAC); - - // For those bits in B that are known to be zero, we can propagate known - // bits from the RHS to V. - Known.Zero |= RHSKnown.Zero & BKnown.Zero; - Known.One |= RHSKnown.One & BKnown.Zero; - // assume(v ^ b = a) + m_ICmp(Pred, m_And(m_V, m_APInt(Mask)), m_APInt(C)))) { + // For one bits in Mask, we can propagate bits from C to V. + Known.Zero |= ~*C & *Mask; + Known.One |= *C & *Mask; + // assume(V | Mask = C) + } else if (match(Cmp, m_ICmp(Pred, m_Or(m_V, m_APInt(Mask)), m_APInt(C)))) { + // For zero bits in Mask, we can propagate bits from C to V. + Known.Zero |= ~*C & ~*Mask; + Known.One |= *C & ~*Mask; + // assume(V ^ Mask = C) } else if (match(Cmp, - m_c_ICmp(Pred, m_c_Xor(m_V, m_Value(B)), m_Value(A)))) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - KnownBits BKnown = computeKnownBits(B, Depth + 1, QueryNoAC); - - // For those bits in B that are known to be zero, we can propagate known - // bits from the RHS to V. For those bits in B that are known to be one, - // we can propagate inverted known bits from the RHS to V. - Known.Zero |= RHSKnown.Zero & BKnown.Zero; - Known.One |= RHSKnown.One & BKnown.Zero; - Known.Zero |= RHSKnown.One & BKnown.One; - Known.One |= RHSKnown.Zero & BKnown.One; - // assume(v << c = a) - } else if (match(Cmp, m_c_ICmp(Pred, m_Shl(m_V, m_ConstantInt(C)), - m_Value(A))) && - C < BitWidth) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - - // For those bits in RHS that are known, we can propagate them to known - // bits in V shifted to the right by C. - RHSKnown.Zero.lshrInPlace(C); - RHSKnown.One.lshrInPlace(C); + m_ICmp(Pred, m_Xor(m_V, m_APInt(Mask)), m_APInt(C)))) { + // Equivalent to assume(V == Mask ^ C) + Known = Known.unionWith(KnownBits::makeConstant(*C ^ *Mask)); + // assume(V << ShAmt = C) + } else if (match(Cmp, m_ICmp(Pred, m_Shl(m_V, m_ConstantInt(ShAmt)), + m_APInt(C))) && + ShAmt < BitWidth) { + // For those bits in C that are known, we can propagate them to known + // bits in V shifted to the right by ShAmt. + KnownBits RHSKnown = KnownBits::makeConstant(*C); + RHSKnown.Zero.lshrInPlace(ShAmt); + RHSKnown.One.lshrInPlace(ShAmt); Known = Known.unionWith(RHSKnown); - // assume(v >> c = a) - } else if (match(Cmp, m_c_ICmp(Pred, m_Shr(m_V, m_ConstantInt(C)), - m_Value(A))) && - C < BitWidth) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); + // assume(V >> ShAmt = C) + } else if (match(Cmp, m_ICmp(Pred, m_Shr(m_V, m_ConstantInt(ShAmt)), + m_APInt(C))) && + ShAmt < BitWidth) { + KnownBits RHSKnown = KnownBits::makeConstant(*C); // For those bits in RHS that are known, we can propagate them to known // bits in V shifted to the right by C. - Known.Zero |= RHSKnown.Zero << C; - Known.One |= RHSKnown.One << C; + Known.Zero |= RHSKnown.Zero << ShAmt; + Known.One |= RHSKnown.One << ShAmt; } break; case ICmpInst::ICMP_NE: { - // assume (v & b != 0) where b is a power of 2 + // assume (V & B != 0) where B is a power of 2 const APInt *BPow2; - if (match(Cmp, m_ICmp(Pred, m_c_And(m_V, m_Power2(BPow2)), m_Zero()))) { + if (match(Cmp, m_ICmp(Pred, m_And(m_V, m_Power2(BPow2)), m_Zero()))) Known.One |= *BPow2; - } break; } default: const APInt *Offset = nullptr; if (match(Cmp, m_ICmp(Pred, m_CombineOr(m_V, m_Add(m_V, m_APInt(Offset))), - m_Value(A)))) { - KnownBits RHSKnown = computeKnownBits(A, Depth + 1, QueryNoAC); - ConstantRange RHSRange = - ConstantRange::fromKnownBits(RHSKnown, Cmp->isSigned()); - ConstantRange LHSRange = - ConstantRange::makeAllowedICmpRegion(Pred, RHSRange); + m_APInt(C)))) { + ConstantRange LHSRange = ConstantRange::makeAllowedICmpRegion(Pred, *C); if (Offset) LHSRange = LHSRange.sub(*Offset); Known = Known.unionWith(LHSRange.toKnownBits()); |