1; RUN: llc -O2 -mtriple arm < %s | FileCheck %s
2
3; Function Attrs: norecurse nounwind readnone
4define i32 @foo(i32 %vreg0, i32 %vreg1, i32 %vreg2, i32 %vreg3, i32 %vreg4) local_unnamed_addr {
5entry:
6  %conv = zext i32 %vreg2 to i64
7  %conv1 = zext i32 %vreg0 to i64
8  %add2 = add nuw nsw i64 %conv, %conv1
9  %shr = lshr i64 %add2, 32
10  %conv4 = trunc i64 %shr to i32
11  %conv5 = and i64 %add2, 4294967295
12  %add8 = add nuw nsw i64 %conv5, %conv1
13  %shr9 = lshr i64 %add8, 32
14  %conv10 = trunc i64 %shr9 to i32
15  %add11 = add nuw nsw i32 %conv10, %conv4
16  %conv12 = zext i32 %vreg3 to i64
17  %conv14 = zext i32 %vreg1 to i64
18  %add15 = add nuw nsw i64 %conv12, %conv14
19  %shr16 = lshr i64 %add15, 32
20  %conv19 = zext i32 %vreg4 to i64
21  %add20 = add nuw nsw i64 %shr16, %conv19
22  %shr22 = lshr i64 %add20, 32
23  %conv23 = trunc i64 %shr22 to i32
24  %add24 = add nuw nsw i32 %add11, %conv23
25  ret i32 %add24
26
27; CHECK: push	{r11, lr}
28; CHECK-NEXT: adds	r2, r2, r0
29; CHECK-NEXT: mov	r12, #0
30; CHECK-NEXT: adc	lr, r12, #0
31; CHECK-NEXT: adds	r0, r2, r0
32; CHECK-NEXT: ldr	r2, [sp, #8]
33; CHECK-NEXT: adc	r0, r12, #0
34; CHECK-NEXT: adds	r1, r3, r1
35; The interesting bit is the next instruction which looks
36; like is computing a dead r1 but is actually computing a carry
37; for the final adc.
38; CHECK-NEXT: adcs	r1, r2, #0
39; CHECK-NEXT: adc	r0, r0, lr
40; CHECK-NEXT: pop	{r11, lr}
41; CHECK-NEXT: mov	pc, lr
42
43}
44