-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] Fold icmp spred (X *nsw Z), (Y *nsw Z) -> icmp pred Z, 0
if scmp(X, Y)
is known
#118726
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
…, 0` if `scmp(X, Y)` is known
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) Changes
Alive2: https://alive2.llvm.org/ce/z/F2D0GE Full diff: https://github.com/llvm/llvm-project/pull/118726.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fed21db393ed22..e31af8104e147c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5337,6 +5337,15 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
return new ICmpInst(Pred, X, Y);
if (ZKnown.isNegative())
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), X, Y);
+ Value *LessThan = simplifyICmpInst(ICmpInst::ICMP_SLT, X, Y,
+ SQ.getWithInstruction(&I));
+ if (LessThan && match(LessThan, m_One()))
+ return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Z,
+ Constant::getNullValue(Z->getType()));
+ Value *GreaterThan = simplifyICmpInst(ICmpInst::ICMP_SGT, X, Y,
+ SQ.getWithInstruction(&I));
+ if (GreaterThan && match(GreaterThan, m_One()))
+ return new ICmpInst(Pred, Z, Constant::getNullValue(Z->getType()));
}
} else {
bool NonZero;
diff --git a/llvm/test/Transforms/InstCombine/icmp-mul.ll b/llvm/test/Transforms/InstCombine/icmp-mul.ll
index c9f9b6d809e8a5..49e1e11fe6c36f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-mul.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-mul.ll
@@ -1464,3 +1464,107 @@ entry:
%cmp = icmp slt i8 %mul1, %mul2
ret i1 %cmp
}
+
+define i1 @test_icmp_slt_mul_known_sgt(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_slt_mul_known_sgt(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul nsw i64 %x, %z
+ %mul2 = mul nsw i64 %y, %z
+ %cmp = icmp slt i64 %mul1, %mul2
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_sle_mul_known_sgt(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_sle_mul_known_sgt(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], -1
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul nsw i64 %x, %z
+ %mul2 = mul nsw i64 %y, %z
+ %cmp = icmp sle i64 %mul1, %mul2
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_mul_known_slt(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_mul_known_slt(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[Z:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul nsw i64 %x, %z
+ %mul2 = mul nsw i64 %y, %z
+ %cmp = icmp slt i64 %mul2, %mul1
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_slt_mul_known_sgt_commuted1(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul nsw i64 %z, %x
+ %mul2 = mul nsw i64 %y, %z
+ %cmp = icmp slt i64 %mul1, %mul2
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_slt_mul_known_sgt_commuted2(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul nsw i64 %x, %z
+ %mul2 = mul nsw i64 %z, %y
+ %cmp = icmp slt i64 %mul1, %mul2
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_slt_mul_unknown(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_slt_mul_unknown(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[Y:%.*]] = add i64 [[X:%.*]], 1
+; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i64 [[X]], [[Z:%.*]]
+; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add i64 %x, 1
+ %mul1 = mul nsw i64 %x, %z
+ %mul2 = mul nsw i64 %z, %y
+ %cmp = icmp slt i64 %mul1, %mul2
+ ret i1 %cmp
+}
+
+define i1 @test_icmp_slt_mul_no_nsw(i64 %x, i64 %z) {
+; CHECK-LABEL: @test_icmp_slt_mul_no_nsw(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[Y:%.*]] = add nsw i64 [[X:%.*]], 1
+; CHECK-NEXT: [[MUL1:%.*]] = mul i64 [[X]], [[Z:%.*]]
+; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %y = add nsw i64 %x, 1
+ %mul1 = mul i64 %x, %z
+ %mul2 = mul nsw i64 %z, %y
+ %cmp = icmp slt i64 %mul1, %mul2
+ ret i1 %cmp
+}
|
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
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/11628 Here is the relevant piece of the build log for the reference
|
Alive2: https://alive2.llvm.org/ce/z/F2D0GE