Skip to content

Commit 8021870

Browse files
committed
Implement the fold
1 parent 5fb00cc commit 8021870

File tree

3 files changed

+33
-23
lines changed

3 files changed

+33
-23
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -3551,9 +3551,7 @@ Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
35513551
Pred = ICmpInst::getSwappedPredicate(Pred);
35523552
std::swap(LHS, RHS);
35533553
}
3554-
3555-
Intrinsic::ID IID =
3556-
ICmpInst::isSigned(Pred) ? Intrinsic::scmp : Intrinsic::ucmp;
3554+
bool IsSigned = ICmpInst::isSigned(Pred);
35573555

35583556
bool Replace = false;
35593557
ICmpInst::Predicate ExtendedCmpPredicate;
@@ -3575,6 +3573,33 @@ Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
35753573
ICmpInst::getSwappedPredicate(ExtendedCmpPredicate) == Pred))
35763574
Replace = true;
35773575

3576+
// (x == y) ? 0 : (x > y ? 1 : -1)
3577+
ICmpInst::Predicate FalseBranchSelectPredicate;
3578+
ConstantInt *InnerTV, *InnerFV;
3579+
if (Pred == ICmpInst::ICMP_EQ && match(TV, m_Zero()) &&
3580+
match(FV, m_Select(m_c_ICmp(FalseBranchSelectPredicate, m_Specific(LHS),
3581+
m_Specific(RHS)),
3582+
m_ConstantInt(InnerTV), m_ConstantInt(InnerFV)))) {
3583+
if (!ICmpInst::isGT(FalseBranchSelectPredicate)) {
3584+
FalseBranchSelectPredicate =
3585+
ICmpInst::getSwappedPredicate(FalseBranchSelectPredicate);
3586+
std::swap(LHS, RHS);
3587+
}
3588+
3589+
if (!InnerTV->isOne()) {
3590+
std::swap(InnerTV, InnerFV);
3591+
std::swap(LHS, RHS);
3592+
}
3593+
3594+
if (ICmpInst::isGT(FalseBranchSelectPredicate) && InnerTV->isOne() &&
3595+
InnerFV->isAllOnesValue()) {
3596+
IsSigned = ICmpInst::isSigned(FalseBranchSelectPredicate);
3597+
Replace = true;
3598+
}
3599+
}
3600+
3601+
Intrinsic::ID IID =
3602+
IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
35783603
if (Replace)
35793604
return replaceInstUsesWith(
35803605
SI, Builder.CreateIntrinsic(SI.getType(), IID, {LHS, RHS}));

llvm/test/Transforms/InstCombine/scmp.ll

+4-16
Original file line numberDiff line numberDiff line change
@@ -348,10 +348,7 @@ define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
348348
define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
349349
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350350
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
352-
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
353-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
354-
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
351+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
355352
; CHECK-NEXT: ret i8 [[R]]
356353
;
357354
%eq = icmp eq i32 %x, %y
@@ -364,10 +361,7 @@ define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
364361
define i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {
365362
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
366363
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
367-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
368-
; CHECK-NEXT: [[GT:%.*]] = icmp slt i32 [[X]], [[Y]]
369-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
370-
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
364+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
371365
; CHECK-NEXT: ret i8 [[R]]
372366
;
373367
%eq = icmp eq i32 %x, %y
@@ -380,10 +374,7 @@ define i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {
380374
define i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {
381375
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
382376
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
383-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
384-
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
385-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 -1, i8 1
386-
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
377+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
387378
; CHECK-NEXT: ret i8 [[R]]
388379
;
389380
%eq = icmp eq i32 %x, %y
@@ -396,10 +387,7 @@ define i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {
396387
define i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {
397388
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
398389
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
399-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
400-
; CHECK-NEXT: [[GT:%.*]] = icmp slt i32 [[X]], [[Y]]
401-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 -1, i8 1
402-
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
390+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
403391
; CHECK-NEXT: ret i8 [[R]]
404392
;
405393
%eq = icmp eq i32 %x, %y

llvm/test/Transforms/InstCombine/ucmp.ll

+1-4
Original file line numberDiff line numberDiff line change
@@ -546,10 +546,7 @@ define i8 @ucmp_from_select_gt_and_lt(i32 %x, i32 %y) {
546546
define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
547547
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
548548
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
549-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
550-
; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[X]], [[Y]]
551-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
552-
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
549+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
553550
; CHECK-NEXT: ret i8 [[R]]
554551
;
555552
%eq = icmp eq i32 %x, %y

0 commit comments

Comments
 (0)