1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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 @ssub_sat32(i32 %a, i32 %b) {
25; CHECK-LABEL: @ssub_sat32(
26; CHECK-NEXT:  entry:
27; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
28; CHECK-NEXT:    ret i32 [[TMP0]]
29;
30entry:
31  %conv = sext i32 %a to i64
32  %conv1 = sext i32 %b to i64
33  %sub = sub i64 %conv, %conv1
34  %0 = icmp slt i64 %sub, 2147483647
35  %spec.store.select = select i1 %0, i64 %sub, i64 2147483647
36  %1 = icmp sgt i64 %spec.store.select, -2147483648
37  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
38  %conv7 = trunc i64 %spec.store.select8 to i32
39  ret i32 %conv7
40}
41
42define i32 @smul_sat32(i32 %a, i32 %b) {
43; CHECK-LABEL: @smul_sat32(
44; CHECK-NEXT:  entry:
45; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
46; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
47; CHECK-NEXT:    [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
48; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
49; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
50; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
51; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
52; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
53; CHECK-NEXT:    ret i32 [[CONV7]]
54;
55entry:
56  %conv = sext i32 %a to i64
57  %conv1 = sext i32 %b to i64
58  %add = mul i64 %conv1, %conv
59  %0 = icmp slt i64 %add, 2147483647
60  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
61  %1 = icmp sgt i64 %spec.store.select, -2147483648
62  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
63  %conv7 = trunc i64 %spec.store.select8 to i32
64  ret i32 %conv7
65}
66
67define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) {
68; CHECK-LABEL: @sadd_sat16(
69; CHECK-NEXT:  entry:
70; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B:%.*]], i16 [[A:%.*]])
71; CHECK-NEXT:    ret i16 [[TMP0]]
72;
73entry:
74  %conv = sext i16 %a to i32
75  %conv1 = sext i16 %b to i32
76  %add = add i32 %conv1, %conv
77  %0 = icmp slt i32 %add, 32767
78  %spec.store.select = select i1 %0, i32 %add, i32 32767
79  %1 = icmp sgt i32 %spec.store.select, -32768
80  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
81  %conv9 = trunc i32 %spec.store.select10 to i16
82  ret i16 %conv9
83}
84
85define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) {
86; CHECK-LABEL: @ssub_sat16(
87; CHECK-NEXT:  entry:
88; CHECK-NEXT:    [[TMP0:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[A:%.*]], i16 [[B:%.*]])
89; CHECK-NEXT:    ret i16 [[TMP0]]
90;
91entry:
92  %conv = sext i16 %a to i32
93  %conv1 = sext i16 %b to i32
94  %sub = sub i32 %conv, %conv1
95  %0 = icmp slt i32 %sub, 32767
96  %spec.store.select = select i1 %0, i32 %sub, i32 32767
97  %1 = icmp sgt i32 %spec.store.select, -32768
98  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
99  %conv9 = trunc i32 %spec.store.select10 to i16
100  ret i16 %conv9
101}
102
103define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) {
104; CHECK-LABEL: @sadd_sat8(
105; CHECK-NEXT:  entry:
106; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B:%.*]], i8 [[A:%.*]])
107; CHECK-NEXT:    ret i8 [[TMP0]]
108;
109entry:
110  %conv = sext i8 %a to i32
111  %conv1 = sext i8 %b to i32
112  %add = add i32 %conv1, %conv
113  %0 = icmp slt i32 %add, 127
114  %spec.store.select = select i1 %0, i32 %add, i32 127
115  %1 = icmp sgt i32 %spec.store.select, -128
116  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
117  %conv9 = trunc i32 %spec.store.select10 to i8
118  ret i8 %conv9
119}
120
121define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) {
122; CHECK-LABEL: @ssub_sat8(
123; CHECK-NEXT:  entry:
124; CHECK-NEXT:    [[TMP0:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[A:%.*]], i8 [[B:%.*]])
125; CHECK-NEXT:    ret i8 [[TMP0]]
126;
127entry:
128  %conv = sext i8 %a to i32
129  %conv1 = sext i8 %b to i32
130  %sub = sub i32 %conv, %conv1
131  %0 = icmp slt i32 %sub, 127
132  %spec.store.select = select i1 %0, i32 %sub, i32 127
133  %1 = icmp sgt i32 %spec.store.select, -128
134  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
135  %conv9 = trunc i32 %spec.store.select10 to i8
136  ret i8 %conv9
137}
138
139define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) {
140; CHECK-LABEL: @sadd_sat64(
141; CHECK-NEXT:  entry:
142; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.sadd.sat.i64(i64 [[B:%.*]], i64 [[A:%.*]])
143; CHECK-NEXT:    ret i64 [[TMP0]]
144;
145entry:
146  %conv = sext i64 %a to i65
147  %conv1 = sext i64 %b to i65
148  %add = add i65 %conv1, %conv
149  %0 = icmp slt i65 %add, 9223372036854775807
150  %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807
151  %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
152  %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
153  %conv9 = trunc i65 %spec.store.select10 to i64
154  ret i64 %conv9
155}
156
157define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) {
158; CHECK-LABEL: @ssub_sat64(
159; CHECK-NEXT:  entry:
160; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ssub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
161; CHECK-NEXT:    ret i64 [[TMP0]]
162;
163entry:
164  %conv = sext i64 %a to i65
165  %conv1 = sext i64 %b to i65
166  %sub = sub i65 %conv, %conv1
167  %0 = icmp slt i65 %sub, 9223372036854775807
168  %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807
169  %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
170  %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
171  %conv9 = trunc i65 %spec.store.select10 to i64
172  ret i64 %conv9
173}
174
175define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) {
176; CHECK-LABEL: @sadd_sat4(
177; CHECK-NEXT:  entry:
178; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
179; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
180; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
181; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 7
182; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 7
183; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
184; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
185; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
186; CHECK-NEXT:    ret i4 [[CONV9]]
187;
188entry:
189  %conv = sext i4 %a to i32
190  %conv1 = sext i4 %b to i32
191  %add = add i32 %conv1, %conv
192  %0 = icmp slt i32 %add, 7
193  %spec.store.select = select i1 %0, i32 %add, i32 7
194  %1 = icmp sgt i32 %spec.store.select, -8
195  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
196  %conv9 = trunc i32 %spec.store.select10 to i4
197  ret i4 %conv9
198}
199
200define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) {
201; CHECK-LABEL: @ssub_sat4(
202; CHECK-NEXT:  entry:
203; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
204; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
205; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
206; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[SUB]], 7
207; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 7
208; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
209; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
210; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
211; CHECK-NEXT:    ret i4 [[CONV9]]
212;
213entry:
214  %conv = sext i4 %a to i32
215  %conv1 = sext i4 %b to i32
216  %sub = sub i32 %conv, %conv1
217  %0 = icmp slt i32 %sub, 7
218  %spec.store.select = select i1 %0, i32 %sub, i32 7
219  %1 = icmp sgt i32 %spec.store.select, -8
220  %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
221  %conv9 = trunc i32 %spec.store.select10 to i4
222  ret i4 %conv9
223}
224
225define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) {
226; CHECK-LABEL: @sadd_satv4i32(
227; CHECK-NEXT:  entry:
228; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
229; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
230;
231entry:
232  %conv = sext <4 x i32> %a to <4 x i64>
233  %conv1 = sext <4 x i32> %b to <4 x i64>
234  %add = add <4 x i64> %conv1, %conv
235  %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
236  %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
237  %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
238  %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>
239  %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
240  ret <4 x i32> %conv7
241}
242
243define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) {
244; CHECK-LABEL: @ssub_satv4i32(
245; CHECK-NEXT:  entry:
246; CHECK-NEXT:    [[TMP0:%.*]] = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> [[B:%.*]], <4 x i32> [[A:%.*]])
247; CHECK-NEXT:    ret <4 x i32> [[TMP0]]
248;
249entry:
250  %conv = sext <4 x i32> %a to <4 x i64>
251  %conv1 = sext <4 x i32> %b to <4 x i64>
252  %add = sub <4 x i64> %conv1, %conv
253  %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
254  %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
255  %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
256  %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>
257  %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
258  ret <4 x i32> %conv7
259}
260
261define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
262; CHECK-LABEL: @sadd_satv4i4(
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]]
265; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
266; 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>
267; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
268; 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>
269; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
270;
271entry:
272  %add = add <4 x i32> %a, %b
273  %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
274  %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
275  %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
276  %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>
277  ret <4 x i32> %spec.store.select8
278}
279
280define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) {
281; CHECK-LABEL: @ssub_satv4i4(
282; CHECK-NEXT:  entry:
283; CHECK-NEXT:    [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]]
284; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
285; 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>
286; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
287; 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>
288; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
289;
290entry:
291  %add = sub <4 x i32> %a, %b
292  %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
293  %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
294  %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
295  %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>
296  ret <4 x i32> %spec.store.select8
297}
298
299
300define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) {
301; CHECK-LABEL: @sadd_sat32_extrause_1(
302; CHECK-NEXT:  entry:
303; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
304; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
305; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT8]])
306; CHECK-NEXT:    ret i32 [[TMP0]]
307;
308entry:
309  %conv = sext i32 %a to i64
310  %conv1 = sext i32 %b to i64
311  %add = add i64 %conv1, %conv
312  %0 = icmp slt i64 %add, 2147483647
313  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
314  %1 = icmp sgt i64 %spec.store.select, -2147483648
315  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
316  %conv7 = trunc i64 %spec.store.select8 to i32
317  call void @use64(i64 %spec.store.select8)
318  ret i32 %conv7
319}
320
321define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) {
322; CHECK-LABEL: @sadd_sat32_extrause_2(
323; CHECK-NEXT:  entry:
324; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
325; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
326; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
327; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
328; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
329; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
330; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
331; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
332; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT]])
333; CHECK-NEXT:    ret i32 [[CONV7]]
334;
335entry:
336  %conv = sext i32 %a to i64
337  %conv1 = sext i32 %b to i64
338  %add = add i64 %conv1, %conv
339  %0 = icmp slt i64 %add, 2147483647
340  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
341  %1 = icmp sgt i64 %spec.store.select, -2147483648
342  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
343  %conv7 = trunc i64 %spec.store.select8 to i32
344  call void @use64(i64 %spec.store.select)
345  ret i32 %conv7
346}
347
348define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) {
349; CHECK-LABEL: @sadd_sat32_extrause_3(
350; CHECK-NEXT:  entry:
351; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
352; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
353; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
354; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
355; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
356; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
357; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
358; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
359; CHECK-NEXT:    call void @use64(i64 [[ADD]])
360; CHECK-NEXT:    ret i32 [[CONV7]]
361;
362entry:
363  %conv = sext i32 %a to i64
364  %conv1 = sext i32 %b to i64
365  %add = add i64 %conv1, %conv
366  %0 = icmp slt i64 %add, 2147483647
367  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
368  %1 = icmp sgt i64 %spec.store.select, -2147483648
369  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
370  %conv7 = trunc i64 %spec.store.select8 to i32
371  call void @use64(i64 %add)
372  ret i32 %conv7
373}
374
375define i32 @sadd_sat32_trunc(i32 %a, i32 %b) {
376; CHECK-LABEL: @sadd_sat32_trunc(
377; CHECK-NEXT:  entry:
378; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
379; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
380; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
381; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 32767
382; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 32767
383; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -32768
384; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -32768
385; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
386; CHECK-NEXT:    ret i32 [[CONV7]]
387;
388entry:
389  %conv = sext i32 %a to i64
390  %conv1 = sext i32 %b to i64
391  %add = add i64 %conv1, %conv
392  %0 = icmp slt i64 %add, 32767
393  %spec.store.select = select i1 %0, i64 %add, i64 32767
394  %1 = icmp sgt i64 %spec.store.select, -32768
395  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768
396  %conv7 = trunc i64 %spec.store.select8 to i32
397  ret i32 %conv7
398}
399
400define i32 @sadd_sat32_ext16(i32 %a, i16 %b) {
401; CHECK-LABEL: @sadd_sat32_ext16(
402; CHECK-NEXT:  entry:
403; CHECK-NEXT:    [[TMP0:%.*]] = sext i16 [[B:%.*]] to i32
404; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 [[A:%.*]])
405; CHECK-NEXT:    ret i32 [[TMP1]]
406;
407entry:
408  %conv = sext i32 %a to i64
409  %conv1 = sext i16 %b to i64
410  %add = add i64 %conv1, %conv
411  %0 = icmp slt i64 %add, 2147483647
412  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
413  %1 = icmp sgt i64 %spec.store.select, -2147483648
414  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
415  %conv7 = trunc i64 %spec.store.select8 to i32
416  ret i32 %conv7
417}
418
419define i8 @sadd_sat8_ext8(i8 %a, i16 %b) {
420; CHECK-LABEL: @sadd_sat8_ext8(
421; CHECK-NEXT:  entry:
422; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
423; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
424; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
425; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 127
426; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 127
427; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128
428; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128
429; CHECK-NEXT:    [[CONV7:%.*]] = trunc i32 [[SPEC_STORE_SELECT8]] to i8
430; CHECK-NEXT:    ret i8 [[CONV7]]
431;
432entry:
433  %conv = sext i8 %a to i32
434  %conv1 = sext i16 %b to i32
435  %add = add i32 %conv1, %conv
436  %0 = icmp slt i32 %add, 127
437  %spec.store.select = select i1 %0, i32 %add, i32 127
438  %1 = icmp sgt i32 %spec.store.select, -128
439  %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128
440  %conv7 = trunc i32 %spec.store.select8 to i8
441  ret i8 %conv7
442}
443
444define i32 @sadd_sat32_zext(i32 %a, i32 %b) {
445; CHECK-LABEL: @sadd_sat32_zext(
446; CHECK-NEXT:  entry:
447; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[A:%.*]] to i64
448; CHECK-NEXT:    [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64
449; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]]
450; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[ADD]], 2147483647
451; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
452; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT]] to i32
453; CHECK-NEXT:    ret i32 [[CONV7]]
454;
455entry:
456  %conv = zext i32 %a to i64
457  %conv1 = zext i32 %b to i64
458  %add = add i64 %conv1, %conv
459  %0 = icmp slt i64 %add, 2147483647
460  %spec.store.select = select i1 %0, i64 %add, i64 2147483647
461  %1 = icmp sgt i64 %spec.store.select, -2147483648
462  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
463  %conv7 = trunc i64 %spec.store.select8 to i32
464  ret i32 %conv7
465}
466
467define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) {
468; CHECK-LABEL: @sadd_sat32_maxmin(
469; CHECK-NEXT:  entry:
470; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
471; CHECK-NEXT:    ret i32 [[TMP0]]
472;
473entry:
474  %conv = sext i32 %a to i64
475  %conv1 = sext i32 %b to i64
476  %add = add i64 %conv1, %conv
477  %0 = icmp sgt i64 %add, -2147483648
478  %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
479  %1 = icmp slt i64 %spec.store.select, 2147483647
480  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
481  %conv7 = trunc i64 %spec.store.select8 to i32
482  ret i32 %conv7
483}
484
485define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) {
486; CHECK-LABEL: @sadd_sat32_notrunc(
487; CHECK-NEXT:  entry:
488; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[B:%.*]], i32 [[A:%.*]])
489; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = sext i32 [[TMP0]] to i64
490; CHECK-NEXT:    ret i64 [[SPEC_STORE_SELECT8]]
491;
492entry:
493  %conv = sext i32 %a to i64
494  %conv1 = sext i32 %b to i64
495  %add = add i64 %conv1, %conv
496  %0 = icmp sgt i64 %add, -2147483648
497  %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
498  %1 = icmp slt i64 %spec.store.select, 2147483647
499  %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
500  ret i64 %spec.store.select8
501}
502
503declare void @use64(i64)
504