summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 7fe129b8456f..129823e0e98a 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -413,6 +413,18 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
isGuaranteedNotToBeUndef(Op0, Q.AC, Q.CxtI, Q.DT, Depth + 1);
Known = KnownBits::mul(Known, Known2, SelfMultiply);
+ if (SelfMultiply) {
+ unsigned SignBits = ComputeNumSignBits(Op0, DemandedElts, Q, Depth + 1);
+ unsigned TyBits = Op0->getType()->getScalarSizeInBits();
+ unsigned OutValidBits = 2 * (TyBits - SignBits + 1);
+
+ if (OutValidBits < TyBits) {
+ APInt KnownZeroMask =
+ APInt::getHighBitsSet(TyBits, TyBits - OutValidBits + 1);
+ Known.Zero |= KnownZeroMask;
+ }
+ }
+
// Only make use of no-wrap flags if we failed to compute the sign bit
// directly. This matters if the multiplication always overflows, in
// which case we prefer to follow the result of the direct computation,
@@ -727,17 +739,16 @@ static void computeKnownBitsFromCmp(const Value *V, CmpInst::Predicate Pred,
// 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);
+ RHSKnown >>= ShAmt;
Known = Known.unionWith(RHSKnown);
// assume(V >> ShAmt = C)
} else if (match(LHS, m_Shr(m_V, m_ConstantInt(ShAmt))) &&
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 << ShAmt;
- Known.One |= RHSKnown.One << ShAmt;
+ KnownBits RHSKnown = KnownBits::makeConstant(*C);
+ RHSKnown <<= ShAmt;
+ Known = Known.unionWith(RHSKnown);
}
break;
case ICmpInst::ICMP_NE: {
@@ -1829,18 +1840,16 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Intrinsic::abs: {
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
bool IntMinIsPoison = match(II->getArgOperand(1), m_One());
- Known = Known2.abs(IntMinIsPoison);
+ Known = Known.unionWith(Known2.abs(IntMinIsPoison));
break;
}
case Intrinsic::bitreverse:
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
- Known.Zero |= Known2.Zero.reverseBits();
- Known.One |= Known2.One.reverseBits();
+ Known = Known.unionWith(Known2.reverseBits());
break;
case Intrinsic::bswap:
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
- Known.Zero |= Known2.Zero.byteSwap();
- Known.One |= Known2.One.byteSwap();
+ Known = Known.unionWith(Known2.byteSwap());
break;
case Intrinsic::ctlz: {
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
@@ -1890,10 +1899,9 @@ static void computeKnownBitsFromOperator(const Operator *I,
computeKnownBits(I->getOperand(0), DemandedElts, Known2, Q, Depth + 1);
computeKnownBits(I->getOperand(1), DemandedElts, Known3, Q, Depth + 1);
- Known.Zero =
- Known2.Zero.shl(ShiftAmt) | Known3.Zero.lshr(BitWidth - ShiftAmt);
- Known.One =
- Known2.One.shl(ShiftAmt) | Known3.One.lshr(BitWidth - ShiftAmt);
+ Known2 <<= ShiftAmt;
+ Known3 >>= BitWidth - ShiftAmt;
+ Known = Known2.unionWith(Known3);
break;
}
case Intrinsic::uadd_sat: