xref: /llvm-project/llvm/test/Transforms/InstCombine/sadd_sat.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
5
6define 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]]
11;
12entry:
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
22}
23
24define 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]]
29;
30entry:
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
38}
39
40define 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]]
45;
46entry:
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
56}
57
58define 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]]
63;
64entry:
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
72}
73
74define 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]]
84;
85entry:
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
95}
96
97define 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]]
107;
108entry:
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
116}
117
118define 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]]
123;
124entry:
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
134}
135
136define 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]]
141;
142entry:
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
150}
151
152define 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]]
157;
158entry:
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
168}
169
170define 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]]
175;
176entry:
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
184}
185
186define 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]]
191;
192entry:
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
202}
203
204define 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]]
209;
210entry:
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
218}
219
220define 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]]
225;
226entry:
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
236}
237
238define 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]]
243;
244entry:
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
252}
253
254define 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]]
259;
260entry:
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
270}
271
272define 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]]
277;
278entry:
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
288}
289
290define 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]]
300;
301entry:
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
311}
312
313define 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]]
323;
324entry:
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
334}
335
336define <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]]
341;
342entry:
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
352}
353
354define <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]]
359;
360entry:
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
368}
369
370define <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]]
375;
376entry:
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
386}
387
388define <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]]
393;
394entry:
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
402}
403
404define <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> splat (i32 15))
409; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16))
410; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
411;
412entry:
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
419}
420
421define <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> splat (i32 15))
426; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16))
427; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
428;
429entry:
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
436}
437
438
439define 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]]
446;
447entry:
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
458}
459
460define 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]]
471;
472entry:
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
483}
484
485define 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]]
496;
497entry:
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
506}
507
508define 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]]
519;
520entry:
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
531}
532
533define 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]]
544;
545entry:
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
554}
555
556define 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]]
566;
567entry:
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
577}
578
579define 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]]
585;
586entry:
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
596}
597
598define 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]]
608;
609entry:
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
619}
620
621define 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]]
630;
631entry:
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
641}
642
643define 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]]
648;
649entry:
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
659}
660
661define 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]]
667;
668entry:
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
677}
678
679define 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]]
686;
687entry:
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
695}
696
697define 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]]
704;
705entry:
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
715}
716
717define 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]]
726;
727entry:
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
737}
738
739define 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]]
749;
750entry:
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
760}
761
762define 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]]
769;
770entry:
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
780}
781
782define <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> splat (i16 -128))
789; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[SPEC_STORE_SELECT]], <2 x i16> splat (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]]
792;
793entry:
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
803}
804
805define <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:%.*]], splat (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]]
812;
813entry:
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
823}
824
825define 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]]
832;
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
841}
842
843define 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]]
849;
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
857}
858
859declare void @use64(i64)
860declare i64 @llvm.smin.i64(i64, i64)
861declare i64 @llvm.smax.i64(i64, i64)
862declare i32 @llvm.smin.i32(i32, i32)
863declare i32 @llvm.smax.i32(i32, i32)
864declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
865declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
866