Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -55,6 +55,11 @@ const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr, OptimizationRemarkEmitter *ORE = nullptr); + /// Compute known bits for add/sub using LHS/RHS known bits. + void computeKnownBitsForAddSub(bool Add, bool NSW, + APInt &KnownZero, APInt &KnownOne, + APInt &LHSKnownZero, APInt &LHSKnownOne, + APInt &RHSKnownZero, APInt &RHSKnownOne); /// Compute known bits from the range metadata. /// \p KnownZero the set of bits that are known to be zero /// \p KnownOne the set of bits that are known to be one Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -250,37 +250,29 @@ return ::ComputeNumSignBits(V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT)); } -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); - +/// 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) { // Carry in a 1 for a subtract, rather than a 0. - APInt CarryIn(BitWidth, 0); + APInt CarryIn(KnownZero.getBitWidth(), 0); if (!Add) { // Sum = LHS + ~RHS + 1 - std::swap(KnownZero2, KnownOne2); + std::swap(RHSKnownZero, RHSKnownOne); CarryIn.setBit(0); } - APInt PossibleSumZero = ~LHSKnownZero + ~KnownZero2 + CarryIn; - APInt PossibleSumOne = LHSKnownOne + KnownOne2 + CarryIn; + APInt PossibleSumZero = ~LHSKnownZero + ~RHSKnownZero + CarryIn; + APInt PossibleSumOne = LHSKnownOne + RHSKnownOne + CarryIn; // Compute known bits of the carry. - APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ KnownZero2); - APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ KnownOne2; + APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ RHSKnownZero); + APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ RHSKnownOne; // Compute set of known bits (where all three relevant bits are known). APInt LHSKnown = LHSKnownZero | LHSKnownOne; - APInt RHSKnown = KnownZero2 | KnownOne2; + APInt RHSKnown = RHSKnownZero | RHSKnownOne; APInt CarryKnown = CarryKnownZero | CarryKnownOne; APInt Known = LHSKnown & RHSKnown & CarryKnown; @@ -296,14 +288,36 @@ 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() && KnownZero2.isNegative()) + if (LHSKnownZero.isNegative() && RHSKnownZero.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() && KnownOne2.isNegative()) + else if (LHSKnownOne.isNegative() && RHSKnownOne.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, Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -538,7 +538,7 @@ LHSKnownZero, LHSKnownOne, Depth + 1) || ShrinkDemandedConstant(I, 1, DemandedFromOps) || SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps, - LHSKnownZero, LHSKnownOne, Depth + 1)) { + RHSKnownZero, RHSKnownOne, Depth + 1)) { // Disable the nsw and nuw flags here: We can no longer guarantee that // we won't wrap after simplification. Removing the nsw/nuw flags is // legal here because the top bit is not demanded. @@ -549,9 +549,10 @@ } } - // Otherwise just hand the add/sub off to computeKnownBits to fill in - // the known zeros and ones. - computeKnownBits(V, KnownZero, KnownOne, Depth, CxtI); + // Otherwise compute the known bits using the RHS/LHS known bits. + bool NSW = cast(I)->hasNoSignedWrap(); + computeKnownBitsForAddSub(V, NSW, KnownZero, KnownOne, LHSKnownZero, + LHSKnownOne, RHSKnownZero, RHSKnownOne); break; } case Instruction::Shl: