@@ -21,6 +21,27 @@ entry:
21
21
ret i32 %conv7
22
22
}
23
23
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
+
24
45
define i32 @ssub_sat32 (i32 %a , i32 %b ) {
25
46
; CHECK-LABEL: @ssub_sat32(
26
47
; CHECK-NEXT: entry:
@@ -39,6 +60,27 @@ entry:
39
60
ret i32 %conv7
40
61
}
41
62
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
+
42
84
define i32 @smul_sat32 (i32 %a , i32 %b ) {
43
85
; CHECK-LABEL: @smul_sat32(
44
86
; CHECK-NEXT: entry:
@@ -64,6 +106,27 @@ entry:
64
106
ret i32 %conv7
65
107
}
66
108
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
+
67
130
define signext i16 @sadd_sat16 (i16 signext %a , i16 signext %b ) {
68
131
; CHECK-LABEL: @sadd_sat16(
69
132
; CHECK-NEXT: entry:
@@ -82,6 +145,27 @@ entry:
82
145
ret i16 %conv9
83
146
}
84
147
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
+
85
169
define signext i16 @ssub_sat16 (i16 signext %a , i16 signext %b ) {
86
170
; CHECK-LABEL: @ssub_sat16(
87
171
; CHECK-NEXT: entry:
@@ -100,6 +184,27 @@ entry:
100
184
ret i16 %conv9
101
185
}
102
186
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
+
103
208
define signext i8 @sadd_sat8 (i8 signext %a , i8 signext %b ) {
104
209
; CHECK-LABEL: @sadd_sat8(
105
210
; CHECK-NEXT: entry:
@@ -118,6 +223,27 @@ entry:
118
223
ret i8 %conv9
119
224
}
120
225
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
+
121
247
define signext i8 @ssub_sat8 (i8 signext %a , i8 signext %b ) {
122
248
; CHECK-LABEL: @ssub_sat8(
123
249
; CHECK-NEXT: entry:
@@ -136,6 +262,27 @@ entry:
136
262
ret i8 %conv9
137
263
}
138
264
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
+
139
286
define signext i64 @sadd_sat64 (i64 signext %a , i64 signext %b ) {
140
287
; CHECK-LABEL: @sadd_sat64(
141
288
; CHECK-NEXT: entry:
@@ -240,6 +387,27 @@ entry:
240
387
ret <4 x i32 > %conv7
241
388
}
242
389
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
+
243
411
define <4 x i32 > @ssub_satv4i32 (<4 x i32 > %a , <4 x i32 > %b ) {
244
412
; CHECK-LABEL: @ssub_satv4i32(
245
413
; CHECK-NEXT: entry:
@@ -258,6 +426,27 @@ entry:
258
426
ret <4 x i32 > %conv7
259
427
}
260
428
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
+
261
450
define <4 x i32 > @sadd_satv4i4 (<4 x i32 > %a , <4 x i32 > %b ) {
262
451
; CHECK-LABEL: @sadd_satv4i4(
263
452
; CHECK-NEXT: entry:
@@ -501,3 +690,9 @@ entry:
501
690
}
502
691
503
692
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