diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2251,8 +2251,19 @@ case ICmpInst::ICMP_EQ: // Potential folds for this case should already be handled. break; - case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change - case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change + case ICmpInst::ICMP_UGT: + // We can treat equality of MIN_UINT as being ULE MIN_UINT. + if (LHSC->isMinValue(false)) + return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue() + 1, + false, false); + // (X == 13 | X u> 14) -> no change + break; + case ICmpInst::ICMP_SGT: + // We can treat equality of MIN_SINT as being ULE MIN_SINT. + if (LHSC->isMinValue(true)) + return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue() + 1, + true, false); + // (X == 13 | X s> 14) -> no change break; } break; @@ -2261,6 +2272,10 @@ default: llvm_unreachable("Unknown integer condition code!"); case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change + // We can treat equality of MAX_UINT as being UGE MAX_UINT. + if (RHSC->isMaxValue(false)) + return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue(), + false, false); break; case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) -> (X-13) u> 2 assert(!RHSC->isMaxValue(false) && "Missed icmp simplification"); @@ -2272,7 +2287,12 @@ switch (PredR) { default: llvm_unreachable("Unknown integer condition code!"); - case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change + case ICmpInst::ICMP_EQ: + // We can treat equality of MAX_SINT as being SGE MAX_SINT. + if (RHSC->isMaxValue(true)) + return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue(), + true, false); + // (X s< 13 | X == 14) -> no change break; case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) s> 2 assert(!RHSC->isMaxValue(true) && "Missed icmp simplification"); diff --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll --- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll +++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll @@ -255,10 +255,8 @@ define i1 @PR42691_1(i32 %x) { ; CHECK-LABEL: @PR42691_1( -; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 %x, 0 -; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 %x, 2147483647 -; CHECK-NEXT: [[C:%.*]] = or i1 [[C1]], [[C2]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 %x, 2147483646 +; CHECK-NEXT: ret i1 [[TMP1]] ; %c1 = icmp slt i32 %x, 0 %c2 = icmp eq i32 %x, 2147483647 @@ -279,10 +277,8 @@ define i1 @PR42691_3(i32 %x) { ; CHECK-LABEL: @PR42691_3( -; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 %x, -1 -; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 %x, -2147483648 -; CHECK-NEXT: [[C:%.*]] = or i1 [[C1]], [[C2]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 %x, -2147483647 +; CHECK-NEXT: ret i1 [[TMP1]] ; %c1 = icmp sge i32 %x, 0 %c2 = icmp eq i32 %x, -2147483648 @@ -303,10 +299,9 @@ define i1 @PR42691_5(i32 %x) { ; CHECK-LABEL: @PR42691_5( -; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 %x, 1 -; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 %x, 2147483647 -; CHECK-NEXT: [[C:%.*]] = or i1 [[C1]], [[C2]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[X_OFF:%.*]] = add i32 %x, -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 +; CHECK-NEXT: ret i1 [[TMP1]] ; %c1 = icmp slt i32 %x, 1 %c2 = icmp eq i32 %x, 2147483647 @@ -316,10 +311,9 @@ define i1 @PR42691_6(i32 %x) { ; CHECK-LABEL: @PR42691_6( -; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 %x, -2147483647 -; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 %x, -1 -; CHECK-NEXT: [[C:%.*]] = or i1 [[C1]], [[C2]] -; CHECK-NEXT: ret i1 [[C]] +; CHECK-NEXT: [[X_OFF:%.*]] = add i32 %x, 2147483647 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 +; CHECK-NEXT: ret i1 [[TMP1]] ; %c1 = icmp ult i32 %x, 2147483649 %c2 = icmp eq i32 %x, 4294967295