Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / Thumb2 / LowOverheadLoops / cond-vector-reduce-mve-codegen.ll
blob9346098f0371b4b637c8505ae445ab765091a151
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(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, ptr 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:    vctp.32 r3
24 ; CHECK-NEXT:    vmov q0, q1
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:    add.w r12, r12, #4
30 ; CHECK-NEXT:    vpt.i32 eq, q3, zr
31 ; CHECK-NEXT:    vmovt q1, q2
32 ; CHECK-NEXT:    vctp.32 r3
33 ; CHECK-NEXT:    vpst
34 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
35 ; CHECK-NEXT:    subs r3, #4
36 ; CHECK-NEXT:    vmul.i32 q1, q1, q2
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, ptr %a, i32 %index
56   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
57   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
58   %tmp3 = getelementptr inbounds i32, ptr %b, i32 %index
59   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp3, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
60   %tmp5 = getelementptr inbounds i32, ptr %c, i32 %index
61   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp5, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
62   %rem = urem i32 %index, 16
63   %rem.broadcast.splatinsert = insertelement <4 x i32> undef, i32 %rem, i32 0
64   %rem.broadcast.splat = shufflevector <4 x i32> %rem.broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
65   %cmp = icmp eq <4 x i32> %rem.broadcast.splat, <i32 0, i32 0, i32 0, i32 0>
66   %wide.masked.load = select <4 x i1> %cmp, <4 x i32> %wide.masked.load.b, <4 x i32> %wide.masked.load.c
67   %mul = mul nsw <4 x i32> %wide.masked.load, %wide.masked.load.a
68   %add = add nsw <4 x i32> %mul, %vec.phi
69   %index.next = add i32 %index, 4
70   %tmp7 = icmp eq i32 %index.next, %n.vec
71   br i1 %tmp7, label %middle.block, label %vector.body
73 middle.block:                                     ; preds = %vector.body
74   %tmp8 = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
75   %tmp9 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %tmp8)
76   br label %for.cond.cleanup
78 for.cond.cleanup:                                 ; preds = %middle.block, %entry
79   %res.0.lcssa = phi i32 [ 0, %entry ], [ %tmp9, %middle.block ]
80   ret i32 %res.0.lcssa
83 define dso_local i32 @vpsel_mul_reduce_add_2(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b,
84 ; CHECK-LABEL: vpsel_mul_reduce_add_2:
85 ; CHECK:       @ %bb.0: @ %entry
86 ; CHECK-NEXT:    push {r4, r5, r7, lr}
87 ; CHECK-NEXT:    vpush {d8, d9}
88 ; CHECK-NEXT:    ldr.w r12, [sp, #32]
89 ; CHECK-NEXT:    cmp.w r12, #0
90 ; CHECK-NEXT:    beq .LBB1_4
91 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
92 ; CHECK-NEXT:    add.w r4, r12, #3
93 ; CHECK-NEXT:    vmov.i32 q1, #0x0
94 ; CHECK-NEXT:    bic r4, r4, #3
95 ; CHECK-NEXT:    sub.w lr, r4, #4
96 ; CHECK-NEXT:    movs r4, #1
97 ; CHECK-NEXT:    add.w lr, r4, lr, lsr #2
98 ; CHECK-NEXT:    movs r4, #0
99 ; CHECK-NEXT:  .LBB1_2: @ %vector.body
100 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
101 ; CHECK-NEXT:    vctp.32 r12
102 ; CHECK-NEXT:    and r5, r4, #15
103 ; CHECK-NEXT:    vmov q0, q1
104 ; CHECK-NEXT:    vpsttt
105 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
106 ; CHECK-NEXT:    vldrwt.u32 q2, [r3], #16
107 ; CHECK-NEXT:    vldrwt.u32 q3, [r2], #16
108 ; CHECK-NEXT:    vdup.32 q4, r5
109 ; CHECK-NEXT:    adds r4, #4
110 ; CHECK-NEXT:    vpt.i32 eq, q4, zr
111 ; CHECK-NEXT:    vsubt.i32 q1, q3, q2
112 ; CHECK-NEXT:    vctp.32 r12
113 ; CHECK-NEXT:    vpst
114 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
115 ; CHECK-NEXT:    sub.w r12, r12, #4
116 ; CHECK-NEXT:    vmul.i32 q1, q1, q2
117 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
118 ; CHECK-NEXT:    le lr, .LBB1_2
119 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
120 ; CHECK-NEXT:    vpsel q0, q1, q0
121 ; CHECK-NEXT:    vaddv.u32 r0, q0
122 ; CHECK-NEXT:    vpop {d8, d9}
123 ; CHECK-NEXT:    pop {r4, r5, r7, pc}
124 ; CHECK-NEXT:  .LBB1_4:
125 ; CHECK-NEXT:    movs r0, #0
126 ; CHECK-NEXT:    vpop {d8, d9}
127 ; CHECK-NEXT:    pop {r4, r5, r7, pc}
128                                          ptr noalias nocapture readonly %c, ptr noalias nocapture readonly %d, i32 %N) {
129 entry:
130   %cmp8 = icmp eq i32 %N, 0
131   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
133 vector.ph:                                        ; preds = %entry
134   %n.rnd.up = add i32 %N, 3
135   %n.vec = and i32 %n.rnd.up, -4
136   br label %vector.body
138 vector.body:                                      ; preds = %vector.body, %vector.ph
139   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
140   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
141   %tmp = getelementptr inbounds i32, ptr %a, i32 %index
142   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
143   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
144   %tmp3 = getelementptr inbounds i32, ptr %b, i32 %index
145   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp3, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
146   %tmp5 = getelementptr inbounds i32, ptr %c, i32 %index
147   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp5, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
148   %tmp7 = getelementptr inbounds i32, ptr %d, i32 %index
149   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp7, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
150   %sub = sub <4 x i32> %wide.masked.load.c, %wide.masked.load.d
151   %rem = urem i32 %index, 16
152   %rem.broadcast.splatinsert = insertelement <4 x i32> undef, i32 %rem, i32 0
153   %rem.broadcast.splat = shufflevector <4 x i32> %rem.broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
154   %cmp = icmp eq <4 x i32> %rem.broadcast.splat, <i32 0, i32 0, i32 0, i32 0>
155   %sel = select <4 x i1> %cmp, <4 x i32> %sub, <4 x i32> %wide.masked.load.b
156   %mul = mul  <4 x i32> %sel, %wide.masked.load.a
157   %add = add  <4 x i32> %mul, %vec.phi
158   %index.next = add i32 %index, 4
159   %cmp.exit = icmp eq i32 %index.next, %n.vec
160   br i1 %cmp.exit, label %middle.block, label %vector.body
162 middle.block:                                     ; preds = %vector.body
163   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
164   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
165   br label %for.cond.cleanup
167 for.cond.cleanup:                                 ; preds = %middle.block, %entry
168   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
169   ret i32 %res.0.lcssa
172 define dso_local i32 @and_mul_reduce_add(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b,
173 ; CHECK-LABEL: and_mul_reduce_add:
174 ; CHECK:       @ %bb.0: @ %entry
175 ; CHECK-NEXT:    push {r4, lr}
176 ; CHECK-NEXT:    sub sp, #4
177 ; CHECK-NEXT:    ldr.w r12, [sp, #12]
178 ; CHECK-NEXT:    cmp.w r12, #0
179 ; CHECK-NEXT:    beq .LBB2_4
180 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
181 ; CHECK-NEXT:    add.w lr, r12, #3
182 ; CHECK-NEXT:    movs r4, #1
183 ; CHECK-NEXT:    bic lr, lr, #3
184 ; CHECK-NEXT:    vmov.i32 q1, #0x0
185 ; CHECK-NEXT:    sub.w lr, lr, #4
186 ; CHECK-NEXT:    add.w r4, r4, lr, lsr #2
187 ; CHECK-NEXT:    dls lr, r4
188 ; CHECK-NEXT:  .LBB2_2: @ %vector.body
189 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
190 ; CHECK-NEXT:    vctp.32 r12
191 ; CHECK-NEXT:    vmov q0, q1
192 ; CHECK-NEXT:    vpstt
193 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
194 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
195 ; CHECK-NEXT:    vstr p0, [sp] @ 4-byte Spill
196 ; CHECK-NEXT:    sub.w r12, r12, #4
197 ; CHECK-NEXT:    vsub.i32 q1, q2, q1
198 ; CHECK-NEXT:    vpsttt
199 ; CHECK-NEXT:    vcmpt.i32 eq, q1, zr
200 ; CHECK-NEXT:    vldrwt.u32 q1, [r3], #16
201 ; CHECK-NEXT:    vldrwt.u32 q2, [r2], #16
202 ; CHECK-NEXT:    vmul.i32 q1, q2, q1
203 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
204 ; CHECK-NEXT:    le lr, .LBB2_2
205 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
206 ; CHECK-NEXT:    vldr p0, [sp] @ 4-byte Reload
207 ; CHECK-NEXT:    vpsel q0, q1, q0
208 ; CHECK-NEXT:    vaddv.u32 r0, q0
209 ; CHECK-NEXT:    add sp, #4
210 ; CHECK-NEXT:    pop {r4, pc}
211 ; CHECK-NEXT:  .LBB2_4:
212 ; CHECK-NEXT:    movs r0, #0
213 ; CHECK-NEXT:    add sp, #4
214 ; CHECK-NEXT:    pop {r4, pc}
215                                          ptr noalias nocapture readonly %c, ptr noalias nocapture readonly %d, i32 %N) {
216 entry:
217   %cmp8 = icmp eq i32 %N, 0
218   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
220 vector.ph:                                        ; preds = %entry
221   %n.rnd.up = add i32 %N, 3
222   %n.vec = and i32 %n.rnd.up, -4
223   br label %vector.body
225 vector.body:                                      ; preds = %vector.body, %vector.ph
226   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
227   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
228   %tmp = getelementptr inbounds i32, ptr %a, i32 %index
229   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
230   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
231   %tmp3 = getelementptr inbounds i32, ptr %b, i32 %index
232   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp3, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
233   %sub = sub <4 x i32> %wide.masked.load.a, %wide.masked.load.b
234   %cmp = icmp eq <4 x i32> %sub, <i32 0, i32 0, i32 0, i32 0>
235   %mask = and <4 x i1> %cmp, %tmp1
236   %tmp5 = getelementptr inbounds i32, ptr %c, i32 %index
237   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp5, i32 4, <4 x i1> %mask, <4 x i32> undef)
238   %tmp7 = getelementptr inbounds i32, ptr %d, i32 %index
239   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp7, i32 4, <4 x i1> %mask, <4 x i32> undef)
240   %mul = mul  <4 x i32> %wide.masked.load.c, %wide.masked.load.d
241   %add = add  <4 x i32> %mul, %vec.phi
242   %index.next = add i32 %index, 4
243   %cmp.exit = icmp eq i32 %index.next, %n.vec
244   br i1 %cmp.exit, label %middle.block, label %vector.body
246 middle.block:                                     ; preds = %vector.body
247   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
248   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
249   br label %for.cond.cleanup
251 for.cond.cleanup:                                 ; preds = %middle.block, %entry
252   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
253   ret i32 %res.0.lcssa
256 define dso_local i32 @or_mul_reduce_add(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, ptr noalias nocapture readonly %c, ptr noalias nocapture readonly %d, i32 %N) {
257 ; CHECK-LABEL: or_mul_reduce_add:
258 ; CHECK:       @ %bb.0: @ %entry
259 ; CHECK-NEXT:    push {r4, lr}
260 ; CHECK-NEXT:    sub sp, #4
261 ; CHECK-NEXT:    ldr.w r12, [sp, #12]
262 ; CHECK-NEXT:    cmp.w r12, #0
263 ; CHECK-NEXT:    beq .LBB3_4
264 ; CHECK-NEXT:  @ %bb.1: @ %vector.ph
265 ; CHECK-NEXT:    add.w lr, r12, #3
266 ; CHECK-NEXT:    movs r4, #1
267 ; CHECK-NEXT:    bic lr, lr, #3
268 ; CHECK-NEXT:    vmov.i32 q1, #0x0
269 ; CHECK-NEXT:    sub.w lr, lr, #4
270 ; CHECK-NEXT:    add.w r4, r4, lr, lsr #2
271 ; CHECK-NEXT:    dls lr, r4
272 ; CHECK-NEXT:  .LBB3_2: @ %vector.body
273 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
274 ; CHECK-NEXT:    vctp.32 r12
275 ; CHECK-NEXT:    vmov q0, q1
276 ; CHECK-NEXT:    vpstt
277 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
278 ; CHECK-NEXT:    vldrwt.u32 q2, [r0], #16
279 ; CHECK-NEXT:    vstr p0, [sp] @ 4-byte Spill
280 ; CHECK-NEXT:    vpnot
281 ; CHECK-NEXT:    vsub.i32 q1, q2, q1
282 ; CHECK-NEXT:    sub.w r12, r12, #4
283 ; CHECK-NEXT:    vpstee
284 ; CHECK-NEXT:    vcmpt.i32 ne, q1, zr
285 ; CHECK-NEXT:    vldrwe.u32 q1, [r3], #16
286 ; CHECK-NEXT:    vldrwe.u32 q2, [r2], #16
287 ; CHECK-NEXT:    vmul.i32 q1, q2, q1
288 ; CHECK-NEXT:    vadd.i32 q1, q1, q0
289 ; CHECK-NEXT:    le lr, .LBB3_2
290 ; CHECK-NEXT:  @ %bb.3: @ %middle.block
291 ; CHECK-NEXT:    vldr p0, [sp] @ 4-byte Reload
292 ; CHECK-NEXT:    vpsel q0, q1, q0
293 ; CHECK-NEXT:    vaddv.u32 r0, q0
294 ; CHECK-NEXT:    add sp, #4
295 ; CHECK-NEXT:    pop {r4, pc}
296 ; CHECK-NEXT:  .LBB3_4:
297 ; CHECK-NEXT:    movs r0, #0
298 ; CHECK-NEXT:    add sp, #4
299 ; CHECK-NEXT:    pop {r4, pc}
300 entry:
301   %cmp8 = icmp eq i32 %N, 0
302   br i1 %cmp8, label %for.cond.cleanup, label %vector.ph
304 vector.ph:                                        ; preds = %entry
305   %n.rnd.up = add i32 %N, 3
306   %n.vec = and i32 %n.rnd.up, -4
307   br label %vector.body
309 vector.body:                                      ; preds = %vector.body, %vector.ph
310   %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
311   %vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %add, %vector.body ]
312   %tmp = getelementptr inbounds i32, ptr %a, i32 %index
313   %tmp1 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
314   %wide.masked.load.a = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
315   %tmp3 = getelementptr inbounds i32, ptr %b, i32 %index
316   %wide.masked.load.b = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp3, i32 4, <4 x i1> %tmp1, <4 x i32> undef)
317   %sub = sub <4 x i32> %wide.masked.load.a, %wide.masked.load.b
318   %cmp = icmp eq <4 x i32> %sub, <i32 0, i32 0, i32 0, i32 0>
319   %mask = or <4 x i1> %cmp, %tmp1
320   %tmp5 = getelementptr inbounds i32, ptr %c, i32 %index
321   %wide.masked.load.c = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp5, i32 4, <4 x i1> %mask, <4 x i32> undef)
322   %tmp7 = getelementptr inbounds i32, ptr %d, i32 %index
323   %wide.masked.load.d = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp7, i32 4, <4 x i1> %mask, <4 x i32> undef)
324   %mul = mul  <4 x i32> %wide.masked.load.c, %wide.masked.load.d
325   %add = add  <4 x i32> %mul, %vec.phi
326   %index.next = add i32 %index, 4
327   %cmp.exit = icmp eq i32 %index.next, %n.vec
328   br i1 %cmp.exit, label %middle.block, label %vector.body
330 middle.block:                                     ; preds = %vector.body
331   %acc = select <4 x i1> %tmp1, <4 x i32> %add, <4 x i32> %vec.phi
332   %reduce = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %acc)
333   br label %for.cond.cleanup
335 for.cond.cleanup:                                 ; preds = %middle.block, %entry
336   %res.0.lcssa = phi i32 [ 0, %entry ], [ %reduce, %middle.block ]
337   ret i32 %res.0.lcssa
340 define dso_local void @continue_on_zero(ptr noalias nocapture %arg, ptr noalias nocapture readonly %arg1, i32 %arg2) {
341 ; CHECK-LABEL: continue_on_zero:
342 ; CHECK:       @ %bb.0: @ %bb
343 ; CHECK-NEXT:    push {r7, lr}
344 ; CHECK-NEXT:    cmp r2, #0
345 ; CHECK-NEXT:    it eq
346 ; CHECK-NEXT:    popeq {r7, pc}
347 ; CHECK-NEXT:  .LBB4_1: @ %bb3
348 ; CHECK-NEXT:    dlstp.32 lr, r2
349 ; CHECK-NEXT:  .LBB4_2: @ %bb9
350 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
351 ; CHECK-NEXT:    vldrw.u32 q0, [r1], #16
352 ; CHECK-NEXT:    vpt.i32 ne, q0, zr
353 ; CHECK-NEXT:    vldrwt.u32 q1, [r0]
354 ; CHECK-NEXT:    vmul.i32 q0, q1, q0
355 ; CHECK-NEXT:    vpst
356 ; CHECK-NEXT:    vstrwt.32 q0, [r0], #16
357 ; CHECK-NEXT:    letp lr, .LBB4_2
358 ; CHECK-NEXT:  @ %bb.3: @ %bb27
359 ; CHECK-NEXT:    pop {r7, pc}
361   %tmp = icmp eq i32 %arg2, 0
362   br i1 %tmp, label %bb27, label %bb3
364 bb3:                                              ; preds = %bb
365   %tmp4 = add i32 %arg2, 3
366   %tmp5 = and i32 %tmp4, -4
367   br label %bb9
369 bb9:                                              ; preds = %bb9, %bb3
370   %tmp10 = phi i32 [ 0, %bb3 ], [ %tmp25, %bb9 ]
371   %tmp14 = getelementptr inbounds i32, ptr %arg1, i32 %tmp10
372   %tmp15 = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %tmp10, i32 %arg2)
373   %tmp17 = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp14, i32 4, <4 x i1> %tmp15, <4 x i32> undef)
374   %tmp18 = icmp ne <4 x i32> %tmp17, zeroinitializer
375   %tmp19 = getelementptr inbounds i32, ptr %arg, i32 %tmp10
376   %tmp20 = and <4 x i1> %tmp18, %tmp15
377   %tmp22 = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp19, i32 4, <4 x i1> %tmp20, <4 x i32> undef)
378   %tmp23 = mul nsw <4 x i32> %tmp22, %tmp17
379   call void @llvm.masked.store.v4i32.p0(<4 x i32> %tmp23, ptr %tmp19, i32 4, <4 x i1> %tmp20)
380   %tmp25 = add i32 %tmp10, 4
381   %tmp26 = icmp eq i32 %tmp25, %tmp5
382   br i1 %tmp26, label %bb27, label %bb9
384 bb27:                                             ; preds = %bb9, %bb
385   ret void
388 define dso_local arm_aapcs_vfpcc void @range_test(ptr noalias nocapture %arg, ptr noalias nocapture readonly %arg1, i32 %arg2, i32 %arg3) {
389 ; CHECK-LABEL: range_test:
390 ; CHECK:       @ %bb.0: @ %bb
391 ; CHECK-NEXT:    push {r7, lr}
392 ; CHECK-NEXT:    cmp r3, #0
393 ; CHECK-NEXT:    it eq
394 ; CHECK-NEXT:    popeq {r7, pc}
395 ; CHECK-NEXT:  .LBB5_1: @ %bb4
396 ; CHECK-NEXT:    dlstp.32 lr, r3
397 ; CHECK-NEXT:  .LBB5_2: @ %bb12
398 ; CHECK-NEXT:    @ =>This Inner Loop Header: Depth=1
399 ; CHECK-NEXT:    vldrw.u32 q0, [r0]
400 ; CHECK-NEXT:    vpt.i32 ne, q0, zr
401 ; CHECK-NEXT:    vcmpt.s32 le, q0, r2
402 ; CHECK-NEXT:    vpst
403 ; CHECK-NEXT:    vldrwt.u32 q1, [r1], #16
404 ; CHECK-NEXT:    vmul.i32 q0, q1, q0
405 ; CHECK-NEXT:    vpst
406 ; CHECK-NEXT:    vstrwt.32 q0, [r0], #16
407 ; CHECK-NEXT:    letp lr, .LBB5_2
408 ; CHECK-NEXT:  @ %bb.3: @ %bb32
409 ; CHECK-NEXT:    pop {r7, pc}
411   %tmp = icmp eq i32 %arg3, 0
412   br i1 %tmp, label %bb32, label %bb4
414 bb4:                                              ; preds = %bb
415   %tmp5 = add i32 %arg3, 3
416   %tmp6 = and i32 %tmp5, -4
417   %tmp10 = insertelement <4 x i32> undef, i32 %arg2, i32 0
418   %tmp11 = shufflevector <4 x i32> %tmp10, <4 x i32> undef, <4 x i32> zeroinitializer
419   br label %bb12
421 bb12:                                             ; preds = %bb12, %bb4
422   %tmp13 = phi i32 [ 0, %bb4 ], [ %tmp30, %bb12 ]
423   %tmp17 = getelementptr inbounds i32, ptr %arg, i32 %tmp13
424   %tmp18= call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %tmp13, i32 %arg3)
425   %tmp20 = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp17, i32 4, <4 x i1> %tmp18, <4 x i32> undef)
426   %tmp21 = icmp ne <4 x i32> %tmp20, zeroinitializer
427   %tmp22 = icmp sle <4 x i32> %tmp20, %tmp11
428   %tmp23 = getelementptr inbounds i32, ptr %arg1, i32 %tmp13
429   %tmp24 = and <4 x i1> %tmp22, %tmp21
430   %tmp25 = and <4 x i1> %tmp24, %tmp18
431   %tmp27 = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %tmp23, i32 4, <4 x i1> %tmp25, <4 x i32> undef)
432   %tmp28 = mul nsw <4 x i32> %tmp27, %tmp20
433   call void @llvm.masked.store.v4i32.p0(<4 x i32> %tmp28, ptr %tmp17, i32 4, <4 x i1> %tmp25)
434   %tmp30 = add i32 %tmp13, 4
435   %tmp31 = icmp eq i32 %tmp30, %tmp6
436   br i1 %tmp31, label %bb32, label %bb12
438 bb32:                                             ; preds = %bb12, %bb
439   ret void
442 ; Function Attrs: argmemonly nounwind readonly willreturn
443 declare <4 x i32> @llvm.masked.load.v4i32.p0(ptr, i32 immarg, <4 x i1>, <4 x i32>)
444 declare void @llvm.masked.store.v4i32.p0(<4 x i32>, ptr, i32, <4 x i1>)
446 ; Function Attrs: nounwind readnone willreturn
447 declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32>)
449 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32)