xref: /llvm-project/llvm/test/CodeGen/AArch64/named-vector-shuffle-reverse-sve.ll (revision bfc0317153dca75137fba00b5c28758d6f720963)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs  < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-SELDAG  %s
3; RUN: llc -verify-machineinstrs -O0 < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FASTISEL %s
4
5target triple = "aarch64-unknown-linux-gnu"
6
7;
8; VECTOR_REVERSE - PPR
9;
10
11define <vscale x 2 x i1> @reverse_nxv2i1(<vscale x 2 x i1> %a) #0 {
12; CHECK-LABEL: reverse_nxv2i1:
13; CHECK:       // %bb.0:
14; CHECK-NEXT:    rev p0.d, p0.d
15; CHECK-NEXT:    ret
16
17  %res = call <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1> %a)
18  ret <vscale x 2 x i1> %res
19}
20
21define <vscale x 4 x i1> @reverse_nxv4i1(<vscale x 4 x i1> %a) #0 {
22; CHECK-LABEL: reverse_nxv4i1:
23; CHECK:       // %bb.0:
24; CHECK-NEXT:    rev p0.s, p0.s
25; CHECK-NEXT:    ret
26
27  %res = call <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1> %a)
28  ret <vscale x 4 x i1> %res
29}
30
31define <vscale x 8 x i1> @reverse_nxv8i1(<vscale x 8 x i1> %a) #0 {
32; CHECK-LABEL: reverse_nxv8i1:
33; CHECK:       // %bb.0:
34; CHECK-NEXT:    rev p0.h, p0.h
35; CHECK-NEXT:    ret
36
37  %res = call <vscale x 8 x i1> @llvm.vector.reverse.nxv8i1(<vscale x 8 x i1> %a)
38  ret <vscale x 8 x i1> %res
39}
40
41define <vscale x 16 x i1> @reverse_nxv16i1(<vscale x 16 x i1> %a) #0 {
42; CHECK-LABEL: reverse_nxv16i1:
43; CHECK:       // %bb.0:
44; CHECK-NEXT:    rev p0.b, p0.b
45; CHECK-NEXT:    ret
46
47  %res = call <vscale x 16 x i1> @llvm.vector.reverse.nxv16i1(<vscale x 16 x i1> %a)
48  ret <vscale x 16 x i1> %res
49}
50
51; Verify splitvec type legalisation works as expected.
52define <vscale x 32 x i1> @reverse_nxv32i1(<vscale x 32 x i1> %a) #0 {
53; CHECK-SELDAG-LABEL: reverse_nxv32i1:
54; CHECK-SELDAG:       // %bb.0:
55; CHECK-SELDAG-NEXT:    rev p2.b, p1.b
56; CHECK-SELDAG-NEXT:    rev p1.b, p0.b
57; CHECK-SELDAG-NEXT:    mov p0.b, p2.b
58; CHECK-SELDAG-NEXT:    ret
59;
60; CHECK-FASTISEL-LABEL: reverse_nxv32i1:
61; CHECK-FASTISEL:       // %bb.0:
62; CHECK-FASTISEL-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
63; CHECK-FASTISEL-NEXT:    addvl sp, sp, #-1
64; CHECK-FASTISEL-NEXT:    str p1, [sp, #7, mul vl] // 2-byte Folded Spill
65; CHECK-FASTISEL-NEXT:    mov p1.b, p0.b
66; CHECK-FASTISEL-NEXT:    ldr p0, [sp, #7, mul vl] // 2-byte Folded Reload
67; CHECK-FASTISEL-NEXT:    rev p0.b, p0.b
68; CHECK-FASTISEL-NEXT:    rev p1.b, p1.b
69; CHECK-FASTISEL-NEXT:    addvl sp, sp, #1
70; CHECK-FASTISEL-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
71; CHECK-FASTISEL-NEXT:    ret
72
73  %res = call <vscale x 32 x i1> @llvm.vector.reverse.nxv32i1(<vscale x 32 x i1> %a)
74  ret <vscale x 32 x i1> %res
75}
76
77;
78; VECTOR_REVERSE - ZPR
79;
80
81define <vscale x 16 x i8> @reverse_nxv16i8(<vscale x 16 x i8> %a) #0 {
82; CHECK-LABEL: reverse_nxv16i8:
83; CHECK:       // %bb.0:
84; CHECK-NEXT:    rev z0.b, z0.b
85; CHECK-NEXT:    ret
86
87  %res = call <vscale x 16 x i8> @llvm.vector.reverse.nxv16i8(<vscale x 16 x i8> %a)
88  ret <vscale x 16 x i8> %res
89}
90
91define <vscale x 8 x i16> @reverse_nxv8i16(<vscale x 8 x i16> %a) #0 {
92; CHECK-LABEL: reverse_nxv8i16:
93; CHECK:       // %bb.0:
94; CHECK-NEXT:    rev z0.h, z0.h
95; CHECK-NEXT:    ret
96
97  %res = call <vscale x 8 x i16> @llvm.vector.reverse.nxv8i16(<vscale x 8 x i16> %a)
98  ret <vscale x 8 x i16> %res
99}
100
101define <vscale x 4 x i32> @reverse_nxv4i32(<vscale x 4 x i32> %a) #0 {
102; CHECK-LABEL: reverse_nxv4i32:
103; CHECK:       // %bb.0:
104; CHECK-NEXT:    rev z0.s, z0.s
105; CHECK-NEXT:    ret
106
107  %res = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> %a)
108  ret <vscale x 4 x i32> %res
109}
110
111define <vscale x 2 x i64> @reverse_nxv2i64(<vscale x 2 x i64> %a) #0 {
112; CHECK-LABEL: reverse_nxv2i64:
113; CHECK:       // %bb.0:
114; CHECK-NEXT:    rev z0.d, z0.d
115; CHECK-NEXT:    ret
116
117  %res = call <vscale x 2 x i64> @llvm.vector.reverse.nxv2i64(<vscale x 2 x i64> %a)
118  ret <vscale x 2 x i64> %res
119}
120
121define <vscale x 2 x half> @reverse_nxv2f16(<vscale x 2 x half> %a) #0 {
122; CHECK-LABEL: reverse_nxv2f16:
123; CHECK:       // %bb.0:
124; CHECK-NEXT:    rev z0.d, z0.d
125; CHECK-NEXT:    ret
126
127  %res = call <vscale x 2 x half> @llvm.vector.reverse.nxv2f16(<vscale x 2 x half> %a)
128  ret <vscale x 2 x half> %res
129}
130
131define <vscale x 4 x half> @reverse_nxv4f16(<vscale x 4 x half> %a) #0 {
132; CHECK-LABEL: reverse_nxv4f16:
133; CHECK:       // %bb.0:
134; CHECK-NEXT:    rev z0.s, z0.s
135; CHECK-NEXT:    ret
136
137  %res = call <vscale x 4 x half> @llvm.vector.reverse.nxv4f16(<vscale x 4 x half> %a)
138  ret <vscale x 4 x half> %res
139}
140
141define <vscale x 8 x half> @reverse_nxv8f16(<vscale x 8 x half> %a) #0 {
142; CHECK-LABEL: reverse_nxv8f16:
143; CHECK:       // %bb.0:
144; CHECK-NEXT:    rev z0.h, z0.h
145; CHECK-NEXT:    ret
146
147  %res = call <vscale x 8 x half> @llvm.vector.reverse.nxv8f16(<vscale x 8 x half> %a)
148  ret <vscale x 8 x half> %res
149}
150
151define <vscale x 2 x bfloat> @reverse_nxv2bf16(<vscale x 2 x bfloat> %a) #1 {
152; CHECK-LABEL: reverse_nxv2bf16:
153; CHECK:       // %bb.0:
154; CHECK-NEXT:    rev z0.d, z0.d
155; CHECK-NEXT:    ret
156
157  %res = call <vscale x 2 x bfloat> @llvm.vector.reverse.nxv2bf16(<vscale x 2 x bfloat> %a)
158  ret <vscale x 2 x bfloat> %res
159}
160
161define <vscale x 4 x bfloat> @reverse_nxv4bf16(<vscale x 4 x bfloat> %a) #1 {
162; CHECK-LABEL: reverse_nxv4bf16:
163; CHECK:       // %bb.0:
164; CHECK-NEXT:    rev z0.s, z0.s
165; CHECK-NEXT:    ret
166
167  %res = call <vscale x 4 x bfloat> @llvm.vector.reverse.nxv4bf16(<vscale x 4 x bfloat> %a)
168  ret <vscale x 4 x bfloat> %res
169}
170
171define <vscale x 8 x bfloat> @reverse_nxv8bf16(<vscale x 8 x bfloat> %a) #1 {
172; CHECK-LABEL: reverse_nxv8bf16:
173; CHECK:       // %bb.0:
174; CHECK-NEXT:    rev z0.h, z0.h
175; CHECK-NEXT:    ret
176
177  %res = call <vscale x 8 x bfloat> @llvm.vector.reverse.nxv8bf16(<vscale x 8 x bfloat> %a)
178  ret <vscale x 8 x bfloat> %res
179}
180
181define <vscale x 2 x float> @reverse_nxv2f32(<vscale x 2 x float> %a) #0 {
182; CHECK-LABEL: reverse_nxv2f32:
183; CHECK:       // %bb.0:
184; CHECK-NEXT:    rev z0.d, z0.d
185; CHECK-NEXT:    ret
186
187  %res = call <vscale x 2 x float> @llvm.vector.reverse.nxv2f32(<vscale x 2 x float> %a)  ret <vscale x 2 x float> %res
188}
189
190define <vscale x 4 x float> @reverse_nxv4f32(<vscale x 4 x float> %a) #0 {
191; CHECK-LABEL: reverse_nxv4f32:
192; CHECK:       // %bb.0:
193; CHECK-NEXT:    rev z0.s, z0.s
194; CHECK-NEXT:    ret
195
196  %res = call <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float> %a)  ret <vscale x 4 x float> %res
197}
198
199define <vscale x 2 x double> @reverse_nxv2f64(<vscale x 2 x double> %a) #0 {
200; CHECK-LABEL: reverse_nxv2f64:
201; CHECK:       // %bb.0:
202; CHECK-NEXT:    rev z0.d, z0.d
203; CHECK-NEXT:    ret
204
205  %res = call <vscale x 2 x double> @llvm.vector.reverse.nxv2f64(<vscale x 2 x double> %a)
206  ret <vscale x 2 x double> %res
207}
208
209; Verify promote type legalisation works as expected.
210define <vscale x 2 x i8> @reverse_nxv2i8(<vscale x 2 x i8> %a) #0 {
211; CHECK-LABEL: reverse_nxv2i8:
212; CHECK:       // %bb.0:
213; CHECK-NEXT:    rev z0.d, z0.d
214; CHECK-NEXT:    ret
215
216  %res = call <vscale x 2 x i8> @llvm.vector.reverse.nxv2i8(<vscale x 2 x i8> %a)
217  ret <vscale x 2 x i8> %res
218}
219
220; Verify splitvec type legalisation works as expected.
221define <vscale x 8 x i32> @reverse_nxv8i32(<vscale x 8 x i32> %a) #0 {
222; CHECK-SELDAG-LABEL: reverse_nxv8i32:
223; CHECK-SELDAG:       // %bb.0:
224; CHECK-SELDAG-NEXT:    rev z2.s, z1.s
225; CHECK-SELDAG-NEXT:    rev z1.s, z0.s
226; CHECK-SELDAG-NEXT:    mov z0.d, z2.d
227; CHECK-SELDAG-NEXT:    ret
228;
229; CHECK-FASTISEL-LABEL: reverse_nxv8i32:
230; CHECK-FASTISEL:       // %bb.0:
231; CHECK-FASTISEL-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
232; CHECK-FASTISEL-NEXT:    addvl sp, sp, #-1
233; CHECK-FASTISEL-NEXT:    str z1, [sp] // 16-byte Folded Spill
234; CHECK-FASTISEL-NEXT:    mov z1.d, z0.d
235; CHECK-FASTISEL-NEXT:    ldr z0, [sp] // 16-byte Folded Reload
236; CHECK-FASTISEL-NEXT:    rev z0.s, z0.s
237; CHECK-FASTISEL-NEXT:    rev z1.s, z1.s
238; CHECK-FASTISEL-NEXT:    addvl sp, sp, #1
239; CHECK-FASTISEL-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
240; CHECK-FASTISEL-NEXT:    ret
241
242  %res = call <vscale x 8 x i32> @llvm.vector.reverse.nxv8i32(<vscale x 8 x i32> %a)
243  ret <vscale x 8 x i32> %res
244}
245
246; Verify splitvec type legalisation works as expected.
247define <vscale x 16 x float> @reverse_nxv16f32(<vscale x 16 x float> %a) #0 {
248; CHECK-SELDAG-LABEL: reverse_nxv16f32:
249; CHECK-SELDAG:       // %bb.0:
250; CHECK-SELDAG-NEXT:    rev z5.s, z3.s
251; CHECK-SELDAG-NEXT:    rev z4.s, z2.s
252; CHECK-SELDAG-NEXT:    rev z2.s, z1.s
253; CHECK-SELDAG-NEXT:    rev z3.s, z0.s
254; CHECK-SELDAG-NEXT:    mov z0.d, z5.d
255; CHECK-SELDAG-NEXT:    mov z1.d, z4.d
256; CHECK-SELDAG-NEXT:    ret
257;
258; CHECK-FASTISEL-LABEL: reverse_nxv16f32:
259; CHECK-FASTISEL:       // %bb.0:
260; CHECK-FASTISEL-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
261; CHECK-FASTISEL-NEXT:    addvl sp, sp, #-2
262; CHECK-FASTISEL-NEXT:    str z3, [sp, #1, mul vl] // 16-byte Folded Spill
263; CHECK-FASTISEL-NEXT:    str z2, [sp] // 16-byte Folded Spill
264; CHECK-FASTISEL-NEXT:    mov z2.d, z1.d
265; CHECK-FASTISEL-NEXT:    ldr z1, [sp] // 16-byte Folded Reload
266; CHECK-FASTISEL-NEXT:    mov z3.d, z0.d
267; CHECK-FASTISEL-NEXT:    ldr z0, [sp, #1, mul vl] // 16-byte Folded Reload
268; CHECK-FASTISEL-NEXT:    rev z0.s, z0.s
269; CHECK-FASTISEL-NEXT:    rev z1.s, z1.s
270; CHECK-FASTISEL-NEXT:    rev z2.s, z2.s
271; CHECK-FASTISEL-NEXT:    rev z3.s, z3.s
272; CHECK-FASTISEL-NEXT:    addvl sp, sp, #2
273; CHECK-FASTISEL-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
274; CHECK-FASTISEL-NEXT:    ret
275
276  %res = call <vscale x 16 x float> @llvm.vector.reverse.nxv16f32(<vscale x 16 x float> %a)
277  ret <vscale x 16 x float> %res
278}
279
280
281declare <vscale x 2 x i1> @llvm.vector.reverse.nxv2i1(<vscale x 2 x i1>)
282declare <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1>)
283declare <vscale x 8 x i1> @llvm.vector.reverse.nxv8i1(<vscale x 8 x i1>)
284declare <vscale x 16 x i1> @llvm.vector.reverse.nxv16i1(<vscale x 16 x i1>)
285declare <vscale x 32 x i1> @llvm.vector.reverse.nxv32i1(<vscale x 32 x i1>)
286declare <vscale x 2 x i8> @llvm.vector.reverse.nxv2i8(<vscale x 2 x i8>)
287declare <vscale x 16 x i8> @llvm.vector.reverse.nxv16i8(<vscale x 16 x i8>)
288declare <vscale x 8 x i16> @llvm.vector.reverse.nxv8i16(<vscale x 8 x i16>)
289declare <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32>)
290declare <vscale x 8 x i32> @llvm.vector.reverse.nxv8i32(<vscale x 8 x i32>)
291declare <vscale x 2 x i64> @llvm.vector.reverse.nxv2i64(<vscale x 2 x i64>)
292declare <vscale x 2 x half> @llvm.vector.reverse.nxv2f16(<vscale x 2 x half>)
293declare <vscale x 4 x half> @llvm.vector.reverse.nxv4f16(<vscale x 4 x half>)
294declare <vscale x 8 x half> @llvm.vector.reverse.nxv8f16(<vscale x 8 x half>)
295declare <vscale x 2 x bfloat> @llvm.vector.reverse.nxv2bf16(<vscale x 2 x bfloat>)
296declare <vscale x 4 x bfloat> @llvm.vector.reverse.nxv4bf16(<vscale x 4 x bfloat>)
297declare <vscale x 8 x bfloat> @llvm.vector.reverse.nxv8bf16(<vscale x 8 x bfloat>)
298declare <vscale x 2 x float> @llvm.vector.reverse.nxv2f32(<vscale x 2 x float>)
299declare <vscale x 4 x float> @llvm.vector.reverse.nxv4f32(<vscale x 4 x float>)
300declare <vscale x 16 x float> @llvm.vector.reverse.nxv16f32(<vscale x 16 x float>)
301declare <vscale x 2 x double> @llvm.vector.reverse.nxv2f64(<vscale x 2 x double>)
302
303
304attributes #0 = { nounwind "target-features"="+sve" }
305attributes #1 = { nounwind "target-features"="+sve,+bf16" }
306