[PATCH] D150100: [KnownBits] Improve implementation of `KnownBits::abs`

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun May 7 23:58:51 PDT 2023


goldstein.w.n created this revision.
goldstein.w.n added reviewers: foad, nikic, RKSimon.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
goldstein.w.n requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

`abs` preserves the lowest set bit, so if we know the lowest set bit,
set it in the output.

As well, implement the case where the operand is known negative.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150100

Files:
  llvm/lib/Support/KnownBits.cpp
  llvm/test/Analysis/ValueTracking/knownbits-abs.ll


Index: llvm/test/Analysis/ValueTracking/knownbits-abs.ll
===================================================================
--- llvm/test/Analysis/ValueTracking/knownbits-abs.ll
+++ llvm/test/Analysis/ValueTracking/knownbits-abs.ll
@@ -4,12 +4,7 @@
 
 define i1 @abs_low_bit_set(i8 %x) {
 ; CHECK-LABEL: @abs_low_bit_set(
-; CHECK-NEXT:    [[XX:%.*]] = and i8 [[X:%.*]], -16
-; CHECK-NEXT:    [[V:%.*]] = or i8 [[XX]], 4
-; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[V]], i1 true)
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ABS]], 4
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 0
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %xx = and i8 %x, 240
   %v = or i8 %xx, 4
@@ -36,12 +31,7 @@
 
 define i1 @abs_negative(i8 %x) {
 ; CHECK-LABEL: @abs_negative(
-; CHECK-NEXT:    [[XX:%.*]] = and i8 [[X:%.*]], -16
-; CHECK-NEXT:    [[V:%.*]] = or i8 [[XX]], -124
-; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[V]], i1 true)
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ABS]], 8
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 0
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %xx = and i8 %x, 240
   %v = or i8 %xx, 132
@@ -53,11 +43,7 @@
 
 define i1 @abs_negative2(i8 %x) {
 ; CHECK-LABEL: @abs_negative2(
-; CHECK-NEXT:    [[V:%.*]] = or i8 [[X:%.*]], -125
-; CHECK-NEXT:    [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[V]], i1 true)
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[ABS]], 2
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], 2
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %v = or i8 %x, 131
   %abs = call i8 @llvm.abs.i8(i8 %v, i1 true)
Index: llvm/lib/Support/KnownBits.cpp
===================================================================
--- llvm/lib/Support/KnownBits.cpp
+++ llvm/lib/Support/KnownBits.cpp
@@ -399,7 +399,14 @@
 
   // Absolute value preserves trailing zero count.
   KnownBits KnownAbs(getBitWidth());
-  KnownAbs.Zero.setLowBits(countMinTrailingZeros());
+
+  unsigned Max = countMaxTrailingZeros();
+  unsigned Min = countMinTrailingZeros();
+
+  KnownAbs.Zero.setLowBits(Min);
+  // If we know the lowest set 1, then preserve it.
+  if (Max == Min && Max < getBitWidth())
+    KnownAbs.One.setBit(Max);
 
   // We only know that the absolute values's MSB will be zero if INT_MIN is
   // poison, or there is a set bit that isn't the sign bit (otherwise it could
@@ -407,8 +414,19 @@
   if (IntMinIsPoison || (!One.isZero() && !One.isMinSignedValue()))
     KnownAbs.Zero.setSignBit();
 
-  // FIXME: Handle known negative input?
-  // FIXME: Calculate the negated Known bits and combine them?
+  // If the input is negative, then abs(x) == -x.
+  if (isNegative()) {
+    KnownBits Zero(getBitWidth());
+    Zero.setAllZero();
+
+    KnownBits KnownNeg = computeForAddSub(
+        /*Add*/ false, /*NSW*/ false, Zero, *this);
+
+    // NB: KnownAbs is not always a subset of KnownNeg so we want to get input
+    // from both.
+    KnownAbs.One |= KnownNeg.One;
+    KnownAbs.Zero |= KnownNeg.Zero;
+  }
   return KnownAbs;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150100.520275.patch
Type: text/x-patch
Size: 3047 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230508/dbe39885/attachment.bin>


More information about the llvm-commits mailing list