OSDN Git Service

[Intrinsic] Signed Fixed Point Multiplication Intrinsic
[android-x86/external-llvm.git] / test / CodeGen / X86 / smul_fix.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64
3 ; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefix=X86
4
5 declare  i4  @llvm.smul.fix.i4   (i4,  i4, i32)
6 declare  i32 @llvm.smul.fix.i32  (i32, i32, i32)
7 declare  i64 @llvm.smul.fix.i64  (i64, i64, i32)
8 declare  <4 x i32> @llvm.smul.fix.v4i32(<4 x i32>, <4 x i32>, i32)
9
10 define i32 @func(i32 %x, i32 %y) nounwind {
11 ; X64-LABEL: func:
12 ; X64:       # %bb.0:
13 ; X64-NEXT:    movslq %esi, %rax
14 ; X64-NEXT:    movslq %edi, %rcx
15 ; X64-NEXT:    imulq %rax, %rcx
16 ; X64-NEXT:    movq %rcx, %rax
17 ; X64-NEXT:    shrq $32, %rax
18 ; X64-NEXT:    shldl $30, %ecx, %eax
19 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
20 ; X64-NEXT:    retq
21 ;
22 ; X86-LABEL: func:
23 ; X86:       # %bb.0:
24 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
25 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
26 ; X86-NEXT:    shrdl $2, %edx, %eax
27 ; X86-NEXT:    retl
28   %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 2);
29   ret i32 %tmp;
30 }
31
32 define i64 @func2(i64 %x, i64 %y) {
33 ; X64-LABEL: func2:
34 ; X64:       # %bb.0:
35 ; X64-NEXT:    movq %rdi, %rax
36 ; X64-NEXT:    imulq %rsi
37 ; X64-NEXT:    shrdq $2, %rdx, %rax
38 ; X64-NEXT:    retq
39 ;
40 ; X86-LABEL: func2:
41 ; X86:       # %bb.0:
42 ; X86-NEXT:    pushl %ebp
43 ; X86-NEXT:    .cfi_def_cfa_offset 8
44 ; X86-NEXT:    pushl %ebx
45 ; X86-NEXT:    .cfi_def_cfa_offset 12
46 ; X86-NEXT:    pushl %edi
47 ; X86-NEXT:    .cfi_def_cfa_offset 16
48 ; X86-NEXT:    pushl %esi
49 ; X86-NEXT:    .cfi_def_cfa_offset 20
50 ; X86-NEXT:    .cfi_offset %esi, -20
51 ; X86-NEXT:    .cfi_offset %edi, -16
52 ; X86-NEXT:    .cfi_offset %ebx, -12
53 ; X86-NEXT:    .cfi_offset %ebp, -8
54 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
55 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
56 ; X86-NEXT:    movl %ebx, %eax
57 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
58 ; X86-NEXT:    movl %edx, %esi
59 ; X86-NEXT:    movl %eax, %edi
60 ; X86-NEXT:    movl %ebx, %eax
61 ; X86-NEXT:    mull %ecx
62 ; X86-NEXT:    movl %eax, %ebx
63 ; X86-NEXT:    movl %edx, %ebp
64 ; X86-NEXT:    addl %edi, %ebp
65 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
66 ; X86-NEXT:    adcl $0, %esi
67 ; X86-NEXT:    movl %edi, %eax
68 ; X86-NEXT:    mull %ecx
69 ; X86-NEXT:    addl %ebp, %eax
70 ; X86-NEXT:    adcl %esi, %edx
71 ; X86-NEXT:    movl %edi, %esi
72 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %esi
73 ; X86-NEXT:    addl %edx, %esi
74 ; X86-NEXT:    movl %esi, %ebp
75 ; X86-NEXT:    subl %ecx, %ebp
76 ; X86-NEXT:    testl %edi, %edi
77 ; X86-NEXT:    cmovnsl %esi, %ebp
78 ; X86-NEXT:    movl %ebp, %edx
79 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
80 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
81 ; X86-NEXT:    cmovnsl %ebp, %edx
82 ; X86-NEXT:    shldl $30, %eax, %edx
83 ; X86-NEXT:    shldl $30, %ebx, %eax
84 ; X86-NEXT:    popl %esi
85 ; X86-NEXT:    .cfi_def_cfa_offset 16
86 ; X86-NEXT:    popl %edi
87 ; X86-NEXT:    .cfi_def_cfa_offset 12
88 ; X86-NEXT:    popl %ebx
89 ; X86-NEXT:    .cfi_def_cfa_offset 8
90 ; X86-NEXT:    popl %ebp
91 ; X86-NEXT:    .cfi_def_cfa_offset 4
92 ; X86-NEXT:    retl
93   %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 2);
94   ret i64 %tmp;
95 }
96
97 define i4 @func3(i4 %x, i4 %y) nounwind {
98 ; X64-LABEL: func3:
99 ; X64:       # %bb.0:
100 ; X64-NEXT:    shlb $4, %dil
101 ; X64-NEXT:    sarb $4, %dil
102 ; X64-NEXT:    shlb $4, %sil
103 ; X64-NEXT:    sarb $4, %sil
104 ; X64-NEXT:    movsbl %sil, %ecx
105 ; X64-NEXT:    movsbl %dil, %eax
106 ; X64-NEXT:    imull %ecx, %eax
107 ; X64-NEXT:    movl %eax, %ecx
108 ; X64-NEXT:    shrb $2, %cl
109 ; X64-NEXT:    shrl $8, %eax
110 ; X64-NEXT:    shlb $6, %al
111 ; X64-NEXT:    orb %cl, %al
112 ; X64-NEXT:    # kill: def $al killed $al killed $eax
113 ; X64-NEXT:    retq
114 ;
115 ; X86-LABEL: func3:
116 ; X86:       # %bb.0:
117 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
118 ; X86-NEXT:    shlb $4, %al
119 ; X86-NEXT:    sarb $4, %al
120 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
121 ; X86-NEXT:    shlb $4, %cl
122 ; X86-NEXT:    sarb $4, %cl
123 ; X86-NEXT:    movsbl %cl, %ecx
124 ; X86-NEXT:    movsbl %al, %eax
125 ; X86-NEXT:    imull %ecx, %eax
126 ; X86-NEXT:    shlb $6, %ah
127 ; X86-NEXT:    shrb $2, %al
128 ; X86-NEXT:    orb %ah, %al
129 ; X86-NEXT:    # kill: def $al killed $al killed $eax
130 ; X86-NEXT:    retl
131   %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 2);
132   ret i4 %tmp;
133 }
134
135 define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
136 ; X64-LABEL: vec:
137 ; X64:       # %bb.0:
138 ; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[3,1,2,3]
139 ; X64-NEXT:    movd %xmm2, %eax
140 ; X64-NEXT:    cltq
141 ; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,1,2,3]
142 ; X64-NEXT:    movd %xmm2, %ecx
143 ; X64-NEXT:    movslq %ecx, %rcx
144 ; X64-NEXT:    imulq %rax, %rcx
145 ; X64-NEXT:    movq %rcx, %rax
146 ; X64-NEXT:    shrq $32, %rax
147 ; X64-NEXT:    shldl $30, %ecx, %eax
148 ; X64-NEXT:    movd %eax, %xmm2
149 ; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,0,1]
150 ; X64-NEXT:    movd %xmm3, %eax
151 ; X64-NEXT:    cltq
152 ; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,0,1]
153 ; X64-NEXT:    movd %xmm3, %ecx
154 ; X64-NEXT:    movslq %ecx, %rcx
155 ; X64-NEXT:    imulq %rax, %rcx
156 ; X64-NEXT:    movq %rcx, %rax
157 ; X64-NEXT:    shrq $32, %rax
158 ; X64-NEXT:    shldl $30, %ecx, %eax
159 ; X64-NEXT:    movd %eax, %xmm3
160 ; X64-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
161 ; X64-NEXT:    movd %xmm1, %eax
162 ; X64-NEXT:    cltq
163 ; X64-NEXT:    movd %xmm0, %ecx
164 ; X64-NEXT:    movslq %ecx, %rcx
165 ; X64-NEXT:    imulq %rax, %rcx
166 ; X64-NEXT:    movq %rcx, %rax
167 ; X64-NEXT:    shrq $32, %rax
168 ; X64-NEXT:    shldl $30, %ecx, %eax
169 ; X64-NEXT:    movd %eax, %xmm2
170 ; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,2,3]
171 ; X64-NEXT:    movd %xmm1, %eax
172 ; X64-NEXT:    cltq
173 ; X64-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
174 ; X64-NEXT:    movd %xmm0, %ecx
175 ; X64-NEXT:    movslq %ecx, %rcx
176 ; X64-NEXT:    imulq %rax, %rcx
177 ; X64-NEXT:    movq %rcx, %rax
178 ; X64-NEXT:    shrq $32, %rax
179 ; X64-NEXT:    shldl $30, %ecx, %eax
180 ; X64-NEXT:    movd %eax, %xmm0
181 ; X64-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
182 ; X64-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
183 ; X64-NEXT:    movdqa %xmm2, %xmm0
184 ; X64-NEXT:    retq
185 ;
186 ; X86-LABEL: vec:
187 ; X86:       # %bb.0:
188 ; X86-NEXT:    pushl %ebp
189 ; X86-NEXT:    pushl %ebx
190 ; X86-NEXT:    pushl %edi
191 ; X86-NEXT:    pushl %esi
192 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
193 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
194 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
195 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
196 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
197 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
198 ; X86-NEXT:    movl %edx, %ebp
199 ; X86-NEXT:    shldl $30, %eax, %ebp
200 ; X86-NEXT:    movl %ebx, %eax
201 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
202 ; X86-NEXT:    movl %edx, %ebx
203 ; X86-NEXT:    shldl $30, %eax, %ebx
204 ; X86-NEXT:    movl %edi, %eax
205 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
206 ; X86-NEXT:    movl %edx, %edi
207 ; X86-NEXT:    shldl $30, %eax, %edi
208 ; X86-NEXT:    movl %esi, %eax
209 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
210 ; X86-NEXT:    shldl $30, %eax, %edx
211 ; X86-NEXT:    movl %edx, 12(%ecx)
212 ; X86-NEXT:    movl %edi, 8(%ecx)
213 ; X86-NEXT:    movl %ebx, 4(%ecx)
214 ; X86-NEXT:    movl %ebp, (%ecx)
215 ; X86-NEXT:    movl %ecx, %eax
216 ; X86-NEXT:    popl %esi
217 ; X86-NEXT:    popl %edi
218 ; X86-NEXT:    popl %ebx
219 ; X86-NEXT:    popl %ebp
220 ; X86-NEXT:    retl $4
221   %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 2);
222   ret <4 x i32> %tmp;
223 }
224
225 ; These result in regular integer multiplication
226 define i32 @func4(i32 %x, i32 %y) nounwind {
227 ; X64-LABEL: func4:
228 ; X64:       # %bb.0:
229 ; X64-NEXT:    movl %edi, %eax
230 ; X64-NEXT:    imull %esi, %eax
231 ; X64-NEXT:    retq
232 ;
233 ; X86-LABEL: func4:
234 ; X86:       # %bb.0:
235 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
236 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %eax
237 ; X86-NEXT:    retl
238   %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 0);
239   ret i32 %tmp;
240 }
241
242 define i64 @func5(i64 %x, i64 %y) {
243 ; X64-LABEL: func5:
244 ; X64:       # %bb.0:
245 ; X64-NEXT:    movq %rdi, %rax
246 ; X64-NEXT:    imulq %rsi, %rax
247 ; X64-NEXT:    retq
248 ;
249 ; X86-LABEL: func5:
250 ; X86:       # %bb.0:
251 ; X86-NEXT:    pushl %esi
252 ; X86-NEXT:    .cfi_def_cfa_offset 8
253 ; X86-NEXT:    .cfi_offset %esi, -8
254 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
255 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
256 ; X86-NEXT:    movl %ecx, %eax
257 ; X86-NEXT:    mull %esi
258 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %ecx
259 ; X86-NEXT:    addl %ecx, %edx
260 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %esi
261 ; X86-NEXT:    addl %esi, %edx
262 ; X86-NEXT:    popl %esi
263 ; X86-NEXT:    .cfi_def_cfa_offset 4
264 ; X86-NEXT:    retl
265   %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 0);
266   ret i64 %tmp;
267 }
268
269 define i4 @func6(i4 %x, i4 %y) nounwind {
270 ; X64-LABEL: func6:
271 ; X64:       # %bb.0:
272 ; X64-NEXT:    movl %edi, %eax
273 ; X64-NEXT:    shlb $4, %al
274 ; X64-NEXT:    sarb $4, %al
275 ; X64-NEXT:    shlb $4, %sil
276 ; X64-NEXT:    sarb $4, %sil
277 ; X64-NEXT:    # kill: def $al killed $al killed $eax
278 ; X64-NEXT:    mulb %sil
279 ; X64-NEXT:    retq
280 ;
281 ; X86-LABEL: func6:
282 ; X86:       # %bb.0:
283 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
284 ; X86-NEXT:    shlb $4, %al
285 ; X86-NEXT:    sarb $4, %al
286 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
287 ; X86-NEXT:    shlb $4, %cl
288 ; X86-NEXT:    sarb $4, %cl
289 ; X86-NEXT:    mulb %cl
290 ; X86-NEXT:    retl
291   %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 0);
292   ret i4 %tmp;
293 }
294
295 define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {
296 ; X64-LABEL: vec2:
297 ; X64:       # %bb.0:
298 ; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[3,1,2,3]
299 ; X64-NEXT:    movd %xmm2, %eax
300 ; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,1,2,3]
301 ; X64-NEXT:    movd %xmm2, %ecx
302 ; X64-NEXT:    imull %eax, %ecx
303 ; X64-NEXT:    movd %ecx, %xmm2
304 ; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,0,1]
305 ; X64-NEXT:    movd %xmm3, %eax
306 ; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,0,1]
307 ; X64-NEXT:    movd %xmm3, %ecx
308 ; X64-NEXT:    imull %eax, %ecx
309 ; X64-NEXT:    movd %ecx, %xmm3
310 ; X64-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
311 ; X64-NEXT:    movd %xmm1, %eax
312 ; X64-NEXT:    movd %xmm0, %ecx
313 ; X64-NEXT:    imull %eax, %ecx
314 ; X64-NEXT:    movd %ecx, %xmm2
315 ; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,2,3]
316 ; X64-NEXT:    movd %xmm1, %eax
317 ; X64-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
318 ; X64-NEXT:    movd %xmm0, %ecx
319 ; X64-NEXT:    imull %eax, %ecx
320 ; X64-NEXT:    movd %ecx, %xmm0
321 ; X64-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
322 ; X64-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
323 ; X64-NEXT:    movdqa %xmm2, %xmm0
324 ; X64-NEXT:    retq
325 ;
326 ; X86-LABEL: vec2:
327 ; X86:       # %bb.0:
328 ; X86-NEXT:    pushl %edi
329 ; X86-NEXT:    pushl %esi
330 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
331 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
332 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
333 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
334 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
335 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %edi
336 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %esi
337 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %edx
338 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %ecx
339 ; X86-NEXT:    movl %ecx, 12(%eax)
340 ; X86-NEXT:    movl %edx, 8(%eax)
341 ; X86-NEXT:    movl %esi, 4(%eax)
342 ; X86-NEXT:    movl %edi, (%eax)
343 ; X86-NEXT:    popl %esi
344 ; X86-NEXT:    popl %edi
345 ; X86-NEXT:    retl $4
346   %tmp = call <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0);
347   ret <4 x i32> %tmp;
348 }
349
350 define i64 @func7(i64 %x, i64 %y) nounwind {
351 ; X64-LABEL: func7:
352 ; X64:       # %bb.0:
353 ; X64-NEXT:    movq %rdi, %rax
354 ; X64-NEXT:    imulq %rsi
355 ; X64-NEXT:    shrdq $32, %rdx, %rax
356 ; X64-NEXT:    retq
357 ;
358 ; X86-LABEL: func7:
359 ; X86:       # %bb.0:
360 ; X86-NEXT:    pushl %ebp
361 ; X86-NEXT:    pushl %ebx
362 ; X86-NEXT:    pushl %edi
363 ; X86-NEXT:    pushl %esi
364 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
365 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
366 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
367 ; X86-NEXT:    movl %ecx, %eax
368 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
369 ; X86-NEXT:    movl %edx, %edi
370 ; X86-NEXT:    movl %eax, %ebx
371 ; X86-NEXT:    movl %ecx, %eax
372 ; X86-NEXT:    mull %ebp
373 ; X86-NEXT:    addl %edx, %ebx
374 ; X86-NEXT:    adcl $0, %edi
375 ; X86-NEXT:    movl %esi, %eax
376 ; X86-NEXT:    mull %ebp
377 ; X86-NEXT:    addl %ebx, %eax
378 ; X86-NEXT:    adcl %edi, %edx
379 ; X86-NEXT:    movl %esi, %edi
380 ; X86-NEXT:    imull {{[0-9]+}}(%esp), %edi
381 ; X86-NEXT:    addl %edx, %edi
382 ; X86-NEXT:    movl %edi, %ebx
383 ; X86-NEXT:    subl %ebp, %ebx
384 ; X86-NEXT:    testl %esi, %esi
385 ; X86-NEXT:    cmovnsl %edi, %ebx
386 ; X86-NEXT:    movl %ebx, %edx
387 ; X86-NEXT:    subl %ecx, %edx
388 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
389 ; X86-NEXT:    cmovnsl %ebx, %edx
390 ; X86-NEXT:    popl %esi
391 ; X86-NEXT:    popl %edi
392 ; X86-NEXT:    popl %ebx
393 ; X86-NEXT:    popl %ebp
394 ; X86-NEXT:    retl
395   %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 32);
396   ret i64 %tmp;
397 }
398
399 define i64 @func8(i64 %x, i64 %y) nounwind {
400 ; X64-LABEL: func8:
401 ; X64:       # %bb.0:
402 ; X64-NEXT:    movq %rdi, %rax
403 ; X64-NEXT:    imulq %rsi
404 ; X64-NEXT:    shrdq $63, %rdx, %rax
405 ; X64-NEXT:    retq
406 ;
407 ; X86-LABEL: func8:
408 ; X86:       # %bb.0:
409 ; X86-NEXT:    pushl %ebp
410 ; X86-NEXT:    pushl %ebx
411 ; X86-NEXT:    pushl %edi
412 ; X86-NEXT:    pushl %esi
413 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
414 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
415 ; X86-NEXT:    movl %ecx, %eax
416 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
417 ; X86-NEXT:    movl %edx, %edi
418 ; X86-NEXT:    movl %eax, %ebx
419 ; X86-NEXT:    movl %ecx, %eax
420 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
421 ; X86-NEXT:    movl %edx, %ebp
422 ; X86-NEXT:    addl %ebx, %ebp
423 ; X86-NEXT:    adcl $0, %edi
424 ; X86-NEXT:    movl %esi, %eax
425 ; X86-NEXT:    imull {{[0-9]+}}(%esp)
426 ; X86-NEXT:    movl %edx, %ebx
427 ; X86-NEXT:    movl %eax, %ecx
428 ; X86-NEXT:    movl %esi, %eax
429 ; X86-NEXT:    mull {{[0-9]+}}(%esp)
430 ; X86-NEXT:    addl %ebp, %eax
431 ; X86-NEXT:    adcl %edi, %edx
432 ; X86-NEXT:    adcl $0, %ebx
433 ; X86-NEXT:    addl %ecx, %edx
434 ; X86-NEXT:    adcl $0, %ebx
435 ; X86-NEXT:    movl %edx, %ecx
436 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
437 ; X86-NEXT:    movl %ebx, %esi
438 ; X86-NEXT:    sbbl $0, %esi
439 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
440 ; X86-NEXT:    cmovnsl %ebx, %esi
441 ; X86-NEXT:    cmovnsl %edx, %ecx
442 ; X86-NEXT:    movl %ecx, %edi
443 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
444 ; X86-NEXT:    movl %esi, %edx
445 ; X86-NEXT:    sbbl $0, %edx
446 ; X86-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
447 ; X86-NEXT:    cmovnsl %esi, %edx
448 ; X86-NEXT:    cmovnsl %ecx, %edi
449 ; X86-NEXT:    shldl $1, %edi, %edx
450 ; X86-NEXT:    shrdl $31, %edi, %eax
451 ; X86-NEXT:    popl %esi
452 ; X86-NEXT:    popl %edi
453 ; X86-NEXT:    popl %ebx
454 ; X86-NEXT:    popl %ebp
455 ; X86-NEXT:    retl
456   %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 63);
457   ret i64 %tmp;
458 }