[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / extract-sext-zext.ll
blobf566ebb4f208920c06f63c070a8f5d1cb9200da3
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ISEL
3 ; RUN: llc -mtriple=aarch64-eabi -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL
5 define i64 @extract_v2i64(<2 x i64> %x, i32 %y) {
6 ; CHECK-ISEL-LABEL: extract_v2i64:
7 ; CHECK-ISEL:       // %bb.0:
8 ; CHECK-ISEL-NEXT:    mov x0, v0.d[1]
9 ; CHECK-ISEL-NEXT:    ret
11 ; CHECK-GLOBAL-LABEL: extract_v2i64:
12 ; CHECK-GLOBAL:       // %bb.0:
13 ; CHECK-GLOBAL-NEXT:    mov d0, v0.d[1]
14 ; CHECK-GLOBAL-NEXT:    fmov x0, d0
15 ; CHECK-GLOBAL-NEXT:    ret
16   %ext = extractelement <2 x i64> %x, i32 1
17   ret i64 %ext
20 define i64 @extract_v1i64(<1 x i64> %x, i32 %y) {
21 ; CHECK-ISEL-LABEL: extract_v1i64:
22 ; CHECK-ISEL:       // %bb.0:
23 ; CHECK-ISEL-NEXT:    ret
25 ; CHECK-GLOBAL-LABEL: extract_v1i64:
26 ; CHECK-GLOBAL:       // %bb.0:
27 ; CHECK-GLOBAL-NEXT:    fmov x0, d0
28 ; CHECK-GLOBAL-NEXT:    ret
29   %ext = extractelement <1 x i64> %x, i32 1
30   ret i64 %ext
33 define i32 @extract_v4i32(<4 x i32> %x, i32 %y) {
34 ; CHECK-ISEL-LABEL: extract_v4i32:
35 ; CHECK-ISEL:       // %bb.0:
36 ; CHECK-ISEL-NEXT:    mov w0, v0.s[1]
37 ; CHECK-ISEL-NEXT:    ret
39 ; CHECK-GLOBAL-LABEL: extract_v4i32:
40 ; CHECK-GLOBAL:       // %bb.0:
41 ; CHECK-GLOBAL-NEXT:    mov s0, v0.s[1]
42 ; CHECK-GLOBAL-NEXT:    fmov w0, s0
43 ; CHECK-GLOBAL-NEXT:    ret
44   %ext = extractelement <4 x i32> %x, i32 1
45   ret i32 %ext
48 define i32 @extract_v2i32(<2 x i32> %x, i32 %y) {
49 ; CHECK-ISEL-LABEL: extract_v2i32:
50 ; CHECK-ISEL:       // %bb.0:
51 ; CHECK-ISEL-NEXT:    // kill: def $d0 killed $d0 def $q0
52 ; CHECK-ISEL-NEXT:    mov w0, v0.s[1]
53 ; CHECK-ISEL-NEXT:    ret
55 ; CHECK-GLOBAL-LABEL: extract_v2i32:
56 ; CHECK-GLOBAL:       // %bb.0:
57 ; CHECK-GLOBAL-NEXT:    // kill: def $d0 killed $d0 def $q0
58 ; CHECK-GLOBAL-NEXT:    mov s0, v0.s[1]
59 ; CHECK-GLOBAL-NEXT:    fmov w0, s0
60 ; CHECK-GLOBAL-NEXT:    ret
61   %ext = extractelement <2 x i32> %x, i32 1
62   ret i32 %ext
65 define i16 @extract_v8i16(<8 x i16> %x, i32 %y) {
66 ; CHECK-LABEL: extract_v8i16:
67 ; CHECK:       // %bb.0:
68 ; CHECK-NEXT:    umov w0, v0.h[1]
69 ; CHECK-NEXT:    ret
70   %ext = extractelement <8 x i16> %x, i32 1
71   ret i16 %ext
74 define i16 @extract_v4i16(<4 x i16> %x, i32 %y) {
75 ; CHECK-LABEL: extract_v4i16:
76 ; CHECK:       // %bb.0:
77 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
78 ; CHECK-NEXT:    umov w0, v0.h[1]
79 ; CHECK-NEXT:    ret
80   %ext = extractelement <4 x i16> %x, i32 1
81   ret i16 %ext
84 define i8 @extract_v16i8(<16 x i8> %x, i32 %y) {
85 ; CHECK-LABEL: extract_v16i8:
86 ; CHECK:       // %bb.0:
87 ; CHECK-NEXT:    umov w0, v0.b[1]
88 ; CHECK-NEXT:    ret
89   %ext = extractelement <16 x i8> %x, i32 1
90   ret i8 %ext
93 define i8 @extract_v8i8(<8 x i8> %x, i32 %y) {
94 ; CHECK-LABEL: extract_v8i8:
95 ; CHECK:       // %bb.0:
96 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
97 ; CHECK-NEXT:    umov w0, v0.b[1]
98 ; CHECK-NEXT:    ret
99   %ext = extractelement <8 x i8> %x, i32 1
100   ret i8 %ext
104 define i64 @sv2i32i64(<2 x i32> %x) {
105 ; CHECK-LABEL: sv2i32i64:
106 ; CHECK:       // %bb.0:
107 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
108 ; CHECK-NEXT:    smov x0, v0.s[1]
109 ; CHECK-NEXT:    ret
110   %e = extractelement <2 x i32> %x, i64 1
111   %s = sext i32 %e to i64
112   ret i64 %s
115 define i64 @sv4i32i64(<4 x i32> %x) {
116 ; CHECK-LABEL: sv4i32i64:
117 ; CHECK:       // %bb.0:
118 ; CHECK-NEXT:    smov x0, v0.s[2]
119 ; CHECK-NEXT:    ret
120   %e = extractelement <4 x i32> %x, i64 2
121   %s = sext i32 %e to i64
122   ret i64 %s
125 define i64 @sv4i16i64(<4 x i16> %x) {
126 ; CHECK-LABEL: sv4i16i64:
127 ; CHECK:       // %bb.0:
128 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
129 ; CHECK-NEXT:    smov x0, v0.h[2]
130 ; CHECK-NEXT:    ret
131   %e = extractelement <4 x i16> %x, i64 2
132   %s = sext i16 %e to i64
133   ret i64 %s
136 define i64 @sv8i16i64(<8 x i16> %x) {
137 ; CHECK-LABEL: sv8i16i64:
138 ; CHECK:       // %bb.0:
139 ; CHECK-NEXT:    smov x0, v0.h[2]
140 ; CHECK-NEXT:    ret
141   %e = extractelement <8 x i16> %x, i64 2
142   %s = sext i16 %e to i64
143   ret i64 %s
146 define i64 @sv8i8i64(<8 x i8> %x) {
147 ; CHECK-LABEL: sv8i8i64:
148 ; CHECK:       // %bb.0:
149 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
150 ; CHECK-NEXT:    smov x0, v0.b[2]
151 ; CHECK-NEXT:    ret
152   %e = extractelement <8 x i8> %x, i64 2
153   %s = sext i8 %e to i64
154   ret i64 %s
157 define i64 @sv16i8i64(<16 x i8> %x) {
158 ; CHECK-LABEL: sv16i8i64:
159 ; CHECK:       // %bb.0:
160 ; CHECK-NEXT:    smov x0, v0.b[2]
161 ; CHECK-NEXT:    ret
162   %e = extractelement <16 x i8> %x, i64 2
163   %s = sext i8 %e to i64
164   ret i64 %s
167 define i32 @sv8i16i32(<8 x i16> %x) {
168 ; CHECK-LABEL: sv8i16i32:
169 ; CHECK:       // %bb.0:
170 ; CHECK-NEXT:    smov w0, v0.h[2]
171 ; CHECK-NEXT:    ret
172   %e = extractelement <8 x i16> %x, i64 2
173   %s = sext i16 %e to i32
174   ret i32 %s
177 define i32 @sv4i16i32(<4 x i16> %x) {
178 ; CHECK-LABEL: sv4i16i32:
179 ; CHECK:       // %bb.0:
180 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
181 ; CHECK-NEXT:    smov w0, v0.h[2]
182 ; CHECK-NEXT:    ret
183   %e = extractelement <4 x i16> %x, i64 2
184   %s = sext i16 %e to i32
185   ret i32 %s
188 define i32 @sv16i8i32(<16 x i8> %x) {
189 ; CHECK-LABEL: sv16i8i32:
190 ; CHECK:       // %bb.0:
191 ; CHECK-NEXT:    smov w0, v0.b[2]
192 ; CHECK-NEXT:    ret
193   %e = extractelement <16 x i8> %x, i64 2
194   %s = sext i8 %e to i32
195   ret i32 %s
198 define i32 @sv8i8i32(<8 x i8> %x) {
199 ; CHECK-LABEL: sv8i8i32:
200 ; CHECK:       // %bb.0:
201 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
202 ; CHECK-NEXT:    smov w0, v0.b[2]
203 ; CHECK-NEXT:    ret
204   %e = extractelement <8 x i8> %x, i64 2
205   %s = sext i8 %e to i32
206   ret i32 %s
209 define i16 @sv16i8i16(<16 x i8> %x) {
210 ; CHECK-LABEL: sv16i8i16:
211 ; CHECK:       // %bb.0:
212 ; CHECK-NEXT:    smov w0, v0.b[2]
213 ; CHECK-NEXT:    ret
214   %e = extractelement <16 x i8> %x, i64 2
215   %s = sext i8 %e to i16
216   ret i16 %s
219 define i16 @sv8i8i16(<8 x i8> %x) {
220 ; CHECK-LABEL: sv8i8i16:
221 ; CHECK:       // %bb.0:
222 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
223 ; CHECK-NEXT:    smov w0, v0.b[2]
224 ; CHECK-NEXT:    ret
225   %e = extractelement <8 x i8> %x, i64 2
226   %s = sext i8 %e to i16
227   ret i16 %s
232 define i64 @zv2i32i64(<2 x i32> %x) {
233 ; CHECK-LABEL: zv2i32i64:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
236 ; CHECK-NEXT:    mov w0, v0.s[1]
237 ; CHECK-NEXT:    ret
238   %e = extractelement <2 x i32> %x, i64 1
239   %s = zext i32 %e to i64
240   ret i64 %s
243 define i64 @zv4i32i64(<4 x i32> %x) {
244 ; CHECK-LABEL: zv4i32i64:
245 ; CHECK:       // %bb.0:
246 ; CHECK-NEXT:    mov w0, v0.s[2]
247 ; CHECK-NEXT:    ret
248   %e = extractelement <4 x i32> %x, i64 2
249   %s = zext i32 %e to i64
250   ret i64 %s
253 define i64 @zv4i16i64(<4 x i16> %x) {
254 ; CHECK-LABEL: zv4i16i64:
255 ; CHECK:       // %bb.0:
256 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
257 ; CHECK-NEXT:    umov w0, v0.h[2]
258 ; CHECK-NEXT:    ret
259   %e = extractelement <4 x i16> %x, i64 2
260   %s = zext i16 %e to i64
261   ret i64 %s
264 define i64 @zv8i16i64(<8 x i16> %x) {
265 ; CHECK-LABEL: zv8i16i64:
266 ; CHECK:       // %bb.0:
267 ; CHECK-NEXT:    umov w0, v0.h[2]
268 ; CHECK-NEXT:    ret
269   %e = extractelement <8 x i16> %x, i64 2
270   %s = zext i16 %e to i64
271   ret i64 %s
274 define i64 @zv8i8i64(<8 x i8> %x) {
275 ; CHECK-LABEL: zv8i8i64:
276 ; CHECK:       // %bb.0:
277 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
278 ; CHECK-NEXT:    umov w0, v0.b[2]
279 ; CHECK-NEXT:    ret
280   %e = extractelement <8 x i8> %x, i64 2
281   %s = zext i8 %e to i64
282   ret i64 %s
285 define i64 @zv16i8i64(<16 x i8> %x) {
286 ; CHECK-LABEL: zv16i8i64:
287 ; CHECK:       // %bb.0:
288 ; CHECK-NEXT:    umov w0, v0.b[2]
289 ; CHECK-NEXT:    ret
290   %e = extractelement <16 x i8> %x, i64 2
291   %s = zext i8 %e to i64
292   ret i64 %s
295 define i32 @zv8i16i32(<8 x i16> %x) {
296 ; CHECK-LABEL: zv8i16i32:
297 ; CHECK:       // %bb.0:
298 ; CHECK-NEXT:    umov w0, v0.h[2]
299 ; CHECK-NEXT:    ret
300   %e = extractelement <8 x i16> %x, i64 2
301   %s = zext i16 %e to i32
302   ret i32 %s
305 define i32 @zv4i16i32(<4 x i16> %x) {
306 ; CHECK-LABEL: zv4i16i32:
307 ; CHECK:       // %bb.0:
308 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
309 ; CHECK-NEXT:    umov w0, v0.h[2]
310 ; CHECK-NEXT:    ret
311   %e = extractelement <4 x i16> %x, i64 2
312   %s = zext i16 %e to i32
313   ret i32 %s
316 define i32 @zv16i8i32(<16 x i8> %x) {
317 ; CHECK-LABEL: zv16i8i32:
318 ; CHECK:       // %bb.0:
319 ; CHECK-NEXT:    umov w0, v0.b[2]
320 ; CHECK-NEXT:    ret
321   %e = extractelement <16 x i8> %x, i64 2
322   %s = zext i8 %e to i32
323   ret i32 %s
326 define i32 @zv8i8i32(<8 x i8> %x) {
327 ; CHECK-LABEL: zv8i8i32:
328 ; CHECK:       // %bb.0:
329 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
330 ; CHECK-NEXT:    umov w0, v0.b[2]
331 ; CHECK-NEXT:    ret
332   %e = extractelement <8 x i8> %x, i64 2
333   %s = zext i8 %e to i32
334   ret i32 %s
337 define i16 @zv16i8i16(<16 x i8> %x) {
338 ; CHECK-LABEL: zv16i8i16:
339 ; CHECK:       // %bb.0:
340 ; CHECK-NEXT:    umov w0, v0.b[2]
341 ; CHECK-NEXT:    ret
342   %e = extractelement <16 x i8> %x, i64 2
343   %s = zext i8 %e to i16
344   ret i16 %s
347 define i16 @zv8i8i16(<8 x i8> %x) {
348 ; CHECK-LABEL: zv8i8i16:
349 ; CHECK:       // %bb.0:
350 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
351 ; CHECK-NEXT:    umov w0, v0.b[2]
352 ; CHECK-NEXT:    ret
353   %e = extractelement <8 x i8> %x, i64 2
354   %s = zext i8 %e to i16
355   ret i16 %s
359 define i32 @both_i16i32(<8 x i16> %x) {
360 ; CHECK-LABEL: both_i16i32:
361 ; CHECK:       // %bb.0:
362 ; CHECK-NEXT:    umov w8, v0.h[2]
363 ; CHECK-NEXT:    smov w9, v0.h[2]
364 ; CHECK-NEXT:    eor w0, w8, w9
365 ; CHECK-NEXT:    ret
366   %e = extractelement <8 x i16> %x, i64 2
367   %s = zext i16 %e to i32
368   %t = sext i16 %e to i32
369   %u = xor i32 %s, %t
370   ret i32 %u
373 define i32 @redundant_i16i32(<8 x i16> %x) {
374 ; CHECK-LABEL: redundant_i16i32:
375 ; CHECK:       // %bb.0:
376 ; CHECK-NEXT:    smov w8, v0.h[2]
377 ; CHECK-NEXT:    eor w0, w8, w8, lsl #16
378 ; CHECK-NEXT:    ret
379   %e = extractelement <8 x i16> %x, i64 2
380   %s = sext i16 %e to i32
381   %t = shl i32 %s, 16
382   %u = xor i32 %s, %t
383   ret i32 %u
386 define i32 @both_i8i32(<8 x i8> %x) {
387 ; CHECK-LABEL: both_i8i32:
388 ; CHECK:       // %bb.0:
389 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
390 ; CHECK-NEXT:    umov w8, v0.b[2]
391 ; CHECK-NEXT:    smov w9, v0.b[2]
392 ; CHECK-NEXT:    eor w0, w8, w9
393 ; CHECK-NEXT:    ret
394   %e = extractelement <8 x i8> %x, i64 2
395   %s = zext i8 %e to i32
396   %t = sext i8 %e to i32
397   %u = xor i32 %s, %t
398   ret i32 %u
401 define i32 @redundant_i8i32(<8 x i8> %x) {
402 ; CHECK-LABEL: redundant_i8i32:
403 ; CHECK:       // %bb.0:
404 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
405 ; CHECK-NEXT:    smov w8, v0.b[2]
406 ; CHECK-NEXT:    eor w0, w8, w8, lsl #24
407 ; CHECK-NEXT:    ret
408   %e = extractelement <8 x i8> %x, i64 2
409   %s = sext i8 %e to i32
410   %t = shl i32 %s, 24
411   %u = xor i32 %s, %t
412   ret i32 %u
415 define i64 @both_i32i64(<4 x i32> %x) {
416 ; CHECK-LABEL: both_i32i64:
417 ; CHECK:       // %bb.0:
418 ; CHECK-NEXT:    mov w8, v0.s[2]
419 ; CHECK-NEXT:    smov x9, v0.s[2]
420 ; CHECK-NEXT:    eor x0, x8, x9
421 ; CHECK-NEXT:    ret
422   %e = extractelement <4 x i32> %x, i64 2
423   %s = zext i32 %e to i64
424   %t = sext i32 %e to i64
425   %u = xor i64 %s, %t
426   ret i64 %u
429 define i64 @redundant_i32i64(<4 x i32> %x) {
430 ; CHECK-LABEL: redundant_i32i64:
431 ; CHECK:       // %bb.0:
432 ; CHECK-NEXT:    smov x8, v0.s[2]
433 ; CHECK-NEXT:    eor x0, x8, x8, lsl #32
434 ; CHECK-NEXT:    ret
435   %e = extractelement <4 x i32> %x, i64 2
436   %s = sext i32 %e to i64
437   %t = shl i64 %s, 32
438   %u = xor i64 %s, %t
439   ret i64 %u
442 define i64 @both_i16i64(<8 x i16> %x) {
443 ; CHECK-LABEL: both_i16i64:
444 ; CHECK:       // %bb.0:
445 ; CHECK-NEXT:    umov w8, v0.h[2]
446 ; CHECK-NEXT:    smov x9, v0.h[2]
447 ; CHECK-NEXT:    eor x0, x8, x9
448 ; CHECK-NEXT:    ret
449   %e = extractelement <8 x i16> %x, i64 2
450   %s = zext i16 %e to i64
451   %t = sext i16 %e to i64
452   %u = xor i64 %s, %t
453   ret i64 %u
456 define i64 @redundant_i16i64(<8 x i16> %x) {
457 ; CHECK-LABEL: redundant_i16i64:
458 ; CHECK:       // %bb.0:
459 ; CHECK-NEXT:    smov x8, v0.h[2]
460 ; CHECK-NEXT:    eor x0, x8, x8, lsl #48
461 ; CHECK-NEXT:    ret
462   %e = extractelement <8 x i16> %x, i64 2
463   %s = sext i16 %e to i64
464   %t = shl i64 %s, 48
465   %u = xor i64 %s, %t
466   ret i64 %u
469 define i64 @both_i8i64(<8 x i8> %x) {
470 ; CHECK-LABEL: both_i8i64:
471 ; CHECK:       // %bb.0:
472 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
473 ; CHECK-NEXT:    umov w8, v0.b[2]
474 ; CHECK-NEXT:    smov x9, v0.b[2]
475 ; CHECK-NEXT:    eor x0, x8, x9
476 ; CHECK-NEXT:    ret
477   %e = extractelement <8 x i8> %x, i64 2
478   %s = zext i8 %e to i64
479   %t = sext i8 %e to i64
480   %u = xor i64 %s, %t
481   ret i64 %u
484 define i64 @redundant_i8i64(<8 x i8> %x) {
485 ; CHECK-LABEL: redundant_i8i64:
486 ; CHECK:       // %bb.0:
487 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
488 ; CHECK-NEXT:    smov x8, v0.b[2]
489 ; CHECK-NEXT:    eor x0, x8, x8, lsl #56
490 ; CHECK-NEXT:    ret
491   %e = extractelement <8 x i8> %x, i64 2
492   %s = sext i8 %e to i64
493   %t = shl i64 %s, 56
494   %u = xor i64 %s, %t
495   ret i64 %u