diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1953,6 +1953,30 @@ return new ICmpInst(NewPred, X, NewC); } + const APInt *LHS; + // icmp(X | LHS, C) --> icmp(X, 0) + if (C.isNonNegative() && match(Or, m_c_Or(m_Value(X), m_APInt(LHS)))) { + switch (Pred) { + // X | LHS s< C --> X s< 0 iff LHS s>= C s>= 0 + case ICmpInst::ICMP_SLT: + // X | LHS s>= C --> X s>= 0 iff LHS s>= C s>= 0 + case ICmpInst::ICMP_SGE: + if (LHS->sge(C)) + return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType())); + break; + // X | LHS s<= C --> X s< 0 iff LHS s> C s>= 0 + case ICmpInst::ICMP_SLE: + // X | LHS s> C --> X s>= 0 iff LHS s> C s>= 0 + case ICmpInst::ICMP_SGT: + if (LHS->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; diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -4631,8 +4631,7 @@ define i1 @mul_or_positive_sgt_zero(i8 %a, i8 %b) { ; CHECK-LABEL: @mul_or_positive_sgt_zero( ; CHECK-NEXT: [[MUL1:%.*]] = mul i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or i8 [[MUL1]], 24 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[ADD]], 0 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL1]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %mul1 = mul i8 %a, %b @@ -4644,8 +4643,7 @@ define <2 x i1> @mul_or_postive_sgt_zero_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @mul_or_postive_sgt_zero_vec( ; CHECK-NEXT: [[MUL1:%.*]] = mul <2 x i8> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or <2 x i8> [[MUL1]], -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[ADD]], zeroinitializer +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[MUL1]], ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; @@ -4683,8 +4681,7 @@ define i1 @mul_or_positive_sge_postive(i8 %a, i8 %b) { ; CHECK-LABEL: @mul_or_positive_sge_postive( ; CHECK-NEXT: [[MUL1:%.*]] = mul i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or i8 [[MUL1]], 24 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[ADD]], 23 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL1]], -1 ; CHECK-NEXT: ret i1 [[CMP]] ; %mul1 = mul i8 %a, %b @@ -4696,8 +4693,7 @@ define <2 x i1> @mul_or_postive_sge_positive_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @mul_or_postive_sge_positive_vec( ; CHECK-NEXT: [[MUL1:%.*]] = mul <2 x i8> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or <2 x i8> [[MUL1]], -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[ADD]], +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[MUL1]], ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; @@ -4710,8 +4706,7 @@ define i1 @mul_or_positive_sle_zero(i8 %a, i8 %b) { ; CHECK-LABEL: @mul_or_positive_sle_zero( ; CHECK-NEXT: [[MUL1:%.*]] = mul i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or i8 [[MUL1]], 24 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ADD]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[MUL1]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %mul1 = mul i8 %a, %b @@ -4723,8 +4718,7 @@ define <2 x i1> @mul_or_postive_sle_zero_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @mul_or_postive_sle_zero_vec( ; CHECK-NEXT: [[MUL1:%.*]] = mul <2 x i8> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or <2 x i8> [[MUL1]], -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[ADD]], +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[MUL1]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; @@ -4762,8 +4756,7 @@ define i1 @mul_or_positive_slt_postive(i8 %a, i8 %b) { ; CHECK-LABEL: @mul_or_positive_slt_postive( ; CHECK-NEXT: [[MUL1:%.*]] = mul i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or i8 [[MUL1]], 24 -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[ADD]], 24 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[MUL1]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %mul1 = mul i8 %a, %b @@ -4775,8 +4768,7 @@ define <2 x i1> @mul_or_postive_slt_positive_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @mul_or_postive_slt_positive_vec( ; CHECK-NEXT: [[MUL1:%.*]] = mul <2 x i8> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD:%.*]] = or <2 x i8> [[MUL1]], -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[ADD]], +; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[MUL1]], zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[CMP]] ;