xref: /llvm-project/llvm/test/CodeGen/AArch64/extract-sext-zext.ll (revision 3d18c8cd265c0c0bf1d85226c4770a2dd0f86e8f)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ISEL
3; RUN: llc -mtriple=aarch64 -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL
4
5define 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
10;
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
18}
19
20define 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
24;
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
31}
32
33define 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
38;
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
46}
47
48define 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
54;
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
63}
64
65define 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
72}
73
74define 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
82}
83
84define 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
91}
92
93define 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
101}
102
103
104define 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
113}
114
115define 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
123}
124
125define 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
134}
135
136define 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
144}
145
146define 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
155}
156
157define 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
165}
166
167define 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
175}
176
177define 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
186}
187
188define 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
196}
197
198define 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
207}
208
209define 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
217}
218
219define 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
228}
229
230
231
232define 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
241}
242
243define 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
251}
252
253define 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
262}
263
264define 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
272}
273
274define 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
283}
284
285define 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
293}
294
295define 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
303}
304
305define 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
314}
315
316define 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
324}
325
326define 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
335}
336
337define 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
345}
346
347define 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
356}
357
358
359define 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
371}
372
373define 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
384}
385
386define 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
399}
400
401define 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
413}
414
415define 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
427}
428
429define 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
440}
441
442define 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
454}
455
456define 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
467}
468
469define 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
482}
483
484define 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
496}
497