diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -422,10 +422,12 @@ return KnownBits(Zero.reverseBits(), One.reverseBits()); } - /// Compute known bits for X & -X. + /// Compute known bits for X & -X. The name comes from the X86 BMI instruction + /// BLSI. KnownBits blsi() const; - /// Compute known bits for X ^ (X - 1). + /// Compute known bits for X ^ (X - 1). The name comes from the X86 BMI + /// instruction BLSMSK. KnownBits blsmsk() const; bool operator==(const KnownBits &Other) const { diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -624,20 +624,23 @@ } KnownBits KnownBits::blsi() const { - KnownBits Known(getBitWidth()); - unsigned Min = countMinTrailingZeros(); + unsigned BitWidth = getBitWidth(); + KnownBits Known(Zero, APInt(BitWidth, 0)); unsigned Max = countMaxTrailingZeros(); - Known.Zero.setLowBits(Min); - Known.Zero.setBitsFrom(Max + 0); + Known.Zero.setBitsFrom(std::min(Max + 1, BitWidth)); + unsigned Min = countMinTrailingZeros(); + if (Max == Min && Max < BitWidth) + Known.One.setBit(Max); return Known; } KnownBits KnownBits::blsmsk() const { - KnownBits Known(getBitWidth()); - unsigned Min = countMinTrailingZeros(); + unsigned BitWidth = getBitWidth(); + KnownBits Known(BitWidth); unsigned Max = countMaxTrailingZeros(); - Known.One.setLowBits(Min + 1); - Known.Zero.setBitsFrom(Max + 0); + Known.Zero.setBitsFrom(std::min(Max + 1, BitWidth)); + unsigned Min = countMinTrailingZeros(); + Known.One.setLowBits(std::min(Min + 1, BitWidth)); return Known; }