diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 0f1576050ff..f4734461a62 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1539,6 +1539,14 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, Builder->getInt(CR.getLower())); } } + + // X-C1 (X & -2) == C1 + // iff C1 & 1 == 0 + if (ICI.getPredicate() == ICmpInst::ICMP_ULT && LHSI->hasOneUse() && + LHSV[0] == 0 && RHSV == 2) + return new ICmpInst(ICmpInst::ICMP_EQ, + Builder->CreateAnd(LHSI->getOperand(0), -RHSV), + ConstantExpr::getNeg(LHSC)); } break; } diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 929688195fe..cf8305df2a9 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -1113,3 +1113,13 @@ define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) { %3 = or i1 %1, %2 ret i1 %3 } + +; CHECK: @icmp_add_ult_2 +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, -2 +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[AND]], 14 +; CHECK-NEXT: ret i1 [[CMP]] +define i1 @icmp_add_ult_2(i32 %X) { + %add = add i32 %X, -14 + %cmp = icmp ult i32 %add, 2 + ret i1 %cmp +}