Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2248,6 +2248,15 @@ Constant *NotCI = ConstantExpr::getNot(RHS); if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue()) return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE)); + + // Comparing if all bits outside of a constant mask are set? + // Replace (X | C) == -1 with (X & ~C) == ~C. + // This removes the -1 constant. + if (BO->hasOneUse() && RHS->isAllOnesValue()) { + Constant *NotBOC = ConstantExpr::getNot(BOC); + Value *And = Builder->CreateAnd(BO->getOperand(0), NotBOC); + return new ICmpInst(ICI.getPredicate(), And, NotBOC); + } } break; Index: llvm/trunk/test/Transforms/InstCombine/icmp.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/icmp.ll +++ llvm/trunk/test/Transforms/InstCombine/icmp.ll @@ -1956,3 +1956,26 @@ %cmp = icmp uge i32 %addx, %addy ret i1 %cmp } + +define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) { +; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq( +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, -43 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43 +; CHECK-NEXT: ret i1 [[CMP]] +; + %or = or i32 %x, 42 + %cmp = icmp eq i32 %or, -1 + ret i1 %cmp +} + +define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) { +; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne( +; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, -43 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43 +; CHECK-NEXT: ret i1 [[CMP]] +; + %or = or i32 %x, 42 + %cmp = icmp ne i32 %or, -1 + ret i1 %cmp +} +