diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 56 |
1 files changed, 21 insertions, 35 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index eeb6d49b6a4..6f043666cef 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -250,29 +250,37 @@ unsigned llvm::ComputeNumSignBits(const Value *V, const DataLayout &DL, return ::ComputeNumSignBits(V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT)); } -/// Compute known bits for add/sub using LHS/RHS known bits. -void llvm::computeKnownBitsForAddSub(bool Add, bool NSW, - APInt &KnownZero, APInt &KnownOne, - APInt &LHSKnownZero, APInt &LHSKnownOne, - APInt &RHSKnownZero, APInt &RHSKnownOne) { +static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1, + bool NSW, + APInt &KnownZero, APInt &KnownOne, + APInt &KnownZero2, APInt &KnownOne2, + unsigned Depth, const Query &Q) { + unsigned BitWidth = KnownZero.getBitWidth(); + + // If an initial sequence of bits in the result is not needed, the + // corresponding bits in the operands are not needed. + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); + computeKnownBits(Op0, LHSKnownZero, LHSKnownOne, Depth + 1, Q); + computeKnownBits(Op1, KnownZero2, KnownOne2, Depth + 1, Q); + // Carry in a 1 for a subtract, rather than a 0. uint64_t CarryIn = 0; if (!Add) { // Sum = LHS + ~RHS + 1 - std::swap(RHSKnownZero, RHSKnownOne); + std::swap(KnownZero2, KnownOne2); CarryIn = 1; } - APInt PossibleSumZero = ~LHSKnownZero + ~RHSKnownZero + CarryIn; - APInt PossibleSumOne = LHSKnownOne + RHSKnownOne + CarryIn; + APInt PossibleSumZero = ~LHSKnownZero + ~KnownZero2 + CarryIn; + APInt PossibleSumOne = LHSKnownOne + KnownOne2 + CarryIn; // Compute known bits of the carry. - APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ RHSKnownZero); - APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ RHSKnownOne; + APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ KnownZero2); + APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ KnownOne2; // Compute set of known bits (where all three relevant bits are known). APInt LHSKnown = LHSKnownZero | LHSKnownOne; - APInt RHSKnown = RHSKnownZero | RHSKnownOne; + APInt RHSKnown = KnownZero2 | KnownOne2; APInt CarryKnown = CarryKnownZero | CarryKnownOne; APInt Known = LHSKnown & RHSKnown & CarryKnown; @@ -288,36 +296,14 @@ void llvm::computeKnownBitsForAddSub(bool Add, bool NSW, if (NSW) { // Adding two non-negative numbers, or subtracting a negative number from // a non-negative one, can't wrap into negative. - if (LHSKnownZero.isNegative() && RHSKnownZero.isNegative()) + if (LHSKnownZero.isNegative() && KnownZero2.isNegative()) KnownZero.setSignBit(); // Adding two negative numbers, or subtracting a non-negative number from // a negative one, can't wrap into non-negative. - else if (LHSKnownOne.isNegative() && RHSKnownOne.isNegative()) + else if (LHSKnownOne.isNegative() && KnownOne2.isNegative()) KnownOne.setSignBit(); } } - - // Put the RHS/LHS back how we found them. - if (!Add) { - std::swap(RHSKnownZero, RHSKnownOne); - } -} - -static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1, - bool NSW, - APInt &KnownZero, APInt &KnownOne, - APInt &KnownZero2, APInt &KnownOne2, - unsigned Depth, const Query &Q) { - unsigned BitWidth = KnownZero.getBitWidth(); - - // If an initial sequence of bits in the result is not needed, the - // corresponding bits in the operands are not needed. - APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); - computeKnownBits(Op0, LHSKnownZero, LHSKnownOne, Depth + 1, Q); - computeKnownBits(Op1, KnownZero2, KnownOne2, Depth + 1, Q); - - computeKnownBitsForAddSub(Add, NSW, KnownZero, KnownOne, LHSKnownZero, - LHSKnownOne, KnownZero2, KnownOne2); } static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW, |