xref: /llvm-project/llvm/test/CodeGen/AArch64/neon-reverseshuffle.ll (revision 01c8cd664a9bea23a49c863a39351949ac11a4fd)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon < %s -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel < %s -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5define <2 x i64> @v2i64(<2 x i64> %a) {
6; CHECK-LABEL: v2i64:
7; CHECK:       // %bb.0: // %entry
8; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
9; CHECK-NEXT:    ret
10entry:
11  %V128 = shufflevector <2 x i64> %a, <2 x i64> undef, <2 x i32> <i32 1, i32 0>
12  ret <2 x i64> %V128
13}
14
15define <2 x ptr> @v2p0(<2 x ptr> %a) {
16; CHECK-LABEL: v2p0:
17; CHECK:       // %bb.0: // %entry
18; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
19; CHECK-NEXT:    ret
20entry:
21  %V128 = shufflevector <2 x ptr> %a, <2 x ptr> undef, <2 x i32> <i32 1, i32 0>
22  ret <2 x ptr> %V128
23}
24
25define <4 x i32> @v4i32(<4 x i32> %a) {
26; CHECK-LABEL: v4i32:
27; CHECK:       // %bb.0: // %entry
28; CHECK-NEXT:    rev64 v0.4s, v0.4s
29; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
30; CHECK-NEXT:    ret
31entry:
32  %V128 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
33  ret <4 x i32> %V128
34}
35
36define <2 x i32> @v2i32(<2 x i32> %a) {
37; CHECK-LABEL: v2i32:
38; CHECK:       // %bb.0: // %entry
39; CHECK-NEXT:    rev64 v0.2s, v0.2s
40; CHECK-NEXT:    ret
41entry:
42  %V128 = shufflevector <2 x i32> %a, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
43  ret <2 x i32> %V128
44}
45
46define <8 x i16> @v8i16(<8 x i16> %a) {
47; CHECK-LABEL: v8i16:
48; CHECK:       // %bb.0: // %entry
49; CHECK-NEXT:    rev64 v0.8h, v0.8h
50; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
51; CHECK-NEXT:    ret
52entry:
53  %V128 = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
54  ret <8 x i16> %V128
55}
56
57define <8 x i16> @v8i16_2(<4 x i16> %a, <4 x i16> %b) {
58; CHECK-SD-LABEL: v8i16_2:
59; CHECK-SD:       // %bb.0: // %entry
60; CHECK-SD-NEXT:    adrp x8, .LCPI5_0
61; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 killed $q0_q1 def $q0_q1
62; CHECK-SD-NEXT:    ldr q2, [x8, :lo12:.LCPI5_0]
63; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0_q1 def $q0_q1
64; CHECK-SD-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
65; CHECK-SD-NEXT:    ret
66;
67; CHECK-GI-LABEL: v8i16_2:
68; CHECK-GI:       // %bb.0: // %entry
69; CHECK-GI-NEXT:    adrp x8, .LCPI5_0
70; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0_q1 def $q0_q1
71; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI5_0]
72; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 killed $q0_q1 def $q0_q1
73; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
74; CHECK-GI-NEXT:    ret
75entry:
76  %V128 = shufflevector <4 x i16> %a, <4 x i16> %b, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
77  ret <8 x i16> %V128
78}
79
80define <4 x i16> @v8i16_3(<8 x i16> %a) {
81; CHECK-SD-LABEL: v8i16_3:
82; CHECK-SD:       // %bb.0: // %entry
83; CHECK-SD-NEXT:    rev64 v0.4h, v0.4h
84; CHECK-SD-NEXT:    ret
85;
86; CHECK-GI-LABEL: v8i16_3:
87; CHECK-GI:       // %bb.0: // %entry
88; CHECK-GI-NEXT:    rev64 v0.8h, v0.8h
89; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
90; CHECK-GI-NEXT:    ret
91entry:
92  %V128 = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
93  ret <4 x i16> %V128
94}
95
96define <4 x i16> @v4i16(<4 x i16> %a) {
97; CHECK-LABEL: v4i16:
98; CHECK:       // %bb.0: // %entry
99; CHECK-NEXT:    rev64 v0.4h, v0.4h
100; CHECK-NEXT:    ret
101entry:
102  %V128 = shufflevector <4 x i16> %a, <4 x i16> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
103  ret <4 x i16> %V128
104}
105
106define <16 x i8> @v16i8(<16 x i8> %a) {
107; CHECK-LABEL: v16i8:
108; CHECK:       // %bb.0: // %entry
109; CHECK-NEXT:    rev64 v0.16b, v0.16b
110; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
111; CHECK-NEXT:    ret
112entry:
113  %V128 = shufflevector <16 x i8> %a, <16 x i8> undef, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
114  ret <16 x i8> %V128
115}
116
117define <16 x i8> @v16i8_2(<8 x i8> %a, <8 x i8> %b) {
118; CHECK-SD-LABEL: v16i8_2:
119; CHECK-SD:       // %bb.0: // %entry
120; CHECK-SD-NEXT:    adrp x8, .LCPI9_0
121; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 killed $q0_q1 def $q0_q1
122; CHECK-SD-NEXT:    ldr q2, [x8, :lo12:.LCPI9_0]
123; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0_q1 def $q0_q1
124; CHECK-SD-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
125; CHECK-SD-NEXT:    ret
126;
127; CHECK-GI-LABEL: v16i8_2:
128; CHECK-GI:       // %bb.0: // %entry
129; CHECK-GI-NEXT:    adrp x8, .LCPI9_0
130; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0_q1 def $q0_q1
131; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI9_0]
132; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 killed $q0_q1 def $q0_q1
133; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
134; CHECK-GI-NEXT:    ret
135entry:
136  %V128 = shufflevector <8 x i8> %a, <8 x i8> %b, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
137  ret <16 x i8> %V128
138}
139
140define <8 x i8> @v8i8(<8 x i8> %a) {
141; CHECK-LABEL: v8i8:
142; CHECK:       // %bb.0: // %entry
143; CHECK-NEXT:    rev64 v0.8b, v0.8b
144; CHECK-NEXT:    ret
145entry:
146  %V128 = shufflevector <8 x i8> %a, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
147  ret <8 x i8> %V128
148}
149
150define <2 x double> @v2f64(<2 x double> %a) {
151; CHECK-LABEL: v2f64:
152; CHECK:       // %bb.0: // %entry
153; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
154; CHECK-NEXT:    ret
155entry:
156  %V128 = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> <i32 1, i32 0>
157  ret <2 x double> %V128
158}
159
160define <4 x float> @v4f32(<4 x float> %a) {
161; CHECK-LABEL: v4f32:
162; CHECK:       // %bb.0: // %entry
163; CHECK-NEXT:    rev64 v0.4s, v0.4s
164; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
165; CHECK-NEXT:    ret
166entry:
167  %V128 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
168  ret <4 x float> %V128
169}
170
171define <2 x float> @v2f32(<2 x float> %a) {
172; CHECK-LABEL: v2f32:
173; CHECK:       // %bb.0: // %entry
174; CHECK-NEXT:    rev64 v0.2s, v0.2s
175; CHECK-NEXT:    ret
176entry:
177  %V128 = shufflevector <2 x float> %a, <2 x float> undef, <2 x i32> <i32 1, i32 0>
178  ret <2 x float> %V128
179}
180
181define <8 x half> @v8f16(<8 x half> %a) {
182; CHECK-LABEL: v8f16:
183; CHECK:       // %bb.0: // %entry
184; CHECK-NEXT:    rev64 v0.8h, v0.8h
185; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
186; CHECK-NEXT:    ret
187entry:
188  %V128 = shufflevector <8 x half> %a, <8 x half> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
189  ret <8 x half> %V128
190}
191
192define <4 x half> @v4f16(<4 x half> %a) {
193; CHECK-LABEL: v4f16:
194; CHECK:       // %bb.0: // %entry
195; CHECK-NEXT:    rev64 v0.4h, v0.4h
196; CHECK-NEXT:    ret
197entry:
198  %V128 = shufflevector <4 x half> %a, <4 x half> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
199  ret <4 x half> %V128
200}
201