xref: /llvm-project/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll (revision e30a4fc3e20bf5d9cc2f5bfcb61b4eb0e686a193)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC
3; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64
4
5define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind {
6; SPARC-LABEL: muloti_test:
7; SPARC:       ! %bb.0: ! %start
8; SPARC-NEXT:    save %sp, -96, %sp
9; SPARC-NEXT:    ld [%fp+96], %l2
10; SPARC-NEXT:    mov %i3, %g2
11; SPARC-NEXT:    mov %i2, %g3
12; SPARC-NEXT:    umul %i1, %l2, %l0
13; SPARC-NEXT:    rd %y, %i2
14; SPARC-NEXT:    ld [%fp+92], %l1
15; SPARC-NEXT:    umul %i0, %l2, %i3
16; SPARC-NEXT:    rd %y, %g4
17; SPARC-NEXT:    addcc %i3, %i2, %i2
18; SPARC-NEXT:    addxcc %g4, 0, %i3
19; SPARC-NEXT:    umul %i1, %l1, %g4
20; SPARC-NEXT:    rd %y, %l3
21; SPARC-NEXT:    addcc %g4, %i2, %l4
22; SPARC-NEXT:    addxcc %l3, 0, %i2
23; SPARC-NEXT:    addcc %i3, %i2, %i2
24; SPARC-NEXT:    addxcc %g0, 0, %i3
25; SPARC-NEXT:    umul %i0, %l1, %g4
26; SPARC-NEXT:    rd %y, %l3
27; SPARC-NEXT:    addcc %g4, %i2, %i2
28; SPARC-NEXT:    sra %i0, 31, %g4
29; SPARC-NEXT:    smul %l1, %g4, %l5
30; SPARC-NEXT:    umul %l2, %g4, %l6
31; SPARC-NEXT:    rd %y, %l7
32; SPARC-NEXT:    addxcc %l3, %i3, %l3
33; SPARC-NEXT:    add %l7, %l6, %i3
34; SPARC-NEXT:    add %i3, %l5, %l5
35; SPARC-NEXT:    addcc %i2, %l6, %l6
36; SPARC-NEXT:    umul %g2, %l2, %i3
37; SPARC-NEXT:    rd %y, %i2
38; SPARC-NEXT:    addxcc %l3, %l5, %l3
39; SPARC-NEXT:    umul %g3, %l2, %l2
40; SPARC-NEXT:    rd %y, %l5
41; SPARC-NEXT:    addcc %l2, %i2, %i2
42; SPARC-NEXT:    addxcc %l5, 0, %l2
43; SPARC-NEXT:    umul %g2, %l1, %l5
44; SPARC-NEXT:    rd %y, %l7
45; SPARC-NEXT:    addcc %l5, %i2, %i2
46; SPARC-NEXT:    addxcc %l7, 0, %l5
47; SPARC-NEXT:    addcc %l2, %l5, %l2
48; SPARC-NEXT:    addxcc %g0, 0, %l5
49; SPARC-NEXT:    umul %g3, %l1, %l1
50; SPARC-NEXT:    rd %y, %l7
51; SPARC-NEXT:    addcc %l1, %l2, %l1
52; SPARC-NEXT:    addxcc %l7, %l5, %l2
53; SPARC-NEXT:    addcc %l0, %l1, %l0
54; SPARC-NEXT:    addxcc %l4, %l2, %l1
55; SPARC-NEXT:    addxcc %l6, 0, %l2
56; SPARC-NEXT:    addxcc %l3, 0, %l3
57; SPARC-NEXT:    umul %g2, %i5, %l4
58; SPARC-NEXT:    rd %y, %l5
59; SPARC-NEXT:    sra %l3, 31, %l6
60; SPARC-NEXT:    umul %g3, %i5, %l7
61; SPARC-NEXT:    rd %y, %o0
62; SPARC-NEXT:    addcc %l7, %l5, %l5
63; SPARC-NEXT:    addxcc %o0, 0, %l7
64; SPARC-NEXT:    umul %g2, %i4, %o0
65; SPARC-NEXT:    rd %y, %o1
66; SPARC-NEXT:    addcc %o0, %l5, %l5
67; SPARC-NEXT:    addxcc %o1, 0, %o0
68; SPARC-NEXT:    addcc %l7, %o0, %l7
69; SPARC-NEXT:    addxcc %g0, 0, %o0
70; SPARC-NEXT:    umul %g3, %i4, %o1
71; SPARC-NEXT:    rd %y, %o2
72; SPARC-NEXT:    addcc %o1, %l7, %l7
73; SPARC-NEXT:    sra %i4, 31, %o1
74; SPARC-NEXT:    smul %o1, %g3, %g3
75; SPARC-NEXT:    umul %o1, %g2, %g2
76; SPARC-NEXT:    rd %y, %o3
77; SPARC-NEXT:    addxcc %o2, %o0, %o0
78; SPARC-NEXT:    add %o3, %g3, %g3
79; SPARC-NEXT:    add %g3, %g2, %g3
80; SPARC-NEXT:    addcc %l7, %g2, %l7
81; SPARC-NEXT:    addxcc %o0, %g3, %o0
82; SPARC-NEXT:    addcc %l4, %l0, %g2
83; SPARC-NEXT:    addxcc %l5, %l1, %g3
84; SPARC-NEXT:    addxcc %l7, 0, %l0
85; SPARC-NEXT:    addxcc %o0, 0, %l1
86; SPARC-NEXT:    sra %l1, 31, %l4
87; SPARC-NEXT:    addcc %l2, %l0, %l0
88; SPARC-NEXT:    addxcc %l3, %l1, %l1
89; SPARC-NEXT:    addxcc %l6, %l4, %l2
90; SPARC-NEXT:    smul %i4, %g4, %l3
91; SPARC-NEXT:    umul %i5, %g4, %g4
92; SPARC-NEXT:    rd %y, %l5
93; SPARC-NEXT:    addxcc %l6, %l4, %l4
94; SPARC-NEXT:    add %l5, %g4, %l5
95; SPARC-NEXT:    smul %o1, %i0, %l6
96; SPARC-NEXT:    umul %o1, %i1, %l7
97; SPARC-NEXT:    rd %y, %o0
98; SPARC-NEXT:    add %l5, %l3, %l3
99; SPARC-NEXT:    add %o0, %l6, %l5
100; SPARC-NEXT:    add %l5, %l7, %l5
101; SPARC-NEXT:    addcc %l7, %g4, %g4
102; SPARC-NEXT:    umul %i1, %i5, %l6
103; SPARC-NEXT:    rd %y, %l7
104; SPARC-NEXT:    addxcc %l5, %l3, %l3
105; SPARC-NEXT:    umul %i0, %i5, %i5
106; SPARC-NEXT:    rd %y, %l5
107; SPARC-NEXT:    addcc %i5, %l7, %i5
108; SPARC-NEXT:    addxcc %l5, 0, %l5
109; SPARC-NEXT:    umul %i1, %i4, %i1
110; SPARC-NEXT:    rd %y, %l7
111; SPARC-NEXT:    addcc %i1, %i5, %i1
112; SPARC-NEXT:    addxcc %l7, 0, %i5
113; SPARC-NEXT:    addcc %l5, %i5, %i5
114; SPARC-NEXT:    addxcc %g0, 0, %l5
115; SPARC-NEXT:    umul %i0, %i4, %i0
116; SPARC-NEXT:    rd %y, %i4
117; SPARC-NEXT:    addcc %i0, %i5, %i0
118; SPARC-NEXT:    addxcc %i4, %l5, %i4
119; SPARC-NEXT:    addcc %i0, %g4, %i0
120; SPARC-NEXT:    addxcc %i4, %l3, %i4
121; SPARC-NEXT:    addcc %l6, %l0, %i5
122; SPARC-NEXT:    addxcc %i1, %l1, %i1
123; SPARC-NEXT:    addxcc %i0, %l2, %i0
124; SPARC-NEXT:    addxcc %i4, %l4, %i4
125; SPARC-NEXT:    sra %g3, 31, %g4
126; SPARC-NEXT:    xor %i4, %g4, %i4
127; SPARC-NEXT:    xor %i1, %g4, %i1
128; SPARC-NEXT:    or %i1, %i4, %i1
129; SPARC-NEXT:    xor %i0, %g4, %i0
130; SPARC-NEXT:    xor %i5, %g4, %i4
131; SPARC-NEXT:    or %i4, %i0, %i0
132; SPARC-NEXT:    or %i0, %i1, %i0
133; SPARC-NEXT:    cmp %i0, 0
134; SPARC-NEXT:    bne .LBB0_2
135; SPARC-NEXT:    nop
136; SPARC-NEXT:  ! %bb.1: ! %start
137; SPARC-NEXT:    ba .LBB0_3
138; SPARC-NEXT:    mov %g0, %i4
139; SPARC-NEXT:  .LBB0_2:
140; SPARC-NEXT:    mov 1, %i4
141; SPARC-NEXT:  .LBB0_3: ! %start
142; SPARC-NEXT:    mov %g3, %i0
143; SPARC-NEXT:    ret
144; SPARC-NEXT:    restore %g0, %g2, %o1
145;
146; SPARC64-LABEL: muloti_test:
147; SPARC64:         .register %g2, #scratch
148; SPARC64-NEXT:    .register %g3, #scratch
149; SPARC64-NEXT:  ! %bb.0: ! %start
150; SPARC64-NEXT:    save %sp, -176, %sp
151; SPARC64-NEXT:    mov %i3, %i4
152; SPARC64-NEXT:    mov %i1, %i5
153; SPARC64-NEXT:    mov %i0, %l2
154; SPARC64-NEXT:    srax %i0, 63, %i3
155; SPARC64-NEXT:    mov %i3, %o0
156; SPARC64-NEXT:    mov %i0, %o1
157; SPARC64-NEXT:    mov %g0, %o2
158; SPARC64-NEXT:    call __multi3
159; SPARC64-NEXT:    mov %i4, %o3
160; SPARC64-NEXT:    mov %o0, %l0
161; SPARC64-NEXT:    mov %o1, %l1
162; SPARC64-NEXT:    mov %g0, %o0
163; SPARC64-NEXT:    mov %i1, %o1
164; SPARC64-NEXT:    mov %g0, %o2
165; SPARC64-NEXT:    call __multi3
166; SPARC64-NEXT:    mov %i4, %o3
167; SPARC64-NEXT:    mov %o1, %i1
168; SPARC64-NEXT:    mov %g0, %i0
169; SPARC64-NEXT:    add %l1, %o0, %l3
170; SPARC64-NEXT:    cmp %l3, %l1
171; SPARC64-NEXT:    movcs %xcc, 1, %i0
172; SPARC64-NEXT:    srl %i0, 0, %i0
173; SPARC64-NEXT:    add %l0, %i0, %l0
174; SPARC64-NEXT:    srax %l0, 63, %l1
175; SPARC64-NEXT:    srax %i2, 63, %i4
176; SPARC64-NEXT:    mov %g0, %o0
177; SPARC64-NEXT:    mov %i5, %o1
178; SPARC64-NEXT:    mov %i4, %o2
179; SPARC64-NEXT:    call __multi3
180; SPARC64-NEXT:    mov %i2, %o3
181; SPARC64-NEXT:    mov %g0, %i5
182; SPARC64-NEXT:    mov %g0, %g2
183; SPARC64-NEXT:    add %o1, %l3, %i0
184; SPARC64-NEXT:    cmp %i0, %o1
185; SPARC64-NEXT:    movcs %xcc, 1, %i5
186; SPARC64-NEXT:    srl %i5, 0, %i5
187; SPARC64-NEXT:    add %o0, %i5, %i5
188; SPARC64-NEXT:    srax %i5, 63, %g3
189; SPARC64-NEXT:    add %l1, %g3, %g3
190; SPARC64-NEXT:    add %l0, %i5, %i5
191; SPARC64-NEXT:    cmp %i5, %l0
192; SPARC64-NEXT:    movcs %xcc, 1, %g2
193; SPARC64-NEXT:    srl %g2, 0, %g2
194; SPARC64-NEXT:    add %g3, %g2, %l0
195; SPARC64-NEXT:    mov %i3, %o0
196; SPARC64-NEXT:    mov %l2, %o1
197; SPARC64-NEXT:    mov %i4, %o2
198; SPARC64-NEXT:    call __multi3
199; SPARC64-NEXT:    mov %i2, %o3
200; SPARC64-NEXT:    mov %g0, %i2
201; SPARC64-NEXT:    mov %g0, %i3
202; SPARC64-NEXT:    add %o0, %l0, %i4
203; SPARC64-NEXT:    add %o1, %i5, %i5
204; SPARC64-NEXT:    cmp %i5, %o1
205; SPARC64-NEXT:    movcs %xcc, 1, %i2
206; SPARC64-NEXT:    srl %i2, 0, %i2
207; SPARC64-NEXT:    add %i4, %i2, %i2
208; SPARC64-NEXT:    srax %i0, 63, %i4
209; SPARC64-NEXT:    xor %i2, %i4, %i2
210; SPARC64-NEXT:    xor %i5, %i4, %i4
211; SPARC64-NEXT:    or %i4, %i2, %i2
212; SPARC64-NEXT:    movrnz %i2, 1, %i3
213; SPARC64-NEXT:    srl %i3, 0, %i2
214; SPARC64-NEXT:    ret
215; SPARC64-NEXT:    restore
216start:
217  %0 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %l, i128 %r)
218  %1 = extractvalue { i128, i1 } %0, 0
219  %2 = extractvalue { i128, i1 } %0, 1
220  %3 = zext i1 %2 to i8
221  %4 = insertvalue { i128, i8 } undef, i128 %1, 0
222  %5 = insertvalue { i128, i8 } %4, i8 %3, 1
223  ret { i128, i8 } %5
224}
225
226declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128)
227