[PATCH] D85000: [ValueTracking] Improve llvm.abs handling in computeKnownBits.

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 21:32:19 PDT 2020


craig.topper created this revision.
craig.topper added reviewers: RKSimon, spatel, lebedev.ri.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
craig.topper requested review of this revision.

Add the optimizations we have in the SelectionDAG version.
Known non-negative copies all known bits. Any known one other than
the sign bit makes result non-negative.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85000

Files:
  llvm/lib/Analysis/ValueTracking.cpp
  llvm/test/Transforms/InstCombine/abs-intrinsic.ll


Index: llvm/test/Transforms/InstCombine/abs-intrinsic.ll
===================================================================
--- llvm/test/Transforms/InstCombine/abs-intrinsic.ll
+++ llvm/test/Transforms/InstCombine/abs-intrinsic.ll
@@ -51,3 +51,24 @@
   %and2 = and i32 %abs, -4
   ret i32 %and2
 }
+
+; FIXME: We can just remove this abs all together.
+define i1 @abs_known_positive_input(i31 %x) {
+; CHECK-LABEL: @abs_known_positive_input(
+; CHECK-NEXT:    ret i1 true
+;
+  %zext = zext i31 %x to i32
+  %abs = call i32 @llvm.abs.i32(i32 %zext, i1 false)
+  %c2 = icmp sge i32 %abs, 0
+  ret i1 %c2
+}
+
+define i1 @abs_known_not_int_min(i32 %x) {
+; CHECK-LABEL: @abs_known_not_int_min(
+; CHECK-NEXT:    ret i1 true
+;
+  %or = or i32 %x, 1
+  %abs = call i32 @llvm.abs.i32(i32 %or, i1 false)
+  %c2 = icmp sge i32 %abs, 0
+  ret i1 %c2
+}
Index: llvm/lib/Analysis/ValueTracking.cpp
===================================================================
--- llvm/lib/Analysis/ValueTracking.cpp
+++ llvm/lib/Analysis/ValueTracking.cpp
@@ -1644,13 +1644,24 @@
       default: break;
       case Intrinsic::abs:
         computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
-        // Otherwise, if this call is undefined for INT_MIN, the result is
-        // positive.
-        if (match(II->getArgOperand(1), m_One()))
-          Known.Zero.setSignBit();
+
+        // If the source's MSB is zero then we know the rest of the bits.
+        if (Known2.isNonNegative()) {
+          Known.Zero |= Known2.Zero;
+          Known.One |= Known2.One;
+          break;
+        }
+
         // Absolute value preserves trailing zero count.
         Known.Zero.setLowBits(Known2.Zero.countTrailingOnes());
-        // FIXME: Handle known negative/non-negative input?
+
+        // If this call is undefined for INT_MIN, the result is positive. We
+        // also know it can't be INT_MIN if there is a set bit that isn't the
+        // sign bit.
+        Known2.One.clearSignBit();
+        if (match(II->getArgOperand(1), m_One()) || Known2.One.getBoolValue())
+          Known.Zero.setSignBit();
+        // FIXME: Handle known negative input?
         // FIXME: Calculate the negated Known bits and combine them?
         break;
       case Intrinsic::bitreverse:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85000.282123.patch
Type: text/x-patch
Size: 2273 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200731/7d468730/attachment.bin>


More information about the llvm-commits mailing list