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