Skip to content

Commit d479849

Browse files
authored
[InstCombine] Fold (x == y) ? 0 : (x > y ? 1 : -1) into ucmp/scmp(x,y) (#107314)
This also handles commuted cases of the same fold, with either the condition or the true/false values of the inner select being swapped.
1 parent 40d6497 commit d479849

File tree

6 files changed

+191
-61
lines changed

6 files changed

+191
-61
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

+27-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,32 @@ 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+
const APInt *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_APInt(InnerTV), m_APInt(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->isAllOnes()) {
3596+
IsSigned = ICmpInst::isSigned(FalseBranchSelectPredicate);
3597+
Replace = true;
3598+
}
3599+
}
3600+
3601+
Intrinsic::ID IID = IsSigned ? Intrinsic::scmp : Intrinsic::ucmp;
35783602
if (Replace)
35793603
return replaceInstUsesWith(
35803604
SI, Builder.CreateIntrinsic(SI.getType(), IID, {LHS, RHS}));

llvm/test/Transforms/InstCombine/compare-3way.ll

+10-29
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ define void @test_low_sgt(i64 %a, i64 %b) {
1515
; CHECK: normal:
1616
; CHECK-NEXT: ret void
1717
; CHECK: unreached:
18-
; CHECK-NEXT: [[EQ:%.*]] = icmp ne i64 [[A]], [[B]]
19-
; CHECK-NEXT: [[RESULT:%.*]] = zext i1 [[EQ]] to i32
18+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
2019
; CHECK-NEXT: call void @use(i32 [[RESULT]])
2120
; CHECK-NEXT: ret void
2221
;
@@ -62,10 +61,7 @@ define void @test_low_sge(i64 %a, i64 %b) {
6261
; CHECK: normal:
6362
; CHECK-NEXT: ret void
6463
; CHECK: unreached:
65-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
66-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
67-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
68-
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[EQ]], i32 0, i32 [[DOT]]
64+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
6965
; CHECK-NEXT: call void @use(i32 [[RESULT]])
7066
; CHECK-NEXT: ret void
7167
;
@@ -114,8 +110,7 @@ define void @test_low_ne(i64 %a, i64 %b) {
114110
; CHECK: normal:
115111
; CHECK-NEXT: ret void
116112
; CHECK: unreached:
117-
; CHECK-NEXT: [[EQ:%.*]] = icmp ne i64 [[A]], [[B]]
118-
; CHECK-NEXT: [[RESULT:%.*]] = zext i1 [[EQ]] to i32
113+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
119114
; CHECK-NEXT: call void @use(i32 [[RESULT]])
120115
; CHECK-NEXT: ret void
121116
;
@@ -212,8 +207,7 @@ define void @test_mid_sge(i64 %a, i64 %b) {
212207
; CHECK: normal:
213208
; CHECK-NEXT: ret void
214209
; CHECK: unreached:
215-
; CHECK-NEXT: [[EQ:%.*]] = icmp ne i64 [[A]], [[B]]
216-
; CHECK-NEXT: [[RESULT:%.*]] = zext i1 [[EQ]] to i32
210+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
217211
; CHECK-NEXT: call void @use(i32 [[RESULT]])
218212
; CHECK-NEXT: ret void
219213
;
@@ -238,10 +232,7 @@ define void @test_mid_sle(i64 %a, i64 %b) {
238232
; CHECK: normal:
239233
; CHECK-NEXT: ret void
240234
; CHECK: unreached:
241-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
242-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
243-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
244-
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[EQ]], i32 0, i32 [[DOT]]
235+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
245236
; CHECK-NEXT: call void @use(i32 [[RESULT]])
246237
; CHECK-NEXT: ret void
247238
;
@@ -266,9 +257,8 @@ define void @test_mid_ne(i64 %a, i64 %b) {
266257
; CHECK: normal:
267258
; CHECK-NEXT: ret void
268259
; CHECK: unreached:
269-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
270-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
271-
; CHECK-NEXT: call void @use(i32 [[DOT]])
260+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
261+
; CHECK-NEXT: call void @use(i32 [[RESULT]])
272262
; CHECK-NEXT: ret void
273263
;
274264
%eq = icmp eq i64 %a, %b
@@ -338,10 +328,7 @@ define void @test_high_slt(i64 %a, i64 %b) {
338328
; CHECK: normal:
339329
; CHECK-NEXT: ret void
340330
; CHECK: unreached:
341-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
342-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
343-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
344-
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[EQ]], i32 0, i32 [[DOT]]
331+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
345332
; CHECK-NEXT: call void @use(i32 [[RESULT]])
346333
; CHECK-NEXT: ret void
347334
;
@@ -389,10 +376,7 @@ define void @test_high_sle(i64 %a, i64 %b) {
389376
; CHECK: normal:
390377
; CHECK-NEXT: ret void
391378
; CHECK: unreached:
392-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
393-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
394-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
395-
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[EQ]], i32 0, i32 [[DOT]]
379+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
396380
; CHECK-NEXT: call void @use(i32 [[RESULT]])
397381
; CHECK-NEXT: ret void
398382
;
@@ -417,10 +401,7 @@ define void @test_high_ne(i64 %a, i64 %b) {
417401
; CHECK: normal:
418402
; CHECK-NEXT: ret void
419403
; CHECK: unreached:
420-
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
421-
; CHECK-NEXT: [[SLT:%.*]] = icmp slt i64 [[A]], [[B]]
422-
; CHECK-NEXT: [[DOT:%.*]] = select i1 [[SLT]], i32 -1, i32 1
423-
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[EQ]], i32 0, i32 [[DOT]]
404+
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
424405
; CHECK-NEXT: call void @use(i32 [[RESULT]])
425406
; CHECK-NEXT: ret void
426407
;

llvm/test/Transforms/InstCombine/scmp.ll

+130
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,133 @@ define i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
343343
%r = select i1 %gt, i8 1, i8 %lt
344344
ret i8 %r
345345
}
346+
347+
; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)
348+
define i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
349+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
352+
; CHECK-NEXT: ret i8 [[R]]
353+
;
354+
%eq = icmp eq i32 %x, %y
355+
%gt = icmp sgt i32 %x, %y
356+
%sel1 = select i1 %gt, i8 1, i8 -1
357+
%r = select i1 %eq, i8 0, i8 %sel1
358+
ret i8 %r
359+
}
360+
361+
define i8 @scmp_from_select_eq_and_gt_inverse(i32 %x, i32 %y) {
362+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(
363+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
364+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
365+
; CHECK-NEXT: ret i8 [[R]]
366+
;
367+
%ne = icmp ne i32 %x, %y
368+
%gt = icmp sgt i32 %x, %y
369+
%sel1 = select i1 %gt, i8 1, i8 -1
370+
%r = select i1 %ne, i8 %sel1, i8 0
371+
ret i8 %r
372+
}
373+
374+
define <4 x i8> @scmp_from_select_eq_and_gt_vec(<4 x i32> %x, <4 x i32> %y) {
375+
; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(
376+
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
377+
; CHECK-NEXT: [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
378+
; CHECK-NEXT: ret <4 x i8> [[R]]
379+
;
380+
%eq = icmp eq <4 x i32> %x, %y
381+
%gt = icmp sgt <4 x i32> %x, %y
382+
%sel1 = select <4 x i1> %gt, <4 x i8> splat(i8 1), <4 x i8> splat(i8 -1)
383+
%r = select <4 x i1> %eq, <4 x i8> splat(i8 0), <4 x i8> %sel1
384+
ret <4 x i8> %r
385+
}
386+
387+
define i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {
388+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
389+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
390+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
391+
; CHECK-NEXT: ret i8 [[R]]
392+
;
393+
%eq = icmp eq i32 %x, %y
394+
%gt = icmp slt i32 %x, %y
395+
%sel1 = select i1 %gt, i8 1, i8 -1
396+
%r = select i1 %eq, i8 0, i8 %sel1
397+
ret i8 %r
398+
}
399+
400+
define i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {
401+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
402+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
403+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
404+
; CHECK-NEXT: ret i8 [[R]]
405+
;
406+
%eq = icmp eq i32 %x, %y
407+
%gt = icmp sgt i32 %x, %y
408+
%sel1 = select i1 %gt, i8 -1, i8 1
409+
%r = select i1 %eq, i8 0, i8 %sel1
410+
ret i8 %r
411+
}
412+
413+
define i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {
414+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
415+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
416+
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
417+
; CHECK-NEXT: ret i8 [[R]]
418+
;
419+
%eq = icmp eq i32 %x, %y
420+
%gt = icmp slt i32 %x, %y
421+
%sel1 = select i1 %gt, i8 -1, i8 1
422+
%r = select i1 %eq, i8 0, i8 %sel1
423+
ret i8 %r
424+
}
425+
426+
; Negative test: true value of outer select is not zero
427+
define i8 @scmp_from_select_eq_and_gt_neg1(i32 %x, i32 %y) {
428+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
429+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430+
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
431+
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
432+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
433+
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]
434+
; CHECK-NEXT: ret i8 [[R]]
435+
;
436+
%eq = icmp eq i32 %x, %y
437+
%gt = icmp sgt i32 %x, %y
438+
%sel1 = select i1 %gt, i8 1, i8 -1
439+
%r = select i1 %eq, i8 5, i8 %sel1
440+
ret i8 %r
441+
}
442+
443+
; Negative test: true value of inner select is not 1 or -1
444+
define i8 @scmp_from_select_eq_and_gt_neg2(i32 %x, i32 %y) {
445+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(
446+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
447+
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
448+
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
449+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1
450+
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
451+
; CHECK-NEXT: ret i8 [[R]]
452+
;
453+
%eq = icmp eq i32 %x, %y
454+
%gt = icmp sgt i32 %x, %y
455+
%sel1 = select i1 %gt, i8 2, i8 -1
456+
%r = select i1 %eq, i8 0, i8 %sel1
457+
ret i8 %r
458+
}
459+
460+
; Negative test: false value of inner select is not 1 or -1
461+
define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
462+
; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(
463+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
464+
; CHECK-NEXT: [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
465+
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
466+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22
467+
; CHECK-NEXT: [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
468+
; CHECK-NEXT: ret i8 [[R]]
469+
;
470+
%eq = icmp eq i32 %x, %y
471+
%gt = icmp sgt i32 %x, %y
472+
%sel1 = select i1 %gt, i8 1, i8 22
473+
%r = select i1 %eq, i8 0, i8 %sel1
474+
ret i8 %r
475+
}

llvm/test/Transforms/InstCombine/select-select.ll

+7-23
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,7 @@ define <2 x i8> @sel_shuf_narrowing_commute2(<4 x i8> %x, <4 x i8> %y, <2 x i8>
177177

178178
define i8 @strong_order_cmp_slt_eq(i32 %a, i32 %b) {
179179
; CHECK-LABEL: @strong_order_cmp_slt_eq(
180-
; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
181-
; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
182-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
183-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
180+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
184181
; CHECK-NEXT: ret i8 [[SEL_EQ]]
185182
;
186183
%cmp.lt = icmp slt i32 %a, %b
@@ -192,10 +189,7 @@ define i8 @strong_order_cmp_slt_eq(i32 %a, i32 %b) {
192189

193190
define i8 @strong_order_cmp_ult_eq(i32 %a, i32 %b) {
194191
; CHECK-LABEL: @strong_order_cmp_ult_eq(
195-
; CHECK-NEXT: [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
196-
; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
197-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
198-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
192+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
199193
; CHECK-NEXT: ret i8 [[SEL_EQ]]
200194
;
201195
%cmp.lt = icmp ult i32 %a, %b
@@ -252,10 +246,7 @@ define i8 @strong_order_cmp_slt_ult_wrong_pred(i32 %a, i32 %b) {
252246

253247
define i8 @strong_order_cmp_sgt_eq(i32 %a, i32 %b) {
254248
; CHECK-LABEL: @strong_order_cmp_sgt_eq(
255-
; CHECK-NEXT: [[CMP_GT:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
256-
; CHECK-NEXT: [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
257-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
258-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
249+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
259250
; CHECK-NEXT: ret i8 [[SEL_EQ]]
260251
;
261252
%cmp.gt = icmp sgt i32 %a, %b
@@ -267,10 +258,7 @@ define i8 @strong_order_cmp_sgt_eq(i32 %a, i32 %b) {
267258

268259
define i8 @strong_order_cmp_ugt_eq(i32 %a, i32 %b) {
269260
; CHECK-LABEL: @strong_order_cmp_ugt_eq(
270-
; CHECK-NEXT: [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
271-
; CHECK-NEXT: [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
272-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
273-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
261+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
274262
; CHECK-NEXT: ret i8 [[SEL_EQ]]
275263
;
276264
%cmp.gt = icmp ugt i32 %a, %b
@@ -395,9 +383,7 @@ define i8 @strong_order_cmp_slt_eq_slt_not_oneuse(i32 %a, i32 %b) {
395383
; CHECK-LABEL: @strong_order_cmp_slt_eq_slt_not_oneuse(
396384
; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
397385
; CHECK-NEXT: call void @use1(i1 [[CMP_LT]])
398-
; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1
399-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
400-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]]
386+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
401387
; CHECK-NEXT: ret i8 [[SEL_EQ]]
402388
;
403389
%cmp.lt = icmp slt i32 %a, %b
@@ -410,11 +396,9 @@ define i8 @strong_order_cmp_slt_eq_slt_not_oneuse(i32 %a, i32 %b) {
410396

411397
define i8 @strong_order_cmp_sgt_eq_eq_not_oneuse(i32 %a, i32 %b) {
412398
; CHECK-LABEL: @strong_order_cmp_sgt_eq_eq_not_oneuse(
413-
; CHECK-NEXT: [[CMP_GT:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
414-
; CHECK-NEXT: [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 -1
415-
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]]
399+
; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
416400
; CHECK-NEXT: call void @use1(i1 [[CMP_EQ]])
417-
; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_GT]]
401+
; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]])
418402
; CHECK-NEXT: ret i8 [[SEL_EQ]]
419403
;
420404
%cmp.gt = icmp sgt i32 %a, %b

llvm/test/Transforms/InstCombine/sink_to_unreachable.ll

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ define void @test_01(i32 %x, i32 %y) {
1010
; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1111
; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[UNREACHED:%.*]]
1212
; CHECK: unreached:
13-
; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X]], [[Y]]
14-
; CHECK-NEXT: [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32
13+
; CHECK-NEXT: [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
1514
; CHECK-NEXT: call void @use(i32 [[COMPARATOR]])
1615
; CHECK-NEXT: unreachable
1716
; CHECK: exit:
@@ -42,8 +41,7 @@ define void @test_02(i32 %x, i32 %y) {
4241
; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
4342
; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
4443
; CHECK: unreached:
45-
; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X]], [[Y]]
46-
; CHECK-NEXT: [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32
44+
; CHECK-NEXT: [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
4745
; CHECK-NEXT: call void @use(i32 [[COMPARATOR]])
4846
; CHECK-NEXT: unreachable
4947
; CHECK: exit:
@@ -77,8 +75,7 @@ define i32 @test_03(i32 %x, i32 %y) {
7775
; CHECK-NEXT: [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
7876
; CHECK-NEXT: br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
7977
; CHECK: unreached:
80-
; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X]], [[Y]]
81-
; CHECK-NEXT: [[COMPARATOR:%.*]] = zext i1 [[C1]] to i32
78+
; CHECK-NEXT: [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
8279
; CHECK-NEXT: ret i32 [[COMPARATOR]]
8380
; CHECK: exit:
8481
; CHECK-NEXT: ret i32 0

0 commit comments

Comments
 (0)