1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
6 define i32 @sadd_sat32(i32 %a, i32 %b) {
7 ; CHECK-LABEL: @sadd_sat32(
9 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
10 ; CHECK-NEXT: ret i32 [[TMP0]]
13 %conv = sext i32 %a to i64
14 %conv1 = sext i32 %b to i64
15 %add = add i64 %conv1, %conv
16 %0 = icmp slt i64 %add, 2147483647
17 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
18 %1 = icmp sgt i64 %spec.store.select, -2147483648
19 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
20 %conv7 = trunc i64 %spec.store.select8 to i32
24 define i32 @sadd_sat32_mm(i32 %a, i32 %b) {
25 ; CHECK-LABEL: @sadd_sat32_mm(
27 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
28 ; CHECK-NEXT: ret i32 [[TMP0]]
31 %conv = sext i32 %a to i64
32 %conv1 = sext i32 %b to i64
33 %add = add i64 %conv1, %conv
34 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
35 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
36 %conv7 = trunc i64 %spec.store.select8 to i32
40 define i32 @ssub_sat32(i32 %a, i32 %b) {
41 ; CHECK-LABEL: @ssub_sat32(
43 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
44 ; CHECK-NEXT: ret i32 [[TMP0]]
47 %conv = sext i32 %a to i64
48 %conv1 = sext i32 %b to i64
49 %sub = sub i64 %conv, %conv1
50 %0 = icmp slt i64 %sub, 2147483647
51 %spec.store.select = select i1 %0, i64 %sub, i64 2147483647
52 %1 = icmp sgt i64 %spec.store.select, -2147483648
53 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
54 %conv7 = trunc i64 %spec.store.select8 to i32
58 define i32 @ssub_sat32_mm(i32 %a, i32 %b) {
59 ; CHECK-LABEL: @ssub_sat32_mm(
61 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
62 ; CHECK-NEXT: ret i32 [[TMP0]]
65 %conv = sext i32 %a to i64
66 %conv1 = sext i32 %b to i64
67 %sub = sub i64 %conv, %conv1
68 %spec.store.select = call i64 @llvm.smin.i64(i64 %sub, i64 2147483647)
69 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
70 %conv7 = trunc i64 %spec.store.select8 to i32
74 define i32 @smul_sat32(i32 %a, i32 %b) {
75 ; CHECK-LABEL: @smul_sat32(
77 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
78 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
79 ; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
80 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
81 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
82 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
83 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
84 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
85 ; CHECK-NEXT: ret i32 [[CONV7]]
88 %conv = sext i32 %a to i64
89 %conv1 = sext i32 %b to i64
90 %add = mul i64 %conv1, %conv
91 %0 = icmp slt i64 %add, 2147483647
92 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
93 %1 = icmp sgt i64 %spec.store.select, -2147483648
94 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
95 %conv7 = trunc i64 %spec.store.select8 to i32
99 define i32 @smul_sat32_mm(i32 %a, i32 %b) {
100 ; CHECK-LABEL: @smul_sat32_mm(
102 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
103 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
104 ; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
105 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
106 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
107 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
108 ; CHECK-NEXT: ret i32 [[CONV7]]
111 %conv = sext i32 %a to i64
112 %conv1 = sext i32 %b to i64
113 %add = mul i64 %conv1, %conv
114 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
115 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
116 %conv7 = trunc i64 %spec.store.select8 to i32
120 define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) {
121 ; CHECK-LABEL: @sadd_sat16(
123 ; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]])
124 ; CHECK-NEXT: ret i16 [[TMP0]]
127 %conv = sext i16 %a to i32
128 %conv1 = sext i16 %b to i32
129 %add = add i32 %conv1, %conv
130 %0 = icmp slt i32 %add, 32767
131 %spec.store.select = select i1 %0, i32 %add, i32 32767
132 %1 = icmp sgt i32 %spec.store.select, -32768
133 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
134 %conv9 = trunc i32 %spec.store.select10 to i16
138 define signext i16 @sadd_sat16_mm(i16 signext %a, i16 signext %b) {
139 ; CHECK-LABEL: @sadd_sat16_mm(
141 ; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]])
142 ; CHECK-NEXT: ret i16 [[TMP0]]
145 %conv = sext i16 %a to i32
146 %conv1 = sext i16 %b to i32
147 %add = add i32 %conv1, %conv
148 %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 32767)
149 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
150 %conv9 = trunc i32 %spec.store.select10 to i16
154 define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) {
155 ; CHECK-LABEL: @ssub_sat16(
157 ; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]])
158 ; CHECK-NEXT: ret i16 [[TMP0]]
161 %conv = sext i16 %a to i32
162 %conv1 = sext i16 %b to i32
163 %sub = sub i32 %conv, %conv1
164 %0 = icmp slt i32 %sub, 32767
165 %spec.store.select = select i1 %0, i32 %sub, i32 32767
166 %1 = icmp sgt i32 %spec.store.select, -32768
167 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
168 %conv9 = trunc i32 %spec.store.select10 to i16
172 define signext i16 @ssub_sat16_mm(i16 signext %a, i16 signext %b) {
173 ; CHECK-LABEL: @ssub_sat16_mm(
175 ; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]])
176 ; CHECK-NEXT: ret i16 [[TMP0]]
179 %conv = sext i16 %a to i32
180 %conv1 = sext i16 %b to i32
181 %sub = sub i32 %conv, %conv1
182 %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 32767)
183 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
184 %conv9 = trunc i32 %spec.store.select10 to i16
188 define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) {
189 ; CHECK-LABEL: @sadd_sat8(
191 ; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
192 ; CHECK-NEXT: ret i8 [[TMP0]]
195 %conv = sext i8 %a to i32
196 %conv1 = sext i8 %b to i32
197 %add = add i32 %conv1, %conv
198 %0 = icmp slt i32 %add, 127
199 %spec.store.select = select i1 %0, i32 %add, i32 127
200 %1 = icmp sgt i32 %spec.store.select, -128
201 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
202 %conv9 = trunc i32 %spec.store.select10 to i8
206 define signext i8 @sadd_sat8_mm(i8 signext %a, i8 signext %b) {
207 ; CHECK-LABEL: @sadd_sat8_mm(
209 ; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
210 ; CHECK-NEXT: ret i8 [[TMP0]]
213 %conv = sext i8 %a to i32
214 %conv1 = sext i8 %b to i32
215 %add = add i32 %conv1, %conv
216 %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 127)
217 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
218 %conv9 = trunc i32 %spec.store.select10 to i8
222 define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) {
223 ; CHECK-LABEL: @ssub_sat8(
225 ; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
226 ; CHECK-NEXT: ret i8 [[TMP0]]
229 %conv = sext i8 %a to i32
230 %conv1 = sext i8 %b to i32
231 %sub = sub i32 %conv, %conv1
232 %0 = icmp slt i32 %sub, 127
233 %spec.store.select = select i1 %0, i32 %sub, i32 127
234 %1 = icmp sgt i32 %spec.store.select, -128
235 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
236 %conv9 = trunc i32 %spec.store.select10 to i8
240 define signext i8 @ssub_sat8_mm(i8 signext %a, i8 signext %b) {
241 ; CHECK-LABEL: @ssub_sat8_mm(
243 ; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
244 ; CHECK-NEXT: ret i8 [[TMP0]]
247 %conv = sext i8 %a to i32
248 %conv1 = sext i8 %b to i32
249 %sub = sub i32 %conv, %conv1
250 %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 127)
251 %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
252 %conv9 = trunc i32 %spec.store.select10 to i8
256 define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) {
257 ; CHECK-LABEL: @sadd_sat64(
259 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[B:%.*]], i64 [[A:%.*]])
260 ; CHECK-NEXT: ret i64 [[TMP0]]
263 %conv = sext i64 %a to i65
264 %conv1 = sext i64 %b to i65
265 %add = add i65 %conv1, %conv
266 %0 = icmp slt i65 %add, 9223372036854775807
267 %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807
268 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
269 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
270 %conv9 = trunc i65 %spec.store.select10 to i64
274 define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) {
275 ; CHECK-LABEL: @ssub_sat64(
277 ; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.ssub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
278 ; CHECK-NEXT: ret i64 [[TMP0]]
281 %conv = sext i64 %a to i65
282 %conv1 = sext i64 %b to i65
283 %sub = sub i65 %conv, %conv1
284 %0 = icmp slt i65 %sub, 9223372036854775807
285 %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807
286 %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
287 %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
288 %conv9 = trunc i65 %spec.store.select10 to i64
292 define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) {
293 ; CHECK-LABEL: @sadd_sat4(
295 ; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
296 ; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
297 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
298 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ADD]], 7
299 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 7
300 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
301 ; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
302 ; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
303 ; CHECK-NEXT: ret i4 [[CONV9]]
306 %conv = sext i4 %a to i32
307 %conv1 = sext i4 %b to i32
308 %add = add i32 %conv1, %conv
309 %0 = icmp slt i32 %add, 7
310 %spec.store.select = select i1 %0, i32 %add, i32 7
311 %1 = icmp sgt i32 %spec.store.select, -8
312 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
313 %conv9 = trunc i32 %spec.store.select10 to i4
317 define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) {
318 ; CHECK-LABEL: @ssub_sat4(
320 ; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
321 ; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
322 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
323 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[SUB]], 7
324 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 7
325 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
326 ; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
327 ; CHECK-NEXT: [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
328 ; CHECK-NEXT: ret i4 [[CONV9]]
331 %conv = sext i4 %a to i32
332 %conv1 = sext i4 %b to i32
333 %sub = sub i32 %conv, %conv1
334 %0 = icmp slt i32 %sub, 7
335 %spec.store.select = select i1 %0, i32 %sub, i32 7
336 %1 = icmp sgt i32 %spec.store.select, -8
337 %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
338 %conv9 = trunc i32 %spec.store.select10 to i4
342 define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) {
343 ; CHECK-LABEL: @sadd_satv4i32(
345 ; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
346 ; CHECK-NEXT: ret <4 x i32> [[TMP0]]
349 %conv = sext <4 x i32> %a to <4 x i64>
350 %conv1 = sext <4 x i32> %b to <4 x i64>
351 %add = add <4 x i64> %conv1, %conv
352 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
353 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
354 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
355 %spec.store.select8 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
356 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
360 define <4 x i32> @sadd_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
361 ; CHECK-LABEL: @sadd_satv4i32_mm(
363 ; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
364 ; CHECK-NEXT: ret <4 x i32> [[TMP0]]
367 %conv = sext <4 x i32> %a to <4 x i64>
368 %conv1 = sext <4 x i32> %b to <4 x i64>
369 %add = add <4 x i64> %conv1, %conv
370 %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>)
371 %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>)
372 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
376 define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) {
377 ; CHECK-LABEL: @ssub_satv4i32(
379 ; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
380 ; CHECK-NEXT: ret <4 x i32> [[TMP0]]
383 %conv = sext <4 x i32> %a to <4 x i64>
384 %conv1 = sext <4 x i32> %b to <4 x i64>
385 %add = sub <4 x i64> %conv1, %conv
386 %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
387 %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
388 %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
389 %spec.store.select8 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
390 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
394 define <4 x i32> @ssub_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
395 ; CHECK-LABEL: @ssub_satv4i32_mm(
397 ; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
398 ; CHECK-NEXT: ret <4 x i32> [[TMP0]]
401 %conv = sext <4 x i32> %a to <4 x i64>
402 %conv1 = sext <4 x i32> %b to <4 x i64>
403 %add = sub <4 x i64> %conv1, %conv
404 %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>)
405 %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>)
406 %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
410 define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
411 ; CHECK-LABEL: @sadd_satv4i4(
413 ; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]]
414 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
415 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15>
416 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
417 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>
418 ; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]]
421 %add = add <4 x i32> %a, %b
422 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
423 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
424 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
425 %spec.store.select8 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>
426 ret <4 x i32> %spec.store.select8
429 define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) {
430 ; CHECK-LABEL: @ssub_satv4i4(
432 ; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]]
433 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
434 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15>
435 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
436 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>
437 ; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]]
440 %add = sub <4 x i32> %a, %b
441 %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
442 %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
443 %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
444 %spec.store.select8 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>
445 ret <4 x i32> %spec.store.select8
449 define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) {
450 ; CHECK-LABEL: @sadd_sat32_extrause_1(
452 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
453 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
454 ; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT8]])
455 ; CHECK-NEXT: ret i32 [[TMP0]]
458 %conv = sext i32 %a to i64
459 %conv1 = sext i32 %b to i64
460 %add = add i64 %conv1, %conv
461 %0 = icmp slt i64 %add, 2147483647
462 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
463 %1 = icmp sgt i64 %spec.store.select, -2147483648
464 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
465 %conv7 = trunc i64 %spec.store.select8 to i32
466 call void @use64(i64 %spec.store.select8)
470 define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) {
471 ; CHECK-LABEL: @sadd_sat32_extrause_2(
473 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
474 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
475 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
476 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
477 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
478 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
479 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
480 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
481 ; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT]])
482 ; CHECK-NEXT: ret i32 [[CONV7]]
485 %conv = sext i32 %a to i64
486 %conv1 = sext i32 %b to i64
487 %add = add i64 %conv1, %conv
488 %0 = icmp slt i64 %add, 2147483647
489 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
490 %1 = icmp sgt i64 %spec.store.select, -2147483648
491 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
492 %conv7 = trunc i64 %spec.store.select8 to i32
493 call void @use64(i64 %spec.store.select)
497 define i32 @sadd_sat32_extrause_2_mm(i32 %a, i32 %b) {
498 ; CHECK-LABEL: @sadd_sat32_extrause_2_mm(
500 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
501 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
502 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
503 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
504 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
505 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
506 ; CHECK-NEXT: call void @use64(i64 [[SPEC_STORE_SELECT]])
507 ; CHECK-NEXT: ret i32 [[CONV7]]
510 %conv = sext i32 %a to i64
511 %conv1 = sext i32 %b to i64
512 %add = add i64 %conv1, %conv
513 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
514 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
515 %conv7 = trunc i64 %spec.store.select8 to i32
516 call void @use64(i64 %spec.store.select)
520 define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) {
521 ; CHECK-LABEL: @sadd_sat32_extrause_3(
523 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
524 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
525 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
526 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
527 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
528 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
529 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
530 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
531 ; CHECK-NEXT: call void @use64(i64 [[ADD]])
532 ; CHECK-NEXT: ret i32 [[CONV7]]
535 %conv = sext i32 %a to i64
536 %conv1 = sext i32 %b to i64
537 %add = add i64 %conv1, %conv
538 %0 = icmp slt i64 %add, 2147483647
539 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
540 %1 = icmp sgt i64 %spec.store.select, -2147483648
541 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
542 %conv7 = trunc i64 %spec.store.select8 to i32
543 call void @use64(i64 %add)
547 define i32 @sadd_sat32_extrause_3_mm(i32 %a, i32 %b) {
548 ; CHECK-LABEL: @sadd_sat32_extrause_3_mm(
550 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
551 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
552 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
553 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
554 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
555 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
556 ; CHECK-NEXT: call void @use64(i64 [[ADD]])
557 ; CHECK-NEXT: ret i32 [[CONV7]]
560 %conv = sext i32 %a to i64
561 %conv1 = sext i32 %b to i64
562 %add = add i64 %conv1, %conv
563 %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
564 %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
565 %conv7 = trunc i64 %spec.store.select8 to i32
566 call void @use64(i64 %add)
570 define i32 @sadd_sat32_trunc(i32 %a, i32 %b) {
571 ; CHECK-LABEL: @sadd_sat32_trunc(
573 ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
574 ; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
575 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
576 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[ADD]], 32767
577 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 32767
578 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -32768
579 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -32768
580 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
581 ; CHECK-NEXT: ret i32 [[CONV7]]
584 %conv = sext i32 %a to i64
585 %conv1 = sext i32 %b to i64
586 %add = add i64 %conv1, %conv
587 %0 = icmp slt i64 %add, 32767
588 %spec.store.select = select i1 %0, i64 %add, i64 32767
589 %1 = icmp sgt i64 %spec.store.select, -32768
590 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768
591 %conv7 = trunc i64 %spec.store.select8 to i32
595 define i32 @sadd_sat32_ext16(i32 %a, i16 %b) {
596 ; CHECK-LABEL: @sadd_sat32_ext16(
598 ; CHECK-NEXT: [[TMP0:%.*]] = sext i16 [[B:%.*]] to i32
599 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[A:%.*]])
600 ; CHECK-NEXT: ret i32 [[TMP1]]
603 %conv = sext i32 %a to i64
604 %conv1 = sext i16 %b to i64
605 %add = add i64 %conv1, %conv
606 %0 = icmp slt i64 %add, 2147483647
607 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
608 %1 = icmp sgt i64 %spec.store.select, -2147483648
609 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
610 %conv7 = trunc i64 %spec.store.select8 to i32
614 define i8 @sadd_sat8_ext8(i8 %a, i16 %b) {
615 ; CHECK-LABEL: @sadd_sat8_ext8(
617 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
618 ; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
619 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
620 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[ADD]], 127
621 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 127
622 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128
623 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128
624 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i32 [[SPEC_STORE_SELECT8]] to i8
625 ; CHECK-NEXT: ret i8 [[CONV7]]
628 %conv = sext i8 %a to i32
629 %conv1 = sext i16 %b to i32
630 %add = add i32 %conv1, %conv
631 %0 = icmp slt i32 %add, 127
632 %spec.store.select = select i1 %0, i32 %add, i32 127
633 %1 = icmp sgt i32 %spec.store.select, -128
634 %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128
635 %conv7 = trunc i32 %spec.store.select8 to i8
639 define i32 @sadd_sat32_zext(i32 %a, i32 %b) {
640 ; CHECK-LABEL: @sadd_sat32_zext(
642 ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[A:%.*]] to i64
643 ; CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64
644 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]]
645 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[ADD]], 2147483647
646 ; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
647 ; CHECK-NEXT: [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT]] to i32
648 ; CHECK-NEXT: ret i32 [[CONV7]]
651 %conv = zext i32 %a to i64
652 %conv1 = zext i32 %b to i64
653 %add = add i64 %conv1, %conv
654 %0 = icmp slt i64 %add, 2147483647
655 %spec.store.select = select i1 %0, i64 %add, i64 2147483647
656 %1 = icmp sgt i64 %spec.store.select, -2147483648
657 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
658 %conv7 = trunc i64 %spec.store.select8 to i32
662 define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) {
663 ; CHECK-LABEL: @sadd_sat32_maxmin(
665 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
666 ; CHECK-NEXT: ret i32 [[TMP0]]
669 %conv = sext i32 %a to i64
670 %conv1 = sext i32 %b to i64
671 %add = add i64 %conv1, %conv
672 %0 = icmp sgt i64 %add, -2147483648
673 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
674 %1 = icmp slt i64 %spec.store.select, 2147483647
675 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
676 %conv7 = trunc i64 %spec.store.select8 to i32
680 define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) {
681 ; CHECK-LABEL: @sadd_sat32_notrunc(
683 ; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
684 ; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
685 ; CHECK-NEXT: ret i64 [[SPEC_STORE_SELECT8]]
688 %conv = sext i32 %a to i64
689 %conv1 = sext i32 %b to i64
690 %add = add i64 %conv1, %conv
691 %0 = icmp sgt i64 %add, -2147483648
692 %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
693 %1 = icmp slt i64 %spec.store.select, 2147483647
694 %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
695 ret i64 %spec.store.select8
698 declare void @use64(i64)
699 declare i64 @llvm.smin.i64(i64, i64)
700 declare i64 @llvm.smax.i64(i64, i64)
701 declare i32 @llvm.smin.i32(i32, i32)
702 declare i32 @llvm.smax.i32(i32, i32)
703 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
704 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)