1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=armv6-unknown-linux-gnu | FileCheck %s --check-prefixes=ARMV6
3 ; RUN: llc < %s -mtriple=armv7-unknown-linux-gnu | FileCheck %s --check-prefixes=ARMV7
5 define { i128, i8 } @muloti_test(i128 %l, i128 %r) unnamed_addr #0 {
6 ; ARMV6-LABEL: muloti_test:
7 ; ARMV6: @ %bb.0: @ %start
8 ; ARMV6-NEXT: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
9 ; ARMV6-NEXT: sub sp, sp, #28
10 ; ARMV6-NEXT: ldr r7, [sp, #72]
11 ; ARMV6-NEXT: mov r6, r0
12 ; ARMV6-NEXT: str r0, [sp, #8] @ 4-byte Spill
13 ; ARMV6-NEXT: ldr r4, [sp, #84]
14 ; ARMV6-NEXT: umull r1, r0, r2, r7
15 ; ARMV6-NEXT: mov lr, r7
16 ; ARMV6-NEXT: umull r5, r10, r4, r2
17 ; ARMV6-NEXT: str r1, [r6]
18 ; ARMV6-NEXT: ldr r6, [sp, #80]
19 ; ARMV6-NEXT: umull r1, r7, r3, r6
20 ; ARMV6-NEXT: str r7, [sp, #12] @ 4-byte Spill
21 ; ARMV6-NEXT: add r1, r5, r1
22 ; ARMV6-NEXT: umull r7, r5, r6, r2
23 ; ARMV6-NEXT: mov r6, lr
24 ; ARMV6-NEXT: str r7, [sp, #16] @ 4-byte Spill
25 ; ARMV6-NEXT: mov r7, #0
26 ; ARMV6-NEXT: adds r1, r5, r1
27 ; ARMV6-NEXT: str r1, [sp, #4] @ 4-byte Spill
28 ; ARMV6-NEXT: adc r1, r7, #0
29 ; ARMV6-NEXT: str r1, [sp, #24] @ 4-byte Spill
30 ; ARMV6-NEXT: ldr r1, [sp, #64]
31 ; ARMV6-NEXT: ldr r7, [sp, #76]
32 ; ARMV6-NEXT: ldr r5, [sp, #64]
33 ; ARMV6-NEXT: umull r12, r9, r7, r1
34 ; ARMV6-NEXT: ldr r1, [sp, #68]
35 ; ARMV6-NEXT: umull r11, r8, r1, lr
36 ; ARMV6-NEXT: add r12, r11, r12
37 ; ARMV6-NEXT: umull r11, lr, r5, lr
38 ; ARMV6-NEXT: mov r5, r6
39 ; ARMV6-NEXT: mov r6, #0
40 ; ARMV6-NEXT: adds r12, lr, r12
41 ; ARMV6-NEXT: umull r2, lr, r2, r7
42 ; ARMV6-NEXT: adc r6, r6, #0
43 ; ARMV6-NEXT: str r6, [sp, #20] @ 4-byte Spill
44 ; ARMV6-NEXT: ldr r6, [sp, #16] @ 4-byte Reload
45 ; ARMV6-NEXT: adds r11, r11, r6
46 ; ARMV6-NEXT: ldr r6, [sp, #4] @ 4-byte Reload
47 ; ARMV6-NEXT: adc r6, r12, r6
48 ; ARMV6-NEXT: mov r12, #0
49 ; ARMV6-NEXT: umlal r0, r12, r3, r5
50 ; ARMV6-NEXT: ldr r5, [sp, #8] @ 4-byte Reload
51 ; ARMV6-NEXT: str r6, [sp, #16] @ 4-byte Spill
52 ; ARMV6-NEXT: ldr r6, [sp, #64]
53 ; ARMV6-NEXT: adds r0, r2, r0
54 ; ARMV6-NEXT: str r0, [r5, #4]
55 ; ARMV6-NEXT: adcs r0, r12, lr
56 ; ARMV6-NEXT: mov r2, #0
57 ; ARMV6-NEXT: adc r2, r2, #0
58 ; ARMV6-NEXT: orrs lr, r6, r1
59 ; ARMV6-NEXT: ldr r6, [sp, #80]
60 ; ARMV6-NEXT: movne lr, #1
61 ; ARMV6-NEXT: umlal r0, r2, r3, r7
62 ; ARMV6-NEXT: orrs r12, r6, r4
63 ; ARMV6-NEXT: movne r12, #1
64 ; ARMV6-NEXT: cmp r9, #0
65 ; ARMV6-NEXT: ldr r6, [sp, #12] @ 4-byte Reload
66 ; ARMV6-NEXT: movne r9, #1
67 ; ARMV6-NEXT: cmp r8, #0
68 ; ARMV6-NEXT: movne r8, #1
69 ; ARMV6-NEXT: cmp r6, #0
70 ; ARMV6-NEXT: movne r6, #1
71 ; ARMV6-NEXT: cmp r10, #0
72 ; ARMV6-NEXT: movne r10, #1
73 ; ARMV6-NEXT: cmp r1, #0
74 ; ARMV6-NEXT: movne r1, #1
75 ; ARMV6-NEXT: cmp r7, #0
76 ; ARMV6-NEXT: movne r7, #1
77 ; ARMV6-NEXT: cmp r4, #0
78 ; ARMV6-NEXT: movne r4, #1
79 ; ARMV6-NEXT: cmp r3, #0
80 ; ARMV6-NEXT: movne r3, #1
81 ; ARMV6-NEXT: adds r0, r0, r11
82 ; ARMV6-NEXT: str r0, [r5, #8]
83 ; ARMV6-NEXT: and r1, r1, r7
84 ; ARMV6-NEXT: ldr r0, [sp, #16] @ 4-byte Reload
85 ; ARMV6-NEXT: orr r1, r1, r8
86 ; ARMV6-NEXT: orr r1, r1, r9
87 ; ARMV6-NEXT: adcs r0, r2, r0
88 ; ARMV6-NEXT: str r0, [r5, #12]
89 ; ARMV6-NEXT: and r0, r4, r3
90 ; ARMV6-NEXT: ldr r2, [sp, #24] @ 4-byte Reload
91 ; ARMV6-NEXT: orr r0, r0, r10
92 ; ARMV6-NEXT: orr r0, r0, r6
93 ; ARMV6-NEXT: orr r0, r0, r2
94 ; ARMV6-NEXT: ldr r2, [sp, #20] @ 4-byte Reload
95 ; ARMV6-NEXT: orr r1, r1, r2
96 ; ARMV6-NEXT: and r2, lr, r12
97 ; ARMV6-NEXT: orr r1, r2, r1
98 ; ARMV6-NEXT: orr r0, r1, r0
99 ; ARMV6-NEXT: mov r1, #0
100 ; ARMV6-NEXT: adc r1, r1, #0
101 ; ARMV6-NEXT: orr r0, r0, r1
102 ; ARMV6-NEXT: and r0, r0, #1
103 ; ARMV6-NEXT: strb r0, [r5, #16]
104 ; ARMV6-NEXT: add sp, sp, #28
105 ; ARMV6-NEXT: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
107 ; ARMV7-LABEL: muloti_test:
108 ; ARMV7: @ %bb.0: @ %start
109 ; ARMV7-NEXT: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
110 ; ARMV7-NEXT: sub sp, sp, #36
111 ; ARMV7-NEXT: ldr r5, [sp, #84]
112 ; ARMV7-NEXT: mov r8, r0
113 ; ARMV7-NEXT: ldr r1, [sp, #72]
114 ; ARMV7-NEXT: ldr r10, [sp, #80]
115 ; ARMV7-NEXT: ldr r9, [sp, #76]
116 ; ARMV7-NEXT: umull r4, lr, r5, r1
117 ; ARMV7-NEXT: umull r0, r7, r2, r10
118 ; ARMV7-NEXT: str r4, [sp, #24] @ 4-byte Spill
119 ; ARMV7-NEXT: ldr r4, [sp, #88]
120 ; ARMV7-NEXT: umull r1, r6, r1, r10
121 ; ARMV7-NEXT: str r0, [sp, #32] @ 4-byte Spill
122 ; ARMV7-NEXT: umull r11, r0, r2, r5
123 ; ARMV7-NEXT: str r6, [sp, #20] @ 4-byte Spill
124 ; ARMV7-NEXT: str r1, [sp, #28] @ 4-byte Spill
125 ; ARMV7-NEXT: umull r6, r12, r3, r4
126 ; ARMV7-NEXT: ldr r1, [sp, #92]
127 ; ARMV7-NEXT: str r0, [sp, #8] @ 4-byte Spill
128 ; ARMV7-NEXT: mov r0, #0
129 ; ARMV7-NEXT: umlal r7, r0, r3, r10
130 ; ARMV7-NEXT: str r6, [sp, #16] @ 4-byte Spill
131 ; ARMV7-NEXT: umull r6, r1, r1, r2
132 ; ARMV7-NEXT: umull r2, r4, r4, r2
133 ; ARMV7-NEXT: str r6, [sp, #4] @ 4-byte Spill
134 ; ARMV7-NEXT: str r2, [sp, #12] @ 4-byte Spill
135 ; ARMV7-NEXT: adds r2, r11, r7
136 ; ARMV7-NEXT: ldr r7, [sp, #8] @ 4-byte Reload
137 ; ARMV7-NEXT: mov r11, #0
138 ; ARMV7-NEXT: str r4, [sp] @ 4-byte Spill
139 ; ARMV7-NEXT: umull r6, r4, r9, r10
140 ; ARMV7-NEXT: adcs r9, r0, r7
141 ; ARMV7-NEXT: ldr r0, [sp, #32] @ 4-byte Reload
142 ; ARMV7-NEXT: adc r10, r11, #0
143 ; ARMV7-NEXT: stm r8, {r0, r2}
144 ; ARMV7-NEXT: ldr r0, [sp, #24] @ 4-byte Reload
145 ; ARMV7-NEXT: umlal r9, r10, r3, r5
146 ; ARMV7-NEXT: ldr r2, [sp, #20] @ 4-byte Reload
147 ; ARMV7-NEXT: add r0, r6, r0
148 ; ARMV7-NEXT: adds r0, r2, r0
149 ; ARMV7-NEXT: ldr r6, [sp, #4] @ 4-byte Reload
150 ; ARMV7-NEXT: adc r2, r11, #0
151 ; ARMV7-NEXT: str r2, [sp, #32] @ 4-byte Spill
152 ; ARMV7-NEXT: ldr r2, [sp, #16] @ 4-byte Reload
153 ; ARMV7-NEXT: ldr r7, [sp, #28] @ 4-byte Reload
154 ; ARMV7-NEXT: add r2, r6, r2
155 ; ARMV7-NEXT: ldr r6, [sp] @ 4-byte Reload
156 ; ARMV7-NEXT: adds r2, r6, r2
157 ; ARMV7-NEXT: ldr r6, [sp, #12] @ 4-byte Reload
158 ; ARMV7-NEXT: adc r11, r11, #0
159 ; ARMV7-NEXT: adds r7, r7, r6
160 ; ARMV7-NEXT: ldr r6, [sp, #92]
161 ; ARMV7-NEXT: adc r0, r0, r2
162 ; ARMV7-NEXT: str r0, [sp, #28] @ 4-byte Spill
163 ; ARMV7-NEXT: ldr r0, [sp, #92]
164 ; ARMV7-NEXT: cmp r3, #0
165 ; ARMV7-NEXT: movwne r3, #1
166 ; ARMV7-NEXT: ldr r2, [sp, #76]
167 ; ARMV7-NEXT: cmp r0, #0
168 ; ARMV7-NEXT: movwne r0, #1
169 ; ARMV7-NEXT: cmp r1, #0
170 ; ARMV7-NEXT: movwne r1, #1
171 ; ARMV7-NEXT: cmp r12, #0
172 ; ARMV7-NEXT: and r0, r0, r3
173 ; ARMV7-NEXT: movwne r12, #1
174 ; ARMV7-NEXT: cmp r5, #0
175 ; ARMV7-NEXT: orr r0, r0, r1
176 ; ARMV7-NEXT: movwne r5, #1
177 ; ARMV7-NEXT: cmp r2, #0
178 ; ARMV7-NEXT: mov r1, r2
179 ; ARMV7-NEXT: mov r3, r2
180 ; ARMV7-NEXT: movwne r1, #1
181 ; ARMV7-NEXT: cmp r4, #0
182 ; ARMV7-NEXT: ldr r2, [sp, #72]
183 ; ARMV7-NEXT: movwne r4, #1
184 ; ARMV7-NEXT: cmp lr, #0
185 ; ARMV7-NEXT: and r1, r1, r5
186 ; ARMV7-NEXT: movwne lr, #1
187 ; ARMV7-NEXT: orrs r2, r2, r3
188 ; ARMV7-NEXT: ldr r3, [sp, #88]
189 ; ARMV7-NEXT: movwne r2, #1
190 ; ARMV7-NEXT: orr r1, r1, r4
191 ; ARMV7-NEXT: orr r0, r0, r12
192 ; ARMV7-NEXT: orrs r3, r3, r6
193 ; ARMV7-NEXT: orr r1, r1, lr
194 ; ARMV7-NEXT: movwne r3, #1
195 ; ARMV7-NEXT: adds r7, r9, r7
196 ; ARMV7-NEXT: str r7, [r8, #8]
197 ; ARMV7-NEXT: and r2, r2, r3
198 ; ARMV7-NEXT: ldr r7, [sp, #28] @ 4-byte Reload
199 ; ARMV7-NEXT: orr r0, r0, r11
200 ; ARMV7-NEXT: adcs r7, r10, r7
201 ; ARMV7-NEXT: str r7, [r8, #12]
202 ; ARMV7-NEXT: ldr r7, [sp, #32] @ 4-byte Reload
203 ; ARMV7-NEXT: orr r1, r1, r7
204 ; ARMV7-NEXT: orr r1, r2, r1
205 ; ARMV7-NEXT: orr r0, r1, r0
206 ; ARMV7-NEXT: mov r1, #0
207 ; ARMV7-NEXT: adc r1, r1, #0
208 ; ARMV7-NEXT: orr r0, r0, r1
209 ; ARMV7-NEXT: and r0, r0, #1
210 ; ARMV7-NEXT: strb r0, [r8, #16]
211 ; ARMV7-NEXT: add sp, sp, #36
212 ; ARMV7-NEXT: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
214 %0 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %l, i128 %r) #2
215 %1 = extractvalue { i128, i1 } %0, 0
216 %2 = extractvalue { i128, i1 } %0, 1
217 %3 = zext i1 %2 to i8
218 %4 = insertvalue { i128, i8 } undef, i128 %1, 0
219 %5 = insertvalue { i128, i8 } %4, i8 %3, 1
223 ; Function Attrs: nounwind readnone speculatable
224 declare { i128, i1 } @llvm.umul.with.overflow.i128(i128, i128) #1
226 attributes #0 = { nounwind readnone uwtable }
227 attributes #1 = { nounwind readnone speculatable }
228 attributes #2 = { nounwind }