[test] Pre-commit llvm.experimental.memset.pattern tests prior to MemoryLocation...
[llvm-project.git] / llvm / test / Transforms / InterleavedAccess / AArch64 / fixed-deinterleave-intrinsics.ll
blob09e2c53465cd7307ab5c7face13cc4bb899364bc
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
15 ; NEON-NEXT:    ret void
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
29   ret void
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
38 ; NEON-NEXT:    ret void
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
52   ret void
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
61 ; NEON-NEXT:    ret void
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
75   ret void
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
84 ; NEON-NEXT:    ret void
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
98   ret void
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
121   ret void
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
144   ret void
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
167   ret void
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
184   ret void
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
201   ret void
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
218   ret void
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
235   ret void
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
252   ret void
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
269   ret void
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
286   ret void
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
318   ret void
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
350   ret void
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>)