Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -1990,6 +1990,34 @@ } } + // If the KnownBits of LHS and RHS at same bit position differ, + // LHS and RHS are not equal. + 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); + APInt RHSKnownZero(BitWidth, 0, 1); + APInt RHSKnownOne(BitWidth, 0, 1); + computeKnownBits(RHS, RHSKnownZero, RHSKnownOne); + switch (Pred) { + // TODO: Handle for other icmp instructions. + default: + break; + case ICmpInst::ICMP_EQ: { + if (((LHSKnownOne & RHSKnownZero) != 0) || + ((LHSKnownZero & RHSKnownOne) != 0)) + return ConstantInt::getFalse(CI->getContext()); + break; + } + case ICmpInst::ICMP_NE: + if (((LHSKnownOne & RHSKnownZero) != 0) || + ((LHSKnownZero & RHSKnownOne) != 0)) + 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/InstCombine/align-2d-gep.ll =================================================================== --- test/Transforms/InstCombine/align-2d-gep.ll +++ test/Transforms/InstCombine/align-2d-gep.ll @@ -31,7 +31,7 @@ store <2 x double>, <2 x double>* %r, align 8 %indvar.next = add i64 %j, 2 - %exitcond = icmp eq i64 %indvar.next, 557 + %exitcond = icmp eq i64 %indvar.next, 556 br i1 %exitcond, label %bb11, label %bb1 bb11: Index: test/Transforms/InstSimplify/compare.ll =================================================================== --- test/Transforms/InstSimplify/compare.ll +++ test/Transforms/InstSimplify/compare.ll @@ -883,3 +883,27 @@ ; CHECK: ret i1 false } +@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 +}