[llvm] 0f8b40a - [ValueTracking] Add better support for ConstantRange(Shl)

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 12 12:12:40 PDT 2023


Author: Noah Goldstein
Date: 2023-10-12T14:12:26-05:00
New Revision: 0f8b40a82ebeec65eb560d85368b1540333897f8

URL: https://github.com/llvm/llvm-project/commit/0f8b40a82ebeec65eb560d85368b1540333897f8
DIFF: https://github.com/llvm/llvm-project/commit/0f8b40a82ebeec65eb560d85368b1540333897f8.diff

LOG: [ValueTracking] Add better support for ConstantRange(Shl)

1) If LHS is constant:
    - The low bits of the LHS is set, the lower bound is non-zero
    - The upper bound can be capped at popcount(LHS) high bits
2) If RHS is constant:
    - The upper bound can be capped at (Width - RHS) high bits

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ValueTracking/constant-ranges.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e186431934d2294..9b29d64c97f797b 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8553,7 +8553,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)) && C->ult(Width)) {
+      Upper = APInt::getBitsSetFrom(Width, C->getZExtValue()) + 1;
     }
     break;
 

diff  --git a/llvm/test/Analysis/ValueTracking/constant-ranges.ll b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
index e425c1547bc3a60..14331c251ff5239 100644
--- a/llvm/test/Analysis/ValueTracking/constant-ranges.ll
+++ b/llvm/test/Analysis/ValueTracking/constant-ranges.ll
@@ -3,9 +3,7 @@
 
 define i1 @shl_C_X_ugt(i8 %x) {
 ; CHECK-LABEL: @shl_C_X_ugt(
-; CHECK-NEXT:    [[SHL:%.*]] = shl i8 7, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[SHL]], -32
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %shl = shl i8 7, %x
   %r = icmp ugt i8 %shl, 224
@@ -14,9 +12,7 @@ define i1 @shl_C_X_ugt(i8 %x) {
 
 define i1 @shl_C_X_ugt2(i8 %x) {
 ; CHECK-LABEL: @shl_C_X_ugt2(
-; CHECK-NEXT:    [[SHL:%.*]] = shl i8 5, [[X:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[SHL]], -64
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %shl = shl i8 5, %x
   %r = icmp ugt i8 %shl, 192
@@ -69,9 +65,7 @@ define i1 @shl_C_X_ugt_todo(i8 %x) {
 
 define i1 @shl_X_C_ugt(i8 %x) {
 ; CHECK-LABEL: @shl_X_C_ugt(
-; CHECK-NEXT:    [[SHL:%.*]] = shl i8 [[X:%.*]], 6
-; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[SHL]], -64
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %shl = shl i8 %x, 6
   %r = icmp ugt i8 %shl, 192


        


More information about the llvm-commits mailing list