[llvm] [ValueTracking] Extend known bits of `mul` with self and constant (PR #81892)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 16 11:58:35 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();
----------------
goldsteinn wrote:

There are no real hard rules for what gets in. It mostly up to the judgement of whoever is reviewing/the community. Generally there is a tradeoff between code maintainability+compilation speed vs compilation quality. If its considered unlikely that the compilation quality aspect will ever actually pay off (no realworld case), the maintainability+compilation speed will often win out. Either way the primary reviewer of this (nikic) has made his opinion clear, so if you want to get this in I would:

1) Make it correct
2) Try compiling a few codebases with it and see if it ever actually applies. If it does, link to the code snippets where it applies and it will make you case much stronger.

https://github.com/llvm/llvm-project/pull/81892


More information about the llvm-commits mailing list