[X86] X86DAGToDAGISel - attempt to merge XMM/YMM loads with YMM/ZMM loads of the...
[llvm-project.git] / llvm / test / CodeGen / Thumb2 / mve-vldst4.ll
blob219541cffb940fa339842f02b23877f9fef3a8cd
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp -verify-machineinstrs %s -o - | FileCheck %s
4 define void @vldst4(ptr nocapture readonly %pIn, ptr nocapture %pOut, i32 %numRows, i32 %numCols, i32 %scale.coerce) #0 {
5 ; CHECK-LABEL: vldst4:
6 ; CHECK:       @ %bb.0: @ %entry
7 ; CHECK-NEXT:    .save {r7, lr}
8 ; CHECK-NEXT:    push {r7, lr}
9 ; CHECK-NEXT:    .vsave {d8, d9, d10, d11, d12, d13}
10 ; CHECK-NEXT:    vpush {d8, d9, d10, d11, d12, d13}
11 ; CHECK-NEXT:    mul r12, r3, r2
12 ; CHECK-NEXT:    lsrs.w r2, r12, #2
13 ; CHECK-NEXT:    beq.w .LBB0_3
14 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
15 ; CHECK-NEXT:    mvn r3, #7
16 ; CHECK-NEXT:    ldr r2, [sp, #56]
17 ; CHECK-NEXT:    and.w r3, r3, r12, lsr #2
18 ; CHECK-NEXT:    sub.w r12, r3, #8
19 ; CHECK-NEXT:    movs r3, #1
20 ; CHECK-NEXT:    add.w lr, r3, r12, lsr #3
21 ; CHECK-NEXT:  .LBB0_2: @ %vector.body
22 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
23 ; CHECK-NEXT:    vldrh.u16 q1, [r0, #32]
24 ; CHECK-NEXT:    vldrh.u16 q4, [r0, #48]
25 ; CHECK-NEXT:    vldrh.u16 q3, [r0], #64
26 ; CHECK-NEXT:    vmovx.f16 s26, s4
27 ; CHECK-NEXT:    vins.f16 s4, s6
28 ; CHECK-NEXT:    vmovx.f16 s6, s6
29 ; CHECK-NEXT:    vldrh.u16 q5, [r0, #-48]
30 ; CHECK-NEXT:    vmovx.f16 s27, s16
31 ; CHECK-NEXT:    vins.f16 s26, s6
32 ; CHECK-NEXT:    vmovx.f16 s6, s18
33 ; CHECK-NEXT:    vmovx.f16 s8, s7
34 ; CHECK-NEXT:    vmovx.f16 s10, s5
35 ; CHECK-NEXT:    vmovx.f16 s24, s12
36 ; CHECK-NEXT:    vins.f16 s10, s8
37 ; CHECK-NEXT:    vins.f16 s27, s6
38 ; CHECK-NEXT:    vmovx.f16 s6, s14
39 ; CHECK-NEXT:    vmovx.f16 s8, s19
40 ; CHECK-NEXT:    vmovx.f16 s11, s17
41 ; CHECK-NEXT:    vmov.f32 s0, s13
42 ; CHECK-NEXT:    vins.f16 s11, s8
43 ; CHECK-NEXT:    vmovx.f16 s25, s20
44 ; CHECK-NEXT:    vins.f16 s24, s6
45 ; CHECK-NEXT:    vmovx.f16 s6, s22
46 ; CHECK-NEXT:    vmovx.f16 s1, s15
47 ; CHECK-NEXT:    vmovx.f16 s8, s13
48 ; CHECK-NEXT:    vins.f16 s20, s22
49 ; CHECK-NEXT:    vins.f16 s16, s18
50 ; CHECK-NEXT:    vmov.f32 s2, s5
51 ; CHECK-NEXT:    vins.f16 s25, s6
52 ; CHECK-NEXT:    vmov.f32 s3, s17
53 ; CHECK-NEXT:    vins.f16 s0, s15
54 ; CHECK-NEXT:    vmovx.f16 s9, s21
55 ; CHECK-NEXT:    vins.f16 s8, s1
56 ; CHECK-NEXT:    vmovx.f16 s1, s23
57 ; CHECK-NEXT:    vins.f16 s12, s14
58 ; CHECK-NEXT:    vins.f16 s21, s23
59 ; CHECK-NEXT:    vmov.f32 s14, s4
60 ; CHECK-NEXT:    vmov.f32 s15, s16
61 ; CHECK-NEXT:    vins.f16 s9, s1
62 ; CHECK-NEXT:    vmov.f32 s13, s20
63 ; CHECK-NEXT:    vmul.f16 q6, q6, r2
64 ; CHECK-NEXT:    vmul.f16 q3, q3, r2
65 ; CHECK-NEXT:    vins.f16 s2, s7
66 ; CHECK-NEXT:    vins.f16 s3, s19
67 ; CHECK-NEXT:    vmov.f32 s1, s21
68 ; CHECK-NEXT:    vmul.f16 q0, q0, r2
69 ; CHECK-NEXT:    vmovx.f16 s4, s12
70 ; CHECK-NEXT:    vmovx.f16 s6, s24
71 ; CHECK-NEXT:    vmul.f16 q2, q2, r2
72 ; CHECK-NEXT:    vmovx.f16 s7, s0
73 ; CHECK-NEXT:    vins.f16 s0, s8
74 ; CHECK-NEXT:    vmovx.f16 s8, s8
75 ; CHECK-NEXT:    vins.f16 s4, s6
76 ; CHECK-NEXT:    vmovx.f16 s5, s1
77 ; CHECK-NEXT:    vmovx.f16 s6, s9
78 ; CHECK-NEXT:    vins.f16 s7, s8
79 ; CHECK-NEXT:    vins.f16 s5, s6
80 ; CHECK-NEXT:    vmovx.f16 s6, s13
81 ; CHECK-NEXT:    vmovx.f16 s8, s25
82 ; CHECK-NEXT:    vins.f16 s6, s8
83 ; CHECK-NEXT:    vmovx.f16 s19, s2
84 ; CHECK-NEXT:    vmovx.f16 s8, s10
85 ; CHECK-NEXT:    vmovx.f16 s18, s14
86 ; CHECK-NEXT:    vins.f16 s19, s8
87 ; CHECK-NEXT:    vmovx.f16 s8, s26
88 ; CHECK-NEXT:    vins.f16 s18, s8
89 ; CHECK-NEXT:    vmovx.f16 s23, s3
90 ; CHECK-NEXT:    vmovx.f16 s8, s11
91 ; CHECK-NEXT:    vins.f16 s14, s26
92 ; CHECK-NEXT:    vins.f16 s23, s8
93 ; CHECK-NEXT:    vmovx.f16 s22, s15
94 ; CHECK-NEXT:    vins.f16 s15, s27
95 ; CHECK-NEXT:    vmovx.f16 s8, s27
96 ; CHECK-NEXT:    vins.f16 s12, s24
97 ; CHECK-NEXT:    vins.f16 s13, s25
98 ; CHECK-NEXT:    vins.f16 s3, s11
99 ; CHECK-NEXT:    vins.f16 s1, s9
100 ; CHECK-NEXT:    vins.f16 s2, s10
101 ; CHECK-NEXT:    vins.f16 s22, s8
102 ; CHECK-NEXT:    vmov q2, q3
103 ; CHECK-NEXT:    vmov.f32 s17, s0
104 ; CHECK-NEXT:    vmov.f32 s10, s4
105 ; CHECK-NEXT:    vmov q6, q0
106 ; CHECK-NEXT:    vmov.f32 s11, s7
107 ; CHECK-NEXT:    vmov.f32 s9, s0
108 ; CHECK-NEXT:    vmov.f32 s17, s2
109 ; CHECK-NEXT:    vmov.f32 s16, s14
110 ; CHECK-NEXT:    vmov.f32 s21, s3
111 ; CHECK-NEXT:    vstrh.16 q4, [r1, #32]
112 ; CHECK-NEXT:    vmov.f32 s20, s15
113 ; CHECK-NEXT:    vmov.f32 s7, s5
114 ; CHECK-NEXT:    vstrh.16 q5, [r1, #48]
115 ; CHECK-NEXT:    vstrh.16 q2, [r1], #64
116 ; CHECK-NEXT:    vmov.f32 s4, s13
117 ; CHECK-NEXT:    vmov.f32 s5, s25
118 ; CHECK-NEXT:    vstrh.16 q1, [r1, #-48]
119 ; CHECK-NEXT:    le lr, .LBB0_2
120 ; CHECK-NEXT:  .LBB0_3: @ %while.end
121 ; CHECK-NEXT:    vpop {d8, d9, d10, d11, d12, d13}
122 ; CHECK-NEXT:    pop {r7, pc}
123 entry:
124   %tmp.0.extract.trunc = trunc i32 %scale.coerce to i16
125   %l0 = bitcast i16 %tmp.0.extract.trunc to half
126   %mul = mul i32 %numCols, %numRows
127   %shr = lshr i32 %mul, 2
128   %cmp38 = icmp eq i32 %shr, 0
129   br i1 %cmp38, label %while.end, label %vector.ph
131 vector.ph:                                        ; preds = %vector.memcheck
132   %n.vec = and i32 %shr, 1073741816
133   %l2 = shl nuw i32 %n.vec, 2
134   %ind.end = getelementptr half, ptr %pIn, i32 %l2
135   %l3 = shl nuw i32 %n.vec, 2
136   %ind.end48 = getelementptr half, ptr %pOut, i32 %l3
137   %ind.end50 = sub nsw i32 %shr, %n.vec
138   %broadcast.splatinsert55 = insertelement <8 x half> undef, half %l0, i32 0
139   %broadcast.splat56 = shufflevector <8 x half> %broadcast.splatinsert55, <8 x half> undef, <8 x i32> zeroinitializer
140   br label %vector.body
142 vector.body:                                      ; preds = %vector.body, %vector.ph
143   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
144   %l4 = shl i32 %index, 2
145   %next.gep = getelementptr half, ptr %pIn, i32 %l4
146   %l5 = shl i32 %index, 2
147   %wide.vec = load <32 x half>, ptr %next.gep, align 2
148   %strided.vec = shufflevector <32 x half> %wide.vec, <32 x half> undef, <8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
149   %strided.vec52 = shufflevector <32 x half> %wide.vec, <32 x half> undef, <8 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 29>
150   %strided.vec53 = shufflevector <32 x half> %wide.vec, <32 x half> undef, <8 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30>
151   %strided.vec54 = shufflevector <32 x half> %wide.vec, <32 x half> undef, <8 x i32> <i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 31>
152   %l7 = fmul <8 x half> %strided.vec, %broadcast.splat56
153   %l8 = fmul <8 x half> %strided.vec52, %broadcast.splat56
154   %l9 = fmul <8 x half> %strided.vec53, %broadcast.splat56
155   %l10 = fmul <8 x half> %strided.vec54, %broadcast.splat56
156   %l11 = getelementptr inbounds half, ptr %pOut, i32 %l5
157   %l13 = shufflevector <8 x half> %l7, <8 x half> %l8, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
158   %l14 = shufflevector <8 x half> %l9, <8 x half> %l10, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
159   %interleaved.vec = shufflevector <16 x half> %l13, <16 x half> %l14, <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
160   store <32 x half> %interleaved.vec, ptr %l11, align 2
161   %index.next = add i32 %index, 8
162   %l15 = icmp eq i32 %index.next, %n.vec
163   br i1 %l15, label %while.end, label %vector.body
165 while.end:                                        ; preds = %while.body, %middle.block, %entry
166   ret void