[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AArch64 / sve-streaming-mode-fixed-length-permute-rev.ll
blob88fb73e649672e1a8cc78937135229a9e3b310b3
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mattr=+sve -force-streaming-compatible-sve < %s | FileCheck %s
3 ; RUN: llc -mattr=+sme -force-streaming-compatible-sve < %s | FileCheck %s
6 target triple = "aarch64-unknown-linux-gnu"
8 ; REVB pattern for shuffle v32i8 -> v16i16
9 define void @test_revbv16i16(ptr %a) {
10 ; CHECK-LABEL: test_revbv16i16:
11 ; CHECK:       // %bb.0:
12 ; CHECK-NEXT:    ptrue p0.h
13 ; CHECK-NEXT:    ldp q0, q1, [x0]
14 ; CHECK-NEXT:    revb z0.h, p0/m, z0.h
15 ; CHECK-NEXT:    revb z1.h, p0/m, z1.h
16 ; CHECK-NEXT:    stp q0, q1, [x0]
17 ; CHECK-NEXT:    ret
18   %tmp1 = load <32 x i8>, ptr %a
19   %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> undef, <32 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14, i32 17, i32 16, i32 19, i32 18, i32 21, i32 20, i32 23, i32 22, i32 undef, i32 24, i32 27, i32 undef, i32 29, i32 28, i32 undef, i32 undef>
20   store <32 x i8> %tmp2, ptr %a
21   ret void
24 ; REVB pattern for shuffle v32i8 -> v8i32
25 define void @test_revbv8i32(ptr %a) {
26 ; CHECK-LABEL: test_revbv8i32:
27 ; CHECK:       // %bb.0:
28 ; CHECK-NEXT:    ptrue p0.s
29 ; CHECK-NEXT:    ldp q0, q1, [x0]
30 ; CHECK-NEXT:    revb z0.s, p0/m, z0.s
31 ; CHECK-NEXT:    revb z1.s, p0/m, z1.s
32 ; CHECK-NEXT:    stp q0, q1, [x0]
33 ; CHECK-NEXT:    ret
34   %tmp1 = load <32 x i8>, ptr %a
35   %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> undef, <32 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12, i32 19, i32 18, i32 17, i32 16, i32 23, i32 22, i32 21, i32 20, i32 27, i32 undef, i32 undef, i32 undef, i32 31, i32 30, i32 29, i32 undef>
36   store <32 x i8> %tmp2, ptr %a
37   ret void
40 ; REVB pattern for shuffle v32i8 -> v4i64
41 define void @test_revbv4i64(ptr %a) {
42 ; CHECK-LABEL: test_revbv4i64:
43 ; CHECK:       // %bb.0:
44 ; CHECK-NEXT:    ptrue p0.d
45 ; CHECK-NEXT:    ldp q0, q1, [x0]
46 ; CHECK-NEXT:    revb z0.d, p0/m, z0.d
47 ; CHECK-NEXT:    revb z1.d, p0/m, z1.d
48 ; CHECK-NEXT:    stp q0, q1, [x0]
49 ; CHECK-NEXT:    ret
50   %tmp1 = load <32 x i8>, ptr %a
51   %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> undef, <32 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 23, i32 22, i32 21, i32 20, i32 19, i32 18, i32 17, i32 16, i32 31, i32 30, i32 29, i32 undef, i32 27, i32 undef, i32 undef, i32 undef>
52   store <32 x i8> %tmp2, ptr %a
53   ret void
56 ; REVH pattern for shuffle v16i16 -> v8i32
57 define void @test_revhv8i32(ptr %a) {
58 ; CHECK-LABEL: test_revhv8i32:
59 ; CHECK:       // %bb.0:
60 ; CHECK-NEXT:    ptrue p0.s
61 ; CHECK-NEXT:    ldp q0, q1, [x0]
62 ; CHECK-NEXT:    revh z0.s, p0/m, z0.s
63 ; CHECK-NEXT:    revh z1.s, p0/m, z1.s
64 ; CHECK-NEXT:    stp q0, q1, [x0]
65 ; CHECK-NEXT:    ret
66   %tmp1 = load <16 x i16>, ptr %a
67   %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> undef, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
68   store <16 x i16> %tmp2, ptr %a
69   ret void
72 ; REVH pattern for shuffle v16f16 -> v8f32
73 define void @test_revhv8f32(ptr %a) {
74 ; CHECK-LABEL: test_revhv8f32:
75 ; CHECK:       // %bb.0:
76 ; CHECK-NEXT:    ptrue p0.s
77 ; CHECK-NEXT:    ldp q0, q1, [x0]
78 ; CHECK-NEXT:    revh z0.s, p0/m, z0.s
79 ; CHECK-NEXT:    revh z1.s, p0/m, z1.s
80 ; CHECK-NEXT:    stp q0, q1, [x0]
81 ; CHECK-NEXT:    ret
82   %tmp1 = load <16 x half>, ptr %a
83   %tmp2 = shufflevector <16 x half> %tmp1, <16 x half> undef, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
84   store <16 x half> %tmp2, ptr %a
85   ret void
88 ; REVH pattern for shuffle v16i16 -> v4i64
89 define void @test_revhv4i64(ptr %a) {
90 ; CHECK-LABEL: test_revhv4i64:
91 ; CHECK:       // %bb.0:
92 ; CHECK-NEXT:    ptrue p0.d
93 ; CHECK-NEXT:    ldp q0, q1, [x0]
94 ; CHECK-NEXT:    revh z0.d, p0/m, z0.d
95 ; CHECK-NEXT:    revh z1.d, p0/m, z1.d
96 ; CHECK-NEXT:    stp q0, q1, [x0]
97 ; CHECK-NEXT:    ret
98   %tmp1 = load <16 x i16>, ptr %a
99   %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> undef, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12>
100   store <16 x i16> %tmp2, ptr %a
101   ret void
104 ; REVW pattern for shuffle v8i32 -> v4i64
105 define void @test_revwv4i64(ptr %a) {
106 ; CHECK-LABEL: test_revwv4i64:
107 ; CHECK:       // %bb.0:
108 ; CHECK-NEXT:    ptrue p0.d
109 ; CHECK-NEXT:    ldp q0, q1, [x0]
110 ; CHECK-NEXT:    revw z0.d, p0/m, z0.d
111 ; CHECK-NEXT:    revw z1.d, p0/m, z1.d
112 ; CHECK-NEXT:    stp q0, q1, [x0]
113 ; CHECK-NEXT:    ret
114   %tmp1 = load <8 x i32>, ptr %a
115   %tmp2 = shufflevector <8 x i32> %tmp1, <8 x i32> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
116   store <8 x i32> %tmp2, ptr %a
117   ret void
120 ; REVW pattern for shuffle v8f32 -> v4f64
121 define void @test_revwv4f64(ptr %a) {
122 ; CHECK-LABEL: test_revwv4f64:
123 ; CHECK:       // %bb.0:
124 ; CHECK-NEXT:    ptrue p0.d
125 ; CHECK-NEXT:    ldp q0, q1, [x0]
126 ; CHECK-NEXT:    revw z0.d, p0/m, z0.d
127 ; CHECK-NEXT:    revw z1.d, p0/m, z1.d
128 ; CHECK-NEXT:    stp q0, q1, [x0]
129 ; CHECK-NEXT:    ret
130   %tmp1 = load <8 x float>, ptr %a
131   %tmp2 = shufflevector <8 x float> %tmp1, <8 x float> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
132   store <8 x float> %tmp2, ptr %a
133   ret void
136 define <16 x i8> @test_revv16i8(ptr %a) {
137 ; CHECK-LABEL: test_revv16i8:
138 ; CHECK:       // %bb.0:
139 ; CHECK-NEXT:    ptrue p0.d
140 ; CHECK-NEXT:    ldr q0, [x0]
141 ; CHECK-NEXT:    revb z0.d, p0/m, z0.d
142 ; CHECK-NEXT:    // kill: def $q0 killed $q0 killed $z0
143 ; CHECK-NEXT:    ret
144   %tmp1 = load <16 x i8>, ptr %a
145   %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
146   ret <16 x i8> %tmp2
149 ; REVW pattern for shuffle two v8i32 inputs with the second input available.
150 define void @test_revwv8i32v8i32(ptr %a, ptr %b) {
151 ; CHECK-LABEL: test_revwv8i32v8i32:
152 ; CHECK:       // %bb.0:
153 ; CHECK-NEXT:    ptrue p0.d
154 ; CHECK-NEXT:    ldp q0, q1, [x1]
155 ; CHECK-NEXT:    revw z0.d, p0/m, z0.d
156 ; CHECK-NEXT:    revw z1.d, p0/m, z1.d
157 ; CHECK-NEXT:    stp q0, q1, [x0]
158 ; CHECK-NEXT:    ret
159   %tmp1 = load <8 x i32>, ptr %a
160   %tmp2 = load <8 x i32>, ptr %b
161   %tmp3 = shufflevector <8 x i32> %tmp1, <8 x i32> %tmp2, <8 x i32> <i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
162   store <8 x i32> %tmp3, ptr %a
163   ret void
166 define void @test_revhv32i16(ptr %a) {
167 ; CHECK-LABEL: test_revhv32i16:
168 ; CHECK:       // %bb.0:
169 ; CHECK-NEXT:    ptrue p0.d
170 ; CHECK-NEXT:    ldp q0, q1, [x0, #32]
171 ; CHECK-NEXT:    ldp q2, q3, [x0]
172 ; CHECK-NEXT:    revh z0.d, p0/m, z0.d
173 ; CHECK-NEXT:    revh z1.d, p0/m, z1.d
174 ; CHECK-NEXT:    revh z2.d, p0/m, z2.d
175 ; CHECK-NEXT:    revh z3.d, p0/m, z3.d
176 ; CHECK-NEXT:    stp q0, q1, [x0, #32]
177 ; CHECK-NEXT:    stp q2, q3, [x0]
178 ; CHECK-NEXT:    ret
179   %tmp1 = load <32 x i16>, ptr %a
180   %tmp2 = shufflevector <32 x i16> %tmp1, <32 x i16> undef, <32 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12, i32 19, i32 18, i32 17, i32 16, i32 23, i32 22, i32 21, i32 20, i32 27, i32 undef, i32 undef, i32 undef, i32 31, i32 30, i32 29, i32 undef>
181   store <32 x i16> %tmp2, ptr %a
182   ret void
185 define void @test_rev_elts_fail(ptr %a) {
186 ; CHECK-LABEL: test_rev_elts_fail:
187 ; CHECK:       // %bb.0:
188 ; CHECK-NEXT:    ldp q1, q0, [x0]
189 ; CHECK-NEXT:    mov z2.d, z0.d[1]
190 ; CHECK-NEXT:    fmov x8, d0
191 ; CHECK-NEXT:    mov z0.d, z1.d[1]
192 ; CHECK-NEXT:    fmov x9, d2
193 ; CHECK-NEXT:    stp x9, x8, [sp, #-32]!
194 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
195 ; CHECK-NEXT:    fmov x8, d1
196 ; CHECK-NEXT:    fmov x9, d0
197 ; CHECK-NEXT:    stp x9, x8, [sp, #16]
198 ; CHECK-NEXT:    ldp q1, q0, [sp]
199 ; CHECK-NEXT:    stp q0, q1, [x0]
200 ; CHECK-NEXT:    add sp, sp, #32
201 ; CHECK-NEXT:    ret
202   %tmp1 = load <4 x i64>, ptr %a
203   %tmp2 = shufflevector <4 x i64> %tmp1, <4 x i64> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
204   store <4 x i64> %tmp2, ptr %a
205   ret void
208 ; This is the same test as above, but with sve2p1 it can use the REVD instruction to reverse
209 ; the double-words within quard-words.
210 define void @test_revdv4i64_sve2p1(ptr %a) #1 {
211 ; CHECK-LABEL: test_revdv4i64_sve2p1:
212 ; CHECK:       // %bb.0:
213 ; CHECK-NEXT:    ptrue p0.d, vl2
214 ; CHECK-NEXT:    ldp q0, q1, [x0]
215 ; CHECK-NEXT:    revd z0.q, p0/m, z0.q
216 ; CHECK-NEXT:    revd z1.q, p0/m, z1.q
217 ; CHECK-NEXT:    stp q0, q1, [x0]
218 ; CHECK-NEXT:    ret
219   %tmp1 = load <4 x i64>, ptr %a
220   %tmp2 = shufflevector <4 x i64> %tmp1, <4 x i64> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
221   store <4 x i64> %tmp2, ptr %a
222   ret void
225 define void @test_revdv4f64_sve2p1(ptr %a) #1 {
226 ; CHECK-LABEL: test_revdv4f64_sve2p1:
227 ; CHECK:       // %bb.0:
228 ; CHECK-NEXT:    ptrue p0.d
229 ; CHECK-NEXT:    ldp q0, q1, [x0]
230 ; CHECK-NEXT:    revd z0.q, p0/m, z0.q
231 ; CHECK-NEXT:    revd z1.q, p0/m, z1.q
232 ; CHECK-NEXT:    stp q0, q1, [x0]
233 ; CHECK-NEXT:    ret
234   %tmp1 = load <4 x double>, ptr %a
235   %tmp2 = shufflevector <4 x double> %tmp1, <4 x double> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
236   store <4 x double> %tmp2, ptr %a
237   ret void
240 define void @test_revv8i32(ptr %a) {
241 ; CHECK-LABEL: test_revv8i32:
242 ; CHECK:       // %bb.0:
243 ; CHECK-NEXT:    sub sp, sp, #32
244 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
245 ; CHECK-NEXT:    ldp q0, q3, [x0]
246 ; CHECK-NEXT:    mov z1.s, z0.s[1]
247 ; CHECK-NEXT:    mov z2.s, z0.s[2]
248 ; CHECK-NEXT:    mov z4.s, z0.s[3]
249 ; CHECK-NEXT:    fmov w8, s0
250 ; CHECK-NEXT:    mov z0.s, z3.s[1]
251 ; CHECK-NEXT:    fmov w9, s1
252 ; CHECK-NEXT:    mov z1.s, z3.s[2]
253 ; CHECK-NEXT:    stp w9, w8, [sp, #24]
254 ; CHECK-NEXT:    fmov w8, s2
255 ; CHECK-NEXT:    fmov w9, s4
256 ; CHECK-NEXT:    mov z2.s, z3.s[3]
257 ; CHECK-NEXT:    stp w9, w8, [sp, #16]
258 ; CHECK-NEXT:    fmov w8, s3
259 ; CHECK-NEXT:    fmov w9, s0
260 ; CHECK-NEXT:    stp w9, w8, [sp, #8]
261 ; CHECK-NEXT:    fmov w8, s1
262 ; CHECK-NEXT:    fmov w9, s2
263 ; CHECK-NEXT:    stp w9, w8, [sp]
264 ; CHECK-NEXT:    ldp q0, q1, [sp]
265 ; CHECK-NEXT:    stp q0, q1, [x0]
266 ; CHECK-NEXT:    add sp, sp, #32
267 ; CHECK-NEXT:    ret
268   %tmp1 = load <8 x i32>, ptr %a
269   %tmp2 = shufflevector <8 x i32> %tmp1, <8 x i32> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
270   store <8 x i32> %tmp2, ptr %a
271   ret void
273 attributes #1 = { "target-features"="+sve2p1" }