[llvm] 59720dc - [InstCombine] Fold `icmp spred (X *nsw Z), (Y *nsw Z) -> icmp pred Z, 0` if `scmp(X, Y)` is known (#118726)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 5 03:59:37 PST 2024
Author: Yingwei Zheng
Date: 2024-12-05T19:59:31+08:00
New Revision: 59720dc703f7f207d013b065d0ed7d3af7168bcc
URL: https://github.com/llvm/llvm-project/commit/59720dc703f7f207d013b065d0ed7d3af7168bcc
DIFF: https://github.com/llvm/llvm-project/commit/59720dc703f7f207d013b065d0ed7d3af7168bcc.diff
LOG: [InstCombine] Fold `icmp spred (X *nsw Z), (Y *nsw Z) -> icmp pred Z, 0` if `scmp(X, Y)` is known (#118726)
```
icmp spred (X *nsw Z), (Y *nsw Z) -> icmp swap(spred) Z, 0 if X s< Y
icmp spred (X *nsw Z), (Y *nsw Z) -> icmp spred Z, 0 if X s> Y
```
Alive2: https://alive2.llvm.org/ce/z/F2D0GE
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-mul.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 56391d320e8b37..cab781d9d1ff25 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5347,6 +5347,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
+}
More information about the llvm-commits
mailing list