diff options
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 19 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/align-2d-gep.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/compare.ll | 19 |
3 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 3684fda854f..b06d9948ac1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2241,6 +2241,25 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, } } + // If a bit is known to be zero for A and known to be one for B, + // then A and B cannot be equal. + if (ICmpInst::isEquality(Pred)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { + uint32_t BitWidth = CI->getBitWidth(); + APInt LHSKnownZero(BitWidth, 0); + APInt LHSKnownOne(BitWidth, 0); + computeKnownBits(LHS, LHSKnownZero, LHSKnownOne); + APInt RHSKnownZero(BitWidth, 0); + APInt RHSKnownOne(BitWidth, 0); + computeKnownBits(RHS, RHSKnownZero, RHSKnownOne); + if (((LHSKnownOne & RHSKnownZero) != 0) || + ((LHSKnownZero & RHSKnownOne) != 0)) + return (Pred == ICmpInst::ICMP_EQ) + ? ConstantInt::getFalse(CI->getContext()) + : ConstantInt::getTrue(CI->getContext()); + } + } + // Special logic for binary operators. BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS); BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS); diff --git a/llvm/test/Transforms/InstCombine/align-2d-gep.ll b/llvm/test/Transforms/InstCombine/align-2d-gep.ll index 5bca46d5a21..f6a877684ce 100644 --- a/llvm/test/Transforms/InstCombine/align-2d-gep.ll +++ b/llvm/test/Transforms/InstCombine/align-2d-gep.ll @@ -31,7 +31,7 @@ bb1: store <2 x double><double 0.0, double 0.0>, <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: diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index 105e244ed8c..89fd6362d78 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -883,3 +883,22 @@ define i1 @returns_nonnull() { ; CHECK: ret i1 false } +; If a bit is known to be zero for A and known to be one for B, +; then A and B cannot be equal. +define i1 @icmp_eq_const(i32 %a) nounwind { + %b = mul nsw i32 %a, -2 + %c = icmp eq i32 %b, 1 + ret i1 %c + +; CHECK-LABEL: @icmp_eq_const +; CHECK-NEXT: ret i1 false +} + +define i1 @icmp_ne_const(i32 %a) nounwind { + %b = mul nsw i32 %a, -2 + %c = icmp ne i32 %b, 1 + ret i1 %c + +; CHECK-LABEL: @icmp_ne_const +; CHECK-NEXT: ret i1 true +} |