Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2438,6 +2438,18 @@ // (icmp cond A B) if cond is equality return new ICmpInst(I.getPredicate(), A, B); } + // (icmp eq (a * ~1) 1) -> will always evaluate to false + // TODO: generalize this for all constants whose trailing zero's are less + // than known trailing zero's of LHS + const APInt *AP1; + if (I.getPredicate() == ICmpInst::ICMP_EQ && match(Op1, m_APInt(AP1)) && + CI->isOne()) { + APInt Op0KnownZero(BitWidth, 0, 1); + APInt Op0KnownOne(BitWidth, 0, 1); + computeKnownBits(Op0, Op0KnownZero, Op0KnownOne); + if (Op0KnownZero.countTrailingOnes() >= 1) + return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getType())); + } // If we have an icmp le or icmp ge instruction, turn it into the // appropriate icmp lt or icmp gt instruction. This allows us to rely on Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -1365,3 +1365,17 @@ %2 = icmp slt i32 %1, -10 ret i1 %2 } + +@a = common global i32 0, align 4 +@b = common global i32 0, align 4 + +; CHECK-LABEL: @icmp_eq_const +; CHECK-NEXT: store i32 0, i32* @b +define void @icmp_eq_const() nounwind { + %1 = load i32* @a, align 4 + %2 = mul nsw i32 %1, -2 + %3 = icmp eq i32 %2, 1 + %4 = zext i1 %3 to i32 + store i32 %4, i32* @b, align 4 + ret void +}