// (X != 13 & X u< 14) -> X < 13
if (LHSC->getValue() == (RHSC->getValue() - 1))
return Builder.CreateICmpULT(LHS0, LHSC);
- if (LHSC->isZero()) // (X != 0 & X u< 14) -> X-1 u< 13
+ if (LHSC->isZero()) // (X != 0 & X u< C) -> X-1 u< C-1
return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
false, true);
break; // (X != 13 & X u< 15) -> no change
// (X != 13 & X s< 14) -> X < 13
if (LHSC->getValue() == (RHSC->getValue() - 1))
return Builder.CreateICmpSLT(LHS0, LHSC);
- break; // (X != 13 & X s< 15) -> no change
+ // (X != INT_MIN & X s< C) -> X-(INT_MIN+1) u< (C-(INT_MIN+1))
+ if (LHSC->isMinValue(true))
+ return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+ true, true);
+ break; // (X != 13 & X s< 15) -> no change
case ICmpInst::ICMP_NE:
// Potential folds for this case should already be handled.
break;
// (X u> 13 & X != 14) -> X u> 14
if (RHSC->getValue() == (LHSC->getValue() + 1))
return Builder.CreateICmp(PredL, LHS0, RHSC);
+ // X u> C & X != UINT_MAX -> (X-(C+1)) u< UINT_MAX-(C+1)
+ if (RHSC->isMaxValue(false))
+ return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+ false, true);
break; // (X u> 13 & X != 15) -> no change
- case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) <u 1
+ case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) u< 1
return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
false, true);
}
// (X s> 13 & X != 14) -> X s> 14
if (RHSC->getValue() == (LHSC->getValue() + 1))
return Builder.CreateICmp(PredL, LHS0, RHSC);
+ // X s> C & X != INT_MAX -> (X-(C+1)) u< INT_MAX-(C+1)
+ if (RHSC->isMaxValue(true))
+ return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(),
+ true, true);
break; // (X s> 13 & X != 15) -> no change
- case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) s< 1
+ case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) u< 1
return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue(), true,
true);
}
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:
+ // (X == 0 || X u> C) -> (X-1) u>= C
+ 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:
+ // (X == INT_MIN || X s> C) -> (X-(INT_MIN+1)) u>= C-INT_MIN
+ if (LHSC->isMinValue(true))
+ return insertRangeTest(LHS0, LHSC->getValue() + 1, RHSC->getValue() + 1,
+ true, false);
+ // (X == 13 | X s> 14) -> no change
break;
}
break;
default:
llvm_unreachable("Unknown integer condition code!");
case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
+ // (X u< C || X == UINT_MAX) => (X-C) u>= UINT_MAX-C
+ 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");
switch (PredR) {
default:
llvm_unreachable("Unknown integer condition code!");
- case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change
+ case ICmpInst::ICMP_EQ:
+ // (X s< C || X == INT_MAX) => (X-C) u>= INT_MAX-C
+ 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
+ case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) u> 2
assert(!RHSC->isMaxValue(true) && "Missed icmp simplification");
return insertRangeTest(LHS0, LHSC->getValue(), RHSC->getValue() + 1, true,
false);
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
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
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
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
define i1 @PR42691_8(i32 %x) {
; CHECK-LABEL: @PR42691_8(
-; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 %x, 14
-; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 %x, -2147483648
-; CHECK-NEXT: [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: [[X_OFF:%.*]] = add i32 %x, 2147483647
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -2147483635
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%c1 = icmp slt i32 %x, 14
%c2 = icmp ne i32 %x, -2147483648
define i1 @PR42691_9(i32 %x) {
; CHECK-LABEL: @PR42691_9(
-; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 %x, 13
-; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 %x, 2147483647
-; CHECK-NEXT: [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: [[X_OFF:%.*]] = add i32 %x, -14
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2147483633
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%c1 = icmp sgt i32 %x, 13
%c2 = icmp ne i32 %x, 2147483647
define i1 @PR42691_10(i32 %x) {
; CHECK-LABEL: @PR42691_10(
-; CHECK-NEXT: [[C1:%.*]] = icmp ugt i32 %x, 13
-; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 %x, -1
-; CHECK-NEXT: [[C:%.*]] = and i1 [[C1]], [[C2]]
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: [[X_OFF:%.*]] = add i32 %x, -14
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -15
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%c1 = icmp ugt i32 %x, 13
%c2 = icmp ne i32 %x, 4294967295