[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / Thumb2 / LowOverheadLoops / cond-vector-reduce-mve-codegen.ll
blob3de54247ad8e706cb80ab86b0bdeeb6e5a395ebb
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve -tail-predication=enabled --verify-machineinstrs %s -o - | FileCheck %s
4 define dso_local i32 @vpsel_mul_reduce_add(i32* noalias nocapture readonly %a, i32* noalias nocapture readonly %b, i32* noalias nocapture readonly %c, i32 %N) {
5 ; CHECK-LABEL: vpsel_mul_reduce_add:
6 ; CHECK:       @ %bb.0: @ %entry
7 ; CHECK-NEXT:    cmp r3, #0
8 ; CHECK-NEXT:    itt eq
9 ; CHECK-NEXT:    moveq r0, #0
10 ; CHECK-NEXT:    bxeq lr
11 ; CHECK-NEXT:  .LBB0_1: @ %vector.ph
12 ; CHECK-NEXT:    push {r4, lr}
13 ; CHECK-NEXT:    add.w r12, r3, #3
14 ; CHECK-NEXT:    mov.w lr, #1
15 ; CHECK-NEXT:    bic r12, r12, #3
16 ; CHECK-NEXT:    vmov.i32 q1, #0x0
17 ; CHECK-NEXT:    sub.w r12, r12, #4
18 ; CHECK-NEXT:    add.w lr, lr, r12, lsr #2
19 ; CHECK-NEXT:    mov.w r12, #0
20 ; CHECK-NEXT:  .LBB0_2: @ %vector.body
21 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
22 ; CHECK-NEXT:    and r4, r12, #15
23 ; CHECK-NEXT:    vmov q0, q1
24 ; CHECK-NEXT:    vctp.32 r3
25 ; CHECK-NEXT:    vpstt
26 ; CHECK-NEXT:    vldrwt.u32 q1, [r2], #16
27 ; CHECK-NEXT:    vldrwt.u32 q2, [r1], #16
28 ; CHECK-NEXT:    vdup.32 q3, r4
29 ; CHECK-NEXT:    vpt.i32 eq, q3, zr
30 ; CHECK-NEXT:    vmovt q1, q2
31 ; CHECK-NEXT:    vctp.32 r3
32 ; CHECK-NEXT:    vpst
33 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
34 ; CHECK-NEXT:    vmul.i32 q1, q1, q2
35 ; CHECK-NEXT:    add.w r12, r12, #4
36 ; CHECK-NEXT:    subs r3, #4
37 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
38 ; CHECK-NEXT:    le lr, .LBB0_2
39 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
40 ; CHECK-NEXT:    vpsel q0, q1, q0
41 ; CHECK-NEXT:    vaddv.u32 r0, q0
42 ; CHECK-NEXT:    pop {r4, pc}
43 entry:
44   %cmp8 = icmp eq i32 %N, 0
45   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
47 vector.ph:                                        ; preds = %entry
48   %n.rnd.up = add i32 %N, 3
49   %n.vec = and i32 %n.rnd.up, -4
50   br label %vector.body
52 vector.body:                                      ; preds = %vector.body, %vector.ph
53   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
54   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
55   %tmp = getelementptr inbounds i32, i32* %a, i32 %index
56   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
57   %tmp2 = bitcast i32* %tmp to <4 x i32>*
58   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp2, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
59   %tmp3 = getelementptr inbounds i32, i32* %b, i32 %index
60   %tmp4 = bitcast i32* %tmp3 to <4 x i32>*
61   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp4, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
62   %tmp5 = getelementptr inbounds i32, i32* %c, i32 %index
63   %tmp6 = bitcast i32* %tmp5 to <4 x i32>*
64   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp6, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
65   %rem = urem i32 %index, 16
66   %rem.broadcast.splatinsert = insertelement <4 x i32> undef, i32 %rem, i32 0
67   %rem.broadcast.splat = shufflevector <4 x i32> %rem.broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
68   %cmp = icmp eq <4 x i32> %rem.broadcast.splat, <i32 0, i32 0, i32 0, i32 0>
69   %wide.masked.load = select <4 x i1> %cmp, <4 x i32> %wide.masked.load.b, <4 x i32> %wide.masked.load.c
70   %mul = mul nsw <4 x i32> %wide.masked.load, %wide.masked.load.a
71   %add = add nsw <4 x i32> %mul, %vec.phi
72   %index.next = add i32 %index, 4
73   %tmp7 = icmp eq i32 %index.next, %n.vec
74   br i1 %tmp7, label %middle.block, label %vector.body
76 middle.block:                                     ; preds = %vector.body
77   %tmp8 = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
78   %tmp9 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %tmp8)
79   br label %for.cond.cleanup
81 for.cond.cleanup:                                 ; preds = %middle.block, %entry
82   %res.0.lcssa = phi i32 [ 0, %entry ], [ %tmp9, %middle.block ]
83   ret i32 %res.0.lcssa
86 define dso_local i32 @vpsel_mul_reduce_add_2(i32* noalias nocapture readonly %a, i32* noalias nocapture readonly %b,
87 ; CHECK-LABEL: vpsel_mul_reduce_add_2:
88 ; CHECK:       @ %bb.0: @ %entry
89 ; CHECK-NEXT:    push {r4, r5, r7, lr}
90 ; CHECK-NEXT:    vpush {d8, d9}
91 ; CHECK-NEXT:    ldr.w r12, [sp, #32]
92 ; CHECK-NEXT:    cmp.w r12, #0
93 ; CHECK-NEXT:    beq .LBB1_4
94 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
95 ; CHECK-NEXT:    add.w r4, r12, #3
96 ; CHECK-NEXT:    vmov.i32 q1, #0x0
97 ; CHECK-NEXT:    bic r4, r4, #3
98 ; CHECK-NEXT:    sub.w lr, r4, #4
99 ; CHECK-NEXT:    movs r4, #1
100 ; CHECK-NEXT:    add.w lr, r4, lr, lsr #2
101 ; CHECK-NEXT:    movs r4, #0
102 ; CHECK-NEXT:  .LBB1_2: @ %vector.body
103 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
104 ; CHECK-NEXT:    and r5, r4, #15
105 ; CHECK-NEXT:    vmov q0, q1
106 ; CHECK-NEXT:    vctp.32 r12
107 ; CHECK-NEXT:    vpsttt
108 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
109 ; CHECK-NEXT:    vldrwt.u32 q2, [r3], #16
110 ; CHECK-NEXT:    vldrwt.u32 q3, [r2], #16
111 ; CHECK-NEXT:    vdup.32 q4, r5
112 ; CHECK-NEXT:    vpt.i32 eq, q4, zr
113 ; CHECK-NEXT:    vsubt.i32 q1, q3, q2
114 ; CHECK-NEXT:    vctp.32 r12
115 ; CHECK-NEXT:    vpst
116 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
117 ; CHECK-NEXT:    vmul.i32 q1, q1, q2
118 ; CHECK-NEXT:    adds r4, #4
119 ; CHECK-NEXT:    sub.w r12, r12, #4
120 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
121 ; CHECK-NEXT:    le lr, .LBB1_2
122 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
123 ; CHECK-NEXT:    vpsel q0, q1, q0
124 ; CHECK-NEXT:    vaddv.u32 r0, q0
125 ; CHECK-NEXT:    vpop {d8, d9}
126 ; CHECK-NEXT:    pop {r4, r5, r7, pc}
127 ; CHECK-NEXT:  .LBB1_4:
128 ; CHECK-NEXT:    movs r0, #0
129 ; CHECK-NEXT:    vpop {d8, d9}
130 ; CHECK-NEXT:    pop {r4, r5, r7, pc}
131                                          i32* noalias nocapture readonly %c, i32* noalias nocapture readonly %d, i32 %N) {
132 entry:
133   %cmp8 = icmp eq i32 %N, 0
134   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
136 vector.ph:                                        ; preds = %entry
137   %n.rnd.up = add i32 %N, 3
138   %n.vec = and i32 %n.rnd.up, -4
139   br label %vector.body
141 vector.body:                                      ; preds = %vector.body, %vector.ph
142   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
143   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
144   %tmp = getelementptr inbounds i32, i32* %a, i32 %index
145   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
146   %tmp2 = bitcast i32* %tmp to <4 x i32>*
147   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp2, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
148   %tmp3 = getelementptr inbounds i32, i32* %b, i32 %index
149   %tmp4 = bitcast i32* %tmp3 to <4 x i32>*
150   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp4, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
151   %tmp5 = getelementptr inbounds i32, i32* %c, i32 %index
152   %tmp6 = bitcast i32* %tmp5 to <4 x i32>*
153   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp6, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
154   %tmp7 = getelementptr inbounds i32, i32* %d, i32 %index
155   %tmp8 = bitcast i32* %tmp7 to <4 x i32>*
156   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp8, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
157   %sub = sub <4 x i32> %wide.masked.load.c, %wide.masked.load.d
158   %rem = urem i32 %index, 16
159   %rem.broadcast.splatinsert = insertelement <4 x i32> undef, i32 %rem, i32 0
160   %rem.broadcast.splat = shufflevector <4 x i32> %rem.broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
161   %cmp = icmp eq <4 x i32> %rem.broadcast.splat, <i32 0, i32 0, i32 0, i32 0>
162   %sel = select <4 x i1> %cmp, <4 x i32> %sub, <4 x i32> %wide.masked.load.b
163   %mul = mul  <4 x i32> %sel, %wide.masked.load.a
164   %add = add  <4 x i32> %mul, %vec.phi
165   %index.next = add i32 %index, 4
166   %cmp.exit = icmp eq i32 %index.next, %n.vec
167   br i1 %cmp.exit, label %middle.block, label %vector.body
169 middle.block:                                     ; preds = %vector.body
170   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
171   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
172   br label %for.cond.cleanup
174 for.cond.cleanup:                                 ; preds = %middle.block, %entry
175   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
176   ret i32 %res.0.lcssa
179 define dso_local i32 @and_mul_reduce_add(i32* noalias nocapture readonly %a, i32* noalias nocapture readonly %b,
180 ; CHECK-LABEL: and_mul_reduce_add:
181 ; CHECK:       @ %bb.0: @ %entry
182 ; CHECK-NEXT:    push {r4, lr}
183 ; CHECK-NEXT:    sub sp, #4
184 ; CHECK-NEXT:    ldr.w r12, [sp, #12]
185 ; CHECK-NEXT:    cmp.w r12, #0
186 ; CHECK-NEXT:    beq .LBB2_4
187 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
188 ; CHECK-NEXT:    add.w lr, r12, #3
189 ; CHECK-NEXT:    movs r4, #1
190 ; CHECK-NEXT:    bic lr, lr, #3
191 ; CHECK-NEXT:    vmov.i32 q1, #0x0
192 ; CHECK-NEXT:    sub.w lr, lr, #4
193 ; CHECK-NEXT:    add.w r4, r4, lr, lsr #2
194 ; CHECK-NEXT:    dls lr, r4
195 ; CHECK-NEXT:  .LBB2_2: @ %vector.body
196 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
197 ; CHECK-NEXT:    vctp.32 r12
198 ; CHECK-NEXT:    vmov q0, q1
199 ; CHECK-NEXT:    vpstt
200 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
201 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
202 ; CHECK-NEXT:    vstr p0, [sp] @ 4-byte Spill
203 ; CHECK-NEXT:    vsub.i32 q1, q2, q1
204 ; CHECK-NEXT:    sub.w r12, r12, #4
205 ; CHECK-NEXT:    vpsttt
206 ; CHECK-NEXT:    vcmpt.i32 eq, q1, zr
207 ; CHECK-NEXT:    vldrwt.u32 q1, [r3], #16
208 ; CHECK-NEXT:    vldrwt.u32 q2, [r2], #16
209 ; CHECK-NEXT:    vmul.i32 q1, q2, q1
210 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
211 ; CHECK-NEXT:    le lr, .LBB2_2
212 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
213 ; CHECK-NEXT:    vldr p0, [sp] @ 4-byte Reload
214 ; CHECK-NEXT:    vpsel q0, q1, q0
215 ; CHECK-NEXT:    vaddv.u32 r0, q0
216 ; CHECK-NEXT:    add sp, #4
217 ; CHECK-NEXT:    pop {r4, pc}
218 ; CHECK-NEXT:  .LBB2_4:
219 ; CHECK-NEXT:    movs r0, #0
220 ; CHECK-NEXT:    add sp, #4
221 ; CHECK-NEXT:    pop {r4, pc}
222                                          i32* noalias nocapture readonly %c, i32* noalias nocapture readonly %d, i32 %N) {
223 entry:
224   %cmp8 = icmp eq i32 %N, 0
225   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
227 vector.ph:                                        ; preds = %entry
228   %n.rnd.up = add i32 %N, 3
229   %n.vec = and i32 %n.rnd.up, -4
230   br label %vector.body
232 vector.body:                                      ; preds = %vector.body, %vector.ph
233   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
234   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
235   %tmp = getelementptr inbounds i32, i32* %a, i32 %index
236   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
237   %tmp2 = bitcast i32* %tmp to <4 x i32>*
238   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp2, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
239   %tmp3 = getelementptr inbounds i32, i32* %b, i32 %index
240   %tmp4 = bitcast i32* %tmp3 to <4 x i32>*
241   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp4, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
242   %sub = sub <4 x i32> %wide.masked.load.a, %wide.masked.load.b
243   %cmp = icmp eq <4 x i32> %sub, <i32 0, i32 0, i32 0, i32 0>
244   %mask = and <4 x i1> %cmp, %tmp1
245   %tmp5 = getelementptr inbounds i32, i32* %c, i32 %index
246   %tmp6 = bitcast i32* %tmp5 to <4 x i32>*
247   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp6, i32 4, <4 x i1> %mask, <4 x i32> undef)
248   %tmp7 = getelementptr inbounds i32, i32* %d, i32 %index
249   %tmp8 = bitcast i32* %tmp7 to <4 x i32>*
250   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp8, i32 4, <4 x i1> %mask, <4 x i32> undef)
251   %mul = mul  <4 x i32> %wide.masked.load.c, %wide.masked.load.d
252   %add = add  <4 x i32> %mul, %vec.phi
253   %index.next = add i32 %index, 4
254   %cmp.exit = icmp eq i32 %index.next, %n.vec
255   br i1 %cmp.exit, label %middle.block, label %vector.body
257 middle.block:                                     ; preds = %vector.body
258   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
259   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
260   br label %for.cond.cleanup
262 for.cond.cleanup:                                 ; preds = %middle.block, %entry
263   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
264   ret i32 %res.0.lcssa
267 define dso_local i32 @or_mul_reduce_add(i32* noalias nocapture readonly %a, i32* noalias nocapture readonly %b, i32* noalias nocapture readonly %c, i32* noalias nocapture readonly %d, i32 %N) {
268 ; CHECK-LABEL: or_mul_reduce_add:
269 ; CHECK:       @ %bb.0: @ %entry
270 ; CHECK-NEXT:    push {r4, lr}
271 ; CHECK-NEXT:    sub sp, #4
272 ; CHECK-NEXT:    ldr.w r12, [sp, #12]
273 ; CHECK-NEXT:    cmp.w r12, #0
274 ; CHECK-NEXT:    beq .LBB3_4
275 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
276 ; CHECK-NEXT:    add.w lr, r12, #3
277 ; CHECK-NEXT:    movs r4, #1
278 ; CHECK-NEXT:    bic lr, lr, #3
279 ; CHECK-NEXT:    vmov.i32 q1, #0x0
280 ; CHECK-NEXT:    sub.w lr, lr, #4
281 ; CHECK-NEXT:    add.w r4, r4, lr, lsr #2
282 ; CHECK-NEXT:    dls lr, r4
283 ; CHECK-NEXT:  .LBB3_2: @ %vector.body
284 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
285 ; CHECK-NEXT:    vctp.32 r12
286 ; CHECK-NEXT:    vmov q0, q1
287 ; CHECK-NEXT:    vpstt
288 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
289 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
290 ; CHECK-NEXT:    vstr p0, [sp] @ 4-byte Spill
291 ; CHECK-NEXT:    vsub.i32 q1, q2, q1
292 ; CHECK-NEXT:    vpnot
293 ; CHECK-NEXT:    vpstee
294 ; CHECK-NEXT:    vcmpt.i32 ne, q1, zr
295 ; CHECK-NEXT:    vldrwe.u32 q1, [r3], #16
296 ; CHECK-NEXT:    vldrwe.u32 q2, [r2], #16
297 ; CHECK-NEXT:    sub.w r12, r12, #4
298 ; CHECK-NEXT:    vmul.i32 q1, q2, q1
299 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
300 ; CHECK-NEXT:    le lr, .LBB3_2
301 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
302 ; CHECK-NEXT:    vldr p0, [sp] @ 4-byte Reload
303 ; CHECK-NEXT:    vpsel q0, q1, q0
304 ; CHECK-NEXT:    vaddv.u32 r0, q0
305 ; CHECK-NEXT:    add sp, #4
306 ; CHECK-NEXT:    pop {r4, pc}
307 ; CHECK-NEXT:  .LBB3_4:
308 ; CHECK-NEXT:    movs r0, #0
309 ; CHECK-NEXT:    add sp, #4
310 ; CHECK-NEXT:    pop {r4, pc}
311 entry:
312   %cmp8 = icmp eq i32 %N, 0
313   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
315 vector.ph:                                        ; preds = %entry
316   %n.rnd.up = add i32 %N, 3
317   %n.vec = and i32 %n.rnd.up, -4
318   br label %vector.body
320 vector.body:                                      ; preds = %vector.body, %vector.ph
321   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
322   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
323   %tmp = getelementptr inbounds i32, i32* %a, i32 %index
324   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
325   %tmp2 = bitcast i32* %tmp to <4 x i32>*
326   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp2, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
327   %tmp3 = getelementptr inbounds i32, i32* %b, i32 %index
328   %tmp4 = bitcast i32* %tmp3 to <4 x i32>*
329   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp4, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
330   %sub = sub <4 x i32> %wide.masked.load.a, %wide.masked.load.b
331   %cmp = icmp eq <4 x i32> %sub, <i32 0, i32 0, i32 0, i32 0>
332   %mask = or <4 x i1> %cmp, %tmp1
333   %tmp5 = getelementptr inbounds i32, i32* %c, i32 %index
334   %tmp6 = bitcast i32* %tmp5 to <4 x i32>*
335   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp6, i32 4, <4 x i1> %mask, <4 x i32> undef)
336   %tmp7 = getelementptr inbounds i32, i32* %d, i32 %index
337   %tmp8 = bitcast i32* %tmp7 to <4 x i32>*
338   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp8, i32 4, <4 x i1> %mask, <4 x i32> undef)
339   %mul = mul  <4 x i32> %wide.masked.load.c, %wide.masked.load.d
340   %add = add  <4 x i32> %mul, %vec.phi
341   %index.next = add i32 %index, 4
342   %cmp.exit = icmp eq i32 %index.next, %n.vec
343   br i1 %cmp.exit, label %middle.block, label %vector.body
345 middle.block:                                     ; preds = %vector.body
346   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
347   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
348   br label %for.cond.cleanup
350 for.cond.cleanup:                                 ; preds = %middle.block, %entry
351   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
352   ret i32 %res.0.lcssa
355 define dso_local void @continue_on_zero(i32* noalias nocapture %arg, i32* noalias nocapture readonly %arg1, i32 %arg2) {
356 ; CHECK-LABEL: continue_on_zero:
357 ; CHECK:       @ %bb.0: @ %bb
358 ; CHECK-NEXT:    push {r7, lr}
359 ; CHECK-NEXT:    cmp r2, #0
360 ; CHECK-NEXT:    it eq
361 ; CHECK-NEXT:    popeq {r7, pc}
362 ; CHECK-NEXT:  .LBB4_1: @ %bb3
363 ; CHECK-NEXT:    dlstp.32 lr, r2
364 ; CHECK-NEXT:  .LBB4_2: @ %bb9
365 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
366 ; CHECK-NEXT:    vldrw.u32 q0, [r1], #16
367 ; CHECK-NEXT:    vpt.i32 ne, q0, zr
368 ; CHECK-NEXT:    vldrwt.u32 q1, [r0]
369 ; CHECK-NEXT:    vmul.i32 q0, q1, q0
370 ; CHECK-NEXT:    vpst
371 ; CHECK-NEXT:    vstrwt.32 q0, [r0], #16
372 ; CHECK-NEXT:    letp lr, .LBB4_2
373 ; CHECK-NEXT:  @ %bb.3: @ %bb27
374 ; CHECK-NEXT:    pop {r7, pc}
376   %tmp = icmp eq i32 %arg2, 0
377   br i1 %tmp, label %bb27, label %bb3
379 bb3:                                              ; preds = %bb
380   %tmp4 = add i32 %arg2, 3
381   %tmp5 = and i32 %tmp4, -4
382   br label %bb9
384 bb9:                                              ; preds = %bb9, %bb3
385   %tmp10 = phi i32 [ 0, %bb3 ], [ %tmp25, %bb9 ]
386   %tmp14 = getelementptr inbounds i32, i32* %arg1, i32 %tmp10
387   %tmp15 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %tmp10, i32 %arg2)
388   %tmp16 = bitcast i32* %tmp14 to <4 x i32>*
389   %tmp17 = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp16, i32 4, <4 x i1> %tmp15, <4 x i32> undef)
390   %tmp18 = icmp ne <4 x i32> %tmp17, zeroinitializer
391   %tmp19 = getelementptr inbounds i32, i32* %arg, i32 %tmp10
392   %tmp20 = and <4 x i1> %tmp18, %tmp15
393   %tmp21 = bitcast i32* %tmp19 to <4 x i32>*
394   %tmp22 = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp21, i32 4, <4 x i1> %tmp20, <4 x i32> undef)
395   %tmp23 = mul nsw <4 x i32> %tmp22, %tmp17
396   %tmp24 = bitcast i32* %tmp19 to <4 x i32>*
397   call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> %tmp23, <4 x i32>* %tmp24, i32 4, <4 x i1> %tmp20)
398   %tmp25 = add i32 %tmp10, 4
399   %tmp26 = icmp eq i32 %tmp25, %tmp5
400   br i1 %tmp26, label %bb27, label %bb9
402 bb27:                                             ; preds = %bb9, %bb
403   ret void
406 define dso_local arm_aapcs_vfpcc void @range_test(i32* noalias nocapture %arg, i32* noalias nocapture readonly %arg1, i32 %arg2, i32 %arg3) {
407 ; CHECK-LABEL: range_test:
408 ; CHECK:       @ %bb.0: @ %bb
409 ; CHECK-NEXT:    push {r7, lr}
410 ; CHECK-NEXT:    cmp r3, #0
411 ; CHECK-NEXT:    it eq
412 ; CHECK-NEXT:    popeq {r7, pc}
413 ; CHECK-NEXT:  .LBB5_1: @ %bb4
414 ; CHECK-NEXT:    dlstp.32 lr, r3
415 ; CHECK-NEXT:  .LBB5_2: @ %bb12
416 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
417 ; CHECK-NEXT:    vldrw.u32 q0, [r0]
418 ; CHECK-NEXT:    vptt.i32 ne, q0, zr
419 ; CHECK-NEXT:    vcmpt.s32 le, q0, r2
420 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
421 ; CHECK-NEXT:    vmul.i32 q0, q1, q0
422 ; CHECK-NEXT:    vpst
423 ; CHECK-NEXT:    vstrwt.32 q0, [r0], #16
424 ; CHECK-NEXT:    letp lr, .LBB5_2
425 ; CHECK-NEXT:  @ %bb.3: @ %bb32
426 ; CHECK-NEXT:    pop {r7, pc}
428   %tmp = icmp eq i32 %arg3, 0
429   br i1 %tmp, label %bb32, label %bb4
431 bb4:                                              ; preds = %bb
432   %tmp5 = add i32 %arg3, 3
433   %tmp6 = and i32 %tmp5, -4
434   %tmp10 = insertelement <4 x i32> undef, i32 %arg2, i32 0
435   %tmp11 = shufflevector <4 x i32> %tmp10, <4 x i32> undef, <4 x i32> zeroinitializer
436   br label %bb12
438 bb12:                                             ; preds = %bb12, %bb4
439   %tmp13 = phi i32 [ 0, %bb4 ], [ %tmp30, %bb12 ]
440   %tmp17 = getelementptr inbounds i32, i32* %arg, i32 %tmp13
441   %tmp18= call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %tmp13, i32 %arg3)
442   %tmp19 = bitcast i32* %tmp17 to <4 x i32>*
443   %tmp20 = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp19, i32 4, <4 x i1> %tmp18, <4 x i32> undef)
444   %tmp21 = icmp ne <4 x i32> %tmp20, zeroinitializer
445   %tmp22 = icmp sle <4 x i32> %tmp20, %tmp11
446   %tmp23 = getelementptr inbounds i32, i32* %arg1, i32 %tmp13
447   %tmp24 = and <4 x i1> %tmp22, %tmp21
448   %tmp25 = and <4 x i1> %tmp24, %tmp18
449   %tmp26 = bitcast i32* %tmp23 to <4 x i32>*
450   %tmp27 = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %tmp26, i32 4, <4 x i1> %tmp25, <4 x i32> undef)
451   %tmp28 = mul nsw <4 x i32> %tmp27, %tmp20
452   %tmp29 = bitcast i32* %tmp17 to <4 x i32>*
453   call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> %tmp28, <4 x i32>* %tmp29, i32 4, <4 x i1> %tmp25)
454   %tmp30 = add i32 %tmp13, 4
455   %tmp31 = icmp eq i32 %tmp30, %tmp6
456   br i1 %tmp31, label %bb32, label %bb12
458 bb32:                                             ; preds = %bb12, %bb
459   ret void
462 ; Function Attrs: argmemonly nounwind readonly willreturn
463 declare <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>*, i32 immarg, <4 x i1>, <4 x i32>)
464 declare void @llvm.masked.store.v4i32.p0v4i32(<4 x i32>, <4 x i32>*, i32, <4 x i1>)
466 ; Function Attrs: nounwind readnone willreturn
467 declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
469 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32)