[llvm] [ValueTracking] Improve constant range computation for `shl` and `and`. (PR #68446)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 20:22:56 PDT 2023


================
@@ -8581,7 +8581,20 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
           Lower = *C;
           Upper = C->shl(ShiftAmount) + 1;
         }
+      } else {
+        // If lowbit is set, value can never be zero.
+        if ((*C)[0])
+          Lower = APInt::getOneBitSet(Width, 0);
+        // If we are shifting a constant the largest it can be is if the longest
+        // sequence of consecutive ones is shifted to the highbits (breaking
+        // ties for which sequence is higher). At the moment we take a liberal
+        // upper bound on this by just popcounting the constant.
+        // TODO: There may be a bitwise trick for it longest/highest
+        // consecutative sequence of ones (naive method is O(Width) loop).
+        Upper = APInt::getHighBitsSet(Width, C->popcount()) + 1;
       }
+    } else if (match(BO.getOperand(1), m_APInt(C))) {
+      Upper = APInt::getBitsSetFrom(Width, C->getZExtValue()) + 1;
----------------
dtcxzyw wrote:

I think you need to check the range of C here. Otherwise, the assertions in `APInt::getBitsSetFrom` will fail.
https://github.com/llvm/llvm-project/blob/fa23a2396b6c8d64c3acc47223459ecb75938391/llvm/include/llvm/ADT/APInt.h#L1337-L1355


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


More information about the llvm-commits mailing list