Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / AArch64 / sat-add.ll
blob4d865a2b14b74da94085de0eca6f2983e3b073d7
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 ; There are at least 3 potential patterns corresponding to an unsigned saturated add: min, cmp with sum, cmp with not.
5 ; Test each of those patterns with i8/i16/i32/i64.
6 ; Test each of those with a constant operand and a variable operand.
7 ; Test each of those with a 128-bit vector type.
9 define i8 @unsigned_sat_constant_i8_using_min(i8 %x) {
10 ; CHECK-LABEL: unsigned_sat_constant_i8_using_min:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    and w8, w0, #0xff
13 ; CHECK-NEXT:    cmp w8, #213 // =213
14 ; CHECK-NEXT:    mov w8, #-43
15 ; CHECK-NEXT:    csel w8, w0, w8, lo
16 ; CHECK-NEXT:    add w0, w8, #42 // =42
17 ; CHECK-NEXT:    ret
18   %c = icmp ult i8 %x, -43
19   %s = select i1 %c, i8 %x, i8 -43
20   %r = add i8 %s, 42
21   ret i8 %r
24 define i8 @unsigned_sat_constant_i8_using_cmp_sum(i8 %x) {
25 ; CHECK-LABEL: unsigned_sat_constant_i8_using_cmp_sum:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    and w8, w0, #0xff
28 ; CHECK-NEXT:    add w8, w8, #42 // =42
29 ; CHECK-NEXT:    tst w8, #0x100
30 ; CHECK-NEXT:    csinv w0, w8, wzr, eq
31 ; CHECK-NEXT:    ret
32   %a = add i8 %x, 42
33   %c = icmp ugt i8 %x, %a
34   %r = select i1 %c, i8 -1, i8 %a
35   ret i8 %r
38 define i8 @unsigned_sat_constant_i8_using_cmp_notval(i8 %x) {
39 ; CHECK-LABEL: unsigned_sat_constant_i8_using_cmp_notval:
40 ; CHECK:       // %bb.0:
41 ; CHECK-NEXT:    and w8, w0, #0xff
42 ; CHECK-NEXT:    add w9, w0, #42 // =42
43 ; CHECK-NEXT:    cmp w8, #213 // =213
44 ; CHECK-NEXT:    csinv w0, w9, wzr, ls
45 ; CHECK-NEXT:    ret
46   %a = add i8 %x, 42
47   %c = icmp ugt i8 %x, -43
48   %r = select i1 %c, i8 -1, i8 %a
49   ret i8 %r
52 define i16 @unsigned_sat_constant_i16_using_min(i16 %x) {
53 ; CHECK-LABEL: unsigned_sat_constant_i16_using_min:
54 ; CHECK:       // %bb.0:
55 ; CHECK-NEXT:    mov w8, #65493
56 ; CHECK-NEXT:    cmp w8, w0, uxth
57 ; CHECK-NEXT:    mov w8, #-43
58 ; CHECK-NEXT:    csel w8, w0, w8, hi
59 ; CHECK-NEXT:    add w0, w8, #42 // =42
60 ; CHECK-NEXT:    ret
61   %c = icmp ult i16 %x, -43
62   %s = select i1 %c, i16 %x, i16 -43
63   %r = add i16 %s, 42
64   ret i16 %r
67 define i16 @unsigned_sat_constant_i16_using_cmp_sum(i16 %x) {
68 ; CHECK-LABEL: unsigned_sat_constant_i16_using_cmp_sum:
69 ; CHECK:       // %bb.0:
70 ; CHECK-NEXT:    and w8, w0, #0xffff
71 ; CHECK-NEXT:    add w8, w8, #42 // =42
72 ; CHECK-NEXT:    tst w8, #0x10000
73 ; CHECK-NEXT:    csinv w0, w8, wzr, eq
74 ; CHECK-NEXT:    ret
75   %a = add i16 %x, 42
76   %c = icmp ugt i16 %x, %a
77   %r = select i1 %c, i16 -1, i16 %a
78   ret i16 %r
81 define i16 @unsigned_sat_constant_i16_using_cmp_notval(i16 %x) {
82 ; CHECK-LABEL: unsigned_sat_constant_i16_using_cmp_notval:
83 ; CHECK:       // %bb.0:
84 ; CHECK-NEXT:    mov w9, #65493
85 ; CHECK-NEXT:    add w8, w0, #42 // =42
86 ; CHECK-NEXT:    cmp w9, w0, uxth
87 ; CHECK-NEXT:    csinv w0, w8, wzr, hs
88 ; CHECK-NEXT:    ret
89   %a = add i16 %x, 42
90   %c = icmp ugt i16 %x, -43
91   %r = select i1 %c, i16 -1, i16 %a
92   ret i16 %r
95 define i32 @unsigned_sat_constant_i32_using_min(i32 %x) {
96 ; CHECK-LABEL: unsigned_sat_constant_i32_using_min:
97 ; CHECK:       // %bb.0:
98 ; CHECK-NEXT:    cmn w0, #43 // =43
99 ; CHECK-NEXT:    mov w8, #-43
100 ; CHECK-NEXT:    csel w8, w0, w8, lo
101 ; CHECK-NEXT:    add w0, w8, #42 // =42
102 ; CHECK-NEXT:    ret
103   %c = icmp ult i32 %x, -43
104   %s = select i1 %c, i32 %x, i32 -43
105   %r = add i32 %s, 42
106   ret i32 %r
109 define i32 @unsigned_sat_constant_i32_using_cmp_sum(i32 %x) {
110 ; CHECK-LABEL: unsigned_sat_constant_i32_using_cmp_sum:
111 ; CHECK:       // %bb.0:
112 ; CHECK-NEXT:    adds w8, w0, #42 // =42
113 ; CHECK-NEXT:    csinv w0, w8, wzr, lo
114 ; CHECK-NEXT:    ret
115   %a = add i32 %x, 42
116   %c = icmp ugt i32 %x, %a
117   %r = select i1 %c, i32 -1, i32 %a
118   ret i32 %r
121 define i32 @unsigned_sat_constant_i32_using_cmp_notval(i32 %x) {
122 ; CHECK-LABEL: unsigned_sat_constant_i32_using_cmp_notval:
123 ; CHECK:       // %bb.0:
124 ; CHECK-NEXT:    adds w8, w0, #42 // =42
125 ; CHECK-NEXT:    csinv w0, w8, wzr, lo
126 ; CHECK-NEXT:    ret
127   %a = add i32 %x, 42
128   %c = icmp ugt i32 %x, -43
129   %r = select i1 %c, i32 -1, i32 %a
130   ret i32 %r
133 define i64 @unsigned_sat_constant_i64_using_min(i64 %x) {
134 ; CHECK-LABEL: unsigned_sat_constant_i64_using_min:
135 ; CHECK:       // %bb.0:
136 ; CHECK-NEXT:    cmn x0, #43 // =43
137 ; CHECK-NEXT:    mov x8, #-43
138 ; CHECK-NEXT:    csel x8, x0, x8, lo
139 ; CHECK-NEXT:    add x0, x8, #42 // =42
140 ; CHECK-NEXT:    ret
141   %c = icmp ult i64 %x, -43
142   %s = select i1 %c, i64 %x, i64 -43
143   %r = add i64 %s, 42
144   ret i64 %r
147 define i64 @unsigned_sat_constant_i64_using_cmp_sum(i64 %x) {
148 ; CHECK-LABEL: unsigned_sat_constant_i64_using_cmp_sum:
149 ; CHECK:       // %bb.0:
150 ; CHECK-NEXT:    adds x8, x0, #42 // =42
151 ; CHECK-NEXT:    csinv x0, x8, xzr, lo
152 ; CHECK-NEXT:    ret
153   %a = add i64 %x, 42
154   %c = icmp ugt i64 %x, %a
155   %r = select i1 %c, i64 -1, i64 %a
156   ret i64 %r
159 define i64 @unsigned_sat_constant_i64_using_cmp_notval(i64 %x) {
160 ; CHECK-LABEL: unsigned_sat_constant_i64_using_cmp_notval:
161 ; CHECK:       // %bb.0:
162 ; CHECK-NEXT:    adds x8, x0, #42 // =42
163 ; CHECK-NEXT:    csinv x0, x8, xzr, lo
164 ; CHECK-NEXT:    ret
165   %a = add i64 %x, 42
166   %c = icmp ugt i64 %x, -43
167   %r = select i1 %c, i64 -1, i64 %a
168   ret i64 %r
171 define i8 @unsigned_sat_variable_i8_using_min(i8 %x, i8 %y) {
172 ; CHECK-LABEL: unsigned_sat_variable_i8_using_min:
173 ; CHECK:       // %bb.0:
174 ; CHECK-NEXT:    and w8, w0, #0xff
175 ; CHECK-NEXT:    mvn w9, w1
176 ; CHECK-NEXT:    cmp w8, w9, uxtb
177 ; CHECK-NEXT:    csinv w8, w0, w1, lo
178 ; CHECK-NEXT:    add w0, w8, w1
179 ; CHECK-NEXT:    ret
180   %noty = xor i8 %y, -1
181   %c = icmp ult i8 %x, %noty
182   %s = select i1 %c, i8 %x, i8 %noty
183   %r = add i8 %s, %y
184   ret i8 %r
187 define i8 @unsigned_sat_variable_i8_using_cmp_sum(i8 %x, i8 %y) {
188 ; CHECK-LABEL: unsigned_sat_variable_i8_using_cmp_sum:
189 ; CHECK:       // %bb.0:
190 ; CHECK-NEXT:    and w8, w0, #0xff
191 ; CHECK-NEXT:    add w8, w8, w1, uxtb
192 ; CHECK-NEXT:    tst w8, #0x100
193 ; CHECK-NEXT:    csinv w0, w8, wzr, eq
194 ; CHECK-NEXT:    ret
195   %a = add i8 %x, %y
196   %c = icmp ugt i8 %x, %a
197   %r = select i1 %c, i8 -1, i8 %a
198   ret i8 %r
201 define i8 @unsigned_sat_variable_i8_using_cmp_notval(i8 %x, i8 %y) {
202 ; CHECK-LABEL: unsigned_sat_variable_i8_using_cmp_notval:
203 ; CHECK:       // %bb.0:
204 ; CHECK-NEXT:    and w8, w0, #0xff
205 ; CHECK-NEXT:    mvn w9, w1
206 ; CHECK-NEXT:    add w10, w0, w1
207 ; CHECK-NEXT:    cmp w8, w9, uxtb
208 ; CHECK-NEXT:    csinv w0, w10, wzr, ls
209 ; CHECK-NEXT:    ret
210   %noty = xor i8 %y, -1
211   %a = add i8 %x, %y
212   %c = icmp ugt i8 %x, %noty
213   %r = select i1 %c, i8 -1, i8 %a
214   ret i8 %r
217 define i16 @unsigned_sat_variable_i16_using_min(i16 %x, i16 %y) {
218 ; CHECK-LABEL: unsigned_sat_variable_i16_using_min:
219 ; CHECK:       // %bb.0:
220 ; CHECK-NEXT:    and w8, w0, #0xffff
221 ; CHECK-NEXT:    mvn w9, w1
222 ; CHECK-NEXT:    cmp w8, w9, uxth
223 ; CHECK-NEXT:    csinv w8, w0, w1, lo
224 ; CHECK-NEXT:    add w0, w8, w1
225 ; CHECK-NEXT:    ret
226   %noty = xor i16 %y, -1
227   %c = icmp ult i16 %x, %noty
228   %s = select i1 %c, i16 %x, i16 %noty
229   %r = add i16 %s, %y
230   ret i16 %r
233 define i16 @unsigned_sat_variable_i16_using_cmp_sum(i16 %x, i16 %y) {
234 ; CHECK-LABEL: unsigned_sat_variable_i16_using_cmp_sum:
235 ; CHECK:       // %bb.0:
236 ; CHECK-NEXT:    and w8, w0, #0xffff
237 ; CHECK-NEXT:    add w8, w8, w1, uxth
238 ; CHECK-NEXT:    tst w8, #0x10000
239 ; CHECK-NEXT:    csinv w0, w8, wzr, eq
240 ; CHECK-NEXT:    ret
241   %a = add i16 %x, %y
242   %c = icmp ugt i16 %x, %a
243   %r = select i1 %c, i16 -1, i16 %a
244   ret i16 %r
247 define i16 @unsigned_sat_variable_i16_using_cmp_notval(i16 %x, i16 %y) {
248 ; CHECK-LABEL: unsigned_sat_variable_i16_using_cmp_notval:
249 ; CHECK:       // %bb.0:
250 ; CHECK-NEXT:    and w8, w0, #0xffff
251 ; CHECK-NEXT:    mvn w9, w1
252 ; CHECK-NEXT:    add w10, w0, w1
253 ; CHECK-NEXT:    cmp w8, w9, uxth
254 ; CHECK-NEXT:    csinv w0, w10, wzr, ls
255 ; CHECK-NEXT:    ret
256   %noty = xor i16 %y, -1
257   %a = add i16 %x, %y
258   %c = icmp ugt i16 %x, %noty
259   %r = select i1 %c, i16 -1, i16 %a
260   ret i16 %r
263 define i32 @unsigned_sat_variable_i32_using_min(i32 %x, i32 %y) {
264 ; CHECK-LABEL: unsigned_sat_variable_i32_using_min:
265 ; CHECK:       // %bb.0:
266 ; CHECK-NEXT:    mvn w8, w1
267 ; CHECK-NEXT:    cmp w0, w8
268 ; CHECK-NEXT:    csinv w8, w0, w1, lo
269 ; CHECK-NEXT:    add w0, w8, w1
270 ; CHECK-NEXT:    ret
271   %noty = xor i32 %y, -1
272   %c = icmp ult i32 %x, %noty
273   %s = select i1 %c, i32 %x, i32 %noty
274   %r = add i32 %s, %y
275   ret i32 %r
278 define i32 @unsigned_sat_variable_i32_using_cmp_sum(i32 %x, i32 %y) {
279 ; CHECK-LABEL: unsigned_sat_variable_i32_using_cmp_sum:
280 ; CHECK:       // %bb.0:
281 ; CHECK-NEXT:    adds w8, w0, w1
282 ; CHECK-NEXT:    csinv w0, w8, wzr, lo
283 ; CHECK-NEXT:    ret
284   %a = add i32 %x, %y
285   %c = icmp ugt i32 %x, %a
286   %r = select i1 %c, i32 -1, i32 %a
287   ret i32 %r
290 define i32 @unsigned_sat_variable_i32_using_cmp_notval(i32 %x, i32 %y) {
291 ; CHECK-LABEL: unsigned_sat_variable_i32_using_cmp_notval:
292 ; CHECK:       // %bb.0:
293 ; CHECK-NEXT:    mvn w8, w1
294 ; CHECK-NEXT:    add w9, w0, w1
295 ; CHECK-NEXT:    cmp w0, w8
296 ; CHECK-NEXT:    csinv w0, w9, wzr, ls
297 ; CHECK-NEXT:    ret
298   %noty = xor i32 %y, -1
299   %a = add i32 %x, %y
300   %c = icmp ugt i32 %x, %noty
301   %r = select i1 %c, i32 -1, i32 %a
302   ret i32 %r
305 define i64 @unsigned_sat_variable_i64_using_min(i64 %x, i64 %y) {
306 ; CHECK-LABEL: unsigned_sat_variable_i64_using_min:
307 ; CHECK:       // %bb.0:
308 ; CHECK-NEXT:    mvn x8, x1
309 ; CHECK-NEXT:    cmp x0, x8
310 ; CHECK-NEXT:    csinv x8, x0, x1, lo
311 ; CHECK-NEXT:    add x0, x8, x1
312 ; CHECK-NEXT:    ret
313   %noty = xor i64 %y, -1
314   %c = icmp ult i64 %x, %noty
315   %s = select i1 %c, i64 %x, i64 %noty
316   %r = add i64 %s, %y
317   ret i64 %r
320 define i64 @unsigned_sat_variable_i64_using_cmp_sum(i64 %x, i64 %y) {
321 ; CHECK-LABEL: unsigned_sat_variable_i64_using_cmp_sum:
322 ; CHECK:       // %bb.0:
323 ; CHECK-NEXT:    adds x8, x0, x1
324 ; CHECK-NEXT:    csinv x0, x8, xzr, lo
325 ; CHECK-NEXT:    ret
326   %a = add i64 %x, %y
327   %c = icmp ugt i64 %x, %a
328   %r = select i1 %c, i64 -1, i64 %a
329   ret i64 %r
332 define i64 @unsigned_sat_variable_i64_using_cmp_notval(i64 %x, i64 %y) {
333 ; CHECK-LABEL: unsigned_sat_variable_i64_using_cmp_notval:
334 ; CHECK:       // %bb.0:
335 ; CHECK-NEXT:    mvn x8, x1
336 ; CHECK-NEXT:    add x9, x0, x1
337 ; CHECK-NEXT:    cmp x0, x8
338 ; CHECK-NEXT:    csinv x0, x9, xzr, ls
339 ; CHECK-NEXT:    ret
340   %noty = xor i64 %y, -1
341   %a = add i64 %x, %y
342   %c = icmp ugt i64 %x, %noty
343   %r = select i1 %c, i64 -1, i64 %a
344   ret i64 %r
347 define <16 x i8> @unsigned_sat_constant_v16i8_using_min(<16 x i8> %x) {
348 ; CHECK-LABEL: unsigned_sat_constant_v16i8_using_min:
349 ; CHECK:       // %bb.0:
350 ; CHECK-NEXT:    movi v1.16b, #213
351 ; CHECK-NEXT:    umin v0.16b, v0.16b, v1.16b
352 ; CHECK-NEXT:    movi v1.16b, #42
353 ; CHECK-NEXT:    add v0.16b, v0.16b, v1.16b
354 ; CHECK-NEXT:    ret
355   %c = icmp ult <16 x i8> %x, <i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43>
356   %s = select <16 x i1> %c, <16 x i8> %x, <16 x i8> <i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43>
357   %r = add <16 x i8> %s, <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
358   ret <16 x i8> %r
361 define <16 x i8> @unsigned_sat_constant_v16i8_using_cmp_sum(<16 x i8> %x) {
362 ; CHECK-LABEL: unsigned_sat_constant_v16i8_using_cmp_sum:
363 ; CHECK:       // %bb.0:
364 ; CHECK-NEXT:    movi v1.16b, #42
365 ; CHECK-NEXT:    add v1.16b, v0.16b, v1.16b
366 ; CHECK-NEXT:    cmhi v0.16b, v0.16b, v1.16b
367 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
368 ; CHECK-NEXT:    bic v0.4s, #0
369 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
370 ; CHECK-NEXT:    ret
371   %a = add <16 x i8> %x, <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
372   %c = icmp ugt <16 x i8> %x, %a
373   %r = select <16 x i1> %c, <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>, <16 x i8> %a
374   ret <16 x i8> %r
377 define <16 x i8> @unsigned_sat_constant_v16i8_using_cmp_notval(<16 x i8> %x) {
378 ; CHECK-LABEL: unsigned_sat_constant_v16i8_using_cmp_notval:
379 ; CHECK:       // %bb.0:
380 ; CHECK-NEXT:    movi v1.16b, #42
381 ; CHECK-NEXT:    movi v2.16b, #213
382 ; CHECK-NEXT:    add v1.16b, v0.16b, v1.16b
383 ; CHECK-NEXT:    cmhi v0.16b, v0.16b, v2.16b
384 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
385 ; CHECK-NEXT:    bic v0.4s, #0
386 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
387 ; CHECK-NEXT:    ret
388   %a = add <16 x i8> %x, <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
389   %c = icmp ugt <16 x i8> %x, <i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43>
390   %r = select <16 x i1> %c, <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>, <16 x i8> %a
391   ret <16 x i8> %r
394 define <8 x i16> @unsigned_sat_constant_v8i16_using_min(<8 x i16> %x) {
395 ; CHECK-LABEL: unsigned_sat_constant_v8i16_using_min:
396 ; CHECK:       // %bb.0:
397 ; CHECK-NEXT:    mvni v1.8h, #42
398 ; CHECK-NEXT:    umin v0.8h, v0.8h, v1.8h
399 ; CHECK-NEXT:    movi v1.8h, #42
400 ; CHECK-NEXT:    add v0.8h, v0.8h, v1.8h
401 ; CHECK-NEXT:    ret
402   %c = icmp ult <8 x i16> %x, <i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43>
403   %s = select <8 x i1> %c, <8 x i16> %x, <8 x i16> <i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43>
404   %r = add <8 x i16> %s, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
405   ret <8 x i16> %r
408 define <8 x i16> @unsigned_sat_constant_v8i16_using_cmp_sum(<8 x i16> %x) {
409 ; CHECK-LABEL: unsigned_sat_constant_v8i16_using_cmp_sum:
410 ; CHECK:       // %bb.0:
411 ; CHECK-NEXT:    movi v1.8h, #42
412 ; CHECK-NEXT:    add v1.8h, v0.8h, v1.8h
413 ; CHECK-NEXT:    cmhi v0.8h, v0.8h, v1.8h
414 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
415 ; CHECK-NEXT:    bic v0.4s, #0
416 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
417 ; CHECK-NEXT:    ret
418   %a = add <8 x i16> %x, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
419   %c = icmp ugt <8 x i16> %x, %a
420   %r = select <8 x i1> %c, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, <8 x i16> %a
421   ret <8 x i16> %r
424 define <8 x i16> @unsigned_sat_constant_v8i16_using_cmp_notval(<8 x i16> %x) {
425 ; CHECK-LABEL: unsigned_sat_constant_v8i16_using_cmp_notval:
426 ; CHECK:       // %bb.0:
427 ; CHECK-NEXT:    movi v1.8h, #42
428 ; CHECK-NEXT:    mvni v2.8h, #42
429 ; CHECK-NEXT:    add v1.8h, v0.8h, v1.8h
430 ; CHECK-NEXT:    cmhi v0.8h, v0.8h, v2.8h
431 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
432 ; CHECK-NEXT:    bic v0.4s, #0
433 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
434 ; CHECK-NEXT:    ret
435   %a = add <8 x i16> %x, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
436   %c = icmp ugt <8 x i16> %x, <i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43>
437   %r = select <8 x i1> %c, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, <8 x i16> %a
438   ret <8 x i16> %r
441 define <4 x i32> @unsigned_sat_constant_v4i32_using_min(<4 x i32> %x) {
442 ; CHECK-LABEL: unsigned_sat_constant_v4i32_using_min:
443 ; CHECK:       // %bb.0:
444 ; CHECK-NEXT:    mvni v1.4s, #42
445 ; CHECK-NEXT:    umin v0.4s, v0.4s, v1.4s
446 ; CHECK-NEXT:    movi v1.4s, #42
447 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
448 ; CHECK-NEXT:    ret
449   %c = icmp ult <4 x i32> %x, <i32 -43, i32 -43, i32 -43, i32 -43>
450   %s = select <4 x i1> %c, <4 x i32> %x, <4 x i32> <i32 -43, i32 -43, i32 -43, i32 -43>
451   %r = add <4 x i32> %s, <i32 42, i32 42, i32 42, i32 42>
452   ret <4 x i32> %r
455 define <4 x i32> @unsigned_sat_constant_v4i32_using_cmp_sum(<4 x i32> %x) {
456 ; CHECK-LABEL: unsigned_sat_constant_v4i32_using_cmp_sum:
457 ; CHECK:       // %bb.0:
458 ; CHECK-NEXT:    movi v1.4s, #42
459 ; CHECK-NEXT:    add v1.4s, v0.4s, v1.4s
460 ; CHECK-NEXT:    cmhi v0.4s, v0.4s, v1.4s
461 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
462 ; CHECK-NEXT:    bic v0.4s, #0
463 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
464 ; CHECK-NEXT:    ret
465   %a = add <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42>
466   %c = icmp ugt <4 x i32> %x, %a
467   %r = select <4 x i1> %c, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> %a
468   ret <4 x i32> %r
471 define <4 x i32> @unsigned_sat_constant_v4i32_using_cmp_notval(<4 x i32> %x) {
472 ; CHECK-LABEL: unsigned_sat_constant_v4i32_using_cmp_notval:
473 ; CHECK:       // %bb.0:
474 ; CHECK-NEXT:    movi v1.4s, #42
475 ; CHECK-NEXT:    mvni v2.4s, #42
476 ; CHECK-NEXT:    add v1.4s, v0.4s, v1.4s
477 ; CHECK-NEXT:    cmhi v0.4s, v0.4s, v2.4s
478 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
479 ; CHECK-NEXT:    bic v0.4s, #0
480 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
481 ; CHECK-NEXT:    ret
482   %a = add <4 x i32> %x, <i32 42, i32 42, i32 42, i32 42>
483   %c = icmp ugt <4 x i32> %x, <i32 -43, i32 -43, i32 -43, i32 -43>
484   %r = select <4 x i1> %c, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> %a
485   ret <4 x i32> %r
488 define <2 x i64> @unsigned_sat_constant_v2i64_using_min(<2 x i64> %x) {
489 ; CHECK-LABEL: unsigned_sat_constant_v2i64_using_min:
490 ; CHECK:       // %bb.0:
491 ; CHECK-NEXT:    mov x8, #-43
492 ; CHECK-NEXT:    dup v1.2d, x8
493 ; CHECK-NEXT:    mov w9, #42
494 ; CHECK-NEXT:    cmhi v2.2d, v1.2d, v0.2d
495 ; CHECK-NEXT:    bsl v2.16b, v0.16b, v1.16b
496 ; CHECK-NEXT:    dup v0.2d, x9
497 ; CHECK-NEXT:    add v0.2d, v2.2d, v0.2d
498 ; CHECK-NEXT:    ret
499   %c = icmp ult <2 x i64> %x, <i64 -43, i64 -43>
500   %s = select <2 x i1> %c, <2 x i64> %x, <2 x i64> <i64 -43, i64 -43>
501   %r = add <2 x i64> %s, <i64 42, i64 42>
502   ret <2 x i64> %r
505 define <2 x i64> @unsigned_sat_constant_v2i64_using_cmp_sum(<2 x i64> %x) {
506 ; CHECK-LABEL: unsigned_sat_constant_v2i64_using_cmp_sum:
507 ; CHECK:       // %bb.0:
508 ; CHECK-NEXT:    mov w8, #42
509 ; CHECK-NEXT:    dup v1.2d, x8
510 ; CHECK-NEXT:    add v1.2d, v0.2d, v1.2d
511 ; CHECK-NEXT:    cmhi v0.2d, v0.2d, v1.2d
512 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
513 ; CHECK-NEXT:    bic v0.4s, #0
514 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
515 ; CHECK-NEXT:    ret
516   %a = add <2 x i64> %x, <i64 42, i64 42>
517   %c = icmp ugt <2 x i64> %x, %a
518   %r = select <2 x i1> %c, <2 x i64> <i64 -1, i64 -1>, <2 x i64> %a
519   ret <2 x i64> %r
522 define <2 x i64> @unsigned_sat_constant_v2i64_using_cmp_notval(<2 x i64> %x) {
523 ; CHECK-LABEL: unsigned_sat_constant_v2i64_using_cmp_notval:
524 ; CHECK:       // %bb.0:
525 ; CHECK-NEXT:    mov w8, #42
526 ; CHECK-NEXT:    mov x9, #-43
527 ; CHECK-NEXT:    dup v1.2d, x8
528 ; CHECK-NEXT:    dup v2.2d, x9
529 ; CHECK-NEXT:    add v1.2d, v0.2d, v1.2d
530 ; CHECK-NEXT:    cmhi v0.2d, v0.2d, v2.2d
531 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
532 ; CHECK-NEXT:    bic v0.4s, #0
533 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
534 ; CHECK-NEXT:    ret
535   %a = add <2 x i64> %x, <i64 42, i64 42>
536   %c = icmp ugt <2 x i64> %x, <i64 -43, i64 -43>
537   %r = select <2 x i1> %c, <2 x i64> <i64 -1, i64 -1>, <2 x i64> %a
538   ret <2 x i64> %r
541 define <16 x i8> @unsigned_sat_variable_v16i8_using_min(<16 x i8> %x, <16 x i8> %y) {
542 ; CHECK-LABEL: unsigned_sat_variable_v16i8_using_min:
543 ; CHECK:       // %bb.0:
544 ; CHECK-NEXT:    mvn v2.16b, v1.16b
545 ; CHECK-NEXT:    umin v0.16b, v0.16b, v2.16b
546 ; CHECK-NEXT:    add v0.16b, v0.16b, v1.16b
547 ; CHECK-NEXT:    ret
548   %noty = xor <16 x i8> %y, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
549   %c = icmp ult <16 x i8> %x, %noty
550   %s = select <16 x i1> %c, <16 x i8> %x, <16 x i8> %noty
551   %r = add <16 x i8> %s, %y
552   ret <16 x i8> %r
555 define <16 x i8> @unsigned_sat_variable_v16i8_using_cmp_sum(<16 x i8> %x, <16 x i8> %y) {
556 ; CHECK-LABEL: unsigned_sat_variable_v16i8_using_cmp_sum:
557 ; CHECK:       // %bb.0:
558 ; CHECK-NEXT:    add v1.16b, v0.16b, v1.16b
559 ; CHECK-NEXT:    cmhi v0.16b, v0.16b, v1.16b
560 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
561 ; CHECK-NEXT:    bic v0.4s, #0
562 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
563 ; CHECK-NEXT:    ret
564   %a = add <16 x i8> %x, %y
565   %c = icmp ugt <16 x i8> %x, %a
566   %r = select <16 x i1> %c, <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>, <16 x i8> %a
567   ret <16 x i8> %r
570 define <16 x i8> @unsigned_sat_variable_v16i8_using_cmp_notval(<16 x i8> %x, <16 x i8> %y) {
571 ; CHECK-LABEL: unsigned_sat_variable_v16i8_using_cmp_notval:
572 ; CHECK:       // %bb.0:
573 ; CHECK-NEXT:    mvn v2.16b, v1.16b
574 ; CHECK-NEXT:    add v1.16b, v0.16b, v1.16b
575 ; CHECK-NEXT:    cmhi v0.16b, v0.16b, v2.16b
576 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
577 ; CHECK-NEXT:    bic v0.4s, #0
578 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
579 ; CHECK-NEXT:    ret
580   %noty = xor <16 x i8> %y, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
581   %a = add <16 x i8> %x, %y
582   %c = icmp ugt <16 x i8> %x, %noty
583   %r = select <16 x i1> %c, <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>, <16 x i8> %a
584   ret <16 x i8> %r
587 define <8 x i16> @unsigned_sat_variable_v8i16_using_min(<8 x i16> %x, <8 x i16> %y) {
588 ; CHECK-LABEL: unsigned_sat_variable_v8i16_using_min:
589 ; CHECK:       // %bb.0:
590 ; CHECK-NEXT:    mvn v2.16b, v1.16b
591 ; CHECK-NEXT:    umin v0.8h, v0.8h, v2.8h
592 ; CHECK-NEXT:    add v0.8h, v0.8h, v1.8h
593 ; CHECK-NEXT:    ret
594   %noty = xor <8 x i16> %y, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
595   %c = icmp ult <8 x i16> %x, %noty
596   %s = select <8 x i1> %c, <8 x i16> %x, <8 x i16> %noty
597   %r = add <8 x i16> %s, %y
598   ret <8 x i16> %r
601 define <8 x i16> @unsigned_sat_variable_v8i16_using_cmp_sum(<8 x i16> %x, <8 x i16> %y) {
602 ; CHECK-LABEL: unsigned_sat_variable_v8i16_using_cmp_sum:
603 ; CHECK:       // %bb.0:
604 ; CHECK-NEXT:    add v1.8h, v0.8h, v1.8h
605 ; CHECK-NEXT:    cmhi v0.8h, v0.8h, v1.8h
606 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
607 ; CHECK-NEXT:    bic v0.4s, #0
608 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
609 ; CHECK-NEXT:    ret
610   %a = add <8 x i16> %x, %y
611   %c = icmp ugt <8 x i16> %x, %a
612   %r = select <8 x i1> %c, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, <8 x i16> %a
613   ret <8 x i16> %r
616 define <8 x i16> @unsigned_sat_variable_v8i16_using_cmp_notval(<8 x i16> %x, <8 x i16> %y) {
617 ; CHECK-LABEL: unsigned_sat_variable_v8i16_using_cmp_notval:
618 ; CHECK:       // %bb.0:
619 ; CHECK-NEXT:    mvn v2.16b, v1.16b
620 ; CHECK-NEXT:    add v1.8h, v0.8h, v1.8h
621 ; CHECK-NEXT:    cmhi v0.8h, v0.8h, v2.8h
622 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
623 ; CHECK-NEXT:    bic v0.4s, #0
624 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
625 ; CHECK-NEXT:    ret
626   %noty = xor <8 x i16> %y, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
627   %a = add <8 x i16> %x, %y
628   %c = icmp ugt <8 x i16> %x, %noty
629   %r = select <8 x i1> %c, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, <8 x i16> %a
630   ret <8 x i16> %r
633 define <4 x i32> @unsigned_sat_variable_v4i32_using_min(<4 x i32> %x, <4 x i32> %y) {
634 ; CHECK-LABEL: unsigned_sat_variable_v4i32_using_min:
635 ; CHECK:       // %bb.0:
636 ; CHECK-NEXT:    mvn v2.16b, v1.16b
637 ; CHECK-NEXT:    umin v0.4s, v0.4s, v2.4s
638 ; CHECK-NEXT:    add v0.4s, v0.4s, v1.4s
639 ; CHECK-NEXT:    ret
640   %noty = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1>
641   %c = icmp ult <4 x i32> %x, %noty
642   %s = select <4 x i1> %c, <4 x i32> %x, <4 x i32> %noty
643   %r = add <4 x i32> %s, %y
644   ret <4 x i32> %r
647 define <4 x i32> @unsigned_sat_variable_v4i32_using_cmp_sum(<4 x i32> %x, <4 x i32> %y) {
648 ; CHECK-LABEL: unsigned_sat_variable_v4i32_using_cmp_sum:
649 ; CHECK:       // %bb.0:
650 ; CHECK-NEXT:    add v1.4s, v0.4s, v1.4s
651 ; CHECK-NEXT:    cmhi v0.4s, v0.4s, v1.4s
652 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
653 ; CHECK-NEXT:    bic v0.4s, #0
654 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
655 ; CHECK-NEXT:    ret
656   %a = add <4 x i32> %x, %y
657   %c = icmp ugt <4 x i32> %x, %a
658   %r = select <4 x i1> %c, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> %a
659   ret <4 x i32> %r
662 define <4 x i32> @unsigned_sat_variable_v4i32_using_cmp_notval(<4 x i32> %x, <4 x i32> %y) {
663 ; CHECK-LABEL: unsigned_sat_variable_v4i32_using_cmp_notval:
664 ; CHECK:       // %bb.0:
665 ; CHECK-NEXT:    mvn v2.16b, v1.16b
666 ; CHECK-NEXT:    add v1.4s, v0.4s, v1.4s
667 ; CHECK-NEXT:    cmhi v0.4s, v0.4s, v2.4s
668 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
669 ; CHECK-NEXT:    bic v0.4s, #0
670 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
671 ; CHECK-NEXT:    ret
672   %noty = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1>
673   %a = add <4 x i32> %x, %y
674   %c = icmp ugt <4 x i32> %x, %noty
675   %r = select <4 x i1> %c, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, <4 x i32> %a
676   ret <4 x i32> %r
679 define <2 x i64> @unsigned_sat_variable_v2i64_using_min(<2 x i64> %x, <2 x i64> %y) {
680 ; CHECK-LABEL: unsigned_sat_variable_v2i64_using_min:
681 ; CHECK:       // %bb.0:
682 ; CHECK-NEXT:    mvn v2.16b, v1.16b
683 ; CHECK-NEXT:    cmhi v3.2d, v2.2d, v0.2d
684 ; CHECK-NEXT:    bsl v3.16b, v0.16b, v2.16b
685 ; CHECK-NEXT:    add v0.2d, v3.2d, v1.2d
686 ; CHECK-NEXT:    ret
687   %noty = xor <2 x i64> %y, <i64 -1, i64 -1>
688   %c = icmp ult <2 x i64> %x, %noty
689   %s = select <2 x i1> %c, <2 x i64> %x, <2 x i64> %noty
690   %r = add <2 x i64> %s, %y
691   ret <2 x i64> %r
694 define <2 x i64> @unsigned_sat_variable_v2i64_using_cmp_sum(<2 x i64> %x, <2 x i64> %y) {
695 ; CHECK-LABEL: unsigned_sat_variable_v2i64_using_cmp_sum:
696 ; CHECK:       // %bb.0:
697 ; CHECK-NEXT:    add v1.2d, v0.2d, v1.2d
698 ; CHECK-NEXT:    cmhi v0.2d, v0.2d, v1.2d
699 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
700 ; CHECK-NEXT:    bic v0.4s, #0
701 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
702 ; CHECK-NEXT:    ret
703   %a = add <2 x i64> %x, %y
704   %c = icmp ugt <2 x i64> %x, %a
705   %r = select <2 x i1> %c, <2 x i64> <i64 -1, i64 -1>, <2 x i64> %a
706   ret <2 x i64> %r
709 define <2 x i64> @unsigned_sat_variable_v2i64_using_cmp_notval(<2 x i64> %x, <2 x i64> %y) {
710 ; CHECK-LABEL: unsigned_sat_variable_v2i64_using_cmp_notval:
711 ; CHECK:       // %bb.0:
712 ; CHECK-NEXT:    mvn v2.16b, v1.16b
713 ; CHECK-NEXT:    add v1.2d, v0.2d, v1.2d
714 ; CHECK-NEXT:    cmhi v0.2d, v0.2d, v2.2d
715 ; CHECK-NEXT:    bic v1.16b, v1.16b, v0.16b
716 ; CHECK-NEXT:    bic v0.4s, #0
717 ; CHECK-NEXT:    orr v0.16b, v0.16b, v1.16b
718 ; CHECK-NEXT:    ret
719   %noty = xor <2 x i64> %y, <i64 -1, i64 -1>
720   %a = add <2 x i64> %x, %y
721   %c = icmp ugt <2 x i64> %x, %noty
722   %r = select <2 x i1> %c, <2 x i64> <i64 -1, i64 -1>, <2 x i64> %a
723   ret <2 x i64> %r