return new ICmpInst(NewPred, X, NewC);
}
+ const APInt *OrC;
+ // icmp(X | OrC, C) --> icmp(X, 0)
+ if (C.isNonNegative() && match(Or, m_Or(m_Value(X), m_APInt(OrC)))) {
+ switch (Pred) {
+ // X | OrC s< C --> X s< 0 iff OrC s>= C s>= 0
+ case ICmpInst::ICMP_SLT:
+ // X | OrC s>= C --> X s>= 0 iff OrC s>= C s>= 0
+ case ICmpInst::ICMP_SGE:
+ if (OrC->sge(C))
+ return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
+ break;
+ // X | OrC s<= C --> X s< 0 iff OrC s> C s>= 0
+ case ICmpInst::ICMP_SLE:
+ // X | OrC s> C --> X s>= 0 iff OrC s> C s>= 0
+ case ICmpInst::ICMP_SGT:
+ if (OrC->sgt(C))
+ return new ICmpInst(ICmpInst::getFlippedStrictnessPredicate(Pred), X,
+ ConstantInt::getNullValue(X->getType()));
+ break;
+ default:
+ break;
+ }
+ }
+
if (!Cmp.isEquality() || !C.isZero() || !Or->hasOneUse())
return nullptr;
define i1 @or_positive_sgt_zero(i8 %a) {
; CHECK-LABEL: @or_positive_sgt_zero(
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 0
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%b = or i8 %a, 24
define <2 x i1> @or_postive_sgt_zero_vec(<2 x i8> %a) {
; CHECK-LABEL: @or_postive_sgt_zero_vec(
-; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], <i8 -1, i8 -1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
define i1 @or_positive_sge_postive(i8 %a) {
; CHECK-LABEL: @or_positive_sge_postive(
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 23
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%b = or i8 %a, 24
define <2 x i1> @or_postive_sge_positive_vec(<2 x i8> %a) {
; CHECK-LABEL: @or_postive_sge_positive_vec(
-; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[B]], <i8 23, i8 23>
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[A:%.*]], <i8 -1, i8 -1>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
define i1 @or_positive_sle_zero(i8 %a) {
; CHECK-LABEL: @or_positive_sle_zero(
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%b = or i8 %a, 24
define <2 x i1> @or_postive_sle_zero_vec(<2 x i8> %a) {
; CHECK-LABEL: @or_postive_sle_zero_vec(
-; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], <i8 1, i8 1>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
define i1 @or_positive_slt_postive(i8 %a) {
; CHECK-LABEL: @or_positive_slt_postive(
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[B]], 24
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%b = or i8 %a, 24
define <2 x i1> @or_postive_slt_positive_vec(<2 x i8> %a) {
; CHECK-LABEL: @or_postive_slt_positive_vec(
-; CHECK-NEXT: [[B:%.*]] = or <2 x i8> [[A:%.*]], <i8 24, i8 24>
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[B]], <i8 24, i8 24>
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
; CHECK-LABEL: @or_positive_sgt_zero_multi_use(
; CHECK-NEXT: [[B:%.*]] = or i8 [[A:%.*]], 24
; CHECK-NEXT: call void @use_i8(i8 [[B]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[B]], 0
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%b = or i8 %a, 24