const APInt &C) {
Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);
ICmpInst::Predicate Pred = Cmp.getPredicate();
- const APInt *C2;
- APInt SubResult;
+ Type *Ty = Sub->getType();
- // icmp eq/ne (sub C, Y), C -> icmp eq/ne Y, 0
- if (match(X, m_APInt(C2)) && *C2 == C && Cmp.isEquality())
- return new ICmpInst(Cmp.getPredicate(), Y,
- ConstantInt::get(Y->getType(), 0));
+ // (SubC - Y) == C) --> Y == (SubC - C)
+ // (SubC - Y) != C) --> Y != (SubC - C)
+ Constant *SubC;
+ if (Cmp.isEquality() && match(X, m_ImmConstant(SubC))) {
+ return new ICmpInst(Pred, Y,
+ ConstantExpr::getSub(SubC, ConstantInt::get(Ty, C)));
+ }
// (icmp P (sub nuw|nsw C2, Y), C) -> (icmp swap(P) Y, C2-C)
+ const APInt *C2;
+ APInt SubResult;
if (match(X, m_APInt(C2)) &&
((Cmp.isUnsigned() && Sub->hasNoUnsignedWrap()) ||
(Cmp.isSigned() && Sub->hasNoSignedWrap())) &&
!subWithOverflow(SubResult, *C2, C, Cmp.isSigned()))
return new ICmpInst(Cmp.getSwappedPredicate(), Y,
- ConstantInt::get(Y->getType(), SubResult));
+ ConstantInt::get(Ty, SubResult));
// The following transforms are only worth it if the only user of the subtract
// is the icmp.
break;
case Instruction::Sub:
if (BO->hasOneUse()) {
- // Only check for constant LHS here, as constant RHS will be canonicalized
- // to add and use the fold above.
- if (Constant *BOC = dyn_cast<Constant>(BOp0)) {
- // Replace ((sub BOC, B) != C) with (B != BOC-C).
- return new ICmpInst(Pred, BOp1, ConstantExpr::getSub(BOC, RHS));
- } else if (C.isZero()) {
+ if (C.isZero()) {
// Replace ((sub A, B) != 0) with (A != B).
return new ICmpInst(Pred, BOp0, BOp1);
}
; CHECK-LABEL: @neg_eq_43(
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 43
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -43
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub i32 0, %x
; CHECK-LABEL: @neg_ne_44(
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 44
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -44
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub i32 0, %x
; CHECK-LABEL: @neg_nsw_eq_45(
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 45
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -45
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub nsw i32 0, %x
; CHECK-LABEL: @neg_nsw_ne_46(
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[NEGX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 46
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -46
; CHECK-NEXT: ret i1 [[R]]
;
%negx = sub nsw i32 0, %x
; CHECK-LABEL: @subC_eq(
; CHECK-NEXT: [[SUBX:%.*]] = sub i32 -2147483648, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], 43
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483605
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub i32 -2147483648, %x
; CHECK-LABEL: @subC_ne(
; CHECK-NEXT: [[SUBX:%.*]] = sub <2 x i8> <i8 -6, i8 -128>, [[X:%.*]]
; CHECK-NEXT: call void @use_vec(<2 x i8> [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[SUBX]], <i8 -44, i8 -44>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], <i8 38, i8 -84>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%subx = sub <2 x i8> <i8 -6, i8 -128>, %x
; CHECK-LABEL: @subC_nsw_eq(
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -100, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], -2147483648
+; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483548
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub nsw i32 -100, %x
; CHECK-LABEL: @subC_nsw_ne(
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -2147483647, [[X:%.*]]
; CHECK-NEXT: call void @use(i32 [[SUBX]])
-; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[SUBX]], 46
+; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], 2147483603
; CHECK-NEXT: ret i1 [[R]]
;
%subx = sub nsw i32 -2147483647, %x