[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / sadd_sat.ll
blob04dd4f5c038dc4722e474a7c4f75503270b0eb26
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
6 define i32 @sadd_sat32(i32 %a, i32 %b) {
7 ; CHECK-LABEL: @sadd_sat32(
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 @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]]
30 entry:
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
42 define 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]]
55 entry:
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
67 define 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]]
73 entry:
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
85 define 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]]
91 entry:
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
103 define 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]]
109 entry:
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
121 define 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]]
127 entry:
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
139 define 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]]
145 entry:
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
157 define 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]]
163 entry:
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
175 define 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]]
188 entry:
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
200 define 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]]
213 entry:
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
225 define <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]]
231 entry:
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
243 define <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]]
249 entry:
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
261 define <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]]
271 entry:
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
280 define <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]]
290 entry:
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
300 define 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]]
308 entry:
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
321 define 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]]
335 entry:
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
348 define 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]]
362 entry:
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
375 define 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]]
388 entry:
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
400 define 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]]
407 entry:
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
419 define 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]]
432 entry:
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
444 define 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]]
455 entry:
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
467 define 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]]
473 entry:
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
485 define 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]]
492 entry:
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
503 declare void @use64(i64)