[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / vldn_shuffle.ll
blob55d3943bbc7d890944faad93f3a1aff9fea2cb76
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64 | FileCheck %s
4 define void @vld2(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
5 ; CHECK-LABEL: vld2:
6 ; CHECK:       // %bb.0: // %entry
7 ; CHECK-NEXT:    mov x8, xzr
8 ; CHECK-NEXT:  .LBB0_1: // %vector.body
9 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
10 ; CHECK-NEXT:    ld2 { v0.4s, v1.4s }, [x0], #32
11 ; CHECK-NEXT:    fmul v2.4s, v0.4s, v0.4s
12 ; CHECK-NEXT:    fmla v2.4s, v1.4s, v1.4s
13 ; CHECK-NEXT:    str q2, [x1, x8]
14 ; CHECK-NEXT:    add x8, x8, #16
15 ; CHECK-NEXT:    cmp x8, #1, lsl #12 // =4096
16 ; CHECK-NEXT:    b.ne .LBB0_1
17 ; CHECK-NEXT:  // %bb.2: // %while.end
18 ; CHECK-NEXT:    ret
19 entry:
20   br label %vector.body
22 vector.body:                                      ; preds = %vector.body, %entry
23   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
24   %0 = shl i64 %index, 1
25   %next.gep = getelementptr float, ptr %pSrc, i64 %0
26   %next.gep19 = getelementptr float, ptr %pDst, i64 %index
27   %wide.vec = load <8 x float>, ptr %next.gep, align 4
28   %1 = fmul fast <8 x float> %wide.vec, %wide.vec
29   %2 = shufflevector <8 x float> %1, <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
30   %3 = fmul fast <8 x float> %wide.vec, %wide.vec
31   %4 = shufflevector <8 x float> %3, <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
32   %5 = fadd fast <4 x float> %4, %2
33   store <4 x float> %5, ptr %next.gep19, align 4
34   %index.next = add i64 %index, 4
35   %6 = icmp eq i64 %index.next, 1024
36   br i1 %6, label %while.end, label %vector.body
38 while.end:                                        ; preds = %vector.body
39   ret void
42 define void @vld3(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
43 ; CHECK-LABEL: vld3:
44 ; CHECK:       // %bb.0: // %entry
45 ; CHECK-NEXT:    mov x8, xzr
46 ; CHECK-NEXT:  .LBB1_1: // %vector.body
47 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
48 ; CHECK-NEXT:    ld3 { v0.4s, v1.4s, v2.4s }, [x0], #48
49 ; CHECK-NEXT:    fmul v3.4s, v0.4s, v0.4s
50 ; CHECK-NEXT:    fmla v3.4s, v1.4s, v1.4s
51 ; CHECK-NEXT:    fmla v3.4s, v2.4s, v2.4s
52 ; CHECK-NEXT:    str q3, [x1, x8]
53 ; CHECK-NEXT:    add x8, x8, #16
54 ; CHECK-NEXT:    cmp x8, #1, lsl #12 // =4096
55 ; CHECK-NEXT:    b.ne .LBB1_1
56 ; CHECK-NEXT:  // %bb.2: // %while.end
57 ; CHECK-NEXT:    ret
58 entry:
59   br label %vector.body
61 vector.body:                                      ; preds = %vector.body, %entry
62   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
63   %0 = mul i64 %index, 3
64   %next.gep = getelementptr float, ptr %pSrc, i64 %0
65   %next.gep23 = getelementptr float, ptr %pDst, i64 %index
66   %wide.vec = load <12 x float>, ptr %next.gep, align 4
67   %1 = fmul fast <12 x float> %wide.vec, %wide.vec
68   %2 = shufflevector <12 x float> %1, <12 x float> undef, <4 x i32> <i32 0, i32 3, i32 6, i32 9>
69   %3 = fmul fast <12 x float> %wide.vec, %wide.vec
70   %4 = shufflevector <12 x float> %3, <12 x float> undef, <4 x i32> <i32 1, i32 4, i32 7, i32 10>
71   %5 = fadd fast <4 x float> %4, %2
72   %6 = fmul fast <12 x float> %wide.vec, %wide.vec
73   %7 = shufflevector <12 x float> %6, <12 x float> undef, <4 x i32> <i32 2, i32 5, i32 8, i32 11>
74   %8 = fadd fast <4 x float> %5, %7
75   store <4 x float> %8, ptr %next.gep23, align 4
76   %index.next = add i64 %index, 4
77   %9 = icmp eq i64 %index.next, 1024
78   br i1 %9, label %while.end, label %vector.body
80 while.end:                                        ; preds = %vector.body
81   ret void
84 define void @vld4(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
85 ; CHECK-LABEL: vld4:
86 ; CHECK:       // %bb.0: // %entry
87 ; CHECK-NEXT:    mov x8, xzr
88 ; CHECK-NEXT:  .LBB2_1: // %vector.body
89 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
90 ; CHECK-NEXT:    ld4 { v0.4s, v1.4s, v2.4s, v3.4s }, [x0], #64
91 ; CHECK-NEXT:    fmul v4.4s, v0.4s, v0.4s
92 ; CHECK-NEXT:    add x9, x1, x8
93 ; CHECK-NEXT:    add x8, x8, #32
94 ; CHECK-NEXT:    cmp x8, #2, lsl #12 // =8192
95 ; CHECK-NEXT:    fmla v4.4s, v1.4s, v1.4s
96 ; CHECK-NEXT:    fmul v5.4s, v2.4s, v2.4s
97 ; CHECK-NEXT:    fmla v5.4s, v3.4s, v3.4s
98 ; CHECK-NEXT:    st2 { v4.4s, v5.4s }, [x9]
99 ; CHECK-NEXT:    b.ne .LBB2_1
100 ; CHECK-NEXT:  // %bb.2: // %while.end
101 ; CHECK-NEXT:    ret
102 entry:
103   br label %vector.body
105 vector.body:                                      ; preds = %vector.body, %entry
106   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
107   %0 = shl i64 %index, 2
108   %next.gep = getelementptr float, ptr %pSrc, i64 %0
109   %1 = shl i64 %index, 1
110   %wide.vec = load <16 x float>, ptr %next.gep, align 4
111   %2 = fmul fast <16 x float> %wide.vec, %wide.vec
112   %3 = shufflevector <16 x float> %2, <16 x float> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
113   %4 = fmul fast <16 x float> %wide.vec, %wide.vec
114   %5 = shufflevector <16 x float> %4, <16 x float> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
115   %6 = fadd fast <4 x float> %5, %3
116   %7 = fmul fast <16 x float> %wide.vec, %wide.vec
117   %8 = shufflevector <16 x float> %7, <16 x float> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
118   %9 = fmul fast <16 x float> %wide.vec, %wide.vec
119   %10 = shufflevector <16 x float> %9, <16 x float> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
120   %11 = fadd fast <4 x float> %10, %8
121   %12 = getelementptr inbounds float, ptr %pDst, i64 %1
122   %interleaved.vec = shufflevector <4 x float> %6, <4 x float> %11, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
123   store <8 x float> %interleaved.vec, ptr %12, align 4
124   %index.next = add i64 %index, 4
125   %13 = icmp eq i64 %index.next, 1024
126   br i1 %13, label %while.end, label %vector.body
128 while.end:                                        ; preds = %vector.body
129   ret void
132 define void @twosrc(ptr nocapture readonly %pSrc, ptr nocapture readonly %pSrc2, ptr noalias nocapture %pDst, i32 %numSamples) {
133 ; CHECK-LABEL: twosrc:
134 ; CHECK:       // %bb.0: // %entry
135 ; CHECK-NEXT:    mov x8, xzr
136 ; CHECK-NEXT:  .LBB3_1: // %vector.body
137 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
138 ; CHECK-NEXT:    add x9, x0, x8
139 ; CHECK-NEXT:    add x10, x1, x8
140 ; CHECK-NEXT:    add x8, x8, #32
141 ; CHECK-NEXT:    ld2 { v0.4s, v1.4s }, [x9]
142 ; CHECK-NEXT:    cmp x8, #2, lsl #12 // =8192
143 ; CHECK-NEXT:    ld2 { v2.4s, v3.4s }, [x10]
144 ; CHECK-NEXT:    fmul v4.4s, v2.4s, v0.4s
145 ; CHECK-NEXT:    fmla v4.4s, v1.4s, v3.4s
146 ; CHECK-NEXT:    str q4, [x2], #16
147 ; CHECK-NEXT:    b.ne .LBB3_1
148 ; CHECK-NEXT:  // %bb.2: // %while.end
149 ; CHECK-NEXT:    ret
150 entry:
151   br label %vector.body
153 vector.body:                                      ; preds = %vector.body, %entry
154   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
155   %0 = shl i64 %index, 1
156   %next.gep = getelementptr float, ptr %pSrc, i64 %0
157   %1 = shl i64 %index, 1
158   %next.gep23 = getelementptr float, ptr %pSrc2, i64 %1
159   %next.gep24 = getelementptr float, ptr %pDst, i64 %index
160   %wide.vec = load <8 x float>, ptr %next.gep, align 4
161   %wide.vec26 = load <8 x float>, ptr %next.gep23, align 4
162   %2 = fmul fast <8 x float> %wide.vec26, %wide.vec
163   %3 = shufflevector <8 x float> %2, <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
164   %4 = fmul fast <8 x float> %wide.vec26, %wide.vec
165   %5 = shufflevector <8 x float> %4, <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
166   %6 = fadd fast <4 x float> %5, %3
167   store <4 x float> %6, ptr %next.gep24, align 4
168   %index.next = add i64 %index, 4
169   %7 = icmp eq i64 %index.next, 1024
170   br i1 %7, label %while.end, label %vector.body
172 while.end:                                        ; preds = %vector.body
173   ret void
176 define void @vld2_multiuse(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
177 ; CHECK-LABEL: vld2_multiuse:
178 ; CHECK:       // %bb.0: // %entry
179 ; CHECK-NEXT:    mov x8, xzr
180 ; CHECK-NEXT:  .LBB4_1: // %vector.body
181 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
182 ; CHECK-NEXT:    ld2 { v0.4s, v1.4s }, [x0], #32
183 ; CHECK-NEXT:    fmul v2.4s, v0.4s, v0.4s
184 ; CHECK-NEXT:    fmla v2.4s, v1.4s, v1.4s
185 ; CHECK-NEXT:    str q2, [x1, x8]
186 ; CHECK-NEXT:    add x8, x8, #16
187 ; CHECK-NEXT:    cmp x8, #1, lsl #12 // =4096
188 ; CHECK-NEXT:    b.ne .LBB4_1
189 ; CHECK-NEXT:  // %bb.2: // %while.end
190 ; CHECK-NEXT:    ret
191 entry:
192   br label %vector.body
194 vector.body:                                      ; preds = %vector.body, %entry
195   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
196   %0 = shl i64 %index, 1
197   %next.gep = getelementptr float, ptr %pSrc, i64 %0
198   %next.gep19 = getelementptr float, ptr %pDst, i64 %index
199   %wide.vec = load <8 x float>, ptr %next.gep, align 4
200   %1 = fmul fast <8 x float> %wide.vec, %wide.vec
201   %2 = shufflevector <8 x float> %1, <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
202   %3 = shufflevector <8 x float> %1, <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
203   %4 = fadd fast <4 x float> %3, %2
204   store <4 x float> %4, ptr %next.gep19, align 4
205   %index.next = add i64 %index, 4
206   %5 = icmp eq i64 %index.next, 1024
207   br i1 %5, label %while.end, label %vector.body
209 while.end:                                        ; preds = %vector.body
210   ret void
213 define void @vld3_multiuse(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
214 ; CHECK-LABEL: vld3_multiuse:
215 ; CHECK:       // %bb.0: // %entry
216 ; CHECK-NEXT:    mov x8, xzr
217 ; CHECK-NEXT:  .LBB5_1: // %vector.body
218 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
219 ; CHECK-NEXT:    ld3 { v0.4s, v1.4s, v2.4s }, [x0], #48
220 ; CHECK-NEXT:    fmul v3.4s, v0.4s, v0.4s
221 ; CHECK-NEXT:    fmla v3.4s, v1.4s, v1.4s
222 ; CHECK-NEXT:    fmla v3.4s, v2.4s, v2.4s
223 ; CHECK-NEXT:    str q3, [x1, x8]
224 ; CHECK-NEXT:    add x8, x8, #16
225 ; CHECK-NEXT:    cmp x8, #1, lsl #12 // =4096
226 ; CHECK-NEXT:    b.ne .LBB5_1
227 ; CHECK-NEXT:  // %bb.2: // %while.end
228 ; CHECK-NEXT:    ret
229 entry:
230   br label %vector.body
232 vector.body:                                      ; preds = %vector.body, %entry
233   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
234   %0 = mul i64 %index, 3
235   %next.gep = getelementptr float, ptr %pSrc, i64 %0
236   %next.gep23 = getelementptr float, ptr %pDst, i64 %index
237   %wide.vec = load <12 x float>, ptr %next.gep, align 4
238   %1 = fmul fast <12 x float> %wide.vec, %wide.vec
239   %2 = shufflevector <12 x float> %1, <12 x float> undef, <4 x i32> <i32 0, i32 3, i32 6, i32 9>
240   %3 = shufflevector <12 x float> %1, <12 x float> undef, <4 x i32> <i32 1, i32 4, i32 7, i32 10>
241   %4 = fadd fast <4 x float> %3, %2
242   %5 = shufflevector <12 x float> %1, <12 x float> undef, <4 x i32> <i32 2, i32 5, i32 8, i32 11>
243   %6 = fadd fast <4 x float> %4, %5
244   store <4 x float> %6, ptr %next.gep23, align 4
245   %index.next = add i64 %index, 4
246   %7 = icmp eq i64 %index.next, 1024
247   br i1 %7, label %while.end, label %vector.body
249 while.end:                                        ; preds = %vector.body
250   ret void
253 define void @vld4_multiuse(ptr nocapture readonly %pSrc, ptr noalias nocapture %pDst, i32 %numSamples) {
254 ; CHECK-LABEL: vld4_multiuse:
255 ; CHECK:       // %bb.0: // %entry
256 ; CHECK-NEXT:    mov x8, xzr
257 ; CHECK-NEXT:  .LBB6_1: // %vector.body
258 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
259 ; CHECK-NEXT:    ld4 { v0.4s, v1.4s, v2.4s, v3.4s }, [x0], #64
260 ; CHECK-NEXT:    fmul v4.4s, v0.4s, v0.4s
261 ; CHECK-NEXT:    add x9, x1, x8
262 ; CHECK-NEXT:    add x8, x8, #32
263 ; CHECK-NEXT:    cmp x8, #2, lsl #12 // =8192
264 ; CHECK-NEXT:    fmla v4.4s, v1.4s, v1.4s
265 ; CHECK-NEXT:    fmul v5.4s, v2.4s, v2.4s
266 ; CHECK-NEXT:    fmla v5.4s, v3.4s, v3.4s
267 ; CHECK-NEXT:    st2 { v4.4s, v5.4s }, [x9]
268 ; CHECK-NEXT:    b.ne .LBB6_1
269 ; CHECK-NEXT:  // %bb.2: // %while.end
270 ; CHECK-NEXT:    ret
271 entry:
272   br label %vector.body
274 vector.body:                                      ; preds = %vector.body, %entry
275   %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
276   %0 = shl i64 %index, 2
277   %next.gep = getelementptr float, ptr %pSrc, i64 %0
278   %1 = shl i64 %index, 1
279   %wide.vec = load <16 x float>, ptr %next.gep, align 4
280   %2 = fmul fast <16 x float> %wide.vec, %wide.vec
281   %3 = shufflevector <16 x float> %2, <16 x float> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
282   %4 = shufflevector <16 x float> %2, <16 x float> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
283   %5 = fadd fast <4 x float> %4, %3
284   %6 = shufflevector <16 x float> %2, <16 x float> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
285   %7 = shufflevector <16 x float> %2, <16 x float> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
286   %8 = fadd fast <4 x float> %7, %6
287   %9 = getelementptr inbounds float, ptr %pDst, i64 %1
288   %interleaved.vec = shufflevector <4 x float> %5, <4 x float> %8, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
289   store <8 x float> %interleaved.vec, ptr %9, align 4
290   %index.next = add i64 %index, 4
291   %10 = icmp eq i64 %index.next, 1024
292   br i1 %10, label %while.end, label %vector.body
294 while.end:                                        ; preds = %vector.body
295   ret void
298 ; This example has store(shuffle(shuffle(... that would be better to be treated
299 ; as a single store. This avoids the vld2 for data that is already shuffled.
300 define void @transpose_s16_8x8_simpler(ptr nocapture noundef %a) {
301 ; CHECK-LABEL: transpose_s16_8x8_simpler:
302 ; CHECK:       // %bb.0: // %entry
303 ; CHECK-NEXT:    ldp q0, q1, [x0]
304 ; CHECK-NEXT:    ldp q2, q3, [x0, #64]
305 ; CHECK-NEXT:    ldp q4, q5, [x0, #32]
306 ; CHECK-NEXT:    ldp q6, q7, [x0, #96]
307 ; CHECK-NEXT:    trn1 v0.8h, v0.8h, v1.8h
308 ; CHECK-NEXT:    trn1 v1.8h, v2.8h, v3.8h
309 ; CHECK-NEXT:    trn1 v2.8h, v4.8h, v5.8h
310 ; CHECK-NEXT:    trn1 v3.8h, v6.8h, v7.8h
311 ; CHECK-NEXT:    trn1 v0.4s, v0.4s, v1.4s
312 ; CHECK-NEXT:    trn1 v1.4s, v2.4s, v3.4s
313 ; CHECK-NEXT:    zip2 v2.4s, v0.4s, v1.4s
314 ; CHECK-NEXT:    st2 { v0.2s, v1.2s }, [x0]
315 ; CHECK-NEXT:    str q2, [x0, #64]
316 ; CHECK-NEXT:    ret
317 entry:
318   %0 = load <8 x i16>, ptr %a, align 16
319   %arrayidx1 = getelementptr inbounds <8 x i16>, ptr %a, i64 1
320   %1 = load <8 x i16>, ptr %arrayidx1, align 16
321   %shuffle.i = shufflevector <8 x i16> %0, <8 x i16> %1, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
322   %arrayidx2 = getelementptr inbounds <8 x i16>, ptr %a, i64 2
323   %2 = load <8 x i16>, ptr %arrayidx2, align 16
324   %arrayidx3 = getelementptr inbounds <8 x i16>, ptr %a, i64 3
325   %3 = load <8 x i16>, ptr %arrayidx3, align 16
326   %shuffle.i34 = shufflevector <8 x i16> %2, <8 x i16> %3, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
327   %arrayidx5 = getelementptr inbounds <8 x i16>, ptr %a, i64 4
328   %4 = load <8 x i16>, ptr %arrayidx5, align 16
329   %arrayidx6 = getelementptr inbounds <8 x i16>, ptr %a, i64 5
330   %5 = load <8 x i16>, ptr %arrayidx6, align 16
331   %shuffle.i35 = shufflevector <8 x i16> %4, <8 x i16> %5, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
332   %arrayidx8 = getelementptr inbounds <8 x i16>, ptr %a, i64 6
333   %6 = load <8 x i16>, ptr %arrayidx8, align 16
334   %arrayidx9 = getelementptr inbounds <8 x i16>, ptr %a, i64 7
335   %7 = load <8 x i16>, ptr %arrayidx9, align 16
336   %shuffle.i36 = shufflevector <8 x i16> %6, <8 x i16> %7, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
337   %8 = bitcast <8 x i16> %shuffle.i to <4 x i32>
338   %9 = bitcast <8 x i16> %shuffle.i35 to <4 x i32>
339   %shuffle.i37 = shufflevector <4 x i32> %8, <4 x i32> %9, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
340   %10 = bitcast <8 x i16> %shuffle.i34 to <4 x i32>
341   %11 = bitcast <8 x i16> %shuffle.i36 to <4 x i32>
342   %shuffle.i38 = shufflevector <4 x i32> %10, <4 x i32> %11, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
343   %vzip.i = shufflevector <4 x i32> %shuffle.i37, <4 x i32> %shuffle.i38, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
344   %vzip1.i = shufflevector <4 x i32> %shuffle.i37, <4 x i32> %shuffle.i38, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
345   store <4 x i32> %vzip.i, ptr %a, align 16
346   store <4 x i32> %vzip1.i, ptr %arrayidx5, align 16
347   ret void
350 ; Same as above with some different shuffles
351 define void @transpose_s16_8x8_simpler2(ptr nocapture noundef %a) {
352 ; CHECK-LABEL: transpose_s16_8x8_simpler2:
353 ; CHECK:       // %bb.0: // %entry
354 ; CHECK-NEXT:    ldp q0, q2, [x0]
355 ; CHECK-NEXT:    ldp q3, q4, [x0, #64]
356 ; CHECK-NEXT:    ldp q5, q6, [x0, #32]
357 ; CHECK-NEXT:    ldp q7, q16, [x0, #96]
358 ; CHECK-NEXT:    mov v0.h[5], v2.h[4]
359 ; CHECK-NEXT:    zip1 v2.8h, v3.8h, v4.8h
360 ; CHECK-NEXT:    zip1 v3.8h, v5.8h, v6.8h
361 ; CHECK-NEXT:    mov v7.h[5], v16.h[4]
362 ; CHECK-NEXT:    mov v0.s[1], v2.s[0]
363 ; CHECK-NEXT:    uzp1 v1.4s, v3.4s, v7.4s
364 ; CHECK-NEXT:    zip2 v2.4s, v0.4s, v1.4s
365 ; CHECK-NEXT:    st2 { v0.2s, v1.2s }, [x0]
366 ; CHECK-NEXT:    str q2, [x0, #64]
367 ; CHECK-NEXT:    ret
368 entry:
369   %0 = load <8 x i16>, ptr %a, align 16
370   %arrayidx1 = getelementptr inbounds <8 x i16>, ptr %a, i64 1
371   %1 = load <8 x i16>, ptr %arrayidx1, align 16
372   %shuffle.i = shufflevector <8 x i16> %0, <8 x i16> %1, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
373   %arrayidx2 = getelementptr inbounds <8 x i16>, ptr %a, i64 2
374   %2 = load <8 x i16>, ptr %arrayidx2, align 16
375   %arrayidx3 = getelementptr inbounds <8 x i16>, ptr %a, i64 3
376   %3 = load <8 x i16>, ptr %arrayidx3, align 16
377   %shuffle.i34 = shufflevector <8 x i16> %2, <8 x i16> %3, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
378   %arrayidx5 = getelementptr inbounds <8 x i16>, ptr %a, i64 4
379   %4 = load <8 x i16>, ptr %arrayidx5, align 16
380   %arrayidx6 = getelementptr inbounds <8 x i16>, ptr %a, i64 5
381   %5 = load <8 x i16>, ptr %arrayidx6, align 16
382   %shuffle.i35 = shufflevector <8 x i16> %4, <8 x i16> %5, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
383   %arrayidx8 = getelementptr inbounds <8 x i16>, ptr %a, i64 6
384   %6 = load <8 x i16>, ptr %arrayidx8, align 16
385   %arrayidx9 = getelementptr inbounds <8 x i16>, ptr %a, i64 7
386   %7 = load <8 x i16>, ptr %arrayidx9, align 16
387   %shuffle.i36 = shufflevector <8 x i16> %6, <8 x i16> %7, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 4, i32 12, i32 undef, i32 undef>
388   %8 = bitcast <8 x i16> %shuffle.i to <4 x i32>
389   %9 = bitcast <8 x i16> %shuffle.i35 to <4 x i32>
390   %shuffle.i37 = shufflevector <4 x i32> %8, <4 x i32> %9, <4 x i32> <i32 1, i32 4, i32 2, i32 7>
391   %10 = bitcast <8 x i16> %shuffle.i34 to <4 x i32>
392   %11 = bitcast <8 x i16> %shuffle.i36 to <4 x i32>
393   %shuffle.i38 = shufflevector <4 x i32> %10, <4 x i32> %11, <4 x i32> <i32 0, i32 5, i32 3, i32 6>
394   %vzip.i = shufflevector <4 x i32> %shuffle.i37, <4 x i32> %shuffle.i38, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
395   %vzip1.i = shufflevector <4 x i32> %shuffle.i37, <4 x i32> %shuffle.i38, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
396   store <4 x i32> %vzip.i, ptr %a, align 16
397   store <4 x i32> %vzip1.i, ptr %arrayidx5, align 16
398   ret void
402 define void @transpose_s16_8x8(ptr nocapture noundef %0, ptr nocapture noundef %1, ptr nocapture noundef %2, ptr nocapture noundef %3, ptr nocapture noundef %4, ptr nocapture noundef %5, ptr nocapture noundef %6, ptr nocapture noundef %7) {
403 ; CHECK-LABEL: transpose_s16_8x8:
404 ; CHECK:       // %bb.0:
405 ; CHECK-NEXT:    ldr q0, [x0]
406 ; CHECK-NEXT:    ldr q1, [x1]
407 ; CHECK-NEXT:    ldr q3, [x4]
408 ; CHECK-NEXT:    ldr q4, [x5]
409 ; CHECK-NEXT:    ldr q2, [x2]
410 ; CHECK-NEXT:    ldr q5, [x3]
411 ; CHECK-NEXT:    trn1 v16.8h, v0.8h, v1.8h
412 ; CHECK-NEXT:    trn2 v0.8h, v0.8h, v1.8h
413 ; CHECK-NEXT:    ldr q6, [x6]
414 ; CHECK-NEXT:    ldr q7, [x7]
415 ; CHECK-NEXT:    trn1 v17.8h, v3.8h, v4.8h
416 ; CHECK-NEXT:    trn2 v1.8h, v3.8h, v4.8h
417 ; CHECK-NEXT:    trn1 v18.8h, v2.8h, v5.8h
418 ; CHECK-NEXT:    trn2 v2.8h, v2.8h, v5.8h
419 ; CHECK-NEXT:    trn1 v19.8h, v6.8h, v7.8h
420 ; CHECK-NEXT:    trn2 v3.8h, v6.8h, v7.8h
421 ; CHECK-NEXT:    trn1 v4.4s, v16.4s, v17.4s
422 ; CHECK-NEXT:    trn1 v6.4s, v0.4s, v1.4s
423 ; CHECK-NEXT:    trn2 v16.4s, v16.4s, v17.4s
424 ; CHECK-NEXT:    trn2 v0.4s, v0.4s, v1.4s
425 ; CHECK-NEXT:    trn1 v5.4s, v18.4s, v19.4s
426 ; CHECK-NEXT:    trn1 v7.4s, v2.4s, v3.4s
427 ; CHECK-NEXT:    trn2 v17.4s, v18.4s, v19.4s
428 ; CHECK-NEXT:    trn2 v1.4s, v2.4s, v3.4s
429 ; CHECK-NEXT:    st2 { v4.2s, v5.2s }, [x0]
430 ; CHECK-NEXT:    zip2 v2.4s, v4.4s, v5.4s
431 ; CHECK-NEXT:    zip2 v3.4s, v6.4s, v7.4s
432 ; CHECK-NEXT:    zip2 v4.4s, v16.4s, v17.4s
433 ; CHECK-NEXT:    st2 { v6.2s, v7.2s }, [x1]
434 ; CHECK-NEXT:    st2 { v16.2s, v17.2s }, [x2]
435 ; CHECK-NEXT:    st2 { v0.2s, v1.2s }, [x3]
436 ; CHECK-NEXT:    zip2 v0.4s, v0.4s, v1.4s
437 ; CHECK-NEXT:    str q2, [x4]
438 ; CHECK-NEXT:    str q3, [x5]
439 ; CHECK-NEXT:    str q4, [x6]
440 ; CHECK-NEXT:    str q0, [x7]
441 ; CHECK-NEXT:    ret
442   %9 = load <8 x i16>, ptr %0, align 16
443   %10 = load <8 x i16>, ptr %1, align 16
444   %11 = shufflevector <8 x i16> %9, <8 x i16> %10, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
445   %12 = shufflevector <8 x i16> %9, <8 x i16> %10, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
446   %13 = load <8 x i16>, ptr %2, align 16
447   %14 = load <8 x i16>, ptr %3, align 16
448   %15 = shufflevector <8 x i16> %13, <8 x i16> %14, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
449   %16 = shufflevector <8 x i16> %13, <8 x i16> %14, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
450   %17 = load <8 x i16>, ptr %4, align 16
451   %18 = load <8 x i16>, ptr %5, align 16
452   %19 = shufflevector <8 x i16> %17, <8 x i16> %18, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
453   %20 = shufflevector <8 x i16> %17, <8 x i16> %18, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
454   %21 = load <8 x i16>, ptr %6, align 16
455   %22 = load <8 x i16>, ptr %7, align 16
456   %23 = shufflevector <8 x i16> %21, <8 x i16> %22, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
457   %24 = shufflevector <8 x i16> %21, <8 x i16> %22, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
458   %25 = bitcast <8 x i16> %11 to <4 x i32>
459   %26 = bitcast <8 x i16> %19 to <4 x i32>
460   %27 = shufflevector <4 x i32> %25, <4 x i32> %26, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
461   %28 = shufflevector <4 x i32> %25, <4 x i32> %26, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
462   %29 = bitcast <8 x i16> %12 to <4 x i32>
463   %30 = bitcast <8 x i16> %20 to <4 x i32>
464   %31 = shufflevector <4 x i32> %29, <4 x i32> %30, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
465   %32 = shufflevector <4 x i32> %29, <4 x i32> %30, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
466   %33 = bitcast <8 x i16> %15 to <4 x i32>
467   %34 = bitcast <8 x i16> %23 to <4 x i32>
468   %35 = shufflevector <4 x i32> %33, <4 x i32> %34, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
469   %36 = shufflevector <4 x i32> %33, <4 x i32> %34, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
470   %37 = bitcast <8 x i16> %16 to <4 x i32>
471   %38 = bitcast <8 x i16> %24 to <4 x i32>
472   %39 = shufflevector <4 x i32> %37, <4 x i32> %38, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
473   %40 = shufflevector <4 x i32> %37, <4 x i32> %38, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
474   %41 = shufflevector <4 x i32> %27, <4 x i32> %35, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
475   %42 = shufflevector <4 x i32> %27, <4 x i32> %35, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
476   %43 = shufflevector <4 x i32> %31, <4 x i32> %39, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
477   %44 = shufflevector <4 x i32> %31, <4 x i32> %39, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
478   %45 = shufflevector <4 x i32> %28, <4 x i32> %36, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
479   %46 = shufflevector <4 x i32> %28, <4 x i32> %36, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
480   %47 = shufflevector <4 x i32> %32, <4 x i32> %40, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
481   %48 = shufflevector <4 x i32> %32, <4 x i32> %40, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
482   store <4 x i32> %41, ptr %0, align 16
483   store <4 x i32> %43, ptr %1, align 16
484   store <4 x i32> %45, ptr %2, align 16
485   store <4 x i32> %47, ptr %3, align 16
486   store <4 x i32> %42, ptr %4, align 16
487   store <4 x i32> %44, ptr %5, align 16
488   store <4 x i32> %46, ptr %6, align 16
489   store <4 x i32> %48, ptr %7, align 16
490   ret void
493 define void @transpose_s16_8x8_(ptr nocapture noundef %0) {
494 ; CHECK-LABEL: transpose_s16_8x8_:
495 ; CHECK:       // %bb.0:
496 ; CHECK-NEXT:    mov x8, x0
497 ; CHECK-NEXT:    ldp q4, q5, [x0, #64]
498 ; CHECK-NEXT:    mov x9, x0
499 ; CHECK-NEXT:    ldr q0, [x8, #16]!
500 ; CHECK-NEXT:    mov x10, x0
501 ; CHECK-NEXT:    ldr q3, [x0]
502 ; CHECK-NEXT:    ldp q6, q7, [x0, #96]
503 ; CHECK-NEXT:    trn1 v17.8h, v4.8h, v5.8h
504 ; CHECK-NEXT:    ldr q1, [x9, #32]!
505 ; CHECK-NEXT:    trn1 v16.8h, v3.8h, v0.8h
506 ; CHECK-NEXT:    ldr q2, [x10, #48]!
507 ; CHECK-NEXT:    trn2 v4.8h, v4.8h, v5.8h
508 ; CHECK-NEXT:    trn1 v19.8h, v6.8h, v7.8h
509 ; CHECK-NEXT:    trn2 v0.8h, v3.8h, v0.8h
510 ; CHECK-NEXT:    trn2 v3.8h, v6.8h, v7.8h
511 ; CHECK-NEXT:    trn1 v18.8h, v1.8h, v2.8h
512 ; CHECK-NEXT:    trn2 v1.8h, v1.8h, v2.8h
513 ; CHECK-NEXT:    trn1 v5.4s, v16.4s, v17.4s
514 ; CHECK-NEXT:    trn2 v16.4s, v16.4s, v17.4s
515 ; CHECK-NEXT:    trn1 v20.4s, v0.4s, v4.4s
516 ; CHECK-NEXT:    trn1 v6.4s, v18.4s, v19.4s
517 ; CHECK-NEXT:    trn2 v17.4s, v18.4s, v19.4s
518 ; CHECK-NEXT:    trn2 v18.4s, v0.4s, v4.4s
519 ; CHECK-NEXT:    trn1 v21.4s, v1.4s, v3.4s
520 ; CHECK-NEXT:    trn2 v19.4s, v1.4s, v3.4s
521 ; CHECK-NEXT:    zip2 v0.4s, v5.4s, v6.4s
522 ; CHECK-NEXT:    zip2 v2.4s, v16.4s, v17.4s
523 ; CHECK-NEXT:    st2 { v5.2s, v6.2s }, [x0]
524 ; CHECK-NEXT:    zip2 v1.4s, v20.4s, v21.4s
525 ; CHECK-NEXT:    zip2 v3.4s, v18.4s, v19.4s
526 ; CHECK-NEXT:    st2 { v20.2s, v21.2s }, [x8]
527 ; CHECK-NEXT:    st2 { v16.2s, v17.2s }, [x9]
528 ; CHECK-NEXT:    st2 { v18.2s, v19.2s }, [x10]
529 ; CHECK-NEXT:    stp q0, q1, [x0, #64]
530 ; CHECK-NEXT:    stp q2, q3, [x0, #96]
531 ; CHECK-NEXT:    ret
532   %2 = load <8 x i16>, ptr %0, align 16
533   %3 = getelementptr inbounds <8 x i16>, ptr %0, i64 1
534   %4 = load <8 x i16>, ptr %3, align 1
535   %5 = shufflevector <8 x i16> %2, <8 x i16> %4, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
536   %6 = shufflevector <8 x i16> %2, <8 x i16> %4, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
537   %7 = getelementptr inbounds <8 x i16>, ptr %0, i64 2
538   %8 = load <8 x i16>, ptr %7, align 16
539   %9 = getelementptr inbounds <8 x i16>, ptr %0, i64 3
540   %10 = load <8 x i16>, ptr %9, align 16
541   %11 = shufflevector <8 x i16> %8, <8 x i16> %10, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
542   %12 = shufflevector <8 x i16> %8, <8 x i16> %10, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
543   %13 = getelementptr inbounds <8 x i16>, ptr %0, i64 4
544   %14 = load <8 x i16>, ptr %13, align 16
545   %15 = getelementptr inbounds <8 x i16>, ptr %0, i64 5
546   %16 = load <8 x i16>, ptr %15, align 16
547   %17 = shufflevector <8 x i16> %14, <8 x i16> %16, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
548   %18 = shufflevector <8 x i16> %14, <8 x i16> %16, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
549   %19 = getelementptr inbounds <8 x i16>, ptr %0, i64 6
550   %20 = load <8 x i16>, ptr %19, align 16
551   %21 = getelementptr inbounds <8 x i16>, ptr %0, i64 7
552   %22 = load <8 x i16>, ptr %21, align 16
553   %23 = shufflevector <8 x i16> %20, <8 x i16> %22, <8 x i32> <i32 0, i32 8, i32 2, i32 10, i32 4, i32 12, i32 6, i32 14>
554   %24 = shufflevector <8 x i16> %20, <8 x i16> %22, <8 x i32> <i32 1, i32 9, i32 3, i32 11, i32 5, i32 13, i32 7, i32 15>
555   %25 = bitcast <8 x i16> %5 to <4 x i32>
556   %26 = bitcast <8 x i16> %17 to <4 x i32>
557   %27 = shufflevector <4 x i32> %25, <4 x i32> %26, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
558   %28 = shufflevector <4 x i32> %25, <4 x i32> %26, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
559   %29 = bitcast <8 x i16> %6 to <4 x i32>
560   %30 = bitcast <8 x i16> %18 to <4 x i32>
561   %31 = shufflevector <4 x i32> %29, <4 x i32> %30, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
562   %32 = shufflevector <4 x i32> %29, <4 x i32> %30, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
563   %33 = bitcast <8 x i16> %11 to <4 x i32>
564   %34 = bitcast <8 x i16> %23 to <4 x i32>
565   %35 = shufflevector <4 x i32> %33, <4 x i32> %34, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
566   %36 = shufflevector <4 x i32> %33, <4 x i32> %34, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
567   %37 = bitcast <8 x i16> %12 to <4 x i32>
568   %38 = bitcast <8 x i16> %24 to <4 x i32>
569   %39 = shufflevector <4 x i32> %37, <4 x i32> %38, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
570   %40 = shufflevector <4 x i32> %37, <4 x i32> %38, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
571   %41 = shufflevector <4 x i32> %27, <4 x i32> %35, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
572   %42 = shufflevector <4 x i32> %27, <4 x i32> %35, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
573   %43 = shufflevector <4 x i32> %31, <4 x i32> %39, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
574   %44 = shufflevector <4 x i32> %31, <4 x i32> %39, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
575   %45 = shufflevector <4 x i32> %28, <4 x i32> %36, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
576   %46 = shufflevector <4 x i32> %28, <4 x i32> %36, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
577   %47 = shufflevector <4 x i32> %32, <4 x i32> %40, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
578   %48 = shufflevector <4 x i32> %32, <4 x i32> %40, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
579   store <4 x i32> %41, ptr %0, align 16
580   store <4 x i32> %43, ptr %3, align 16
581   store <4 x i32> %45, ptr %7, align 16
582   store <4 x i32> %47, ptr %9, align 16
583   store <4 x i32> %42, ptr %13, align 16
584   store <4 x i32> %44, ptr %15, align 16
585   store <4 x i32> %46, ptr %19, align 16
586   store <4 x i32> %48, ptr %21, align 16
587   ret void
590 define void @store_factor2(ptr %ptr, <4 x i32> %a0, <4 x i32> %a1) {
591 ; CHECK-LABEL: store_factor2:
592 ; CHECK:       // %bb.0:
593 ; CHECK-NEXT:    trn1 v2.4s, v0.4s, v1.4s
594 ; CHECK-NEXT:    trn1 v3.4s, v1.4s, v0.4s
595 ; CHECK-NEXT:    st2 { v2.4s, v3.4s }, [x0]
596 ; CHECK-NEXT:    ret
597   %v0 = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
598   %v1 = shufflevector <4 x i32> %a1, <4 x i32> %a0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
599   %interleaved.vec = shufflevector <4 x i32> %v0, <4 x i32> %v1, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
600   store <8 x i32> %interleaved.vec, ptr %ptr, align 4
601   ret void
604 define void @store_factor2_high(ptr %ptr, ptr %ptr2, <4 x i32> %a0, <4 x i32> %a1) {
605 ; CHECK-LABEL: store_factor2_high:
606 ; CHECK:       // %bb.0:
607 ; CHECK-NEXT:    trn1 v2.4s, v0.4s, v1.4s
608 ; CHECK-NEXT:    trn1 v0.4s, v1.4s, v0.4s
609 ; CHECK-NEXT:    zip1 v1.4s, v2.4s, v0.4s
610 ; CHECK-NEXT:    trn1 v1.4s, v1.4s, v0.4s
611 ; CHECK-NEXT:    zip2 v0.4s, v2.4s, v0.4s
612 ; CHECK-NEXT:    str q1, [x0]
613 ; CHECK-NEXT:    str q0, [x1]
614 ; CHECK-NEXT:    ret
615   %v0 = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
616   %v1 = shufflevector <4 x i32> %a1, <4 x i32> %a0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
617   %interleaved.vec = shufflevector <4 x i32> %v0, <4 x i32> %v1, <4 x i32> <i32 0, i32 4, i32 1, i32 6>
618   %interleaved.vec2 = shufflevector <4 x i32> %v0, <4 x i32> %v1, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
619   store <4 x i32> %interleaved.vec, ptr %ptr, align 4
620   store <4 x i32> %interleaved.vec2, ptr %ptr2, align 4
621   ret void
624 define void @store_factor2_high2(ptr %ptr, ptr %ptr2, <4 x i32> %a0, <4 x i32> %a1) {
625 ; CHECK-LABEL: store_factor2_high2:
626 ; CHECK:       // %bb.0:
627 ; CHECK-NEXT:    zip1 v2.4s, v0.4s, v1.4s
628 ; CHECK-NEXT:    zip2 v0.4s, v0.4s, v1.4s
629 ; CHECK-NEXT:    trn1 v2.4s, v2.4s, v1.4s
630 ; CHECK-NEXT:    str q2, [x0]
631 ; CHECK-NEXT:    str q0, [x1]
632 ; CHECK-NEXT:    ret
633   %interleaved.vec = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 0, i32 4, i32 1, i32 6>
634   %interleaved.vec2 = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 2, i32 6, i32 3, i32 7>
635   store <4 x i32> %interleaved.vec, ptr %ptr, align 4
636   store <4 x i32> %interleaved.vec2, ptr %ptr2, align 4
637   ret void
640 define void @store_factor3(ptr %ptr, <4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2) {
641 ; CHECK-LABEL: store_factor3:
642 ; CHECK:       // %bb.0:
643 ; CHECK-NEXT:    ext v3.16b, v0.16b, v1.16b, #12
644 ; CHECK-NEXT:    ext v6.16b, v1.16b, v2.16b, #12
645 ; CHECK-NEXT:    zip2 v3.4s, v0.4s, v3.4s
646 ; CHECK-NEXT:    mov v3.s[0], v0.s[0]
647 ; CHECK-NEXT:    ext v0.16b, v2.16b, v0.16b, #12
648 ; CHECK-NEXT:    zip2 v4.4s, v1.4s, v6.4s
649 ; CHECK-NEXT:    mov v4.s[0], v1.s[0]
650 ; CHECK-NEXT:    zip2 v5.4s, v2.4s, v0.4s
651 ; CHECK-NEXT:    mov v5.s[0], v2.s[0]
652 ; CHECK-NEXT:    st3 { v3.4s, v4.4s, v5.4s }, [x0]
653 ; CHECK-NEXT:    ret
654   %v0 = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 0, i32 5, i32 3, i32 6>
655   %v1 = shufflevector <4 x i32> %a1, <4 x i32> %a2, <4 x i32> <i32 0, i32 5, i32 3, i32 6>
656   %v2 = shufflevector <4 x i32> %a2, <4 x i32> %a0, <4 x i32> <i32 0, i32 5, i32 3, i32 6>
657   %s0 = shufflevector <4 x i32> %v0, <4 x i32> %v1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
658   %s1 = shufflevector <4 x i32> %v2, <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
659   %interleaved.vec = shufflevector <8 x i32> %s0, <8 x i32> %s1, <12 x i32> <i32 0, i32 4, i32 8, i32 1, i32 5, i32 9, i32 2, i32 6, i32 10, i32 3, i32 7, i32 11>
660   store <12 x i32> %interleaved.vec, ptr %ptr, align 4
661   ret void
664 define void @store_factor4(ptr %ptr, <4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2, <4 x i32> %a3) {
665 ; CHECK-LABEL: store_factor4:
666 ; CHECK:       // %bb.0:
667 ; CHECK-NEXT:    trn1 v4.4s, v0.4s, v1.4s
668 ; CHECK-NEXT:    trn1 v5.4s, v1.4s, v2.4s
669 ; CHECK-NEXT:    trn1 v6.4s, v2.4s, v3.4s
670 ; CHECK-NEXT:    trn1 v7.4s, v3.4s, v0.4s
671 ; CHECK-NEXT:    st4 { v4.4s, v5.4s, v6.4s, v7.4s }, [x0]
672 ; CHECK-NEXT:    ret
673   %v0 = shufflevector <4 x i32> %a0, <4 x i32> %a1, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
674   %v1 = shufflevector <4 x i32> %a1, <4 x i32> %a2, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
675   %v2 = shufflevector <4 x i32> %a2, <4 x i32> %a3, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
676   %v3 = shufflevector <4 x i32> %a3, <4 x i32> %a0, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
677   %s0 = shufflevector <4 x i32> %v0, <4 x i32> %v1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
678   %s1 = shufflevector <4 x i32> %v2, <4 x i32> %v3, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
679   %interleaved.vec = shufflevector <8 x i32> %s0, <8 x i32> %s1, <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 1, i32 5, i32 9, i32 13, i32 2, i32 6, i32 10, i32 14, i32 3, i32 7, i32 11, i32 15>
680   store <16 x i32> %interleaved.vec, ptr %ptr, align 4
681   ret void