Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -263,25 +263,39 @@ CarryIn = 1; } - APInt PossibleSumZero = ~LHSKnownZero + ~RHSKnownZero + CarryIn; - APInt PossibleSumOne = LHSKnownOne + RHSKnownOne + CarryIn; + // Flip the known zeroes so we can add them. + LHSKnownZero.flipAllBits(); + RHSKnownZero.flipAllBits(); + + // Create a sum for the known zeros. + KnownZero |= CarryIn; + KnownZero += LHSKnownZero; + KnownZero += RHSKnownZero; + + // Restore the known zeroes and flip the sum. + LHSKnownZero.flipAllBits(); + RHSKnownZero.flipAllBits(); + KnownZero.flipAllBits(); + + // Create a sum for the known ones. + KnownOne |= CarryIn; + KnownOne += RHSKnownOne; + KnownOne += LHSKnownOne; // Compute known bits of the carry. - APInt CarryKnownZero = ~(PossibleSumZero ^ LHSKnownZero ^ RHSKnownZero); - APInt CarryKnownOne = PossibleSumOne ^ LHSKnownOne ^ RHSKnownOne; + APInt CarryKnownZero = KnownZero ^ LHSKnownZero ^ RHSKnownZero; + APInt CarryKnownOne = KnownOne ^ LHSKnownOne ^ RHSKnownOne; // Compute set of known bits (where all three relevant bits are known). - APInt LHSKnown = LHSKnownZero | LHSKnownOne; - APInt RHSKnown = RHSKnownZero | RHSKnownOne; - APInt CarryKnown = CarryKnownZero | CarryKnownOne; - APInt Known = LHSKnown & RHSKnown & CarryKnown; - - assert((PossibleSumZero & Known) == (PossibleSumOne & Known) && + APInt Known = std::move(CarryKnownZero) | std::move(CarryKnownOne); + Known &= LHSKnownZero | LHSKnownOne; + Known &= RHSKnownZero | RHSKnownOne; + assert((~KnownZero & Known) == (KnownOne & Known) && "known bits of sum differ"); - // Compute known bits of the result. - KnownZero = ~PossibleSumOne & Known; - KnownOne = PossibleSumOne & Known; + // Bits of sums are only known if all input bits were known. + KnownZero &= Known; + KnownOne &= Known; // Are we still trying to solve for the sign bit? if (!Known.isNegative()) {