[PATCH] D156845: [ConstantRange] Calculate precise range for shl by -1

Allen zhong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 29 04:42:59 PDT 2023


Allen updated this revision to Diff 554264.
Allen added a comment.

try to rebase on today's new commit aebe312c <https://reviews.llvm.org/rGaebe312c03a686af397c5e572e1ac9f325624734> according comment


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156845/new/

https://reviews.llvm.org/D156845

Files:
  llvm/lib/IR/ConstantRange.cpp
  llvm/test/Transforms/SCCP/and-add-shl.ll


Index: llvm/test/Transforms/SCCP/and-add-shl.ll
===================================================================
--- llvm/test/Transforms/SCCP/and-add-shl.ll
+++ llvm/test/Transforms/SCCP/and-add-shl.ll
@@ -30,8 +30,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OP1_P2]])
 ; CHECK-NEXT:    [[SHIFT:%.*]] = shl nsw i8 -1, [[X]]
 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[SHIFT]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT]], 32
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 0
 ;
   %op1_p2 = icmp ule i8 %x, 5
   call void @llvm.assume(i1 %op1_p2)
@@ -48,8 +47,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OP1_P2]])
 ; CHECK-NEXT:    [[SHIFT:%.*]] = shl nsw i8 -1, [[X]]
 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[SHIFT]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT]], 48
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 0
 ;
   %op1_p2 = icmp ule i8 %x, 4
   call void @llvm.assume(i1 %op1_p2)
@@ -95,3 +93,22 @@
   %r = and i8 %not, 4   ; expect 8
   ret i8 %r
 }
+
+; Negative test: https://alive2.llvm.org/ce/z/ZZrjkj
+define i32 @positiveShift32(i32 noundef %a, i32 noundef %b) {
+; CHECK-LABEL: define i32 @positiveShift32
+; CHECK-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) {
+; CHECK-NEXT:    [[OP0_P1:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[OP0_P1]])
+; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[B]], 31
+; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[A]], [[SHL_MASK]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SHL]], 2
+; CHECK-NEXT:    ret i32 [[ADD]]
+;
+  %op0_p1 = icmp slt i32 %a, 0
+  call void @llvm.assume(i1 %op0_p1)
+  %shl.mask = and i32 %b, 31
+  %shl = shl i32 %a, %shl.mask ; the %a is not a single element value
+  %add = add nsw i32 %shl, 2
+  ret i32 %add
+}
Index: llvm/lib/IR/ConstantRange.cpp
===================================================================
--- llvm/lib/IR/ConstantRange.cpp
+++ llvm/lib/IR/ConstantRange.cpp
@@ -1477,9 +1477,13 @@
   }
 
   APInt OtherMax = Other.getUnsignedMax();
+  // Make sure single element for negative value just for simplicity,
+  // otherwise we should checking both Lower and Upper for negative value.
+  bool Neg = getSingleElement() && isAllNegative() &&
+             OtherMax.ule(Max.abs().countl_zero());
 
   // There's overflow!
-  if (OtherMax.ugt(Max.countl_zero()))
+  if (OtherMax.ugt(Max.countl_zero()) && !Neg)
     return getFull();
 
   // FIXME: implement the other tricky cases
@@ -1487,6 +1491,10 @@
   Min <<= Other.getUnsignedMin();
   Max <<= OtherMax;
 
+  // For negitive value c, its shifted range is [c<<Other.max) , c<<Other.min)]
+  if (Neg)
+    std::swap(Min, Max);
+
   return ConstantRange::getNonEmpty(std::move(Min), std::move(Max) + 1);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156845.554264.patch
Type: text/x-patch
Size: 2734 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230829/deb2564c/attachment.bin>


More information about the llvm-commits mailing list