-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] isKnownNonNegative 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
base: main
Are you sure you want to change the base?
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. |
Fixes #142283.