Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1715,14 +1715,22 @@ } // (X & C2) > C1 --> (X & C2) != 0, if any bit set in (X & C2) will produce a - // result greater than C1. + // result greater than C1. Also handle (X & C2) < C1 --> (X & C2) == 0. unsigned NumTZ = C2->countTrailingZeros(); - if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && NumTZ < C2->getBitWidth() && - APInt::getOneBitSet(C2->getBitWidth(), NumTZ).ugt(*C1)) { - Constant *Zero = Constant::getNullValue(And->getType()); - return new ICmpInst(ICmpInst::ICMP_NE, And, Zero); + if (NumTZ < C2->getBitWidth()) { + if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && + NumTZ >= C1->getActiveBits()) { + Constant *Zero = Constant::getNullValue(And->getType()); + return new ICmpInst(ICmpInst::ICMP_NE, And, Zero); + } + if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && + NumTZ >= C1->ceilLogBase2()) { + Constant *Zero = Constant::getNullValue(And->getType()); + return new ICmpInst(ICmpInst::ICMP_EQ, And, Zero); + } } + return nullptr; } Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -1141,7 +1141,7 @@ define i1 @test67inverse(i32 %x) { ; CHECK-LABEL: @test67inverse( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[AND]], 32 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %and = and i32 %x, 127