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