[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / InstCombine / sadd_sat.ll
blobc3aba403737b8e3d4b5703a21753fb095a4890f0
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:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
10 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
11 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
12 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
13 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
14 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
15 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
16 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
17 ; CHECK-NEXT:    ret i32 [[CONV7]]
19 entry:
20   %conv = sext i32 %a to i64
21   %conv1 = sext i32 %b to i64
22   %add = add i64 %conv1, %conv
23   %0 = icmp slt i64 %add, 2147483647
24   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
25   %1 = icmp sgt i64 %spec.store.select, -2147483648
26   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
27   %conv7 = trunc i64 %spec.store.select8 to i32
28   ret i32 %conv7
31 define i32 @ssub_sat32(i32 %a, i32 %b) {
32 ; CHECK-LABEL: @ssub_sat32(
33 ; CHECK-NEXT:  entry:
34 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
35 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
36 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i64 [[CONV]], [[CONV1]]
37 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[SUB]], 2147483647
38 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[SUB]], i64 2147483647
39 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
40 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
41 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
42 ; CHECK-NEXT:    ret i32 [[CONV7]]
44 entry:
45   %conv = sext i32 %a to i64
46   %conv1 = sext i32 %b to i64
47   %sub = sub i64 %conv, %conv1
48   %0 = icmp slt i64 %sub, 2147483647
49   %spec.store.select = select i1 %0, i64 %sub, i64 2147483647
50   %1 = icmp sgt i64 %spec.store.select, -2147483648
51   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
52   %conv7 = trunc i64 %spec.store.select8 to i32
53   ret i32 %conv7
56 define i32 @smul_sat32(i32 %a, i32 %b) {
57 ; CHECK-LABEL: @smul_sat32(
58 ; CHECK-NEXT:  entry:
59 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
60 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
61 ; CHECK-NEXT:    [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
62 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
63 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
64 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
65 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
66 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
67 ; CHECK-NEXT:    ret i32 [[CONV7]]
69 entry:
70   %conv = sext i32 %a to i64
71   %conv1 = sext i32 %b to i64
72   %add = mul i64 %conv1, %conv
73   %0 = icmp slt i64 %add, 2147483647
74   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
75   %1 = icmp sgt i64 %spec.store.select, -2147483648
76   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
77   %conv7 = trunc i64 %spec.store.select8 to i32
78   ret i32 %conv7
81 define signext i16 @sadd_sat16(i16 signext %a, i16 signext %b) {
82 ; CHECK-LABEL: @sadd_sat16(
83 ; CHECK-NEXT:  entry:
84 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[A:%.*]] to i32
85 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
86 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
87 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 32767
88 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 32767
89 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -32768
90 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -32768
91 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i16
92 ; CHECK-NEXT:    ret i16 [[CONV9]]
94 entry:
95   %conv = sext i16 %a to i32
96   %conv1 = sext i16 %b to i32
97   %add = add i32 %conv1, %conv
98   %0 = icmp slt i32 %add, 32767
99   %spec.store.select = select i1 %0, i32 %add, i32 32767
100   %1 = icmp sgt i32 %spec.store.select, -32768
101   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
102   %conv9 = trunc i32 %spec.store.select10 to i16
103   ret i16 %conv9
106 define signext i16 @ssub_sat16(i16 signext %a, i16 signext %b) {
107 ; CHECK-LABEL: @ssub_sat16(
108 ; CHECK-NEXT:  entry:
109 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[A:%.*]] to i32
110 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
111 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
112 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[SUB]], 32767
113 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 32767
114 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -32768
115 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -32768
116 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i16
117 ; CHECK-NEXT:    ret i16 [[CONV9]]
119 entry:
120   %conv = sext i16 %a to i32
121   %conv1 = sext i16 %b to i32
122   %sub = sub i32 %conv, %conv1
123   %0 = icmp slt i32 %sub, 32767
124   %spec.store.select = select i1 %0, i32 %sub, i32 32767
125   %1 = icmp sgt i32 %spec.store.select, -32768
126   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -32768
127   %conv9 = trunc i32 %spec.store.select10 to i16
128   ret i16 %conv9
131 define signext i8 @sadd_sat8(i8 signext %a, i8 signext %b) {
132 ; CHECK-LABEL: @sadd_sat8(
133 ; CHECK-NEXT:  entry:
134 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
135 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32
136 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
137 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 127
138 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 127
139 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128
140 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128
141 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i8
142 ; CHECK-NEXT:    ret i8 [[CONV9]]
144 entry:
145   %conv = sext i8 %a to i32
146   %conv1 = sext i8 %b to i32
147   %add = add i32 %conv1, %conv
148   %0 = icmp slt i32 %add, 127
149   %spec.store.select = select i1 %0, i32 %add, i32 127
150   %1 = icmp sgt i32 %spec.store.select, -128
151   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
152   %conv9 = trunc i32 %spec.store.select10 to i8
153   ret i8 %conv9
156 define signext i8 @ssub_sat8(i8 signext %a, i8 signext %b) {
157 ; CHECK-LABEL: @ssub_sat8(
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
160 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i8 [[B:%.*]] to i32
161 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
162 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[SUB]], 127
163 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 127
164 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128
165 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128
166 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i8
167 ; CHECK-NEXT:    ret i8 [[CONV9]]
169 entry:
170   %conv = sext i8 %a to i32
171   %conv1 = sext i8 %b to i32
172   %sub = sub i32 %conv, %conv1
173   %0 = icmp slt i32 %sub, 127
174   %spec.store.select = select i1 %0, i32 %sub, i32 127
175   %1 = icmp sgt i32 %spec.store.select, -128
176   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -128
177   %conv9 = trunc i32 %spec.store.select10 to i8
178   ret i8 %conv9
181 define signext i64 @sadd_sat64(i64 signext %a, i64 signext %b) {
182 ; CHECK-LABEL: @sadd_sat64(
183 ; CHECK-NEXT:  entry:
184 ; CHECK-NEXT:    [[CONV:%.*]] = sext i64 [[A:%.*]] to i65
185 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i64 [[B:%.*]] to i65
186 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i65 [[CONV1]], [[CONV]]
187 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i65 [[ADD]], 9223372036854775807
188 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i65 [[ADD]], i65 9223372036854775807
189 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i65 [[SPEC_STORE_SELECT]], -9223372036854775808
190 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i65 [[SPEC_STORE_SELECT]], i65 -9223372036854775808
191 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i65 [[SPEC_STORE_SELECT10]] to i64
192 ; CHECK-NEXT:    ret i64 [[CONV9]]
194 entry:
195   %conv = sext i64 %a to i65
196   %conv1 = sext i64 %b to i65
197   %add = add i65 %conv1, %conv
198   %0 = icmp slt i65 %add, 9223372036854775807
199   %spec.store.select = select i1 %0, i65 %add, i65 9223372036854775807
200   %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
201   %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
202   %conv9 = trunc i65 %spec.store.select10 to i64
203   ret i64 %conv9
206 define signext i64 @ssub_sat64(i64 signext %a, i64 signext %b) {
207 ; CHECK-LABEL: @ssub_sat64(
208 ; CHECK-NEXT:  entry:
209 ; CHECK-NEXT:    [[CONV:%.*]] = sext i64 [[A:%.*]] to i65
210 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i64 [[B:%.*]] to i65
211 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i65 [[CONV]], [[CONV1]]
212 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i65 [[SUB]], 9223372036854775807
213 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i65 [[SUB]], i65 9223372036854775807
214 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i65 [[SPEC_STORE_SELECT]], -9223372036854775808
215 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i65 [[SPEC_STORE_SELECT]], i65 -9223372036854775808
216 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i65 [[SPEC_STORE_SELECT10]] to i64
217 ; CHECK-NEXT:    ret i64 [[CONV9]]
219 entry:
220   %conv = sext i64 %a to i65
221   %conv1 = sext i64 %b to i65
222   %sub = sub i65 %conv, %conv1
223   %0 = icmp slt i65 %sub, 9223372036854775807
224   %spec.store.select = select i1 %0, i65 %sub, i65 9223372036854775807
225   %1 = icmp sgt i65 %spec.store.select, -9223372036854775808
226   %spec.store.select10 = select i1 %1, i65 %spec.store.select, i65 -9223372036854775808
227   %conv9 = trunc i65 %spec.store.select10 to i64
228   ret i64 %conv9
231 define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) {
232 ; CHECK-LABEL: @sadd_sat4(
233 ; CHECK-NEXT:  entry:
234 ; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
235 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
236 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
237 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 7
238 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 7
239 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
240 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
241 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
242 ; CHECK-NEXT:    ret i4 [[CONV9]]
244 entry:
245   %conv = sext i4 %a to i32
246   %conv1 = sext i4 %b to i32
247   %add = add i32 %conv1, %conv
248   %0 = icmp slt i32 %add, 7
249   %spec.store.select = select i1 %0, i32 %add, i32 7
250   %1 = icmp sgt i32 %spec.store.select, -8
251   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
252   %conv9 = trunc i32 %spec.store.select10 to i4
253   ret i4 %conv9
256 define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) {
257 ; CHECK-LABEL: @ssub_sat4(
258 ; CHECK-NEXT:  entry:
259 ; CHECK-NEXT:    [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
260 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
261 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
262 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[SUB]], 7
263 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[SUB]], i32 7
264 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -8
265 ; CHECK-NEXT:    [[SPEC_STORE_SELECT10:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -8
266 ; CHECK-NEXT:    [[CONV9:%.*]] = trunc i32 [[SPEC_STORE_SELECT10]] to i4
267 ; CHECK-NEXT:    ret i4 [[CONV9]]
269 entry:
270   %conv = sext i4 %a to i32
271   %conv1 = sext i4 %b to i32
272   %sub = sub i32 %conv, %conv1
273   %0 = icmp slt i32 %sub, 7
274   %spec.store.select = select i1 %0, i32 %sub, i32 7
275   %1 = icmp sgt i32 %spec.store.select, -8
276   %spec.store.select10 = select i1 %1, i32 %spec.store.select, i32 -8
277   %conv9 = trunc i32 %spec.store.select10 to i4
278   ret i4 %conv9
281 define <4 x i32> @sadd_satv4i32(<4 x i32> %a, <4 x i32> %b) {
282 ; CHECK-LABEL: @sadd_satv4i32(
283 ; CHECK-NEXT:  entry:
284 ; CHECK-NEXT:    [[CONV:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64>
285 ; CHECK-NEXT:    [[CONV1:%.*]] = sext <4 x i32> [[B:%.*]] to <4 x i64>
286 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw <4 x i64> [[CONV1]], [[CONV]]
287 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i64> [[ADD]], <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
288 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[ADD]], <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
289 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i64> [[SPEC_STORE_SELECT]], <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
290 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i64> [[SPEC_STORE_SELECT]], <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
291 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc <4 x i64> [[SPEC_STORE_SELECT8]] to <4 x i32>
292 ; CHECK-NEXT:    ret <4 x i32> [[CONV7]]
294 entry:
295   %conv = sext <4 x i32> %a to <4 x i64>
296   %conv1 = sext <4 x i32> %b to <4 x i64>
297   %add = add <4 x i64> %conv1, %conv
298   %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
299   %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
300   %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
301   %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>
302   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
303   ret <4 x i32> %conv7
306 define <4 x i32> @ssub_satv4i32(<4 x i32> %a, <4 x i32> %b) {
307 ; CHECK-LABEL: @ssub_satv4i32(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    [[CONV:%.*]] = sext <4 x i32> [[A:%.*]] to <4 x i64>
310 ; CHECK-NEXT:    [[CONV1:%.*]] = sext <4 x i32> [[B:%.*]] to <4 x i64>
311 ; CHECK-NEXT:    [[ADD:%.*]] = sub nsw <4 x i64> [[CONV1]], [[CONV]]
312 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i64> [[ADD]], <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
313 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[ADD]], <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
314 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i64> [[SPEC_STORE_SELECT]], <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
315 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select <4 x i1> [[TMP1]], <4 x i64> [[SPEC_STORE_SELECT]], <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
316 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc <4 x i64> [[SPEC_STORE_SELECT8]] to <4 x i32>
317 ; CHECK-NEXT:    ret <4 x i32> [[CONV7]]
319 entry:
320   %conv = sext <4 x i32> %a to <4 x i64>
321   %conv1 = sext <4 x i32> %b to <4 x i64>
322   %add = sub <4 x i64> %conv1, %conv
323   %0 = icmp slt <4 x i64> %add, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
324   %spec.store.select = select <4 x i1> %0, <4 x i64> %add, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
325   %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
326   %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>
327   %conv7 = trunc <4 x i64> %spec.store.select8 to <4 x i32>
328   ret <4 x i32> %conv7
331 define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
332 ; CHECK-LABEL: @sadd_satv4i4(
333 ; CHECK-NEXT:  entry:
334 ; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]]
335 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
336 ; 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>
337 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
338 ; 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>
339 ; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
341 entry:
342   %add = add <4 x i32> %a, %b
343   %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
344   %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
345   %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
346   %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>
347   ret <4 x i32> %spec.store.select8
350 define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) {
351 ; CHECK-LABEL: @ssub_satv4i4(
352 ; CHECK-NEXT:  entry:
353 ; CHECK-NEXT:    [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]]
354 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt <4 x i32> [[ADD]], <i32 15, i32 15, i32 15, i32 15>
355 ; 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>
356 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i32> [[SPEC_STORE_SELECT]], <i32 -16, i32 -16, i32 -16, i32 -16>
357 ; 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>
358 ; CHECK-NEXT:    ret <4 x i32> [[SPEC_STORE_SELECT8]]
360 entry:
361   %add = sub <4 x i32> %a, %b
362   %0 = icmp slt <4 x i32> %add, <i32 15, i32 15, i32 15, i32 15>
363   %spec.store.select = select <4 x i1> %0, <4 x i32> %add, <4 x i32> <i32 15, i32 15, i32 15, i32 15>
364   %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -16, i32 -16, i32 -16, i32 -16>
365   %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>
366   ret <4 x i32> %spec.store.select8
370 define i32 @sadd_sat32_extrause_1(i32 %a, i32 %b) {
371 ; CHECK-LABEL: @sadd_sat32_extrause_1(
372 ; CHECK-NEXT:  entry:
373 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
374 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
375 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
376 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
377 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
378 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
379 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
380 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
381 ; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT8]])
382 ; CHECK-NEXT:    ret i32 [[CONV7]]
384 entry:
385   %conv = sext i32 %a to i64
386   %conv1 = sext i32 %b to i64
387   %add = add i64 %conv1, %conv
388   %0 = icmp slt i64 %add, 2147483647
389   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
390   %1 = icmp sgt i64 %spec.store.select, -2147483648
391   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
392   %conv7 = trunc i64 %spec.store.select8 to i32
393   call void @use64(i64 %spec.store.select8)
394   ret i32 %conv7
397 define i32 @sadd_sat32_extrause_2(i32 %a, i32 %b) {
398 ; CHECK-LABEL: @sadd_sat32_extrause_2(
399 ; CHECK-NEXT:  entry:
400 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
401 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
402 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
403 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
404 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
405 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
406 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
407 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
408 ; CHECK-NEXT:    call void @use64(i64 [[SPEC_STORE_SELECT]])
409 ; CHECK-NEXT:    ret i32 [[CONV7]]
411 entry:
412   %conv = sext i32 %a to i64
413   %conv1 = sext i32 %b to i64
414   %add = add i64 %conv1, %conv
415   %0 = icmp slt i64 %add, 2147483647
416   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
417   %1 = icmp sgt i64 %spec.store.select, -2147483648
418   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
419   %conv7 = trunc i64 %spec.store.select8 to i32
420   call void @use64(i64 %spec.store.select)
421   ret i32 %conv7
424 define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) {
425 ; CHECK-LABEL: @sadd_sat32_extrause_3(
426 ; CHECK-NEXT:  entry:
427 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
428 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
429 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
430 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
431 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
432 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
433 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
434 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
435 ; CHECK-NEXT:    call void @use64(i64 [[ADD]])
436 ; CHECK-NEXT:    ret i32 [[CONV7]]
438 entry:
439   %conv = sext i32 %a to i64
440   %conv1 = sext i32 %b to i64
441   %add = add i64 %conv1, %conv
442   %0 = icmp slt i64 %add, 2147483647
443   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
444   %1 = icmp sgt i64 %spec.store.select, -2147483648
445   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
446   %conv7 = trunc i64 %spec.store.select8 to i32
447   call void @use64(i64 %add)
448   ret i32 %conv7
451 define i32 @sadd_sat32_trunc(i32 %a, i32 %b) {
452 ; CHECK-LABEL: @sadd_sat32_trunc(
453 ; CHECK-NEXT:  entry:
454 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
455 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
456 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
457 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 32767
458 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 32767
459 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -32768
460 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -32768
461 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
462 ; CHECK-NEXT:    ret i32 [[CONV7]]
464 entry:
465   %conv = sext i32 %a to i64
466   %conv1 = sext i32 %b to i64
467   %add = add i64 %conv1, %conv
468   %0 = icmp slt i64 %add, 32767
469   %spec.store.select = select i1 %0, i64 %add, i64 32767
470   %1 = icmp sgt i64 %spec.store.select, -32768
471   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -32768
472   %conv7 = trunc i64 %spec.store.select8 to i32
473   ret i32 %conv7
476 define i32 @sadd_sat32_ext16(i32 %a, i16 %b) {
477 ; CHECK-LABEL: @sadd_sat32_ext16(
478 ; CHECK-NEXT:  entry:
479 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
480 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i64
481 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
482 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i64 [[ADD]], 2147483647
483 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
484 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[SPEC_STORE_SELECT]], -2147483648
485 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 -2147483648
486 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
487 ; CHECK-NEXT:    ret i32 [[CONV7]]
489 entry:
490   %conv = sext i32 %a to i64
491   %conv1 = sext i16 %b to i64
492   %add = add i64 %conv1, %conv
493   %0 = icmp slt i64 %add, 2147483647
494   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
495   %1 = icmp sgt i64 %spec.store.select, -2147483648
496   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
497   %conv7 = trunc i64 %spec.store.select8 to i32
498   ret i32 %conv7
501 define i8 @sadd_sat8_ext8(i8 %a, i16 %b) {
502 ; CHECK-LABEL: @sadd_sat8_ext8(
503 ; CHECK-NEXT:  entry:
504 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
505 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
506 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
507 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[ADD]], 127
508 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i32 [[ADD]], i32 127
509 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[SPEC_STORE_SELECT]], -128
510 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i32 [[SPEC_STORE_SELECT]], i32 -128
511 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i32 [[SPEC_STORE_SELECT8]] to i8
512 ; CHECK-NEXT:    ret i8 [[CONV7]]
514 entry:
515   %conv = sext i8 %a to i32
516   %conv1 = sext i16 %b to i32
517   %add = add i32 %conv1, %conv
518   %0 = icmp slt i32 %add, 127
519   %spec.store.select = select i1 %0, i32 %add, i32 127
520   %1 = icmp sgt i32 %spec.store.select, -128
521   %spec.store.select8 = select i1 %1, i32 %spec.store.select, i32 -128
522   %conv7 = trunc i32 %spec.store.select8 to i8
523   ret i8 %conv7
526 define i32 @sadd_sat32_zext(i32 %a, i32 %b) {
527 ; CHECK-LABEL: @sadd_sat32_zext(
528 ; CHECK-NEXT:  entry:
529 ; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[A:%.*]] to i64
530 ; CHECK-NEXT:    [[CONV1:%.*]] = zext i32 [[B:%.*]] to i64
531 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[CONV1]], [[CONV]]
532 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[ADD]], 2147483647
533 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 2147483647
534 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT]] to i32
535 ; CHECK-NEXT:    ret i32 [[CONV7]]
537 entry:
538   %conv = zext i32 %a to i64
539   %conv1 = zext i32 %b to i64
540   %add = add i64 %conv1, %conv
541   %0 = icmp slt i64 %add, 2147483647
542   %spec.store.select = select i1 %0, i64 %add, i64 2147483647
543   %1 = icmp sgt i64 %spec.store.select, -2147483648
544   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 -2147483648
545   %conv7 = trunc i64 %spec.store.select8 to i32
546   ret i32 %conv7
549 define i32 @sadd_sat32_maxmin(i32 %a, i32 %b) {
550 ; CHECK-LABEL: @sadd_sat32_maxmin(
551 ; CHECK-NEXT:  entry:
552 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
553 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
554 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
555 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[ADD]], -2147483648
556 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 -2147483648
557 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[SPEC_STORE_SELECT]], 2147483647
558 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 2147483647
559 ; CHECK-NEXT:    [[CONV7:%.*]] = trunc i64 [[SPEC_STORE_SELECT8]] to i32
560 ; CHECK-NEXT:    ret i32 [[CONV7]]
562 entry:
563   %conv = sext i32 %a to i64
564   %conv1 = sext i32 %b to i64
565   %add = add i64 %conv1, %conv
566   %0 = icmp sgt i64 %add, -2147483648
567   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
568   %1 = icmp slt i64 %spec.store.select, 2147483647
569   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
570   %conv7 = trunc i64 %spec.store.select8 to i32
571   ret i32 %conv7
574 define i64 @sadd_sat32_notrunc(i32 %a, i32 %b) {
575 ; CHECK-LABEL: @sadd_sat32_notrunc(
576 ; CHECK-NEXT:  entry:
577 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
578 ; CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
579 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
580 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[ADD]], -2147483648
581 ; CHECK-NEXT:    [[SPEC_STORE_SELECT:%.*]] = select i1 [[TMP0]], i64 [[ADD]], i64 -2147483648
582 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[SPEC_STORE_SELECT]], 2147483647
583 ; CHECK-NEXT:    [[SPEC_STORE_SELECT8:%.*]] = select i1 [[TMP1]], i64 [[SPEC_STORE_SELECT]], i64 2147483647
584 ; CHECK-NEXT:    ret i64 [[SPEC_STORE_SELECT8]]
586 entry:
587   %conv = sext i32 %a to i64
588   %conv1 = sext i32 %b to i64
589   %add = add i64 %conv1, %conv
590   %0 = icmp sgt i64 %add, -2147483648
591   %spec.store.select = select i1 %0, i64 %add, i64 -2147483648
592   %1 = icmp slt i64 %spec.store.select, 2147483647
593   %spec.store.select8 = select i1 %1, i64 %spec.store.select, i64 2147483647
594   ret i64 %spec.store.select8
597 declare void @use64(i64)