Skip to content

Commit 59720dc

Browse files
authored
[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
1 parent 3740fac commit 59720dc

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5347,6 +5347,15 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
53475347
return new ICmpInst(Pred, X, Y);
53485348
if (ZKnown.isNegative())
53495349
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), X, Y);
5350+
Value *LessThan = simplifyICmpInst(ICmpInst::ICMP_SLT, X, Y,
5351+
SQ.getWithInstruction(&I));
5352+
if (LessThan && match(LessThan, m_One()))
5353+
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Z,
5354+
Constant::getNullValue(Z->getType()));
5355+
Value *GreaterThan = simplifyICmpInst(ICmpInst::ICMP_SGT, X, Y,
5356+
SQ.getWithInstruction(&I));
5357+
if (GreaterThan && match(GreaterThan, m_One()))
5358+
return new ICmpInst(Pred, Z, Constant::getNullValue(Z->getType()));
53505359
}
53515360
} else {
53525361
bool NonZero;

llvm/test/Transforms/InstCombine/icmp-mul.ll

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,3 +1464,107 @@ entry:
14641464
%cmp = icmp slt i8 %mul1, %mul2
14651465
ret i1 %cmp
14661466
}
1467+
1468+
define i1 @test_icmp_slt_mul_known_sgt(i64 %x, i64 %z) {
1469+
; CHECK-LABEL: @test_icmp_slt_mul_known_sgt(
1470+
; CHECK-NEXT: entry:
1471+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
1472+
; CHECK-NEXT: ret i1 [[CMP]]
1473+
;
1474+
entry:
1475+
%y = add nsw i64 %x, 1
1476+
%mul1 = mul nsw i64 %x, %z
1477+
%mul2 = mul nsw i64 %y, %z
1478+
%cmp = icmp slt i64 %mul1, %mul2
1479+
ret i1 %cmp
1480+
}
1481+
1482+
define i1 @test_icmp_sle_mul_known_sgt(i64 %x, i64 %z) {
1483+
; CHECK-LABEL: @test_icmp_sle_mul_known_sgt(
1484+
; CHECK-NEXT: entry:
1485+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], -1
1486+
; CHECK-NEXT: ret i1 [[CMP]]
1487+
;
1488+
entry:
1489+
%y = add nsw i64 %x, 1
1490+
%mul1 = mul nsw i64 %x, %z
1491+
%mul2 = mul nsw i64 %y, %z
1492+
%cmp = icmp sle i64 %mul1, %mul2
1493+
ret i1 %cmp
1494+
}
1495+
1496+
define i1 @test_icmp_mul_known_slt(i64 %x, i64 %z) {
1497+
; CHECK-LABEL: @test_icmp_mul_known_slt(
1498+
; CHECK-NEXT: entry:
1499+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[Z:%.*]], 0
1500+
; CHECK-NEXT: ret i1 [[CMP]]
1501+
;
1502+
entry:
1503+
%y = add nsw i64 %x, 1
1504+
%mul1 = mul nsw i64 %x, %z
1505+
%mul2 = mul nsw i64 %y, %z
1506+
%cmp = icmp slt i64 %mul2, %mul1
1507+
ret i1 %cmp
1508+
}
1509+
1510+
define i1 @test_icmp_slt_mul_known_sgt_commuted1(i64 %x, i64 %z) {
1511+
; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted1(
1512+
; CHECK-NEXT: entry:
1513+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
1514+
; CHECK-NEXT: ret i1 [[CMP]]
1515+
;
1516+
entry:
1517+
%y = add nsw i64 %x, 1
1518+
%mul1 = mul nsw i64 %z, %x
1519+
%mul2 = mul nsw i64 %y, %z
1520+
%cmp = icmp slt i64 %mul1, %mul2
1521+
ret i1 %cmp
1522+
}
1523+
1524+
define i1 @test_icmp_slt_mul_known_sgt_commuted2(i64 %x, i64 %z) {
1525+
; CHECK-LABEL: @test_icmp_slt_mul_known_sgt_commuted2(
1526+
; CHECK-NEXT: entry:
1527+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[Z:%.*]], 0
1528+
; CHECK-NEXT: ret i1 [[CMP]]
1529+
;
1530+
entry:
1531+
%y = add nsw i64 %x, 1
1532+
%mul1 = mul nsw i64 %x, %z
1533+
%mul2 = mul nsw i64 %z, %y
1534+
%cmp = icmp slt i64 %mul1, %mul2
1535+
ret i1 %cmp
1536+
}
1537+
1538+
define i1 @test_icmp_slt_mul_unknown(i64 %x, i64 %z) {
1539+
; CHECK-LABEL: @test_icmp_slt_mul_unknown(
1540+
; CHECK-NEXT: entry:
1541+
; CHECK-NEXT: [[Y:%.*]] = add i64 [[X:%.*]], 1
1542+
; CHECK-NEXT: [[MUL1:%.*]] = mul nsw i64 [[X]], [[Z:%.*]]
1543+
; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]
1544+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]
1545+
; CHECK-NEXT: ret i1 [[CMP]]
1546+
;
1547+
entry:
1548+
%y = add i64 %x, 1
1549+
%mul1 = mul nsw i64 %x, %z
1550+
%mul2 = mul nsw i64 %z, %y
1551+
%cmp = icmp slt i64 %mul1, %mul2
1552+
ret i1 %cmp
1553+
}
1554+
1555+
define i1 @test_icmp_slt_mul_no_nsw(i64 %x, i64 %z) {
1556+
; CHECK-LABEL: @test_icmp_slt_mul_no_nsw(
1557+
; CHECK-NEXT: entry:
1558+
; CHECK-NEXT: [[Y:%.*]] = add nsw i64 [[X:%.*]], 1
1559+
; CHECK-NEXT: [[MUL1:%.*]] = mul i64 [[X]], [[Z:%.*]]
1560+
; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i64 [[Z]], [[Y]]
1561+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MUL1]], [[MUL2]]
1562+
; CHECK-NEXT: ret i1 [[CMP]]
1563+
;
1564+
entry:
1565+
%y = add nsw i64 %x, 1
1566+
%mul1 = mul i64 %x, %z
1567+
%mul2 = mul nsw i64 %z, %y
1568+
%cmp = icmp slt i64 %mul1, %mul2
1569+
ret i1 %cmp
1570+
}

0 commit comments

Comments
 (0)