Skip to content

Commit

Permalink
[InstCombine] Add folds for (icmp spred (ssub.sat X, Y), 0) -> `X s…
Browse files Browse the repository at this point in the history
  • Loading branch information
goldsteinn committed May 3, 2023
1 parent 084ff0d commit 13441eb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
20 changes: 20 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3395,6 +3395,11 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
break;
}

case Intrinsic::ssub_sat:
// ssub.sat(a, b) == 0 -> a == b
if (C.isZero())
return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
break;
case Intrinsic::usub_sat: {
// usub.sat(a, b) == 0 -> a <= b
if (C.isZero()) {
Expand Down Expand Up @@ -3593,6 +3598,21 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
}
break;
}
case Intrinsic::ssub_sat:
// ssub.sat(a, b) spred 0 -> a spred b
if (ICmpInst::isSigned(Pred)) {
if (C.isZero())
return new ICmpInst(Pred, II->getArgOperand(0), II->getArgOperand(1));
// X s<= 0 is cannonicalized to X s< 1
if (Pred == ICmpInst::ICMP_SLT && C.isOne())
return new ICmpInst(ICmpInst::ICMP_SLE, II->getArgOperand(0),
II->getArgOperand(1));
// X s>= 0 is cannonicalized to X s> -1
if (Pred == ICmpInst::ICMP_SGT && C.isAllOnes())
return new ICmpInst(ICmpInst::ICMP_SGE, II->getArgOperand(0),
II->getArgOperand(1));
}
break;
default:
break;
}
Expand Down
18 changes: 6 additions & 12 deletions llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,7 @@ define i1 @uadd_sat_ne_zero_fail_multiuse(i8 %x, i8 %y) {

define i1 @ssub_sat_ne_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_ne_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[M]], 0
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand All @@ -907,8 +906,7 @@ define i1 @ssub_sat_ne_fail_nonzero(i8 %x, i8 %y) {

define i1 @ssub_sat_eq_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_eq_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M]], 0
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand All @@ -918,8 +916,7 @@ define i1 @ssub_sat_eq_zero(i8 %x, i8 %y) {

define i1 @ssub_sat_sle_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_sle_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[M]], 1
; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand All @@ -929,8 +926,7 @@ define i1 @ssub_sat_sle_zero(i8 %x, i8 %y) {

define i1 @ssub_sat_sge_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_sge_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[M]], -1
; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand All @@ -940,8 +936,7 @@ define i1 @ssub_sat_sge_zero(i8 %x, i8 %y) {

define i1 @ssub_sat_slt_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_slt_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[M]], 0
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand All @@ -962,8 +957,7 @@ define i1 @ssub_sat_slt_neg1_fail(i8 %x, i8 %y) {

define i1 @ssub_sat_sgt_zero(i8 %x, i8 %y) {
; CHECK-LABEL: @ssub_sat_sgt_zero(
; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[M]], 0
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%m = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
Expand Down

0 comments on commit 13441eb

Please sign in to comment.