1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt < %s -interleaved-access -S | FileCheck %s --check-prefix=NEON
3 ; RUN: opt < %s -interleaved-access -mtriple=aarch64-linux-gnu -mattr=+sve -force-streaming-compatible -S | FileCheck %s --check-prefix=SVE-FIXED
4 ; RUN: opt < %s -passes=interleaved-access -S | FileCheck %s --check-prefix=NEON
5 ; RUN: opt < %s -passes=interleaved-access -mtriple=aarch64-linux-gnu -mattr=+sve -force-streaming-compatible -S | FileCheck %s --check-prefix=SVE-FIXED
7 target triple = "aarch64-linux-gnu"
9 define void @deinterleave_i8_factor2(ptr %ptr) {
10 ; NEON-LABEL: define void @deinterleave_i8_factor2
11 ; NEON-SAME: (ptr [[PTR:%.*]]) {
12 ; NEON-NEXT: [[LDN:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.aarch64.neon.ld2.v16i8.p0(ptr [[PTR]])
13 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[LDN]], 0
14 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[LDN]], 1
17 ; SVE-FIXED-LABEL: define void @deinterleave_i8_factor2
18 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
19 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <32 x i8>, ptr [[PTR]], align 1
20 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> [[LOAD]])
21 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[DEINTERLEAVE]], 0
22 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[DEINTERLEAVE]], 1
23 ; SVE-FIXED-NEXT: ret void
25 %load = load <32 x i8>, ptr %ptr, align 1
26 %deinterleave = tail call { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8> %load)
27 %extract1 = extractvalue { <16 x i8>, <16 x i8> } %deinterleave, 0
28 %extract2 = extractvalue { <16 x i8>, <16 x i8> } %deinterleave, 1
32 define void @deinterleave_i16_factor2(ptr %ptr) {
33 ; NEON-LABEL: define void @deinterleave_i16_factor2
34 ; NEON-SAME: (ptr [[PTR:%.*]]) {
35 ; NEON-NEXT: [[LDN:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.aarch64.neon.ld2.v8i16.p0(ptr [[PTR]])
36 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN]], 0
37 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN]], 1
40 ; SVE-FIXED-LABEL: define void @deinterleave_i16_factor2
41 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
42 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <16 x i16>, ptr [[PTR]], align 2
43 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <8 x i16>, <8 x i16> } @llvm.vector.deinterleave2.v16i16(<16 x i16> [[LOAD]])
44 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[DEINTERLEAVE]], 0
45 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[DEINTERLEAVE]], 1
46 ; SVE-FIXED-NEXT: ret void
48 %load = load <16 x i16>, ptr %ptr, align 2
49 %deinterleave = tail call { <8 x i16>, <8 x i16> } @llvm.vector.deinterleave2.v16i16(<16 x i16> %load)
50 %extract1 = extractvalue { <8 x i16>, <8 x i16> } %deinterleave, 0
51 %extract2 = extractvalue { <8 x i16>, <8 x i16> } %deinterleave, 1
55 define void @deinterleave_8xi32_factor2(ptr %ptr) {
56 ; NEON-LABEL: define void @deinterleave_8xi32_factor2
57 ; NEON-SAME: (ptr [[PTR:%.*]]) {
58 ; NEON-NEXT: [[LDN:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld2.v4i32.p0(ptr [[PTR]])
59 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[LDN]], 0
60 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[LDN]], 1
63 ; SVE-FIXED-LABEL: define void @deinterleave_8xi32_factor2
64 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
65 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <8 x i32>, ptr [[PTR]], align 4
66 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[LOAD]])
67 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DEINTERLEAVE]], 0
68 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DEINTERLEAVE]], 1
69 ; SVE-FIXED-NEXT: ret void
71 %load = load <8 x i32>, ptr %ptr, align 4
72 %deinterleave = tail call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %load)
73 %extract1 = extractvalue { <4 x i32>, <4 x i32> } %deinterleave, 0
74 %extract2 = extractvalue { <4 x i32>, <4 x i32> } %deinterleave, 1
78 define void @deinterleave_i64_factor2(ptr %ptr) {
79 ; NEON-LABEL: define void @deinterleave_i64_factor2
80 ; NEON-SAME: (ptr [[PTR:%.*]]) {
81 ; NEON-NEXT: [[LDN:%.*]] = call { <2 x i64>, <2 x i64> } @llvm.aarch64.neon.ld2.v2i64.p0(ptr [[PTR]])
82 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <2 x i64>, <2 x i64> } [[LDN]], 0
83 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <2 x i64>, <2 x i64> } [[LDN]], 1
86 ; SVE-FIXED-LABEL: define void @deinterleave_i64_factor2
87 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
88 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <4 x i64>, ptr [[PTR]], align 8
89 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <2 x i64>, <2 x i64> } @llvm.vector.deinterleave2.v4i64(<4 x i64> [[LOAD]])
90 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <2 x i64>, <2 x i64> } [[DEINTERLEAVE]], 0
91 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <2 x i64>, <2 x i64> } [[DEINTERLEAVE]], 1
92 ; SVE-FIXED-NEXT: ret void
94 %load = load <4 x i64>, ptr %ptr, align 8
95 %deinterleave = tail call { <2 x i64>, <2 x i64> } @llvm.vector.deinterleave2.v4i64(<4 x i64> %load)
96 %extract1 = extractvalue { <2 x i64>, <2 x i64> } %deinterleave, 0
97 %extract2 = extractvalue { <2 x i64>, <2 x i64> } %deinterleave, 1
101 define void @deinterleave_float_factor2(ptr %ptr) {
102 ; NEON-LABEL: define void @deinterleave_float_factor2
103 ; NEON-SAME: (ptr [[PTR:%.*]]) {
104 ; NEON-NEXT: [[LDN:%.*]] = call { <4 x float>, <4 x float> } @llvm.aarch64.neon.ld2.v4f32.p0(ptr [[PTR]])
105 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <4 x float>, <4 x float> } [[LDN]], 0
106 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <4 x float>, <4 x float> } [[LDN]], 1
107 ; NEON-NEXT: ret void
109 ; SVE-FIXED-LABEL: define void @deinterleave_float_factor2
110 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
111 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <8 x float>, ptr [[PTR]], align 4
112 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float> [[LOAD]])
113 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <4 x float>, <4 x float> } [[DEINTERLEAVE]], 0
114 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <4 x float>, <4 x float> } [[DEINTERLEAVE]], 1
115 ; SVE-FIXED-NEXT: ret void
117 %load = load <8 x float>, ptr %ptr, align 4
118 %deinterleave = tail call { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float> %load)
119 %extract1 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 0
120 %extract2 = extractvalue { <4 x float>, <4 x float> } %deinterleave, 1
124 define void @deinterleave_double_factor2(ptr %ptr) {
125 ; NEON-LABEL: define void @deinterleave_double_factor2
126 ; NEON-SAME: (ptr [[PTR:%.*]]) {
127 ; NEON-NEXT: [[LDN:%.*]] = call { <2 x double>, <2 x double> } @llvm.aarch64.neon.ld2.v2f64.p0(ptr [[PTR]])
128 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <2 x double>, <2 x double> } [[LDN]], 0
129 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <2 x double>, <2 x double> } [[LDN]], 1
130 ; NEON-NEXT: ret void
132 ; SVE-FIXED-LABEL: define void @deinterleave_double_factor2
133 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
134 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <4 x double>, ptr [[PTR]], align 8
135 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <2 x double>, <2 x double> } @llvm.vector.deinterleave2.v4f64(<4 x double> [[LOAD]])
136 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <2 x double>, <2 x double> } [[DEINTERLEAVE]], 0
137 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <2 x double>, <2 x double> } [[DEINTERLEAVE]], 1
138 ; SVE-FIXED-NEXT: ret void
140 %load = load <4 x double>, ptr %ptr, align 8
141 %deinterleave = tail call { <2 x double>, <2 x double> } @llvm.vector.deinterleave2.v4f64(<4 x double> %load)
142 %extract1 = extractvalue { <2 x double>, <2 x double> } %deinterleave, 0
143 %extract2 = extractvalue { <2 x double>, <2 x double> } %deinterleave, 1
147 define void @deinterleave_ptr_factor2(ptr %ptr) {
148 ; NEON-LABEL: define void @deinterleave_ptr_factor2
149 ; NEON-SAME: (ptr [[PTR:%.*]]) {
150 ; NEON-NEXT: [[LDN:%.*]] = call { <2 x ptr>, <2 x ptr> } @llvm.aarch64.neon.ld2.v2p0.p0(ptr [[PTR]])
151 ; NEON-NEXT: [[TMP1:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[LDN]], 0
152 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[LDN]], 1
153 ; NEON-NEXT: ret void
155 ; SVE-FIXED-LABEL: define void @deinterleave_ptr_factor2
156 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
157 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <4 x ptr>, ptr [[PTR]], align 8
158 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <2 x ptr>, <2 x ptr> } @llvm.vector.deinterleave2.v4p0(<4 x ptr> [[LOAD]])
159 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[DEINTERLEAVE]], 0
160 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <2 x ptr>, <2 x ptr> } [[DEINTERLEAVE]], 1
161 ; SVE-FIXED-NEXT: ret void
163 %load = load <4 x ptr>, ptr %ptr, align 8
164 %deinterleave = tail call { <2 x ptr>, <2 x ptr> } @llvm.vector.deinterleave2.v4p0(<4 x ptr> %load)
165 %extract1 = extractvalue { <2 x ptr>, <2 x ptr> } %deinterleave, 0
166 %extract2 = extractvalue { <2 x ptr>, <2 x ptr> } %deinterleave, 1
170 define void @interleave_i8_factor2(ptr %ptr, <16 x i8> %l, <16 x i8> %r) {
171 ; NEON-LABEL: define void @interleave_i8_factor2
172 ; NEON-SAME: (ptr [[PTR:%.*]], <16 x i8> [[L:%.*]], <16 x i8> [[R:%.*]]) {
173 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v16i8.p0(<16 x i8> [[L]], <16 x i8> [[R]], ptr [[PTR]])
174 ; NEON-NEXT: ret void
176 ; SVE-FIXED-LABEL: define void @interleave_i8_factor2
177 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <16 x i8> [[L:%.*]], <16 x i8> [[R:%.*]]) #[[ATTR0]] {
178 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <32 x i8> @llvm.vector.interleave2.v32i8(<16 x i8> [[L]], <16 x i8> [[R]])
179 ; SVE-FIXED-NEXT: store <32 x i8> [[INTERLEAVE]], ptr [[PTR]], align 1
180 ; SVE-FIXED-NEXT: ret void
182 %interleave = tail call <32 x i8> @llvm.vector.interleave2.v32i8(<16 x i8> %l, <16 x i8> %r)
183 store <32 x i8> %interleave, ptr %ptr, align 1
187 define void @interleave_i16_factor2(ptr %ptr, <8 x i16> %l, <8 x i16> %r) {
188 ; NEON-LABEL: define void @interleave_i16_factor2
189 ; NEON-SAME: (ptr [[PTR:%.*]], <8 x i16> [[L:%.*]], <8 x i16> [[R:%.*]]) {
190 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v8i16.p0(<8 x i16> [[L]], <8 x i16> [[R]], ptr [[PTR]])
191 ; NEON-NEXT: ret void
193 ; SVE-FIXED-LABEL: define void @interleave_i16_factor2
194 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <8 x i16> [[L:%.*]], <8 x i16> [[R:%.*]]) #[[ATTR0]] {
195 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <16 x i16> @llvm.vector.interleave2.v16i16(<8 x i16> [[L]], <8 x i16> [[R]])
196 ; SVE-FIXED-NEXT: store <16 x i16> [[INTERLEAVE]], ptr [[PTR]], align 2
197 ; SVE-FIXED-NEXT: ret void
199 %interleave = tail call <16 x i16> @llvm.vector.interleave2.v16i16(<8 x i16> %l, <8 x i16> %r)
200 store <16 x i16> %interleave, ptr %ptr, align 2
204 define void @interleave_i32_factor2(ptr %ptr, <4 x i32> %l, <4 x i32> %r) {
205 ; NEON-LABEL: define void @interleave_i32_factor2
206 ; NEON-SAME: (ptr [[PTR:%.*]], <4 x i32> [[L:%.*]], <4 x i32> [[R:%.*]]) {
207 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v4i32.p0(<4 x i32> [[L]], <4 x i32> [[R]], ptr [[PTR]])
208 ; NEON-NEXT: ret void
210 ; SVE-FIXED-LABEL: define void @interleave_i32_factor2
211 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <4 x i32> [[L:%.*]], <4 x i32> [[R:%.*]]) #[[ATTR0]] {
212 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> [[L]], <4 x i32> [[R]])
213 ; SVE-FIXED-NEXT: store <8 x i32> [[INTERLEAVE]], ptr [[PTR]], align 4
214 ; SVE-FIXED-NEXT: ret void
216 %interleave = tail call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %l, <4 x i32> %r)
217 store <8 x i32> %interleave, ptr %ptr, align 4
221 define void @interleave_i64_factor2(ptr %ptr, <2 x i64> %l, <2 x i64> %r) {
222 ; NEON-LABEL: define void @interleave_i64_factor2
223 ; NEON-SAME: (ptr [[PTR:%.*]], <2 x i64> [[L:%.*]], <2 x i64> [[R:%.*]]) {
224 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2i64.p0(<2 x i64> [[L]], <2 x i64> [[R]], ptr [[PTR]])
225 ; NEON-NEXT: ret void
227 ; SVE-FIXED-LABEL: define void @interleave_i64_factor2
228 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <2 x i64> [[L:%.*]], <2 x i64> [[R:%.*]]) #[[ATTR0]] {
229 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <4 x i64> @llvm.vector.interleave2.v4i64(<2 x i64> [[L]], <2 x i64> [[R]])
230 ; SVE-FIXED-NEXT: store <4 x i64> [[INTERLEAVE]], ptr [[PTR]], align 8
231 ; SVE-FIXED-NEXT: ret void
233 %interleave = tail call <4 x i64> @llvm.vector.interleave2.v4i64(<2 x i64> %l, <2 x i64> %r)
234 store <4 x i64> %interleave, ptr %ptr, align 8
238 define void @interleave_float_factor2(ptr %ptr, <4 x float> %l, <4 x float> %r) {
239 ; NEON-LABEL: define void @interleave_float_factor2
240 ; NEON-SAME: (ptr [[PTR:%.*]], <4 x float> [[L:%.*]], <4 x float> [[R:%.*]]) {
241 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v4f32.p0(<4 x float> [[L]], <4 x float> [[R]], ptr [[PTR]])
242 ; NEON-NEXT: ret void
244 ; SVE-FIXED-LABEL: define void @interleave_float_factor2
245 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <4 x float> [[L:%.*]], <4 x float> [[R:%.*]]) #[[ATTR0]] {
246 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <8 x float> @llvm.vector.interleave2.v8f32(<4 x float> [[L]], <4 x float> [[R]])
247 ; SVE-FIXED-NEXT: store <8 x float> [[INTERLEAVE]], ptr [[PTR]], align 4
248 ; SVE-FIXED-NEXT: ret void
250 %interleave = tail call <8 x float> @llvm.vector.interleave2.v8f32(<4 x float> %l, <4 x float> %r)
251 store <8 x float> %interleave, ptr %ptr, align 4
255 define void @interleave_double_factor2(ptr %ptr, <2 x double> %l, <2 x double> %r) {
256 ; NEON-LABEL: define void @interleave_double_factor2
257 ; NEON-SAME: (ptr [[PTR:%.*]], <2 x double> [[L:%.*]], <2 x double> [[R:%.*]]) {
258 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2f64.p0(<2 x double> [[L]], <2 x double> [[R]], ptr [[PTR]])
259 ; NEON-NEXT: ret void
261 ; SVE-FIXED-LABEL: define void @interleave_double_factor2
262 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <2 x double> [[L:%.*]], <2 x double> [[R:%.*]]) #[[ATTR0]] {
263 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <4 x double> @llvm.vector.interleave2.v4f64(<2 x double> [[L]], <2 x double> [[R]])
264 ; SVE-FIXED-NEXT: store <4 x double> [[INTERLEAVE]], ptr [[PTR]], align 4
265 ; SVE-FIXED-NEXT: ret void
267 %interleave = tail call <4 x double> @llvm.vector.interleave2.v4f64(<2 x double> %l, <2 x double> %r)
268 store <4 x double> %interleave, ptr %ptr, align 4
272 define void @interleave_ptr_factor2(ptr %ptr, <2 x ptr> %l, <2 x ptr> %r) {
273 ; NEON-LABEL: define void @interleave_ptr_factor2
274 ; NEON-SAME: (ptr [[PTR:%.*]], <2 x ptr> [[L:%.*]], <2 x ptr> [[R:%.*]]) {
275 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2p0.p0(<2 x ptr> [[L]], <2 x ptr> [[R]], ptr [[PTR]])
276 ; NEON-NEXT: ret void
278 ; SVE-FIXED-LABEL: define void @interleave_ptr_factor2
279 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <2 x ptr> [[L:%.*]], <2 x ptr> [[R:%.*]]) #[[ATTR0]] {
280 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <4 x ptr> @llvm.vector.interleave2.v4p0(<2 x ptr> [[L]], <2 x ptr> [[R]])
281 ; SVE-FIXED-NEXT: store <4 x ptr> [[INTERLEAVE]], ptr [[PTR]], align 4
282 ; SVE-FIXED-NEXT: ret void
284 %interleave = tail call <4 x ptr> @llvm.vector.interleave2.v4p0(<2 x ptr> %l, <2 x ptr> %r)
285 store <4 x ptr> %interleave, ptr %ptr, align 4
289 define void @deinterleave_wide_i16_factor2(ptr %ptr) #0 {
290 ; NEON-LABEL: define void @deinterleave_wide_i16_factor2
291 ; NEON-SAME: (ptr [[PTR:%.*]]) {
292 ; NEON-NEXT: [[TMP1:%.*]] = getelementptr <8 x i16>, ptr [[PTR]], i64 0
293 ; NEON-NEXT: [[LDN:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.aarch64.neon.ld2.v8i16.p0(ptr [[TMP1]])
294 ; NEON-NEXT: [[TMP2:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN]], 0
295 ; NEON-NEXT: [[TMP3:%.*]] = call <16 x i16> @llvm.vector.insert.v16i16.v8i16(<16 x i16> poison, <8 x i16> [[TMP2]], i64 0)
296 ; NEON-NEXT: [[TMP4:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN]], 1
297 ; NEON-NEXT: [[TMP5:%.*]] = call <16 x i16> @llvm.vector.insert.v16i16.v8i16(<16 x i16> poison, <8 x i16> [[TMP4]], i64 0)
298 ; NEON-NEXT: [[TMP6:%.*]] = getelementptr <8 x i16>, ptr [[PTR]], i64 2
299 ; NEON-NEXT: [[LDN1:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.aarch64.neon.ld2.v8i16.p0(ptr [[TMP6]])
300 ; NEON-NEXT: [[TMP7:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN1]], 0
301 ; NEON-NEXT: [[TMP8:%.*]] = call <16 x i16> @llvm.vector.insert.v16i16.v8i16(<16 x i16> [[TMP3]], <8 x i16> [[TMP7]], i64 8)
302 ; NEON-NEXT: [[TMP9:%.*]] = extractvalue { <8 x i16>, <8 x i16> } [[LDN1]], 1
303 ; NEON-NEXT: [[TMP10:%.*]] = call <16 x i16> @llvm.vector.insert.v16i16.v8i16(<16 x i16> [[TMP5]], <8 x i16> [[TMP9]], i64 8)
304 ; NEON-NEXT: ret void
306 ; SVE-FIXED-LABEL: define void @deinterleave_wide_i16_factor2
307 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]]) #[[ATTR0]] {
308 ; SVE-FIXED-NEXT: [[LOAD:%.*]] = load <32 x i16>, ptr [[PTR]], align 2
309 ; SVE-FIXED-NEXT: [[DEINTERLEAVE:%.*]] = tail call { <16 x i16>, <16 x i16> } @llvm.vector.deinterleave2.v32i16(<32 x i16> [[LOAD]])
310 ; SVE-FIXED-NEXT: [[EXTRACT1:%.*]] = extractvalue { <16 x i16>, <16 x i16> } [[DEINTERLEAVE]], 0
311 ; SVE-FIXED-NEXT: [[EXTRACT2:%.*]] = extractvalue { <16 x i16>, <16 x i16> } [[DEINTERLEAVE]], 1
312 ; SVE-FIXED-NEXT: ret void
314 %load = load <32 x i16>, ptr %ptr, align 2
315 %deinterleave = tail call { <16 x i16>, <16 x i16> } @llvm.vector.deinterleave2.v32i16(<32 x i16> %load)
316 %extract1 = extractvalue { <16 x i16>, <16 x i16> } %deinterleave, 0
317 %extract2 = extractvalue { <16 x i16>, <16 x i16> } %deinterleave, 1
321 define void @interleave_wide_ptr_factor2(ptr %ptr, <8 x ptr> %l, <8 x ptr> %r) {
322 ; NEON-LABEL: define void @interleave_wide_ptr_factor2
323 ; NEON-SAME: (ptr [[PTR:%.*]], <8 x ptr> [[L:%.*]], <8 x ptr> [[R:%.*]]) {
324 ; NEON-NEXT: [[TMP1:%.*]] = getelementptr <2 x ptr>, ptr [[PTR]], i64 0
325 ; NEON-NEXT: [[TMP2:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[L]], i64 0)
326 ; NEON-NEXT: [[TMP3:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[R]], i64 0)
327 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2p0.p0(<2 x ptr> [[TMP2]], <2 x ptr> [[TMP3]], ptr [[TMP1]])
328 ; NEON-NEXT: [[TMP4:%.*]] = getelementptr <2 x ptr>, ptr [[PTR]], i64 2
329 ; NEON-NEXT: [[TMP5:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[L]], i64 2)
330 ; NEON-NEXT: [[TMP6:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[R]], i64 2)
331 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2p0.p0(<2 x ptr> [[TMP5]], <2 x ptr> [[TMP6]], ptr [[TMP4]])
332 ; NEON-NEXT: [[TMP7:%.*]] = getelementptr <2 x ptr>, ptr [[PTR]], i64 4
333 ; NEON-NEXT: [[TMP8:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[L]], i64 4)
334 ; NEON-NEXT: [[TMP9:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[R]], i64 4)
335 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2p0.p0(<2 x ptr> [[TMP8]], <2 x ptr> [[TMP9]], ptr [[TMP7]])
336 ; NEON-NEXT: [[TMP10:%.*]] = getelementptr <2 x ptr>, ptr [[PTR]], i64 6
337 ; NEON-NEXT: [[TMP11:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[L]], i64 6)
338 ; NEON-NEXT: [[TMP12:%.*]] = call <2 x ptr> @llvm.vector.extract.v2p0.v8p0(<8 x ptr> [[R]], i64 6)
339 ; NEON-NEXT: call void @llvm.aarch64.neon.st2.v2p0.p0(<2 x ptr> [[TMP11]], <2 x ptr> [[TMP12]], ptr [[TMP10]])
340 ; NEON-NEXT: ret void
342 ; SVE-FIXED-LABEL: define void @interleave_wide_ptr_factor2
343 ; SVE-FIXED-SAME: (ptr [[PTR:%.*]], <8 x ptr> [[L:%.*]], <8 x ptr> [[R:%.*]]) #[[ATTR0]] {
344 ; SVE-FIXED-NEXT: [[INTERLEAVE:%.*]] = tail call <16 x ptr> @llvm.vector.interleave2.v16p0(<8 x ptr> [[L]], <8 x ptr> [[R]])
345 ; SVE-FIXED-NEXT: store <16 x ptr> [[INTERLEAVE]], ptr [[PTR]], align 4
346 ; SVE-FIXED-NEXT: ret void
348 %interleave = tail call <16 x ptr> @llvm.vector.interleave2.v16p0(<8 x ptr> %l, <8 x ptr> %r)
349 store <16 x ptr> %interleave, ptr %ptr, align 4
353 declare { <16 x i8>, <16 x i8> } @llvm.vector.deinterleave2.v32i8(<32 x i8>)
354 declare { <8 x i16>, <8 x i16> } @llvm.vector.deinterleave2.v16i16(<16 x i16>)
355 declare { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32>)
356 declare { <2 x i64>, <2 x i64> } @llvm.vector.deinterleave2.v4i64(<4 x i64>)
357 declare { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float>)
358 declare { <2 x double>, <2 x double> } @llvm.vector.deinterleave2.v4f64(<4 x double>)
359 declare { <2 x ptr>, <2 x ptr> } @llvm.vector.deinterleave2.v4p0(<4 x ptr>)
360 declare { <16 x i16>, <16 x i16> } @llvm.vector.deinterleave2.v32i16(<32 x i16>)
362 declare <32 x i8> @llvm.vector.interleave2.v32i8(<16 x i8>, <16 x i8>)
363 declare <16 x i16> @llvm.vector.interleave2.v16i16(<8 x i16>, <8 x i16>)
364 declare <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32>, <4 x i32>)
365 declare <4 x i64> @llvm.vector.interleave2.v4i64(<2 x i64>, <2 x i64>)
366 declare <8 x float> @llvm.vector.interleave2.v8f32(<4 x float>, <4 x float>)
367 declare <4 x double> @llvm.vector.interleave2.v4f64(<2 x double>, <2 x double>)
368 declare <4 x ptr> @llvm.vector.interleave2.v4p0(<2 x ptr>, <2 x ptr>)
369 declare <16 x ptr> @llvm.vector.interleave2.v16p0(<8 x ptr>, <8 x ptr>)