[llvm] [ValueTracking] Extend known bits of `mul` with self and constant (PR #81892)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 15 13:25:50 PST 2024
================
@@ -373,11 +373,24 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW,
bool isKnownNegative = false;
bool isKnownNonNegative = false;
+ const APInt *C;
+ unsigned BitWidth = Known.getBitWidth();
+
// If the multiplication is known not to overflow, compute the sign bit.
if (NSW) {
if (Op0 == Op1) {
// The product of a number with itself is non-negative.
isKnownNonNegative = true;
+ } else if (((match(Op0, m_Mul(m_Specific(Op1), m_APInt(C))) &&
+ cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap()) ||
+ (match(Op0, m_Shl(m_Specific(Op1), m_APInt(C))) &&
+ C->ult(BitWidth))) &&
+ !C->isZero() && !Known.isZero()) {
+ // The product of a number with itself and a constant depends on the sign
+ // of the constant.
+ KnownBits KnownC = KnownBits::makeConstant(*C);
+ isKnownNonNegative = KnownC.isNonNegative();
+ isKnownNegative = KnownC.isNegative();
----------------
antoniofrighetto wrote:
Uhmm, right. So the first one is fine, the second one not really: https://alive2.llvm.org/ce/z/9kAM_g (simplified by `simplifyICmpWithZero`). We could consider only `isKnownNonNegative`, but we wouldn't catch the first case.
https://github.com/llvm/llvm-project/pull/81892
More information about the llvm-commits
mailing list