Index: llvm/lib/Support/KnownBits.cpp =================================================================== --- llvm/lib/Support/KnownBits.cpp +++ llvm/lib/Support/KnownBits.cpp @@ -218,8 +218,33 @@ return Known; } + // Determine maximum shift amount, taking NUW/NSW flags into account. + APInt MaxValue = RHS.getMaxValue(); + if (isPowerOf2_32(BitWidth)) + MaxValue &= APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth)); + unsigned MaxShiftAmount = MaxValue.getLimitedValue(BitWidth - 1); + if (NUW) + MaxShiftAmount = std::min(MaxShiftAmount, LHS.countMaxLeadingZeros()); + if (NSW) + MaxShiftAmount = std::min( + MaxShiftAmount, + std::max(LHS.countMaxLeadingZeros(), LHS.countMaxLeadingOnes()) - 1); + + // Fast path for common case where the shift amount is unknown. + if (MinShiftAmount == 0 && MaxShiftAmount == BitWidth - 1) { + Known.Zero.setLowBits(LHS.countMinTrailingZeros()); + if (LHS.isAllOnes()) + Known.One.setSignBit(); + if (NSW) { + if (LHS.isNonNegative()) + Known.makeNonNegative(); + if (LHS.isNegative()) + Known.makeNegative(); + } + return Known; + } + // Find the common bits from all possible shifts. - unsigned MaxShiftAmount = RHS.getMaxValue().getLimitedValue(BitWidth - 1); unsigned ShiftAmtZeroMask = RHS.Zero.zextOrTrunc(32).getZExtValue(); unsigned ShiftAmtOneMask = RHS.One.zextOrTrunc(32).getZExtValue(); Known.Zero.setAllBits();