[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