Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / sadd_sat.ll
blob1cce297122f8a1886e094b01e856dc4096aa34f1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=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(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
10 ; CHECK-NEXT:    ret i32 [[TMP0]]
12 entry:
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
21   ret i32 %conv7
24 define i32 @sadd_sat32_mm(i32 %a, i32 %b) {
25 ; CHECK-LABEL: @sadd_sat32_mm(
26 ; CHECK-NEXT:  entry:
27 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
28 ; CHECK-NEXT:    ret i32 [[TMP0]]
30 entry:
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
37   ret i32 %conv7
40 define i32 @ssub_sat32(i32 %a, i32 %b) {
41 ; CHECK-LABEL: @ssub_sat32(
42 ; CHECK-NEXT:  entry:
43 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
44 ; CHECK-NEXT:    ret i32 [[TMP0]]
46 entry:
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
55   ret i32 %conv7
58 define i32 @ssub_sat32_mm(i32 %a, i32 %b) {
59 ; CHECK-LABEL: @ssub_sat32_mm(
60 ; CHECK-NEXT:  entry:
61 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
62 ; CHECK-NEXT:    ret i32 [[TMP0]]
64 entry:
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
71   ret i32 %conv7
74 define i32 @smul_sat32(i32 %a, i32 %b) {
75 ; CHECK-LABEL: @smul_sat32(
76 ; CHECK-NEXT:  entry:
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:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
81 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
82 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
83 ; CHECK-NEXT:    ret i32 [[CONV7]]
85 entry:
86   %conv = sext i32 %a to i64
87   %conv1 = sext i32 %b to i64
88   %add = mul i64 %conv1, %conv
89   %0 = icmp slt i64 %add, 2147483647
90   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
91   %1 = icmp sgt i64 %spec.store.select, -2147483648
92   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
93   %conv7 = trunc i64 %spec.store.select8 to i32
94   ret i32 %conv7
97 define i32 @smul_sat32_mm(i32 %a, i32 %b) {
98 ; CHECK-LABEL: @smul_sat32_mm(
99 ; CHECK-NEXT:  entry:
100 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
101 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
102 ; CHECK-NEXT:    [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
103 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
104 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
105 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
106 ; CHECK-NEXT:    ret i32 [[CONV7]]
108 entry:
109   %conv = sext i32 %a to i64
110   %conv1 = sext i32 %b to i64
111   %add = mul i64 %conv1, %conv
112   %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
113   %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
114   %conv7 = trunc i64 %spec.store.select8 to i32
115   ret i32 %conv7
118 define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) {
119 ; CHECK-LABEL: @sadd_sat16(
120 ; CHECK-NEXT:  entry:
121 ; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]])
122 ; CHECK-NEXT:    ret i16 [[TMP0]]
124 entry:
125   %conv = sext i16 %a to i32
126   %conv1 = sext i16 %b to i32
127   %add = add i32 %conv1, %conv
128   %0 = icmp slt i32 %add, 32767
129   %spec.store.select = select i1 %0, i32 %add, i32 32767
130   %1 = icmp sgt i32 %spec.store.select, -32768
131   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
132   %conv9 = trunc i32 %spec.store.select10 to i16
133   ret i16 %conv9
136 define signext i16 @sadd_sat16_mm(i16 signext %a, i16 signext %b) {
137 ; CHECK-LABEL: @sadd_sat16_mm(
138 ; CHECK-NEXT:  entry:
139 ; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]])
140 ; CHECK-NEXT:    ret i16 [[TMP0]]
142 entry:
143   %conv = sext i16 %a to i32
144   %conv1 = sext i16 %b to i32
145   %add = add i32 %conv1, %conv
146   %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 32767)
147   %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
148   %conv9 = trunc i32 %spec.store.select10 to i16
149   ret i16 %conv9
152 define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) {
153 ; CHECK-LABEL: @ssub_sat16(
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]])
156 ; CHECK-NEXT:    ret i16 [[TMP0]]
158 entry:
159   %conv = sext i16 %a to i32
160   %conv1 = sext i16 %b to i32
161   %sub = sub i32 %conv, %conv1
162   %0 = icmp slt i32 %sub, 32767
163   %spec.store.select = select i1 %0, i32 %sub, i32 32767
164   %1 = icmp sgt i32 %spec.store.select, -32768
165   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
166   %conv9 = trunc i32 %spec.store.select10 to i16
167   ret i16 %conv9
170 define signext i16 @ssub_sat16_mm(i16 signext %a, i16 signext %b) {
171 ; CHECK-LABEL: @ssub_sat16_mm(
172 ; CHECK-NEXT:  entry:
173 ; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]])
174 ; CHECK-NEXT:    ret i16 [[TMP0]]
176 entry:
177   %conv = sext i16 %a to i32
178   %conv1 = sext i16 %b to i32
179   %sub = sub i32 %conv, %conv1
180   %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 32767)
181   %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
182   %conv9 = trunc i32 %spec.store.select10 to i16
183   ret i16 %conv9
186 define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) {
187 ; CHECK-LABEL: @sadd_sat8(
188 ; CHECK-NEXT:  entry:
189 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
190 ; CHECK-NEXT:    ret i8 [[TMP0]]
192 entry:
193   %conv = sext i8 %a to i32
194   %conv1 = sext i8 %b to i32
195   %add = add i32 %conv1, %conv
196   %0 = icmp slt i32 %add, 127
197   %spec.store.select = select i1 %0, i32 %add, i32 127
198   %1 = icmp sgt i32 %spec.store.select, -128
199   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
200   %conv9 = trunc i32 %spec.store.select10 to i8
201   ret i8 %conv9
204 define signext i8 @sadd_sat8_mm(i8 signext %a, i8 signext %b) {
205 ; CHECK-LABEL: @sadd_sat8_mm(
206 ; CHECK-NEXT:  entry:
207 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
208 ; CHECK-NEXT:    ret i8 [[TMP0]]
210 entry:
211   %conv = sext i8 %a to i32
212   %conv1 = sext i8 %b to i32
213   %add = add i32 %conv1, %conv
214   %spec.store.select = call i32 @llvm.smin.i32(i32 %add, i32 127)
215   %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
216   %conv9 = trunc i32 %spec.store.select10 to i8
217   ret i8 %conv9
220 define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) {
221 ; CHECK-LABEL: @ssub_sat8(
222 ; CHECK-NEXT:  entry:
223 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
224 ; CHECK-NEXT:    ret i8 [[TMP0]]
226 entry:
227   %conv = sext i8 %a to i32
228   %conv1 = sext i8 %b to i32
229   %sub = sub i32 %conv, %conv1
230   %0 = icmp slt i32 %sub, 127
231   %spec.store.select = select i1 %0, i32 %sub, i32 127
232   %1 = icmp sgt i32 %spec.store.select, -128
233   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
234   %conv9 = trunc i32 %spec.store.select10 to i8
235   ret i8 %conv9
238 define signext i8 @ssub_sat8_mm(i8 signext %a, i8 signext %b) {
239 ; CHECK-LABEL: @ssub_sat8_mm(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
242 ; CHECK-NEXT:    ret i8 [[TMP0]]
244 entry:
245   %conv = sext i8 %a to i32
246   %conv1 = sext i8 %b to i32
247   %sub = sub i32 %conv, %conv1
248   %spec.store.select = call i32 @llvm.smin.i32(i32 %sub, i32 127)
249   %spec.store.select10 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -128)
250   %conv9 = trunc i32 %spec.store.select10 to i8
251   ret i8 %conv9
254 define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) {
255 ; CHECK-LABEL: @sadd_sat64(
256 ; CHECK-NEXT:  entry:
257 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[B:%.*]], i64 [[A:%.*]])
258 ; CHECK-NEXT:    ret i64 [[TMP0]]
260 entry:
261   %conv = sext i64 %a to i65
262   %conv1 = sext i64 %b to i65
263   %add = add i65 %conv1, %conv
264   %0 = icmp slt i65 %add, 9223372036854775807
265   %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807
266   %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
267   %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
268   %conv9 = trunc i65 %spec.store.select10 to i64
269   ret i64 %conv9
272 define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) {
273 ; CHECK-LABEL: @ssub_sat64(
274 ; CHECK-NEXT:  entry:
275 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ssub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
276 ; CHECK-NEXT:    ret i64 [[TMP0]]
278 entry:
279   %conv = sext i64 %a to i65
280   %conv1 = sext i64 %b to i65
281   %sub = sub i65 %conv, %conv1
282   %0 = icmp slt i65 %sub, 9223372036854775807
283   %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807
284   %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
285   %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
286   %conv9 = trunc i65 %spec.store.select10 to i64
287   ret i64 %conv9
290 define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) {
291 ; CHECK-LABEL: @sadd_sat4(
292 ; CHECK-NEXT:  entry:
293 ; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
294 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
295 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
296 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 7)
297 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8)
298 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4
299 ; CHECK-NEXT:    ret i4 [[CONV9]]
301 entry:
302   %conv = sext i4 %a to i32
303   %conv1 = sext i4 %b to i32
304   %add = add i32 %conv1, %conv
305   %0 = icmp slt i32 %add, 7
306   %spec.store.select = select i1 %0, i32 %add, i32 7
307   %1 = icmp sgt i32 %spec.store.select, -8
308   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
309   %conv9 = trunc i32 %spec.store.select10 to i4
310   ret i4 %conv9
313 define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) {
314 ; CHECK-LABEL: @ssub_sat4(
315 ; CHECK-NEXT:  entry:
316 ; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
317 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
318 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
319 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[SUB]], i32 7)
320 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8)
321 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4
322 ; CHECK-NEXT:    ret i4 [[CONV9]]
324 entry:
325   %conv = sext i4 %a to i32
326   %conv1 = sext i4 %b to i32
327   %sub = sub i32 %conv, %conv1
328   %0 = icmp slt i32 %sub, 7
329   %spec.store.select = select i1 %0, i32 %sub, i32 7
330   %1 = icmp sgt i32 %spec.store.select, -8
331   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
332   %conv9 = trunc i32 %spec.store.select10 to i4
333   ret i4 %conv9
336 define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) {
337 ; CHECK-LABEL: @sadd_satv4i32(
338 ; CHECK-NEXT:  entry:
339 ; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
340 ; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
342 entry:
343   %conv = sext <4 x i32> %a to <4 x i64>
344   %conv1 = sext <4 x i32> %b to <4 x i64>
345   %add = add <4 x i64> %conv1, %conv
346   %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
347   %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
348   %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
349   %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>
350   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
351   ret <4 x i32> %conv7
354 define <4 x i32> @sadd_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
355 ; CHECK-LABEL: @sadd_satv4i32_mm(
356 ; CHECK-NEXT:  entry:
357 ; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
358 ; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
360 entry:
361   %conv = sext <4 x i32> %a to <4 x i64>
362   %conv1 = sext <4 x i32> %b to <4 x i64>
363   %add = add <4 x i64> %conv1, %conv
364   %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>)
365   %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>)
366   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
367   ret <4 x i32> %conv7
370 define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) {
371 ; CHECK-LABEL: @ssub_satv4i32(
372 ; CHECK-NEXT:  entry:
373 ; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
374 ; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
376 entry:
377   %conv = sext <4 x i32> %a to <4 x i64>
378   %conv1 = sext <4 x i32> %b to <4 x i64>
379   %add = sub <4 x i64> %conv1, %conv
380   %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
381   %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
382   %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
383   %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>
384   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
385   ret <4 x i32> %conv7
388 define <4 x i32> @ssub_satv4i32_mm(<4 x i32> %a, <4 x i32> %b) {
389 ; CHECK-LABEL: @ssub_satv4i32_mm(
390 ; CHECK-NEXT:  entry:
391 ; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
392 ; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
394 entry:
395   %conv = sext <4 x i32> %a to <4 x i64>
396   %conv1 = sext <4 x i32> %b to <4 x i64>
397   %add = sub <4 x i64> %conv1, %conv
398   %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>)
399   %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>)
400   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
401   ret <4 x i32> %conv7
404 define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
405 ; CHECK-LABEL: @sadd_satv4i4(
406 ; CHECK-NEXT:  entry:
407 ; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]]
408 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15>)
409 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>)
410 ; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
412 entry:
413   %add = add <4 x i32> %a, %b
414   %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
415   %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
416   %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
417   %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>
418   ret <4 x i32> %spec.store.select8
421 define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) {
422 ; CHECK-LABEL: @ssub_satv4i4(
423 ; CHECK-NEXT:  entry:
424 ; CHECK-NEXT:    [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]]
425 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> <i32 15, i32 15, i32 15, i32 15>)
426 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> <i32 -16, i32 -16, i32 -16, i32 -16>)
427 ; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
429 entry:
430   %add = sub <4 x i32> %a, %b
431   %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
432   %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
433   %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
434   %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>
435   ret <4 x i32> %spec.store.select8
439 define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) {
440 ; CHECK-LABEL: @sadd_sat32_extrause_1(
441 ; CHECK-NEXT:  entry:
442 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
443 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
444 ; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT8]])
445 ; CHECK-NEXT:    ret i32 [[TMP0]]
447 entry:
448   %conv = sext i32 %a to i64
449   %conv1 = sext i32 %b to i64
450   %add = add i64 %conv1, %conv
451   %0 = icmp slt i64 %add, 2147483647
452   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
453   %1 = icmp sgt i64 %spec.store.select, -2147483648
454   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
455   %conv7 = trunc i64 %spec.store.select8 to i32
456   call void @use64(i64 %spec.store.select8)
457   ret i32 %conv7
460 define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) {
461 ; CHECK-LABEL: @sadd_sat32_extrause_2(
462 ; CHECK-NEXT:  entry:
463 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
464 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
465 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
466 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
467 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
468 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
469 ; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT]])
470 ; CHECK-NEXT:    ret i32 [[CONV7]]
472 entry:
473   %conv = sext i32 %a to i64
474   %conv1 = sext i32 %b to i64
475   %add = add i64 %conv1, %conv
476   %0 = icmp slt i64 %add, 2147483647
477   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
478   %1 = icmp sgt i64 %spec.store.select, -2147483648
479   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
480   %conv7 = trunc i64 %spec.store.select8 to i32
481   call void @use64(i64 %spec.store.select)
482   ret i32 %conv7
485 define i32 @sadd_sat32_extrause_2_mm(i32 %a, i32 %b) {
486 ; CHECK-LABEL: @sadd_sat32_extrause_2_mm(
487 ; CHECK-NEXT:  entry:
488 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
489 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
490 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
491 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
492 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
493 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
494 ; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT]])
495 ; CHECK-NEXT:    ret i32 [[CONV7]]
497 entry:
498   %conv = sext i32 %a to i64
499   %conv1 = sext i32 %b to i64
500   %add = add i64 %conv1, %conv
501   %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
502   %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
503   %conv7 = trunc i64 %spec.store.select8 to i32
504   call void @use64(i64 %spec.store.select)
505   ret i32 %conv7
508 define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) {
509 ; CHECK-LABEL: @sadd_sat32_extrause_3(
510 ; CHECK-NEXT:  entry:
511 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
512 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
513 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
514 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
515 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
516 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
517 ; CHECK-NEXT:    call void @use64(i64 [[ADD]])
518 ; CHECK-NEXT:    ret i32 [[CONV7]]
520 entry:
521   %conv = sext i32 %a to i64
522   %conv1 = sext i32 %b to i64
523   %add = add i64 %conv1, %conv
524   %0 = icmp slt i64 %add, 2147483647
525   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
526   %1 = icmp sgt i64 %spec.store.select, -2147483648
527   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
528   %conv7 = trunc i64 %spec.store.select8 to i32
529   call void @use64(i64 %add)
530   ret i32 %conv7
533 define i32 @sadd_sat32_extrause_3_mm(i32 %a, i32 %b) {
534 ; CHECK-LABEL: @sadd_sat32_extrause_3_mm(
535 ; CHECK-NEXT:  entry:
536 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
537 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
538 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
539 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
540 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
541 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
542 ; CHECK-NEXT:    call void @use64(i64 [[ADD]])
543 ; CHECK-NEXT:    ret i32 [[CONV7]]
545 entry:
546   %conv = sext i32 %a to i64
547   %conv1 = sext i32 %b to i64
548   %add = add i64 %conv1, %conv
549   %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
550   %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
551   %conv7 = trunc i64 %spec.store.select8 to i32
552   call void @use64(i64 %add)
553   ret i32 %conv7
556 define i32 @sadd_sat32_trunc(i32 %a, i32 %b) {
557 ; CHECK-LABEL: @sadd_sat32_trunc(
558 ; CHECK-NEXT:  entry:
559 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
560 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
561 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
562 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 32767)
563 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -32768)
564 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
565 ; CHECK-NEXT:    ret i32 [[CONV7]]
567 entry:
568   %conv = sext i32 %a to i64
569   %conv1 = sext i32 %b to i64
570   %add = add i64 %conv1, %conv
571   %0 = icmp slt i64 %add, 32767
572   %spec.store.select = select i1 %0, i64 %add, i64 32767
573   %1 = icmp sgt i64 %spec.store.select, -32768
574   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768
575   %conv7 = trunc i64 %spec.store.select8 to i32
576   ret i32 %conv7
579 define i32 @sadd_sat32_ext16(i32 %a, i16 %b) {
580 ; CHECK-LABEL: @sadd_sat32_ext16(
581 ; CHECK-NEXT:  entry:
582 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i16 [[B:%.*]] to i32
583 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[A:%.*]])
584 ; CHECK-NEXT:    ret i32 [[TMP1]]
586 entry:
587   %conv = sext i32 %a to i64
588   %conv1 = sext i16 %b to i64
589   %add = add i64 %conv1, %conv
590   %0 = icmp slt i64 %add, 2147483647
591   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
592   %1 = icmp sgt i64 %spec.store.select, -2147483648
593   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
594   %conv7 = trunc i64 %spec.store.select8 to i32
595   ret i32 %conv7
598 define i8 @sadd_sat8_ext8(i8 %a, i16 %b) {
599 ; CHECK-LABEL: @sadd_sat8_ext8(
600 ; CHECK-NEXT:  entry:
601 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
602 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
603 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
604 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 127)
605 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -128)
606 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT8]] to i8
607 ; CHECK-NEXT:    ret i8 [[CONV7]]
609 entry:
610   %conv = sext i8 %a to i32
611   %conv1 = sext i16 %b to i32
612   %add = add i32 %conv1, %conv
613   %0 = icmp slt i32 %add, 127
614   %spec.store.select = select i1 %0, i32 %add, i32 127
615   %1 = icmp sgt i32 %spec.store.select, -128
616   %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128
617   %conv7 = trunc i32 %spec.store.select8 to i8
618   ret i8 %conv7
621 define i32 @sadd_sat32_zext(i32 %a, i32 %b) {
622 ; CHECK-LABEL: @sadd_sat32_zext(
623 ; CHECK-NEXT:  entry:
624 ; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[A:%.*]] to i64
625 ; CHECK-NEXT:    [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64
626 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]]
627 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.umin.i64(i64 [[ADD]], i64 2147483647)
628 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nuw nsw i64 [[SPEC_STORE_SELECT]] to i32
629 ; CHECK-NEXT:    ret i32 [[CONV7]]
631 entry:
632   %conv = zext i32 %a to i64
633   %conv1 = zext i32 %b to i64
634   %add = add i64 %conv1, %conv
635   %0 = icmp slt i64 %add, 2147483647
636   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
637   %1 = icmp sgt i64 %spec.store.select, -2147483648
638   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
639   %conv7 = trunc i64 %spec.store.select8 to i32
640   ret i32 %conv7
643 define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) {
644 ; CHECK-LABEL: @sadd_sat32_maxmin(
645 ; CHECK-NEXT:  entry:
646 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
647 ; CHECK-NEXT:    ret i32 [[TMP0]]
649 entry:
650   %conv = sext i32 %a to i64
651   %conv1 = sext i32 %b to i64
652   %add = add i64 %conv1, %conv
653   %0 = icmp sgt i64 %add, -2147483648
654   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
655   %1 = icmp slt i64 %spec.store.select, 2147483647
656   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
657   %conv7 = trunc i64 %spec.store.select8 to i32
658   ret i32 %conv7
661 define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) {
662 ; CHECK-LABEL: @sadd_sat32_notrunc(
663 ; CHECK-NEXT:  entry:
664 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
665 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
666 ; CHECK-NEXT:    ret i64 [[SPEC_STORE_SELECT8]]
668 entry:
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   ret i64 %spec.store.select8
679 define i32 @ashrA(i64 %a, i32 %b) {
680 ; CHECK-LABEL: @ashrA(
681 ; CHECK-NEXT:  entry:
682 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[A:%.*]], 32
683 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[TMP0]] to i32
684 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP1]], i32 [[B:%.*]])
685 ; CHECK-NEXT:    ret i32 [[TMP2]]
687 entry:
688   %conv = ashr i64 %a, 32
689   %conv1 = sext i32 %b to i64
690   %add = add i64 %conv1, %conv
691   %spec.store.select = call i64 @llvm.smin.i64(i64 %add, i64 2147483647)
692   %spec.store.select8 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
693   %conv7 = trunc i64 %spec.store.select8 to i32
694   ret i32 %conv7
697 define i32 @ashrB(i32 %a, i64 %b) {
698 ; CHECK-LABEL: @ashrB(
699 ; CHECK-NEXT:  entry:
700 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[B:%.*]], 32
701 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[TMP0]] to i32
702 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP1]], i32 [[A:%.*]])
703 ; CHECK-NEXT:    ret i32 [[TMP2]]
705 entry:
706   %conv = sext i32 %a to i64
707   %conv1 = ashr i64 %b, 32
708   %add = add i64 %conv1, %conv
709   %0 = icmp sgt i64 %add, -2147483648
710   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
711   %1 = icmp slt i64 %spec.store.select, 2147483647
712   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
713   %conv7 = trunc i64 %spec.store.select8 to i32
714   ret i32 %conv7
717 define i32 @ashrAB(i64 %a, i64 %b) {
718 ; CHECK-LABEL: @ashrAB(
719 ; CHECK-NEXT:  entry:
720 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[A:%.*]], 32
721 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[B:%.*]], 32
722 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32
723 ; CHECK-NEXT:    [[TMP3:%.*]] = trunc nuw i64 [[TMP0]] to i32
724 ; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP2]], i32 [[TMP3]])
725 ; CHECK-NEXT:    ret i32 [[TMP4]]
727 entry:
728   %conv = ashr i64 %a, 32
729   %conv1 = ashr i64 %b, 32
730   %add = add i64 %conv1, %conv
731   %0 = icmp sgt i64 %add, -2147483648
732   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
733   %1 = icmp slt i64 %spec.store.select, 2147483647
734   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
735   %conv7 = trunc i64 %spec.store.select8 to i32
736   ret i32 %conv7
739 define i32 @ashrA31(i64 %a, i32 %b) {
740 ; CHECK-LABEL: @ashrA31(
741 ; CHECK-NEXT:  entry:
742 ; CHECK-NEXT:    [[CONV:%.*]] = ashr i64 [[A:%.*]], 31
743 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
744 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV]], [[CONV1]]
745 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648)
746 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[SPEC_STORE_SELECT]], i64 2147483647)
747 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
748 ; CHECK-NEXT:    ret i32 [[CONV7]]
750 entry:
751   %conv = ashr i64 %a, 31
752   %conv1 = sext i32 %b to i64
753   %add = add i64 %conv1, %conv
754   %0 = icmp sgt i64 %add, -2147483648
755   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
756   %1 = icmp slt i64 %spec.store.select, 2147483647
757   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
758   %conv7 = trunc i64 %spec.store.select8 to i32
759   ret i32 %conv7
762 define i32 @ashrA33(i64 %a, i32 %b) {
763 ; CHECK-LABEL: @ashrA33(
764 ; CHECK-NEXT:  entry:
765 ; CHECK-NEXT:    [[CONV:%.*]] = ashr i64 [[A:%.*]], 33
766 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nsw i64 [[CONV]] to i32
767 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[B:%.*]])
768 ; CHECK-NEXT:    ret i32 [[TMP1]]
770 entry:
771   %conv = ashr i64 %a, 33
772   %conv1 = sext i32 %b to i64
773   %add = add i64 %conv1, %conv
774   %0 = icmp sgt i64 %add, -2147483648
775   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
776   %1 = icmp slt i64 %spec.store.select, 2147483647
777   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
778   %conv7 = trunc i64 %spec.store.select8 to i32
779   ret i32 %conv7
782 define <2 x i8> @ashrv2i8(<2 x i16> %a, <2 x i8> %b) {
783 ; CHECK-LABEL: @ashrv2i8(
784 ; CHECK-NEXT:  entry:
785 ; CHECK-NEXT:    [[CONV:%.*]] = ashr <2 x i16> [[A:%.*]], <i16 8, i16 12>
786 ; CHECK-NEXT:    [[CONV1:%.*]] = sext <2 x i8> [[B:%.*]] to <2 x i16>
787 ; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i16> [[CONV]], [[CONV1]]
788 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[ADD]], <2 x i16> <i16 -128, i16 -128>)
789 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[SPEC_STORE_SELECT]], <2 x i16> <i16 127, i16 127>)
790 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc nsw <2 x i16> [[SPEC_STORE_SELECT8]] to <2 x i8>
791 ; CHECK-NEXT:    ret <2 x i8> [[CONV7]]
793 entry:
794   %conv = ashr <2 x i16> %a, <i16 8, i16 12>
795   %conv1 = sext <2 x i8> %b to <2 x i16>
796   %add = add <2 x i16> %conv1, %conv
797   %0 = icmp sgt <2 x i16> %add, <i16 -128, i16 -128>
798   %spec.store.select = select <2 x i1> %0, <2 x i16> %add, <2 x i16> <i16 -128, i16 -128>
799   %1 = icmp slt <2 x i16> %spec.store.select, <i16 127, i16 127>
800   %spec.store.select8 = select <2 x i1> %1, <2 x i16> %spec.store.select, <2 x i16> <i16 127, i16 127>
801   %conv7 = trunc <2 x i16> %spec.store.select8 to <2 x i8>
802   ret <2 x i8> %conv7
805 define <2 x i8> @ashrv2i8_s(<2 x i16> %a, <2 x i8> %b) {
806 ; CHECK-LABEL: @ashrv2i8_s(
807 ; CHECK-NEXT:  entry:
808 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 8, i16 8>
809 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw <2 x i16> [[TMP0]] to <2 x i8>
810 ; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[TMP1]], <2 x i8> [[B:%.*]])
811 ; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
813 entry:
814   %conv = ashr <2 x i16> %a, <i16 8, i16 8>
815   %conv1 = sext <2 x i8> %b to <2 x i16>
816   %add = add <2 x i16> %conv1, %conv
817   %0 = icmp sgt <2 x i16> %add, <i16 -128, i16 -128>
818   %spec.store.select = select <2 x i1> %0, <2 x i16> %add, <2 x i16> <i16 -128, i16 -128>
819   %1 = icmp slt <2 x i16> %spec.store.select, <i16 127, i16 127>
820   %spec.store.select8 = select <2 x i1> %1, <2 x i16> %spec.store.select, <2 x i16> <i16 127, i16 127>
821   %conv7 = trunc <2 x i16> %spec.store.select8 to <2 x i8>
822   ret <2 x i8> %conv7
825 define i16 @or(i8 %X, i16 %Y) {
826 ; CHECK-LABEL: @or(
827 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8
828 ; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[TMP1]], -16
829 ; CHECK-NEXT:    [[TMP3:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[X:%.*]], i8 [[TMP2]])
830 ; CHECK-NEXT:    [[L12:%.*]] = sext i8 [[TMP3]] to i16
831 ; CHECK-NEXT:    ret i16 [[L12]]
833   %conv10 = sext i8 %X to i16
834   %conv14 = or i16 %Y, 65520
835   %sub = sub nsw i16 %conv10, %conv14
836   %l9 = icmp sgt i16 %sub, -128
837   %l10 = select i1 %l9, i16 %sub, i16 -128
838   %l11 = icmp slt i16 %l10, 127
839   %l12 = select i1 %l11, i16 %l10, i16 127
840   ret i16 %l12
843 define i16 @const(i8 %X) {
844 ; CHECK-LABEL: @const(
845 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 117)
846 ; CHECK-NEXT:    [[NARROW:%.*]] = add nsw i8 [[TMP1]], 10
847 ; CHECK-NEXT:    [[L12:%.*]] = sext i8 [[NARROW]] to i16
848 ; CHECK-NEXT:    ret i16 [[L12]]
850   %conv10 = sext i8 %X to i16
851   %sub = add i16 %conv10, 10
852   %l9 = icmp sgt i16 %sub, -128
853   %l10 = select i1 %l9, i16 %sub, i16 -128
854   %l11 = icmp slt i16 %l10, 127
855   %l12 = select i1 %l11, i16 %l10, i16 127
856   ret i16 %l12
859 declare void @use64(i64)
860 declare i64 @llvm.smin.i64(i64, i64)
861 declare i64 @llvm.smax.i64(i64, i64)
862 declare i32 @llvm.smin.i32(i32, i32)
863 declare i32 @llvm.smax.i32(i32, i32)
864 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
865 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)