-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[InstCombine] KnownBits::isNonNegative should recognize b - a after a <= b
#145105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-llvm-analysis Author: Ross Kirsling (rkirsling) ChangesFixes #142283. Full diff: https://github.com/llvm/llvm-project/pull/145105.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 73320b556f825..2025079f07572 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -278,7 +278,15 @@ static bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
bool llvm::isKnownNonNegative(const Value *V, const SimplifyQuery &SQ,
unsigned Depth) {
- return computeKnownBits(V, SQ, Depth).isNonNegative();
+ if (computeKnownBits(V, SQ, Depth).isNonNegative())
+ return true;
+
+ Value *X, *Y;
+ if (match(V, m_NSWSub(m_Value(X), m_Value(Y))))
+ if (std::optional<bool> result = isImpliedByDomCondition(ICmpInst::ICMP_SLE, Y, X, SQ.CxtI, SQ.DL))
+ return *result;
+
+ return false;
}
bool llvm::isKnownPositive(const Value *V, const SimplifyQuery &SQ,
diff --git a/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll
new file mode 100644
index 0000000000000..279a6de4125ed
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+define void @test_as_arg(i8 %a, i8 %b) {
+; CHECK-LABEL: define void @test_as_arg(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[COND_END:.*]], label %[[COND_FALSE:.*]]
+; CHECK: [[COND_FALSE]]:
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]]
+; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16
+; CHECK-NEXT: call void @subroutine(i16 [[CONV]])
+; CHECK-NEXT: br label %[[COND_END]]
+; CHECK: [[COND_END]]:
+; CHECK-NEXT: ret void
+;
+ %cmp = icmp sgt i8 %a, %b
+ br i1 %cmp, label %cond.end, label %cond.false
+
+cond.false:
+ %sub = sub nsw i8 %b, %a
+ %conv = sext i8 %sub to i16
+ call void @subroutine(i16 %conv)
+ br label %cond.end
+
+cond.end:
+ ret void
+}
+
+declare void @subroutine(i16)
+
+define i16 @test_as_retval(i8 %a, i8 %b) {
+; CHECK-LABEL: define i16 @test_as_retval(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+; CHECK: [[COND_TRUE]]:
+; CHECK-NEXT: ret i16 0
+; CHECK: [[COND_FALSE]]:
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]]
+; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16
+; CHECK-NEXT: ret i16 [[CONV]]
+;
+ %cmp = icmp sgt i8 %a, %b
+ br i1 %cmp, label %cond.true, label %cond.false
+
+cond.true:
+ ret i16 0
+
+cond.false:
+ %sub = sub nsw i8 %b, %a
+ %conv = sext i8 %sub to i16
+ ret i16 %conv
+}
|
|
@llvm/pr-subscribers-llvm-transforms Author: Ross Kirsling (rkirsling) ChangesFixes #142283. Full diff: https://github.com/llvm/llvm-project/pull/145105.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 73320b556f825..2025079f07572 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -278,7 +278,15 @@ static bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
bool llvm::isKnownNonNegative(const Value *V, const SimplifyQuery &SQ,
unsigned Depth) {
- return computeKnownBits(V, SQ, Depth).isNonNegative();
+ if (computeKnownBits(V, SQ, Depth).isNonNegative())
+ return true;
+
+ Value *X, *Y;
+ if (match(V, m_NSWSub(m_Value(X), m_Value(Y))))
+ if (std::optional<bool> result = isImpliedByDomCondition(ICmpInst::ICMP_SLE, Y, X, SQ.CxtI, SQ.DL))
+ return *result;
+
+ return false;
}
bool llvm::isKnownPositive(const Value *V, const SimplifyQuery &SQ,
diff --git a/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll
new file mode 100644
index 0000000000000..279a6de4125ed
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+define void @test_as_arg(i8 %a, i8 %b) {
+; CHECK-LABEL: define void @test_as_arg(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[COND_END:.*]], label %[[COND_FALSE:.*]]
+; CHECK: [[COND_FALSE]]:
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]]
+; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16
+; CHECK-NEXT: call void @subroutine(i16 [[CONV]])
+; CHECK-NEXT: br label %[[COND_END]]
+; CHECK: [[COND_END]]:
+; CHECK-NEXT: ret void
+;
+ %cmp = icmp sgt i8 %a, %b
+ br i1 %cmp, label %cond.end, label %cond.false
+
+cond.false:
+ %sub = sub nsw i8 %b, %a
+ %conv = sext i8 %sub to i16
+ call void @subroutine(i16 %conv)
+ br label %cond.end
+
+cond.end:
+ ret void
+}
+
+declare void @subroutine(i16)
+
+define i16 @test_as_retval(i8 %a, i8 %b) {
+; CHECK-LABEL: define i16 @test_as_retval(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]]
+; CHECK: [[COND_TRUE]]:
+; CHECK-NEXT: ret i16 0
+; CHECK: [[COND_FALSE]]:
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]]
+; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16
+; CHECK-NEXT: ret i16 [[CONV]]
+;
+ %cmp = icmp sgt i8 %a, %b
+ br i1 %cmp, label %cond.true, label %cond.false
+
+cond.true:
+ ret i16 0
+
+cond.false:
+ %sub = sub nsw i8 %b, %a
+ %conv = sext i8 %sub to i16
+ ret i16 %conv
+}
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
dba9980 to
d80031d
Compare
|
Hmm, the bot seems to be reporting an unrelated flaky failure. Also, mentioning @dtcxzyw since I don't have the ability to edit reviewers. |
nikic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be directly in computeKnownBits() rather than isKnownNonNegative()?
|
The net effect looks good. But this patch converts more sexts into llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp Lines 1500 to 1519 in 463ce01
|
Ignore me. It looks like a GVN problem. |
b - a after a <= bb - a after a <= b
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
214e39e to
68cb10e
Compare
|
Requesting that this be merged once everybody's happy, since I don't have commit rights yet. 🙇 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add a negative test with missing nsw flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
|
Failures on the Linux bot are again unrelated. |
nikic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Alive2: https://alive2.llvm.org/ce/z/an9npN
Fixes #142283.