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
5 declare i4 @llvm.umul.fix.i4 (i4, i4, i32)
6 declare i32 @llvm.umul.fix.i32 (i32, i32, i32)
7 declare i64 @llvm.umul.fix.i64 (i64, i64, i32)
8 declare <4 x i32> @llvm.umul.fix.v4i32(<4 x i32>, <4 x i32>, i32)
10 define i32 @func(i32 %x, i32 %y) nounwind {
13 ; X64-NEXT: movl %esi, %eax
14 ; X64-NEXT: movl %edi, %ecx
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
24 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
25 ; X86-NEXT: mull {{[0-9]+}}(%esp)
26 ; X86-NEXT: shrdl $2, %edx, %eax
28 %tmp = call i32 @llvm.umul.fix.i32(i32 %x, i32 %y, i32 2);
32 define i64 @func2(i64 %x, i64 %y) nounwind {
35 ; X64-NEXT: movq %rdi, %rax
37 ; X64-NEXT: shrdq $2, %rdx, %rax
42 ; X86-NEXT: pushl %ebp
43 ; X86-NEXT: pushl %ebx
44 ; X86-NEXT: pushl %edi
45 ; X86-NEXT: pushl %esi
46 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
47 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
48 ; X86-NEXT: movl %ecx, %eax
49 ; X86-NEXT: mull {{[0-9]+}}(%esp)
50 ; X86-NEXT: movl %edx, %edi
51 ; X86-NEXT: movl %eax, %ebx
52 ; X86-NEXT: movl %ecx, %eax
53 ; X86-NEXT: mull {{[0-9]+}}(%esp)
54 ; X86-NEXT: movl %eax, %ecx
55 ; X86-NEXT: movl %edx, %ebp
56 ; X86-NEXT: addl %ebx, %ebp
57 ; X86-NEXT: adcl $0, %edi
58 ; X86-NEXT: movl %esi, %eax
59 ; X86-NEXT: mull {{[0-9]+}}(%esp)
60 ; X86-NEXT: addl %ebp, %eax
61 ; X86-NEXT: adcl %edi, %edx
62 ; X86-NEXT: imull {{[0-9]+}}(%esp), %esi
63 ; X86-NEXT: addl %esi, %edx
64 ; X86-NEXT: shldl $30, %eax, %edx
65 ; X86-NEXT: shldl $30, %ecx, %eax
71 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 2);
75 define i4 @func3(i4 %x, i4 %y) nounwind {
78 ; X64-NEXT: movl %edi, %eax
79 ; X64-NEXT: andl $15, %esi
80 ; X64-NEXT: andl $15, %eax
81 ; X64-NEXT: imull %esi, %eax
82 ; X64-NEXT: shrb $2, %al
83 ; X64-NEXT: # kill: def $al killed $al killed $eax
88 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
89 ; X86-NEXT: andb $15, %al
90 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
91 ; X86-NEXT: andb $15, %cl
92 ; X86-NEXT: movzbl %cl, %ecx
93 ; X86-NEXT: movzbl %al, %eax
94 ; X86-NEXT: imull %ecx, %eax
95 ; X86-NEXT: shrb $2, %al
96 ; X86-NEXT: # kill: def $al killed $al killed $eax
98 %tmp = call i4 @llvm.umul.fix.i4(i4 %x, i4 %y, i32 2);
102 define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
105 ; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
106 ; X64-NEXT: pmuludq %xmm1, %xmm0
107 ; X64-NEXT: pshufd {{.*#+}} xmm3 = xmm0[0,2,2,3]
108 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
109 ; X64-NEXT: pmuludq %xmm2, %xmm1
110 ; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm1[0,2,2,3]
111 ; X64-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
112 ; X64-NEXT: psrld $2, %xmm3
113 ; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,3,2,3]
114 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,3,2,3]
115 ; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
116 ; X64-NEXT: pslld $30, %xmm0
117 ; X64-NEXT: por %xmm3, %xmm0
122 ; X86-NEXT: pushl %ebp
123 ; X86-NEXT: pushl %ebx
124 ; X86-NEXT: pushl %edi
125 ; X86-NEXT: pushl %esi
126 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
127 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
128 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
129 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
130 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
131 ; X86-NEXT: mull {{[0-9]+}}(%esp)
132 ; X86-NEXT: movl %edx, %ebp
133 ; X86-NEXT: shldl $30, %eax, %ebp
134 ; X86-NEXT: movl %ebx, %eax
135 ; X86-NEXT: mull {{[0-9]+}}(%esp)
136 ; X86-NEXT: movl %edx, %ebx
137 ; X86-NEXT: shldl $30, %eax, %ebx
138 ; X86-NEXT: movl %edi, %eax
139 ; X86-NEXT: mull {{[0-9]+}}(%esp)
140 ; X86-NEXT: movl %edx, %edi
141 ; X86-NEXT: shldl $30, %eax, %edi
142 ; X86-NEXT: movl %esi, %eax
143 ; X86-NEXT: mull {{[0-9]+}}(%esp)
144 ; X86-NEXT: shldl $30, %eax, %edx
145 ; X86-NEXT: movl %edx, 12(%ecx)
146 ; X86-NEXT: movl %edi, 8(%ecx)
147 ; X86-NEXT: movl %ebx, 4(%ecx)
148 ; X86-NEXT: movl %ebp, (%ecx)
149 ; X86-NEXT: movl %ecx, %eax
150 ; X86-NEXT: popl %esi
151 ; X86-NEXT: popl %edi
152 ; X86-NEXT: popl %ebx
153 ; X86-NEXT: popl %ebp
155 %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 2);
159 ; These result in regular integer multiplication
160 define i32 @func4(i32 %x, i32 %y) nounwind {
163 ; X64-NEXT: movl %edi, %eax
164 ; X64-NEXT: imull %esi, %eax
169 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
170 ; X86-NEXT: imull {{[0-9]+}}(%esp), %eax
172 %tmp = call i32 @llvm.umul.fix.i32(i32 %x, i32 %y, i32 0);
176 define i64 @func5(i64 %x, i64 %y) nounwind {
179 ; X64-NEXT: movq %rdi, %rax
180 ; X64-NEXT: imulq %rsi, %rax
185 ; X86-NEXT: pushl %esi
186 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
187 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
188 ; X86-NEXT: movl %ecx, %eax
189 ; X86-NEXT: mull %esi
190 ; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx
191 ; X86-NEXT: addl %ecx, %edx
192 ; X86-NEXT: imull {{[0-9]+}}(%esp), %esi
193 ; X86-NEXT: addl %esi, %edx
194 ; X86-NEXT: popl %esi
196 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 0);
200 define i4 @func6(i4 %x, i4 %y) nounwind {
203 ; X64-NEXT: movl %edi, %eax
204 ; X64-NEXT: andb $15, %al
205 ; X64-NEXT: andb $15, %sil
206 ; X64-NEXT: # kill: def $al killed $al killed $eax
207 ; X64-NEXT: mulb %sil
212 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
213 ; X86-NEXT: andb $15, %al
214 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
215 ; X86-NEXT: andb $15, %cl
218 %tmp = call i4 @llvm.umul.fix.i4(i4 %x, i4 %y, i32 0);
222 define <4 x i32> @vec2(<4 x i32> %x, <4 x i32> %y) nounwind {
225 ; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
226 ; X64-NEXT: pmuludq %xmm1, %xmm0
227 ; X64-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
228 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
229 ; X64-NEXT: pmuludq %xmm2, %xmm1
230 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
231 ; X64-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
236 ; X86-NEXT: pushl %edi
237 ; X86-NEXT: pushl %esi
238 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
239 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
240 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
241 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
242 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
243 ; X86-NEXT: imull {{[0-9]+}}(%esp), %edi
244 ; X86-NEXT: imull {{[0-9]+}}(%esp), %esi
245 ; X86-NEXT: imull {{[0-9]+}}(%esp), %edx
246 ; X86-NEXT: imull {{[0-9]+}}(%esp), %ecx
247 ; X86-NEXT: movl %ecx, 12(%eax)
248 ; X86-NEXT: movl %edx, 8(%eax)
249 ; X86-NEXT: movl %esi, 4(%eax)
250 ; X86-NEXT: movl %edi, (%eax)
251 ; X86-NEXT: popl %esi
252 ; X86-NEXT: popl %edi
254 %tmp = call <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> %x, <4 x i32> %y, i32 0);
258 define i64 @func7(i64 %x, i64 %y) nounwind {
261 ; X64-NEXT: movq %rdi, %rax
262 ; X64-NEXT: mulq %rsi
263 ; X64-NEXT: shrdq $32, %rdx, %rax
268 ; X86-NEXT: pushl %ebp
269 ; X86-NEXT: pushl %ebx
270 ; X86-NEXT: pushl %edi
271 ; X86-NEXT: pushl %esi
272 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
273 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
274 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
275 ; X86-NEXT: movl %ecx, %eax
276 ; X86-NEXT: mull {{[0-9]+}}(%esp)
277 ; X86-NEXT: movl %edx, %edi
278 ; X86-NEXT: movl %eax, %ebx
279 ; X86-NEXT: movl %ecx, %eax
280 ; X86-NEXT: mull %ebp
281 ; X86-NEXT: addl %edx, %ebx
282 ; X86-NEXT: adcl $0, %edi
283 ; X86-NEXT: movl %esi, %eax
284 ; X86-NEXT: mull %ebp
285 ; X86-NEXT: addl %ebx, %eax
286 ; X86-NEXT: adcl %edi, %edx
287 ; X86-NEXT: imull {{[0-9]+}}(%esp), %esi
288 ; X86-NEXT: addl %esi, %edx
289 ; X86-NEXT: popl %esi
290 ; X86-NEXT: popl %edi
291 ; X86-NEXT: popl %ebx
292 ; X86-NEXT: popl %ebp
294 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 32);
298 define i64 @func8(i64 %x, i64 %y) nounwind {
301 ; X64-NEXT: movq %rdi, %rax
302 ; X64-NEXT: mulq %rsi
303 ; X64-NEXT: shrdq $63, %rdx, %rax
308 ; X86-NEXT: pushl %ebp
309 ; X86-NEXT: pushl %ebx
310 ; X86-NEXT: pushl %edi
311 ; X86-NEXT: pushl %esi
312 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
313 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
314 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
315 ; X86-NEXT: movl %ecx, %eax
316 ; X86-NEXT: mull %ebp
317 ; X86-NEXT: movl %edx, %edi
318 ; X86-NEXT: movl %eax, %ebx
319 ; X86-NEXT: movl %ecx, %eax
320 ; X86-NEXT: mull %esi
321 ; X86-NEXT: movl %edx, %ecx
322 ; X86-NEXT: addl %ebx, %ecx
323 ; X86-NEXT: adcl $0, %edi
324 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
325 ; X86-NEXT: mull %ebp
326 ; X86-NEXT: movl %edx, %ebx
327 ; X86-NEXT: movl %eax, %ebp
328 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
329 ; X86-NEXT: mull %esi
330 ; X86-NEXT: addl %ecx, %eax
331 ; X86-NEXT: adcl %edi, %edx
332 ; X86-NEXT: adcl $0, %ebx
333 ; X86-NEXT: addl %ebp, %edx
334 ; X86-NEXT: adcl $0, %ebx
335 ; X86-NEXT: shldl $1, %edx, %ebx
336 ; X86-NEXT: shrdl $31, %edx, %eax
337 ; X86-NEXT: movl %ebx, %edx
338 ; X86-NEXT: popl %esi
339 ; X86-NEXT: popl %edi
340 ; X86-NEXT: popl %ebx
341 ; X86-NEXT: popl %ebp
343 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 63);
347 define i64 @func9(i64 %x, i64 %y) nounwind {
350 ; X64-NEXT: movq %rdi, %rax
351 ; X64-NEXT: mulq %rsi
352 ; X64-NEXT: movq %rdx, %rax
357 ; X86-NEXT: pushl %ebp
358 ; X86-NEXT: pushl %ebx
359 ; X86-NEXT: pushl %edi
360 ; X86-NEXT: pushl %esi
361 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
362 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
363 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp
364 ; X86-NEXT: movl %ecx, %eax
365 ; X86-NEXT: mull %ebp
366 ; X86-NEXT: movl %edx, %edi
367 ; X86-NEXT: movl %eax, %ebx
368 ; X86-NEXT: movl %ecx, %eax
369 ; X86-NEXT: mull %esi
370 ; X86-NEXT: movl %edx, %ecx
371 ; X86-NEXT: addl %ebx, %ecx
372 ; X86-NEXT: adcl $0, %edi
373 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
374 ; X86-NEXT: mull %ebp
375 ; X86-NEXT: movl %edx, %ebx
376 ; X86-NEXT: movl %eax, %ebp
377 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
378 ; X86-NEXT: mull %esi
379 ; X86-NEXT: addl %ecx, %eax
380 ; X86-NEXT: adcl %edi, %edx
381 ; X86-NEXT: adcl $0, %ebx
382 ; X86-NEXT: addl %edx, %ebp
383 ; X86-NEXT: adcl $0, %ebx
384 ; X86-NEXT: movl %ebp, %eax
385 ; X86-NEXT: movl %ebx, %edx
386 ; X86-NEXT: popl %esi
387 ; X86-NEXT: popl %edi
388 ; X86-NEXT: popl %ebx
389 ; X86-NEXT: popl %ebp
391 %tmp = call i64 @llvm.umul.fix.i64(i64 %x, i64 %y, i32 64);