diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3116,13 +3116,30 @@ if (Pred == ICmpInst::ICMP_UGE) return getTrue(ITy); - if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE) { + if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE || + Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT) { KnownBits RHSKnown = computeKnownBits(RHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT); KnownBits YKnown = computeKnownBits(Y, Q.DL, 0, Q.AC, Q.CxtI, Q.DT); - if (RHSKnown.isNonNegative() && YKnown.isNegative()) - return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy); - if (RHSKnown.isNegative() || YKnown.isNonNegative()) - return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy); + + if (ICmpInst::isSigned(Pred)) { + if (RHSKnown.isNonNegative() && YKnown.isNegative()) + return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy); + if (RHSKnown.isNegative() || YKnown.isNonNegative()) + return Pred == ICmpInst::ICMP_SLT ? getFalse(ITy) : getTrue(ITy); + + } else { + // We could also do EQ/NE here, but seems unnecessary as they are + // handled elsewhere so no reason to spend the extra time on + // computeKnownBits. + + // Get NOT of knownbits by swapping ones/zeros + std::swap(RHSKnown.One, RHSKnown.Zero); + KnownBits UniqueBits = RHSKnown & YKnown; + // We know there is a unique bit so equality conditions cannot be + // false. + if (UniqueBits.isNonZero()) + return ICmpInst::isTrueWhenEqual(Pred) ? getFalse(ITy) : getTrue(ITy); + } } } diff --git a/llvm/test/Transforms/InstSimplify/icmp-orx-x.ll b/llvm/test/Transforms/InstSimplify/icmp-orx-x.ll --- a/llvm/test/Transforms/InstSimplify/icmp-orx-x.ll +++ b/llvm/test/Transforms/InstSimplify/icmp-orx-x.ll @@ -3,11 +3,7 @@ define i1 @or_simplify_ule(i8 %y_in, i8 %rhs_in, i1 %c) { ; CHECK-LABEL: @or_simplify_ule( -; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], 1 -; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2 -; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], [[RHS]] -; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[LBO]], [[RHS]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %y = or i8 %y_in, 1 %rhs = and i8 %rhs_in, -2 @@ -18,11 +14,7 @@ define i1 @or_simplify_uge(i8 %y_in, i8 %rhs_in, i1 %c) { ; CHECK-LABEL: @or_simplify_uge( -; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -128 -; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], 127 -; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], [[RHS]] -; CHECK-NEXT: [[R:%.*]] = icmp uge i8 [[RHS]], [[LBO]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %y = or i8 %y_in, 128 %rhs = and i8 %rhs_in, 127 @@ -48,11 +40,7 @@ define i1 @or_simplify_ugt(i8 %y_in, i8 %rhs_in) { ; CHECK-LABEL: @or_simplify_ugt( -; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], 1 -; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2 -; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], [[RHS]] -; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[LBO]], [[RHS]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %y = or i8 %y_in, 1 %rhs = and i8 %rhs_in, -2 @@ -63,11 +51,7 @@ define i1 @or_simplify_ult(i8 %y_in, i8 %rhs_in) { ; CHECK-LABEL: @or_simplify_ult( -; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], 4 -; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -5 -; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], [[RHS]] -; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[RHS]], [[LBO]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %y = or i8 %y_in, 4 %rhs = and i8 %rhs_in, -5 @@ -95,15 +79,11 @@ declare void @foo() define i32 @pr64610() { ; CHECK-LABEL: @pr64610( -; CHECK-NEXT: [[TMP1:%.*]] = load i1, ptr @b, align 2 -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 74, i32 0 -; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP2]], 1 -; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[TMP3]], [[TMP2]] -; CHECK-NEXT: br i1 [[TMP4]], label [[TMP6:%.*]], label [[TMP5:%.*]] -; CHECK: 5: +; CHECK-NEXT: br i1 true, label [[TMP2:%.*]], label [[TMP1:%.*]] +; CHECK: 1: ; CHECK-NEXT: tail call void @foo() -; CHECK-NEXT: br label [[TMP6]] -; CHECK: 6: +; CHECK-NEXT: br label [[TMP2]] +; CHECK: 2: ; CHECK-NEXT: store i1 true, ptr @b, align 2 ; CHECK-NEXT: ret i32 0 ;