Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -1990,6 +1990,31 @@ } } + // (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 + if (match(RHS, m_One())) { + if (ConstantInt *CI = dyn_cast(RHS)) { + uint32_t BitWidth = CI->getBitWidth(); + APInt LHSKnownZero(BitWidth, 0, 1); + APInt LHSKnownOne(BitWidth, 0, 1); + computeKnownBits(LHS, LHSKnownZero, LHSKnownOne); + switch (Pred) { + // TODO: Handle for other icmp instructions. + default: + break; + case ICmpInst::ICMP_EQ: + if (LHSKnownZero.countTrailingOnes() >= 1) + return ConstantInt::getFalse(CI->getContext()); + break; + case ICmpInst::ICMP_NE: + if (LHSKnownZero.countTrailingOnes() >= 1) + return ConstantInt::getTrue(CI->getContext()); + break; + } + } + } + // See if we are doing a comparison with a constant integer. if (ConstantInt *CI = dyn_cast(RHS)) { // Rule out tautological comparisons (eg., ult 0 or uge 0). Index: test/Transforms/InstSimplify/compare.ll =================================================================== --- test/Transforms/InstSimplify/compare.ll +++ test/Transforms/InstSimplify/compare.ll @@ -817,3 +817,28 @@ ; CHECK-LABEL: @compare_always_false_ne ; CHECK-NEXT: ret i1 true } + +@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 +} + +; CHECK-LABEL: @icmp_ne_const +; CHECK-NEXT: store i32 1, i32* @b +define void @icmp_ne_const() nounwind { + %1 = load i32* @a, align 4 + %2 = mul nsw i32 %1, -2 + %3 = icmp ne i32 %2, 1 + %4 = zext i1 %3 to i32 + store i32 %4, i32* @b, align 4 + ret void +}