Skip to content

Commit e3175f7

Browse files
committed
[InstCombine] icmp(X | OrC, C) --> icmp(X, 0)
We can eliminate the or operation based on the predicate and the relation between OrC and C. sge: X | OrC s>= C --> X s>= 0 iff OrC s>= C s>= 0 sgt: X | OrC s> C --> X s>= 0 iff OrC s> C s>= 0 sle: X | OrC s<= C --> X s< 0 iff OrC s> C s>= 0 slt: X | OrC s< C --> X s< 0 iff OrC s>= C s>= 0 Alive2 links: sge: https://alive2.llvm.org/ce/z/W-6FHE sgt: https://alive2.llvm.org/ce/z/TKK2yJ sle: https://alive2.llvm.org/ce/z/vURQGM slt: https://alive2.llvm.org/ce/z/JAsVfw Related issue: #61538 Signed-off-by: Jun Zhang <jun@junz.org> Differential Revision: https://reviews.llvm.org/D147597
1 parent a088bea commit e3175f7

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,6 +1953,30 @@ Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
19531953
return new ICmpInst(NewPred, X, NewC);
19541954
}
19551955

1956+
const APInt *OrC;
1957+
// icmp(X | OrC, C) --> icmp(X, 0)
1958+
if (C.isNonNegative() && match(Or, m_Or(m_Value(X), m_APInt(OrC)))) {
1959+
switch (Pred) {
1960+
// X | OrC s< C --> X s< 0 iff OrC s>= C s>= 0
1961+
case ICmpInst::ICMP_SLT:
1962+
// X | OrC s>= C --> X s>= 0 iff OrC s>= C s>= 0
1963+
case ICmpInst::ICMP_SGE:
1964+
if (OrC->sge(C))
1965+
return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
1966+
break;
1967+
// X | OrC s<= C --> X s< 0 iff OrC s> C s>= 0
1968+
case ICmpInst::ICMP_SLE:
1969+
// X | OrC s> C --> X s>= 0 iff OrC s> C s>= 0
1970+
case ICmpInst::ICMP_SGT:
1971+
if (OrC->sgt(C))
1972+
return new ICmpInst(ICmpInst::getFlippedStrictnessPredicate(Pred), X,
1973+
ConstantInt::getNullValue(X->getType()));
1974+
break;
1975+
default:
1976+
break;
1977+
}
1978+
}
1979+
19561980
if (!Cmp.isEquality() || !C.isZero() || !Or->hasOneUse())
19571981
return nullptr;
19581982

llvm/test/Transforms/InstCombine/icmp.ll

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4633,8 +4633,7 @@ define i1 @zext_notbool_and_ne0(i2 %x, i8 %y) {
46334633

46344634
define i1 @or_positive_sgt_zero(i8 %a) {
46354635
; CHECK-LABEL: @or_positive_sgt_zero(
4636-
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4637-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 0
4636+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
46384637
; CHECK-NEXT: ret i1 [[CMP]]
46394638
;
46404639
%b = or i8 %a, 24
@@ -4644,8 +4643,7 @@ define i1 @or_positive_sgt_zero(i8 %a) {
46444643

46454644
define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) {
46464645
; CHECK-LABEL: @or_postive_sgt_zero_vec(
4647-
; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
4648-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], zeroinitializer
4646+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], <i8 -1, i8 -1>
46494647
; CHECK-NEXT: ret <2 x i1> [[CMP]]
46504648
;
46514649

@@ -4697,8 +4695,7 @@ define <2 x i1> @or_poison_vec_sge_zero_vec(<2 x i8> %a) {
46974695

46984696
define i1 @or_positive_sge_postive(i8 %a) {
46994697
; CHECK-LABEL: @or_positive_sge_postive(
4700-
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4701-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 23
4698+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
47024699
; CHECK-NEXT: ret i1 [[CMP]]
47034700
;
47044701
%b = or i8 %a, 24
@@ -4708,8 +4705,7 @@ define i1 @or_positive_sge_postive(i8 %a) {
47084705

47094706
define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) {
47104707
; CHECK-LABEL: @or_postive_sge_positive_vec(
4711-
; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
4712-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], <i8 23, i8 23>
4708+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], <i8 -1, i8 -1>
47134709
; CHECK-NEXT: ret <2 x i1> [[CMP]]
47144710
;
47154711

@@ -4730,8 +4726,7 @@ define <2 x i1> @or_poison_vec_sge_positive_vec(<2 x i8> %a) {
47304726

47314727
define i1 @or_positive_sle_zero(i8 %a) {
47324728
; CHECK-LABEL: @or_positive_sle_zero(
4733-
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4734-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 1
4729+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
47354730
; CHECK-NEXT: ret i1 [[CMP]]
47364731
;
47374732
%b = or i8 %a, 24
@@ -4741,8 +4736,7 @@ define i1 @or_positive_sle_zero(i8 %a) {
47414736

47424737
define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) {
47434738
; CHECK-LABEL: @or_postive_sle_zero_vec(
4744-
; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
4745-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], <i8 1, i8 1>
4739+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
47464740
; CHECK-NEXT: ret <2 x i1> [[CMP]]
47474741
;
47484742

@@ -4794,8 +4788,7 @@ define <2 x i1> @or_poison_vec_slt_zero_vec(<2 x i8> %a) {
47944788

47954789
define i1 @or_positive_slt_postive(i8 %a) {
47964790
; CHECK-LABEL: @or_positive_slt_postive(
4797-
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
4798-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 24
4791+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
47994792
; CHECK-NEXT: ret i1 [[CMP]]
48004793
;
48014794
%b = or i8 %a, 24
@@ -4805,8 +4798,7 @@ define i1 @or_positive_slt_postive(i8 %a) {
48054798

48064799
define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) {
48074800
; CHECK-LABEL: @or_postive_slt_positive_vec(
4808-
; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
4809-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], <i8 24, i8 24>
4801+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
48104802
; CHECK-NEXT: ret <2 x i1> [[CMP]]
48114803
;
48124804

@@ -4965,7 +4957,7 @@ define i1 @or_positive_sgt_zero_multi_use(i8 %a) {
49654957
; CHECK-LABEL: @or_positive_sgt_zero_multi_use(
49664958
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
49674959
; CHECK-NEXT: call void @use_i8(i8 [[B]])
4968-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 0
4960+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -1
49694961
; CHECK-NEXT: ret i1 [[CMP]]
49704962
;
49714963
%b = or i8 %a, 24

0 commit comments

Comments
 (0)