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