1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -O3 -mtriple=armv8m.main-none-none-eabi -mattr=+dsp < %s | FileCheck %s --check-prefixes=CHECK-LE
3 ; RUN: llc -O3 -mtriple=armv8m.maineb-none-none-eabi -mattr=+dsp < %s | FileCheck %s --check-prefixes=CHECK-BE
5 define i32 @add_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) {
6 ; CHECK-LE-LABEL: add_user:
7 ; CHECK-LE: @ %bb.0: @ %entry
8 ; CHECK-LE-NEXT: cmp r0, #1
9 ; CHECK-LE-NEXT: blt .LBB0_4
10 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader
11 ; CHECK-LE-NEXT: .save {r4, lr}
12 ; CHECK-LE-NEXT: push {r4, lr}
13 ; CHECK-LE-NEXT: sub.w lr, r3, #2
14 ; CHECK-LE-NEXT: subs r2, #2
15 ; CHECK-LE-NEXT: mov.w r12, #0
16 ; CHECK-LE-NEXT: movs r1, #0
17 ; CHECK-LE-NEXT: .LBB0_2: @ %for.body
18 ; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1
19 ; CHECK-LE-NEXT: ldr r3, [lr, #2]!
20 ; CHECK-LE-NEXT: subs r0, #1
21 ; CHECK-LE-NEXT: ldr r4, [r2, #2]!
22 ; CHECK-LE-NEXT: sxtah r1, r1, r3
23 ; CHECK-LE-NEXT: smlad r12, r4, r3, r12
24 ; CHECK-LE-NEXT: bne .LBB0_2
25 ; CHECK-LE-NEXT: @ %bb.3:
26 ; CHECK-LE-NEXT: pop.w {r4, lr}
27 ; CHECK-LE-NEXT: add.w r0, r12, r1
28 ; CHECK-LE-NEXT: bx lr
29 ; CHECK-LE-NEXT: .LBB0_4:
30 ; CHECK-LE-NEXT: mov.w r12, #0
31 ; CHECK-LE-NEXT: movs r1, #0
32 ; CHECK-LE-NEXT: add.w r0, r12, r1
33 ; CHECK-LE-NEXT: bx lr
35 ; CHECK-BE-LABEL: add_user:
36 ; CHECK-BE: @ %bb.0: @ %entry
37 ; CHECK-BE-NEXT: cmp r0, #1
38 ; CHECK-BE-NEXT: blt .LBB0_4
39 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader
40 ; CHECK-BE-NEXT: .save {r4, r5, r7, lr}
41 ; CHECK-BE-NEXT: push {r4, r5, r7, lr}
42 ; CHECK-BE-NEXT: subs r3, #2
43 ; CHECK-BE-NEXT: subs r2, #2
44 ; CHECK-BE-NEXT: mov.w r12, #0
45 ; CHECK-BE-NEXT: movs r1, #0
46 ; CHECK-BE-NEXT: .LBB0_2: @ %for.body
47 ; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1
48 ; CHECK-BE-NEXT: ldrsh lr, [r3, #2]!
49 ; CHECK-BE-NEXT: subs r0, #1
50 ; CHECK-BE-NEXT: ldrsh r4, [r2, #2]!
51 ; CHECK-BE-NEXT: add r1, lr
52 ; CHECK-BE-NEXT: ldrsh.w r5, [r2, #2]
53 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12
54 ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2]
55 ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12
56 ; CHECK-BE-NEXT: bne .LBB0_2
57 ; CHECK-BE-NEXT: @ %bb.3:
58 ; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr}
59 ; CHECK-BE-NEXT: add.w r0, r12, r1
60 ; CHECK-BE-NEXT: bx lr
61 ; CHECK-BE-NEXT: .LBB0_4:
62 ; CHECK-BE-NEXT: mov.w r12, #0
63 ; CHECK-BE-NEXT: movs r1, #0
64 ; CHECK-BE-NEXT: add.w r0, r12, r1
65 ; CHECK-BE-NEXT: bx lr
67 %cmp24 = icmp sgt i32 %arg, 0
68 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
71 %.pre = load i16, ptr %arg3, align 2
72 %.pre27 = load i16, ptr %arg2, align 2
76 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
77 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
78 %res = add i32 %mac1.0.lcssa, %count.final
82 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
83 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
84 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
85 %arrayidx = getelementptr inbounds i16, ptr %arg3, i32 %i.025
86 %0 = load i16, ptr %arrayidx, align 2
87 %add = add nuw nsw i32 %i.025, 1
88 %arrayidx1 = getelementptr inbounds i16, ptr %arg3, i32 %add
89 %1 = load i16, ptr %arrayidx1, align 2
90 %arrayidx3 = getelementptr inbounds i16, ptr %arg2, i32 %i.025
91 %2 = load i16, ptr %arrayidx3, align 2
92 %conv = sext i16 %2 to i32
93 %conv4 = sext i16 %0 to i32
94 %count.next = add i32 %conv4, %count
95 %mul = mul nsw i32 %conv, %conv4
96 %arrayidx6 = getelementptr inbounds i16, ptr %arg2, i32 %add
97 %3 = load i16, ptr %arrayidx6, align 2
98 %conv7 = sext i16 %3 to i32
99 %conv8 = sext i16 %1 to i32
100 %mul9 = mul nsw i32 %conv7, %conv8
101 %add10 = add i32 %mul, %mac1.026
102 %add11 = add i32 %mul9, %add10
103 %exitcond = icmp ne i32 %add, %arg
104 br i1 %exitcond, label %for.body, label %for.cond.cleanup
107 define i32 @mul_bottom_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) {
108 ; CHECK-LE-LABEL: mul_bottom_user:
109 ; CHECK-LE: @ %bb.0: @ %entry
110 ; CHECK-LE-NEXT: cmp r0, #1
111 ; CHECK-LE-NEXT: blt .LBB1_4
112 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader
113 ; CHECK-LE-NEXT: .save {r4, lr}
114 ; CHECK-LE-NEXT: push {r4, lr}
115 ; CHECK-LE-NEXT: sub.w lr, r3, #2
116 ; CHECK-LE-NEXT: subs r2, #2
117 ; CHECK-LE-NEXT: mov.w r12, #0
118 ; CHECK-LE-NEXT: movs r1, #0
119 ; CHECK-LE-NEXT: .LBB1_2: @ %for.body
120 ; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1
121 ; CHECK-LE-NEXT: ldr r3, [lr, #2]!
122 ; CHECK-LE-NEXT: subs r0, #1
123 ; CHECK-LE-NEXT: ldr r4, [r2, #2]!
124 ; CHECK-LE-NEXT: smlad r12, r4, r3, r12
125 ; CHECK-LE-NEXT: sxth r3, r3
126 ; CHECK-LE-NEXT: mul r1, r3, r1
127 ; CHECK-LE-NEXT: bne .LBB1_2
128 ; CHECK-LE-NEXT: @ %bb.3:
129 ; CHECK-LE-NEXT: pop.w {r4, lr}
130 ; CHECK-LE-NEXT: add.w r0, r12, r1
131 ; CHECK-LE-NEXT: bx lr
132 ; CHECK-LE-NEXT: .LBB1_4:
133 ; CHECK-LE-NEXT: mov.w r12, #0
134 ; CHECK-LE-NEXT: movs r1, #0
135 ; CHECK-LE-NEXT: add.w r0, r12, r1
136 ; CHECK-LE-NEXT: bx lr
138 ; CHECK-BE-LABEL: mul_bottom_user:
139 ; CHECK-BE: @ %bb.0: @ %entry
140 ; CHECK-BE-NEXT: cmp r0, #1
141 ; CHECK-BE-NEXT: blt .LBB1_4
142 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader
143 ; CHECK-BE-NEXT: .save {r4, r5, r7, lr}
144 ; CHECK-BE-NEXT: push {r4, r5, r7, lr}
145 ; CHECK-BE-NEXT: subs r3, #2
146 ; CHECK-BE-NEXT: subs r2, #2
147 ; CHECK-BE-NEXT: mov.w r12, #0
148 ; CHECK-BE-NEXT: movs r1, #0
149 ; CHECK-BE-NEXT: .LBB1_2: @ %for.body
150 ; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1
151 ; CHECK-BE-NEXT: ldrsh lr, [r3, #2]!
152 ; CHECK-BE-NEXT: subs r0, #1
153 ; CHECK-BE-NEXT: ldrsh r4, [r2, #2]!
154 ; CHECK-BE-NEXT: ldrsh.w r5, [r2, #2]
155 ; CHECK-BE-NEXT: mul r1, lr, r1
156 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12
157 ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2]
158 ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12
159 ; CHECK-BE-NEXT: bne .LBB1_2
160 ; CHECK-BE-NEXT: @ %bb.3:
161 ; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr}
162 ; CHECK-BE-NEXT: add.w r0, r12, r1
163 ; CHECK-BE-NEXT: bx lr
164 ; CHECK-BE-NEXT: .LBB1_4:
165 ; CHECK-BE-NEXT: mov.w r12, #0
166 ; CHECK-BE-NEXT: movs r1, #0
167 ; CHECK-BE-NEXT: add.w r0, r12, r1
168 ; CHECK-BE-NEXT: bx lr
170 %cmp24 = icmp sgt i32 %arg, 0
171 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
174 %.pre = load i16, ptr %arg3, align 2
175 %.pre27 = load i16, ptr %arg2, align 2
179 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
180 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
181 %res = add i32 %mac1.0.lcssa, %count.final
185 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
186 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
187 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
188 %arrayidx = getelementptr inbounds i16, ptr %arg3, i32 %i.025
189 %0 = load i16, ptr %arrayidx, align 2
190 %add = add nuw nsw i32 %i.025, 1
191 %arrayidx1 = getelementptr inbounds i16, ptr %arg3, i32 %add
192 %1 = load i16, ptr %arrayidx1, align 2
193 %arrayidx3 = getelementptr inbounds i16, ptr %arg2, i32 %i.025
194 %2 = load i16, ptr %arrayidx3, align 2
195 %conv = sext i16 %2 to i32
196 %conv4 = sext i16 %0 to i32
197 %mul = mul nsw i32 %conv, %conv4
198 %arrayidx6 = getelementptr inbounds i16, ptr %arg2, i32 %add
199 %3 = load i16, ptr %arrayidx6, align 2
200 %conv7 = sext i16 %3 to i32
201 %conv8 = sext i16 %1 to i32
202 %mul9 = mul nsw i32 %conv7, %conv8
203 %add10 = add i32 %mul, %mac1.026
204 %add11 = add i32 %mul9, %add10
205 %count.next = mul i32 %conv4, %count
206 %exitcond = icmp ne i32 %add, %arg
207 br i1 %exitcond, label %for.body, label %for.cond.cleanup
210 define i32 @mul_top_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) {
211 ; CHECK-LE-LABEL: mul_top_user:
212 ; CHECK-LE: @ %bb.0: @ %entry
213 ; CHECK-LE-NEXT: cmp r0, #1
214 ; CHECK-LE-NEXT: blt .LBB2_4
215 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader
216 ; CHECK-LE-NEXT: .save {r4, lr}
217 ; CHECK-LE-NEXT: push {r4, lr}
218 ; CHECK-LE-NEXT: subs r3, #2
219 ; CHECK-LE-NEXT: subs r2, #2
220 ; CHECK-LE-NEXT: mov.w r12, #0
221 ; CHECK-LE-NEXT: movs r1, #0
222 ; CHECK-LE-NEXT: .LBB2_2: @ %for.body
223 ; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1
224 ; CHECK-LE-NEXT: ldr lr, [r3, #2]!
225 ; CHECK-LE-NEXT: subs r0, #1
226 ; CHECK-LE-NEXT: ldr r4, [r2, #2]!
227 ; CHECK-LE-NEXT: smlad r12, r4, lr, r12
228 ; CHECK-LE-NEXT: asr.w r4, r4, #16
229 ; CHECK-LE-NEXT: mul r1, r4, r1
230 ; CHECK-LE-NEXT: bne .LBB2_2
231 ; CHECK-LE-NEXT: @ %bb.3:
232 ; CHECK-LE-NEXT: pop.w {r4, lr}
233 ; CHECK-LE-NEXT: add.w r0, r12, r1
234 ; CHECK-LE-NEXT: bx lr
235 ; CHECK-LE-NEXT: .LBB2_4:
236 ; CHECK-LE-NEXT: mov.w r12, #0
237 ; CHECK-LE-NEXT: movs r1, #0
238 ; CHECK-LE-NEXT: add.w r0, r12, r1
239 ; CHECK-LE-NEXT: bx lr
241 ; CHECK-BE-LABEL: mul_top_user:
242 ; CHECK-BE: @ %bb.0: @ %entry
243 ; CHECK-BE-NEXT: cmp r0, #1
244 ; CHECK-BE-NEXT: blt .LBB2_4
245 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader
246 ; CHECK-BE-NEXT: .save {r4, lr}
247 ; CHECK-BE-NEXT: push {r4, lr}
248 ; CHECK-BE-NEXT: subs r3, #2
249 ; CHECK-BE-NEXT: subs r2, #2
250 ; CHECK-BE-NEXT: mov.w r12, #0
251 ; CHECK-BE-NEXT: movs r1, #0
252 ; CHECK-BE-NEXT: .LBB2_2: @ %for.body
253 ; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1
254 ; CHECK-BE-NEXT: ldrsh lr, [r3, #2]!
255 ; CHECK-BE-NEXT: subs r0, #1
256 ; CHECK-BE-NEXT: ldrsh r4, [r2, #2]!
257 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12
258 ; CHECK-BE-NEXT: ldrsh.w r4, [r2, #2]
259 ; CHECK-BE-NEXT: ldrsh.w lr, [r3, #2]
260 ; CHECK-BE-NEXT: mul r1, r4, r1
261 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12
262 ; CHECK-BE-NEXT: bne .LBB2_2
263 ; CHECK-BE-NEXT: @ %bb.3:
264 ; CHECK-BE-NEXT: pop.w {r4, lr}
265 ; CHECK-BE-NEXT: add.w r0, r12, r1
266 ; CHECK-BE-NEXT: bx lr
267 ; CHECK-BE-NEXT: .LBB2_4:
268 ; CHECK-BE-NEXT: mov.w r12, #0
269 ; CHECK-BE-NEXT: movs r1, #0
270 ; CHECK-BE-NEXT: add.w r0, r12, r1
271 ; CHECK-BE-NEXT: bx lr
273 %cmp24 = icmp sgt i32 %arg, 0
274 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
277 %.pre = load i16, ptr %arg3, align 2
278 %.pre27 = load i16, ptr %arg2, align 2
282 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
283 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
284 %res = add i32 %mac1.0.lcssa, %count.final
288 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
289 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
290 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
291 %arrayidx = getelementptr inbounds i16, ptr %arg3, i32 %i.025
292 %0 = load i16, ptr %arrayidx, align 2
293 %add = add nuw nsw i32 %i.025, 1
294 %arrayidx1 = getelementptr inbounds i16, ptr %arg3, i32 %add
295 %1 = load i16, ptr %arrayidx1, align 2
296 %arrayidx3 = getelementptr inbounds i16, ptr %arg2, i32 %i.025
297 %2 = load i16, ptr %arrayidx3, align 2
298 %conv = sext i16 %2 to i32
299 %conv4 = sext i16 %0 to i32
300 %mul = mul nsw i32 %conv, %conv4
301 %arrayidx6 = getelementptr inbounds i16, ptr %arg2, i32 %add
302 %3 = load i16, ptr %arrayidx6, align 2
303 %conv7 = sext i16 %3 to i32
304 %conv8 = sext i16 %1 to i32
305 %mul9 = mul nsw i32 %conv7, %conv8
306 %add10 = add i32 %mul, %mac1.026
307 %add11 = add i32 %mul9, %add10
308 %count.next = mul i32 %conv7, %count
309 %exitcond = icmp ne i32 %add, %arg
310 br i1 %exitcond, label %for.body, label %for.cond.cleanup
313 define i32 @and_user(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) {
314 ; CHECK-LE-LABEL: and_user:
315 ; CHECK-LE: @ %bb.0: @ %entry
316 ; CHECK-LE-NEXT: cmp r0, #1
317 ; CHECK-LE-NEXT: blt .LBB3_4
318 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader
319 ; CHECK-LE-NEXT: .save {r4, lr}
320 ; CHECK-LE-NEXT: push {r4, lr}
321 ; CHECK-LE-NEXT: sub.w lr, r3, #2
322 ; CHECK-LE-NEXT: subs r2, #2
323 ; CHECK-LE-NEXT: mov.w r12, #0
324 ; CHECK-LE-NEXT: movs r1, #0
325 ; CHECK-LE-NEXT: .LBB3_2: @ %for.body
326 ; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1
327 ; CHECK-LE-NEXT: ldr r3, [lr, #2]!
328 ; CHECK-LE-NEXT: subs r0, #1
329 ; CHECK-LE-NEXT: ldr r4, [r2, #2]!
330 ; CHECK-LE-NEXT: smlad r12, r4, r3, r12
331 ; CHECK-LE-NEXT: uxth r3, r3
332 ; CHECK-LE-NEXT: mul r1, r3, r1
333 ; CHECK-LE-NEXT: bne .LBB3_2
334 ; CHECK-LE-NEXT: @ %bb.3:
335 ; CHECK-LE-NEXT: pop.w {r4, lr}
336 ; CHECK-LE-NEXT: add.w r0, r12, r1
337 ; CHECK-LE-NEXT: bx lr
338 ; CHECK-LE-NEXT: .LBB3_4:
339 ; CHECK-LE-NEXT: mov.w r12, #0
340 ; CHECK-LE-NEXT: movs r1, #0
341 ; CHECK-LE-NEXT: add.w r0, r12, r1
342 ; CHECK-LE-NEXT: bx lr
344 ; CHECK-BE-LABEL: and_user:
345 ; CHECK-BE: @ %bb.0: @ %entry
346 ; CHECK-BE-NEXT: cmp r0, #1
347 ; CHECK-BE-NEXT: blt .LBB3_4
348 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader
349 ; CHECK-BE-NEXT: .save {r4, r5, r7, lr}
350 ; CHECK-BE-NEXT: push {r4, r5, r7, lr}
351 ; CHECK-BE-NEXT: subs r3, #2
352 ; CHECK-BE-NEXT: subs r2, #2
353 ; CHECK-BE-NEXT: mov.w r12, #0
354 ; CHECK-BE-NEXT: movs r1, #0
355 ; CHECK-BE-NEXT: .LBB3_2: @ %for.body
356 ; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1
357 ; CHECK-BE-NEXT: ldrh lr, [r3, #2]!
358 ; CHECK-BE-NEXT: subs r0, #1
359 ; CHECK-BE-NEXT: ldrsh r4, [r2, #2]!
360 ; CHECK-BE-NEXT: ldrsh.w r5, [r2, #2]
361 ; CHECK-BE-NEXT: mul r1, lr, r1
362 ; CHECK-BE-NEXT: smlabb r12, r4, lr, r12
363 ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2]
364 ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12
365 ; CHECK-BE-NEXT: bne .LBB3_2
366 ; CHECK-BE-NEXT: @ %bb.3:
367 ; CHECK-BE-NEXT: pop.w {r4, r5, r7, lr}
368 ; CHECK-BE-NEXT: add.w r0, r12, r1
369 ; CHECK-BE-NEXT: bx lr
370 ; CHECK-BE-NEXT: .LBB3_4:
371 ; CHECK-BE-NEXT: mov.w r12, #0
372 ; CHECK-BE-NEXT: movs r1, #0
373 ; CHECK-BE-NEXT: add.w r0, r12, r1
374 ; CHECK-BE-NEXT: bx lr
376 %cmp24 = icmp sgt i32 %arg, 0
377 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
380 %.pre = load i16, ptr %arg3, align 2
381 %.pre27 = load i16, ptr %arg2, align 2
385 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
386 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
387 %res = add i32 %mac1.0.lcssa, %count.final
391 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
392 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
393 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
394 %arrayidx = getelementptr inbounds i16, ptr %arg3, i32 %i.025
395 %0 = load i16, ptr %arrayidx, align 2
396 %add = add nuw nsw i32 %i.025, 1
397 %arrayidx1 = getelementptr inbounds i16, ptr %arg3, i32 %add
398 %arrayidx3 = getelementptr inbounds i16, ptr %arg2, i32 %i.025
399 %arrayidx6 = getelementptr inbounds i16, ptr %arg2, i32 %add
400 %1 = load i16, ptr %arrayidx1, align 2
401 %2 = load i16, ptr %arrayidx3, align 2
402 %conv = sext i16 %2 to i32
403 %conv4 = sext i16 %0 to i32
404 %bottom = and i32 %conv4, 65535
405 %mul = mul nsw i32 %conv, %conv4
406 %3 = load i16, ptr %arrayidx6, align 2
407 %conv7 = sext i16 %3 to i32
408 %conv8 = sext i16 %1 to i32
409 %mul9 = mul nsw i32 %conv7, %conv8
410 %add10 = add i32 %mul, %mac1.026
411 %add11 = add i32 %mul9, %add10
412 %count.next = mul i32 %bottom, %count
413 %exitcond = icmp ne i32 %add, %arg
414 br i1 %exitcond, label %for.body, label %for.cond.cleanup
417 define i32 @multi_uses(i32 %arg, ptr nocapture readnone %arg1, ptr nocapture readonly %arg2, ptr nocapture readonly %arg3) {
418 ; CHECK-LE-LABEL: multi_uses:
419 ; CHECK-LE: @ %bb.0: @ %entry
420 ; CHECK-LE-NEXT: .save {r4, lr}
421 ; CHECK-LE-NEXT: push {r4, lr}
422 ; CHECK-LE-NEXT: cmp r0, #1
423 ; CHECK-LE-NEXT: blt .LBB4_4
424 ; CHECK-LE-NEXT: @ %bb.1: @ %for.body.preheader
425 ; CHECK-LE-NEXT: subs r3, #2
426 ; CHECK-LE-NEXT: subs r2, #2
427 ; CHECK-LE-NEXT: mov.w lr, #0
428 ; CHECK-LE-NEXT: mov.w r12, #0
429 ; CHECK-LE-NEXT: .LBB4_2: @ %for.body
430 ; CHECK-LE-NEXT: @ =>This Inner Loop Header: Depth=1
431 ; CHECK-LE-NEXT: ldr r1, [r3, #2]!
432 ; CHECK-LE-NEXT: subs r0, #1
433 ; CHECK-LE-NEXT: ldr r4, [r2, #2]!
434 ; CHECK-LE-NEXT: smlad lr, r4, r1, lr
435 ; CHECK-LE-NEXT: eor.w r4, r1, r12
436 ; CHECK-LE-NEXT: mul r1, r4, r1
437 ; CHECK-LE-NEXT: lsl.w r12, r1, #16
438 ; CHECK-LE-NEXT: bne .LBB4_2
439 ; CHECK-LE-NEXT: @ %bb.3: @ %for.cond.cleanup
440 ; CHECK-LE-NEXT: add.w r0, lr, r12
441 ; CHECK-LE-NEXT: pop {r4, pc}
442 ; CHECK-LE-NEXT: .LBB4_4:
443 ; CHECK-LE-NEXT: mov.w lr, #0
444 ; CHECK-LE-NEXT: mov.w r12, #0
445 ; CHECK-LE-NEXT: add.w r0, lr, r12
446 ; CHECK-LE-NEXT: pop {r4, pc}
448 ; CHECK-BE-LABEL: multi_uses:
449 ; CHECK-BE: @ %bb.0: @ %entry
450 ; CHECK-BE-NEXT: .save {r4, r5, r7, lr}
451 ; CHECK-BE-NEXT: push {r4, r5, r7, lr}
452 ; CHECK-BE-NEXT: cmp r0, #1
453 ; CHECK-BE-NEXT: blt .LBB4_4
454 ; CHECK-BE-NEXT: @ %bb.1: @ %for.body.preheader
455 ; CHECK-BE-NEXT: subs r3, #2
456 ; CHECK-BE-NEXT: subs r2, #2
457 ; CHECK-BE-NEXT: mov.w r12, #0
458 ; CHECK-BE-NEXT: mov.w lr, #0
459 ; CHECK-BE-NEXT: .LBB4_2: @ %for.body
460 ; CHECK-BE-NEXT: @ =>This Inner Loop Header: Depth=1
461 ; CHECK-BE-NEXT: ldrsh r4, [r2, #2]!
462 ; CHECK-BE-NEXT: subs r0, #1
463 ; CHECK-BE-NEXT: ldrsh r1, [r3, #2]!
464 ; CHECK-BE-NEXT: ldrsh.w r5, [r2, #2]
465 ; CHECK-BE-NEXT: smlabb r12, r4, r1, r12
466 ; CHECK-BE-NEXT: ldrsh.w r4, [r3, #2]
467 ; CHECK-BE-NEXT: smlabb r12, r5, r4, r12
468 ; CHECK-BE-NEXT: eor.w r5, r1, lr
469 ; CHECK-BE-NEXT: mul r1, r5, r1
470 ; CHECK-BE-NEXT: lsl.w lr, r1, #16
471 ; CHECK-BE-NEXT: bne .LBB4_2
472 ; CHECK-BE-NEXT: @ %bb.3: @ %for.cond.cleanup
473 ; CHECK-BE-NEXT: add.w r0, r12, lr
474 ; CHECK-BE-NEXT: pop {r4, r5, r7, pc}
475 ; CHECK-BE-NEXT: .LBB4_4:
476 ; CHECK-BE-NEXT: mov.w r12, #0
477 ; CHECK-BE-NEXT: mov.w lr, #0
478 ; CHECK-BE-NEXT: add.w r0, r12, lr
479 ; CHECK-BE-NEXT: pop {r4, r5, r7, pc}
481 %cmp24 = icmp sgt i32 %arg, 0
482 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
485 %.pre = load i16, ptr %arg3, align 2
486 %.pre27 = load i16, ptr %arg2, align 2
490 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
491 %count.final = phi i32 [ 0, %entry ], [ %count.next, %for.body ]
492 %res = add i32 %mac1.0.lcssa, %count.final
496 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
497 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
498 %count = phi i32 [ %count.next, %for.body ], [ 0, %for.body.preheader ]
499 %arrayidx = getelementptr inbounds i16, ptr %arg3, i32 %i.025
500 %0 = load i16, ptr %arrayidx, align 2
501 %add = add nuw nsw i32 %i.025, 1
502 %arrayidx1 = getelementptr inbounds i16, ptr %arg3, i32 %add
503 %arrayidx3 = getelementptr inbounds i16, ptr %arg2, i32 %i.025
504 %arrayidx6 = getelementptr inbounds i16, ptr %arg2, i32 %add
505 %1 = load i16, ptr %arrayidx1, align 2
506 %2 = load i16, ptr %arrayidx3, align 2
507 %conv = sext i16 %2 to i32
508 %conv4 = sext i16 %0 to i32
509 %bottom = and i32 %conv4, 65535
510 %mul = mul nsw i32 %conv, %conv4
511 %3 = load i16, ptr %arrayidx6, align 2
512 %conv7 = sext i16 %3 to i32
513 %conv8 = sext i16 %1 to i32
514 %mul9 = mul nsw i32 %conv7, %conv8
515 %add10 = add i32 %mul, %mac1.026
516 %shl = shl i32 %conv4, 16
517 %add11 = add i32 %mul9, %add10
518 %xor = xor i32 %bottom, %count
519 %count.next = mul i32 %xor, %shl
520 %exitcond = icmp ne i32 %add, %arg
521 br i1 %exitcond, label %for.body, label %for.cond.cleanup