[llvm] [KnownBits] Improve mul when one operand is a power of two or zero (PR #227687)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 06:23:13 PDT 2026
================
@@ -1154,6 +1154,23 @@ KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,
Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown);
Res.One = BottomKnown.getLoBits(ResultBitsKnown);
+ // If all bits of one operand are known zero except bit K, that operand is
+ // either zero or 1 << K, so the product is either zero or the other operand
+ // shifted left by K. Any bit that is zero in the shifted operand is zero in
+ // the result, even if the known bits are not contiguous. If bit K is known
+ // one, the product is exactly the shifted operand.
+ auto AddBitsForPow2OrZero = [&](const KnownBits &Pow2OrZero,
+ const KnownBits &Other) {
+ if (Pow2OrZero.Zero.popcount() != BitWidth - 1)
+ return;
+ unsigned K = Pow2OrZero.Zero.countr_one();
+ Res.Zero |= Other.Zero.shl(K) | APInt::getLowBitsSet(BitWidth, K);
+ if (!Pow2OrZero.One.isZero())
+ Res.One |= Other.One.shl(K);
----------------
aswinkaliesrm wrote:
Good question. For a general constant the product is a sum of shifted copies of the other operand, so the carries make an optimal result harder. Adding the shifted copies with KnownBits::add would be correct but not optimal. I'd prefer to keep this PR to the zero/power-of-two case, and I can look into the general constant case separately.
https://github.com/llvm/llvm-project/pull/227687
More information about the llvm-commits
mailing list