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

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat May 13 10:55:00 PDT 2023


goldstein.w.n updated this revision to Diff 521929.
goldstein.w.n added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

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,16 +399,41 @@
 
   // Absolute value preserves trailing zero count.
   KnownBits KnownAbs(getBitWidth());
-  KnownAbs.Zero.setLowBits(countMinTrailingZeros());
+
+  unsigned MaxTZ = countMaxTrailingZeros();
+  unsigned MinTZ = countMinTrailingZeros();
+
+  KnownAbs.Zero.setLowBits(MinTZ);
+  // If we know the lowest set 1, then preserve it.
+  if (MaxTZ == MinTZ && MaxTZ < getBitWidth())
+    KnownAbs.One.setBit(MaxTZ);
 
   // 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
   // be INT_MIN).
-  if (IntMinIsPoison || (!One.isZero() && !One.isMinSignedValue()))
+  if (IntMinIsPoison || (!One.isZero() && !One.isMinSignedValue())) {
+    KnownAbs.One.clearSignBit();
     KnownAbs.Zero.setSignBit();
+  }
+
+  // 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);
+
+    // Preserve signbit from `KnownAbs` as it has additional logic for figuring
+    // it out that we don't want to duplicate here.
+    KnownNeg.One.clearSignBit();
+    KnownNeg.Zero.clearSignBit();
+
+    KnownAbs.One |= KnownNeg.One;
+    KnownAbs.Zero |= KnownNeg.Zero;
+  }
 
-  // FIXME: Handle known negative input?
-  // FIXME: Calculate the negated Known bits and combine them?
+  assert(!KnownAbs.hasConflict() && "Bad Output");
   return KnownAbs;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150100.521929.patch
Type: text/x-patch
Size: 3330 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230513/94dc41b1/attachment.bin>


More information about the llvm-commits mailing list