Skip to content

Commit 2b42350

Browse files
committed
[InstCombine] Extend sadd.sat tests to include min/max patterns. NFC
This tests code starting from smin/smax, as opposed to the icmp/select form. Also adds a ARM MVE phase ordering test for vectorizing to sadd.sat from the original IR.
1 parent 7776b19 commit 2b42350

File tree

2 files changed

+378
-0
lines changed

2 files changed

+378
-0
lines changed

llvm/test/Transforms/InstCombine/sadd_sat.ll

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,27 @@ entry:
2121
ret i32 %conv7
2222
}
2323

24+
define i32 @sadd_sat32_mm(i32 %a, i32 %b) {
25+
; CHECK-LABEL: @sadd_sat32_mm(
26+
; CHECK-NEXT: entry:
27+
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
28+
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
29+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
30+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
31+
; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
32+
; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
33+
; CHECK-NEXT: ret i32 [[CONV7]]
34+
;
35+
entry:
36+
%conv = sext i32 %a to i64
37+
%conv1 = sext i32 %b to i64
38+
%add = add i64 %conv1, %conv
39+
%spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
40+
%spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
41+
%conv7 = trunc i64 %spec.store.select8 to i32
42+
ret i32 %conv7
43+
}
44+
2445
define i32 @ssub_sat32(i32 %a, i32 %b) {
2546
; CHECK-LABEL: @ssub_sat32(
2647
; CHECK-NEXT: entry:
@@ -39,6 +60,27 @@ entry:
3960
ret i32 %conv7
4061
}
4162

63+
define i32 @ssub_sat32_mm(i32 %a, i32 %b) {
64+
; CHECK-LABEL: @ssub_sat32_mm(
65+
; CHECK-NEXT: entry:
66+
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
67+
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
68+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i64 [[CONV]], [[CONV1]]
69+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[SUB]], i64 2147483647)
70+
; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
71+
; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
72+
; CHECK-NEXT: ret i32 [[CONV7]]
73+
;
74+
entry:
75+
%conv = sext i32 %a to i64
76+
%conv1 = sext i32 %b to i64
77+
%sub = sub i64 %conv, %conv1
78+
%spec.store.select = call i64 @llvm.smin.i64(i64 %sub, i64 2147483647)
79+
%spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
80+
%conv7 = trunc i64 %spec.store.select8 to i32
81+
ret i32 %conv7
82+
}
83+
4284
define i32 @smul_sat32(i32 %a, i32 %b) {
4385
; CHECK-LABEL: @smul_sat32(
4486
; CHECK-NEXT: entry:
@@ -64,6 +106,27 @@ entry:
64106
ret i32 %conv7
65107
}
66108

109+
define i32 @smul_sat32_mm(i32 %a, i32 %b) {
110+
; CHECK-LABEL: @smul_sat32_mm(
111+
; CHECK-NEXT: entry:
112+
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
113+
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
114+
; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
115+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
116+
; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
117+
; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
118+
; CHECK-NEXT: ret i32 [[CONV7]]
119+
;
120+
entry:
121+
%conv = sext i32 %a to i64
122+
%conv1 = sext i32 %b to i64
123+
%add = mul i64 %conv1, %conv
124+
%spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
125+
%spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
126+
%conv7 = trunc i64 %spec.store.select8 to i32
127+
ret i32 %conv7
128+
}
129+
67130
define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) {
68131
; CHECK-LABEL: @sadd_sat16(
69132
; CHECK-NEXT: entry:
@@ -82,6 +145,27 @@ entry:
82145
ret i16 %conv9
83146
}
84147

148+
define signext i16 @sadd_sat16_mm(i16 signext %a, i16 signext %b) {
149+
; CHECK-LABEL: @sadd_sat16_mm(
150+
; CHECK-NEXT: entry:
151+
; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32
152+
; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
153+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
154+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 32767)
155+
; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -32768)
156+
; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i16
157+
; CHECK-NEXT: ret i16 [[CONV9]]
158+
;
159+
entry:
160+
%conv = sext i16 %a to i32
161+
%conv1 = sext i16 %b to i32
162+
%add = add i32 %conv1, %conv
163+
%spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 32767)
164+
%spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
165+
%conv9 = trunc i32 %spec.store.select10 to i16
166+
ret i16 %conv9
167+
}
168+
85169
define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) {
86170
; CHECK-LABEL: @ssub_sat16(
87171
; CHECK-NEXT: entry:
@@ -100,6 +184,27 @@ entry:
100184
ret i16 %conv9
101185
}
102186

187+
define signext i16 @ssub_sat16_mm(i16 signext %a, i16 signext %b) {
188+
; CHECK-LABEL: @ssub_sat16_mm(
189+
; CHECK-NEXT: entry:
190+
; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32
191+
; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
192+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
193+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[SUB]], i32 32767)
194+
; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -32768)
195+
; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i16
196+
; CHECK-NEXT: ret i16 [[CONV9]]
197+
;
198+
entry:
199+
%conv = sext i16 %a to i32
200+
%conv1 = sext i16 %b to i32
201+
%sub = sub i32 %conv, %conv1
202+
%spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 32767)
203+
%spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
204+
%conv9 = trunc i32 %spec.store.select10 to i16
205+
ret i16 %conv9
206+
}
207+
103208
define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) {
104209
; CHECK-LABEL: @sadd_sat8(
105210
; CHECK-NEXT: entry:
@@ -118,6 +223,27 @@ entry:
118223
ret i8 %conv9
119224
}
120225

226+
define signext i8 @sadd_sat8_mm(i8 signext %a, i8 signext %b) {
227+
; CHECK-LABEL: @sadd_sat8_mm(
228+
; CHECK-NEXT: entry:
229+
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
230+
; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32
231+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
232+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 127)
233+
; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -128)
234+
; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i8
235+
; CHECK-NEXT: ret i8 [[CONV9]]
236+
;
237+
entry:
238+
%conv = sext i8 %a to i32
239+
%conv1 = sext i8 %b to i32
240+
%add = add i32 %conv1, %conv
241+
%spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 127)
242+
%spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
243+
%conv9 = trunc i32 %spec.store.select10 to i8
244+
ret i8 %conv9
245+
}
246+
121247
define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) {
122248
; CHECK-LABEL: @ssub_sat8(
123249
; CHECK-NEXT: entry:
@@ -136,6 +262,27 @@ entry:
136262
ret i8 %conv9
137263
}
138264

265+
define signext i8 @ssub_sat8_mm(i8 signext %a, i8 signext %b) {
266+
; CHECK-LABEL: @ssub_sat8_mm(
267+
; CHECK-NEXT: entry:
268+
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
269+
; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32
270+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
271+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[SUB]], i32 127)
272+
; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -128)
273+
; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i8
274+
; CHECK-NEXT: ret i8 [[CONV9]]
275+
;
276+
entry:
277+
%conv = sext i8 %a to i32
278+
%conv1 = sext i8 %b to i32
279+
%sub = sub i32 %conv, %conv1
280+
%spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 127)
281+
%spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
282+
%conv9 = trunc i32 %spec.store.select10 to i8
283+
ret i8 %conv9
284+
}
285+
139286
define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) {
140287
; CHECK-LABEL: @sadd_sat64(
141288
; CHECK-NEXT: entry:
@@ -240,6 +387,27 @@ entry:
240387
ret <4 x i32> %conv7
241388
}
242389

390+
define <4 x i32> @sadd_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
391+
; CHECK-LABEL: @sadd_satv4i32_mm(
392+
; CHECK-NEXT: entry:
393+
; CHECK-NEXT: [[CONV:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64>
394+
; CHECK-NEXT: [[CONV1:%.*]] = sext <4 x i32> [[B:%.*]] to <4 x i64>
395+
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i64> [[CONV1]], [[CONV]]
396+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[ADD]], <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
397+
; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[SPEC_STORE_SELECT]], <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
398+
; CHECK-NEXT: [[CONV7:%.*]] = trunc <4 x i64> [[SPEC_STORE_SELECT8]] to <4 x i32>
399+
; CHECK-NEXT: ret <4 x i32> [[CONV7]]
400+
;
401+
entry:
402+
%conv = sext <4 x i32> %a to <4 x i64>
403+
%conv1 = sext <4 x i32> %b to <4 x i64>
404+
%add = add <4 x i64> %conv1, %conv
405+
%spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
406+
%spec.store.select8 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
407+
%conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
408+
ret <4 x i32> %conv7
409+
}
410+
243411
define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) {
244412
; CHECK-LABEL: @ssub_satv4i32(
245413
; CHECK-NEXT: entry:
@@ -258,6 +426,27 @@ entry:
258426
ret <4 x i32> %conv7
259427
}
260428

429+
define <4 x i32> @ssub_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
430+
; CHECK-LABEL: @ssub_satv4i32_mm(
431+
; CHECK-NEXT: entry:
432+
; CHECK-NEXT: [[CONV:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64>
433+
; CHECK-NEXT: [[CONV1:%.*]] = sext <4 x i32> [[B:%.*]] to <4 x i64>
434+
; CHECK-NEXT: [[ADD:%.*]] = sub nsw <4 x i64> [[CONV1]], [[CONV]]
435+
; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[ADD]], <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
436+
; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[SPEC_STORE_SELECT]], <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
437+
; CHECK-NEXT: [[CONV7:%.*]] = trunc <4 x i64> [[SPEC_STORE_SELECT8]] to <4 x i32>
438+
; CHECK-NEXT: ret <4 x i32> [[CONV7]]
439+
;
440+
entry:
441+
%conv = sext <4 x i32> %a to <4 x i64>
442+
%conv1 = sext <4 x i32> %b to <4 x i64>
443+
%add = sub <4 x i64> %conv1, %conv
444+
%spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
445+
%spec.store.select8 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
446+
%conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
447+
ret <4 x i32> %conv7
448+
}
449+
261450
define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
262451
; CHECK-LABEL: @sadd_satv4i4(
263452
; CHECK-NEXT: entry:
@@ -501,3 +690,9 @@ entry:
501690
}
502691

503692
declare void @use64(i64)
693+
declare i64 @llvm.smin.i64(i64, i64)
694+
declare i64 @llvm.smax.i64(i64, i64)
695+
declare i32 @llvm.smin.i32(i32, i32)
696+
declare i32 @llvm.smax.i32(i32, i32)
697+
declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
698+
declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)

0 commit comments

Comments
 (0)