Skip to content

Commit 9f60b8b

Browse files
committed
[InstCombine] canonicalize sign-bit-shift of difference to ext(icmp)
icmp is the preferred spelling in IR because icmp analysis is expected to be better than any other analysis. This should lead to more follow-on folding potential. It's difficult to say exactly what we should do in codegen to compensate. For example on AArch64, which of these is preferred: sub w8, w0, w1 lsr w0, w8, #31 vs: cmp w0, w1 cset w0, lt If there are perf regressions, then we should deal with those in codegen on a case-by-case basis. A possible motivating example for better optimization is shown in: https://llvm.org/PR43198 but that will require other transforms before anything changes there. Alive proof: https://rise4fun.com/Alive/o4E Name: sign-bit splat Pre: C1 == (width(%x) - 1) %s = sub nsw %x, %y %r = ashr %s, C1 => %c = icmp slt %x, %y %r = sext %c Name: sign-bit LSB Pre: C1 == (width(%x) - 1) %s = sub nsw %x, %y %r = lshr %s, C1 => %c = icmp slt %x, %y %r = zext %c
1 parent 64f0462 commit 9f60b8b

File tree

4 files changed

+56
-32
lines changed

4 files changed

+56
-32
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,12 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
11311131
}
11321132
}
11331133

1134+
// lshr i32 (X -nsw Y), 31 --> zext (X < Y)
1135+
Value *Y;
1136+
if (ShAmt == BitWidth - 1 &&
1137+
match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
1138+
return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty);
1139+
11341140
if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) {
11351141
unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
11361142
// Oversized shifts are simplified to zero in InstSimplify.
@@ -1293,6 +1299,12 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
12931299
return new SExtInst(NewSh, Ty);
12941300
}
12951301

1302+
// ashr i32 (X -nsw Y), 31 --> sext (X < Y)
1303+
Value *Y;
1304+
if (ShAmt == BitWidth - 1 &&
1305+
match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
1306+
return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);
1307+
12961308
// If the shifted-out value is known-zero, then this is an exact shift.
12971309
if (!I.isExact() &&
12981310
MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {

llvm/test/Transforms/InstCombine/ashr-lshr.ll

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,15 +437,17 @@ define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {
437437

438438
define i32 @lshr_sub_nsw(i32 %x, i32 %y) {
439439
; CHECK-LABEL: @lshr_sub_nsw(
440-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
441-
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 31
440+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
441+
; CHECK-NEXT: [[SHR:%.*]] = zext i1 [[TMP1]] to i32
442442
; CHECK-NEXT: ret i32 [[SHR]]
443443
;
444444
%sub = sub nsw i32 %x, %y
445445
%shr = lshr i32 %sub, 31
446446
ret i32 %shr
447447
}
448448

449+
; negative test - must shift sign-bit
450+
449451
define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) {
450452
; CHECK-LABEL: @lshr_sub_wrong_amount(
451453
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
@@ -457,6 +459,8 @@ define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) {
457459
ret i32 %shr
458460
}
459461

462+
; negative test - must have nsw
463+
460464
define i32 @lshr_sub(i32 %x, i32 %y) {
461465
; CHECK-LABEL: @lshr_sub(
462466
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
@@ -468,6 +472,8 @@ define i32 @lshr_sub(i32 %x, i32 %y) {
468472
ret i32 %shr
469473
}
470474

475+
; negative test - one-use
476+
471477
define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
472478
; CHECK-LABEL: @lshr_sub_nsw_extra_use(
473479
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
@@ -483,8 +489,8 @@ define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
483489

484490
define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) {
485491
; CHECK-LABEL: @lshr_sub_nsw_splat(
486-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]]
487-
; CHECK-NEXT: [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 41, i42 41>
492+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]]
493+
; CHECK-NEXT: [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42>
488494
; CHECK-NEXT: ret <3 x i42> [[SHR]]
489495
;
490496
%sub = sub nsw <3 x i42> %x, %y
@@ -505,15 +511,17 @@ define <3 x i42> @lshr_sub_nsw_splat_undef(<3 x i42> %x, <3 x i42> %y) {
505511

506512
define i17 @ashr_sub_nsw(i17 %x, i17 %y) {
507513
; CHECK-LABEL: @ashr_sub_nsw(
508-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]]
509-
; CHECK-NEXT: [[SHR:%.*]] = ashr i17 [[SUB]], 16
514+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]]
515+
; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i17
510516
; CHECK-NEXT: ret i17 [[SHR]]
511517
;
512518
%sub = sub nsw i17 %x, %y
513519
%shr = ashr i17 %sub, 16
514520
ret i17 %shr
515521
}
516522

523+
; negative test - must shift sign-bit
524+
517525
define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) {
518526
; CHECK-LABEL: @ashr_sub_wrong_amount(
519527
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]]
@@ -525,6 +533,8 @@ define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) {
525533
ret i17 %shr
526534
}
527535

536+
; negative test - must have nsw
537+
528538
define i32 @ashr_sub(i32 %x, i32 %y) {
529539
; CHECK-LABEL: @ashr_sub(
530540
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
@@ -536,6 +546,8 @@ define i32 @ashr_sub(i32 %x, i32 %y) {
536546
ret i32 %shr
537547
}
538548

549+
; negative test - one-use
550+
539551
define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
540552
; CHECK-LABEL: @ashr_sub_nsw_extra_use(
541553
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
@@ -551,8 +563,8 @@ define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
551563

552564
define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) {
553565
; CHECK-LABEL: @ashr_sub_nsw_splat(
554-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]]
555-
; CHECK-NEXT: [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 42, i43 42>
566+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]]
567+
; CHECK-NEXT: [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43>
556568
; CHECK-NEXT: ret <3 x i43> [[SHR]]
557569
;
558570
%sub = sub nsw <3 x i43> %x, %y

llvm/test/Transforms/InstCombine/sub-ashr-and-to-icmp-select.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
define i8 @sub_ashr_and_i8(i8 %x, i8 %y) {
1414
; CHECK-LABEL: @sub_ashr_and_i8(
15-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
15+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
1616
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 0
1717
; CHECK-NEXT: ret i8 [[AND]]
1818
;
@@ -24,7 +24,7 @@ define i8 @sub_ashr_and_i8(i8 %x, i8 %y) {
2424

2525
define i16 @sub_ashr_and_i16(i16 %x, i16 %y) {
2626
; CHECK-LABEL: @sub_ashr_and_i16(
27-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[X:%.*]], [[Y:%.*]]
27+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i16 [[Y:%.*]], [[X:%.*]]
2828
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i16 [[X]], i16 0
2929
; CHECK-NEXT: ret i16 [[AND]]
3030
;
@@ -37,7 +37,7 @@ define i16 @sub_ashr_and_i16(i16 %x, i16 %y) {
3737

3838
define i32 @sub_ashr_and_i32(i32 %x, i32 %y) {
3939
; CHECK-LABEL: @sub_ashr_and_i32(
40-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
40+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
4141
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 0
4242
; CHECK-NEXT: ret i32 [[AND]]
4343
;
@@ -49,7 +49,7 @@ define i32 @sub_ashr_and_i32(i32 %x, i32 %y) {
4949

5050
define i64 @sub_ashr_and_i64(i64 %x, i64 %y) {
5151
; CHECK-LABEL: @sub_ashr_and_i64(
52-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[X:%.*]], [[Y:%.*]]
52+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[Y:%.*]], [[X:%.*]]
5353
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i64 [[X]], i64 0
5454
; CHECK-NEXT: ret i64 [[AND]]
5555
;
@@ -63,7 +63,7 @@ define i64 @sub_ashr_and_i64(i64 %x, i64 %y) {
6363

6464
define i32 @sub_ashr_and_i32_nuw_nsw(i32 %x, i32 %y) {
6565
; CHECK-LABEL: @sub_ashr_and_i32_nuw_nsw(
66-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
66+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
6767
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 0
6868
; CHECK-NEXT: ret i32 [[AND]]
6969
;
@@ -77,7 +77,7 @@ define i32 @sub_ashr_and_i32_nuw_nsw(i32 %x, i32 %y) {
7777

7878
define i32 @sub_ashr_and_i32_commute(i32 %x, i32 %y) {
7979
; CHECK-LABEL: @sub_ashr_and_i32_commute(
80-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
80+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
8181
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 0
8282
; CHECK-NEXT: ret i32 [[AND]]
8383
;
@@ -91,7 +91,7 @@ define i32 @sub_ashr_and_i32_commute(i32 %x, i32 %y) {
9191

9292
define <4 x i32> @sub_ashr_and_i32_vec(<4 x i32> %x, <4 x i32> %y) {
9393
; CHECK-LABEL: @sub_ashr_and_i32_vec(
94-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
94+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
9595
; CHECK-NEXT: [[AND:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[X]], <4 x i32> zeroinitializer
9696
; CHECK-NEXT: ret <4 x i32> [[AND]]
9797
;
@@ -103,7 +103,7 @@ define <4 x i32> @sub_ashr_and_i32_vec(<4 x i32> %x, <4 x i32> %y) {
103103

104104
define <4 x i32> @sub_ashr_and_i32_vec_nuw_nsw(<4 x i32> %x, <4 x i32> %y) {
105105
; CHECK-LABEL: @sub_ashr_and_i32_vec_nuw_nsw(
106-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
106+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
107107
; CHECK-NEXT: [[AND:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[X]], <4 x i32> zeroinitializer
108108
; CHECK-NEXT: ret <4 x i32> [[AND]]
109109
;
@@ -115,7 +115,7 @@ define <4 x i32> @sub_ashr_and_i32_vec_nuw_nsw(<4 x i32> %x, <4 x i32> %y) {
115115

116116
define <4 x i32> @sub_ashr_and_i32_vec_commute(<4 x i32> %x, <4 x i32> %y) {
117117
; CHECK-LABEL: @sub_ashr_and_i32_vec_commute(
118-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
118+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
119119
; CHECK-NEXT: [[AND:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[X]], <4 x i32> zeroinitializer
120120
; CHECK-NEXT: ret <4 x i32> [[AND]]
121121
;
@@ -144,7 +144,7 @@ define i32 @sub_ashr_and_i32_extra_use_sub(i32 %x, i32 %y, i32* %p) {
144144

145145
define i32 @sub_ashr_and_i32_extra_use_and(i32 %x, i32 %y, i32* %p) {
146146
; CHECK-LABEL: @sub_ashr_and_i32_extra_use_and(
147-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
147+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
148148
; CHECK-NEXT: [[AND:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 0
149149
; CHECK-NEXT: store i32 [[AND]], i32* [[P:%.*]], align 4
150150
; CHECK-NEXT: ret i32 [[AND]]
@@ -160,8 +160,8 @@ define i32 @sub_ashr_and_i32_extra_use_and(i32 %x, i32 %y, i32* %p) {
160160

161161
define i32 @sub_ashr_and_i32_extra_use_ashr(i32 %x, i32 %y, i32* %p) {
162162
; CHECK-LABEL: @sub_ashr_and_i32_extra_use_ashr(
163-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y:%.*]], [[X:%.*]]
164-
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31
163+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
164+
; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i32
165165
; CHECK-NEXT: store i32 [[SHR]], i32* [[P:%.*]], align 4
166166
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], [[X]]
167167
; CHECK-NEXT: ret i32 [[AND]]

llvm/test/Transforms/InstCombine/sub-ashr-or-to-icmp-select.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ define i32 @clamp255_i32(i32 %x) {
2626

2727
define i8 @sub_ashr_or_i8(i8 %x, i8 %y) {
2828
; CHECK-LABEL: @sub_ashr_or_i8(
29-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
29+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
3030
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i8 -1, i8 [[X]]
3131
; CHECK-NEXT: ret i8 [[OR]]
3232
;
@@ -38,7 +38,7 @@ define i8 @sub_ashr_or_i8(i8 %x, i8 %y) {
3838

3939
define i16 @sub_ashr_or_i16(i16 %x, i16 %y) {
4040
; CHECK-LABEL: @sub_ashr_or_i16(
41-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[X:%.*]], [[Y:%.*]]
41+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i16 [[Y:%.*]], [[X:%.*]]
4242
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i16 -1, i16 [[X]]
4343
; CHECK-NEXT: ret i16 [[OR]]
4444
;
@@ -50,7 +50,7 @@ define i16 @sub_ashr_or_i16(i16 %x, i16 %y) {
5050

5151
define i32 @sub_ashr_or_i32(i32 %x, i32 %y) {
5252
; CHECK-LABEL: @sub_ashr_or_i32(
53-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
53+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
5454
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[X]]
5555
; CHECK-NEXT: ret i32 [[OR]]
5656
;
@@ -62,7 +62,7 @@ define i32 @sub_ashr_or_i32(i32 %x, i32 %y) {
6262

6363
define i64 @sub_ashr_or_i64(i64 %x, i64 %y) {
6464
; CHECK-LABEL: @sub_ashr_or_i64(
65-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[X:%.*]], [[Y:%.*]]
65+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[Y:%.*]], [[X:%.*]]
6666
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i64 -1, i64 [[X]]
6767
; CHECK-NEXT: ret i64 [[OR]]
6868
;
@@ -76,7 +76,7 @@ define i64 @sub_ashr_or_i64(i64 %x, i64 %y) {
7676

7777
define i32 @sub_ashr_or_i32_nuw_nsw(i32 %x, i32 %y) {
7878
; CHECK-LABEL: @sub_ashr_or_i32_nuw_nsw(
79-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
79+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
8080
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[X]]
8181
; CHECK-NEXT: ret i32 [[OR]]
8282
;
@@ -90,7 +90,7 @@ define i32 @sub_ashr_or_i32_nuw_nsw(i32 %x, i32 %y) {
9090

9191
define i32 @sub_ashr_or_i32_commute(i32 %x, i32 %y) {
9292
; CHECK-LABEL: @sub_ashr_or_i32_commute(
93-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
93+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
9494
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[X]]
9595
; CHECK-NEXT: ret i32 [[OR]]
9696
;
@@ -104,7 +104,7 @@ define i32 @sub_ashr_or_i32_commute(i32 %x, i32 %y) {
104104

105105
define <4 x i32> @sub_ashr_or_i32_vec(<4 x i32> %x, <4 x i32> %y) {
106106
; CHECK-LABEL: @sub_ashr_or_i32_vec(
107-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
107+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
108108
; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> [[X]]
109109
; CHECK-NEXT: ret <4 x i32> [[OR]]
110110
;
@@ -116,7 +116,7 @@ define <4 x i32> @sub_ashr_or_i32_vec(<4 x i32> %x, <4 x i32> %y) {
116116

117117
define <4 x i32> @sub_ashr_or_i32_vec_nuw_nsw(<4 x i32> %x, <4 x i32> %y) {
118118
; CHECK-LABEL: @sub_ashr_or_i32_vec_nuw_nsw(
119-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
119+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
120120
; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> [[X]]
121121
; CHECK-NEXT: ret <4 x i32> [[OR]]
122122
;
@@ -128,7 +128,7 @@ define <4 x i32> @sub_ashr_or_i32_vec_nuw_nsw(<4 x i32> %x, <4 x i32> %y) {
128128

129129
define <4 x i32> @sub_ashr_or_i32_vec_commute(<4 x i32> %x, <4 x i32> %y) {
130130
; CHECK-LABEL: @sub_ashr_or_i32_vec_commute(
131-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], [[Y:%.*]]
131+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[Y:%.*]], [[X:%.*]]
132132
; CHECK-NEXT: [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> [[X]]
133133
; CHECK-NEXT: ret <4 x i32> [[OR]]
134134
;
@@ -157,7 +157,7 @@ define i32 @sub_ashr_or_i32_extra_use_sub(i32 %x, i32 %y, i32* %p) {
157157

158158
define i32 @sub_ashr_or_i32_extra_use_or(i32 %x, i32 %y, i32* %p) {
159159
; CHECK-LABEL: @sub_ashr_or_i32_extra_use_or(
160-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
160+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
161161
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i32 -1, i32 [[X]]
162162
; CHECK-NEXT: store i32 [[OR]], i32* [[P:%.*]], align 4
163163
; CHECK-NEXT: ret i32 [[OR]]
@@ -173,8 +173,8 @@ define i32 @sub_ashr_or_i32_extra_use_or(i32 %x, i32 %y, i32* %p) {
173173

174174
define i32 @sub_ashr_or_i32_extra_use_ashr(i32 %x, i32 %y, i32* %p) {
175175
; CHECK-LABEL: @sub_ashr_or_i32_extra_use_ashr(
176-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y:%.*]], [[X:%.*]]
177-
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31
176+
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
177+
; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i32
178178
; CHECK-NEXT: store i32 [[SHR]], i32* [[P:%.*]], align 4
179179
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHR]], [[X]]
180180
; CHECK-NEXT: ret i32 [[OR]]

0 commit comments

Comments
 (0)