1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-pc-linux-gnu | FileCheck %s --check-prefix=X32
3; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64 --check-prefix=X64-FAST
4; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mattr=idivq-to-divl | FileCheck %s --check-prefix=X64 --check-prefix=X64-SLOW
5
6define zeroext i16 @test1(i16 zeroext %x) nounwind {
7; X32-LABEL: test1:
8; X32:       # %bb.0: # %entry
9; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
10; X32-NEXT:    imull $63551, %eax, %eax # imm = 0xF83F
11; X32-NEXT:    shrl $21, %eax
12; X32-NEXT:    # kill: def $ax killed $ax killed $eax
13; X32-NEXT:    retl
14;
15; X64-LABEL: test1:
16; X64:       # %bb.0: # %entry
17; X64-NEXT:    imull $63551, %edi, %eax # imm = 0xF83F
18; X64-NEXT:    shrl $21, %eax
19; X64-NEXT:    # kill: def $ax killed $ax killed $eax
20; X64-NEXT:    retq
21entry:
22	%div = udiv i16 %x, 33
23	ret i16 %div
24}
25
26define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) nounwind readnone ssp noredzone {
27; X32-LABEL: test2:
28; X32:       # %bb.0: # %entry
29; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
30; X32-NEXT:    imull $43691, %eax, %eax # imm = 0xAAAB
31; X32-NEXT:    shrl $17, %eax
32; X32-NEXT:    # kill: def $ax killed $ax killed $eax
33; X32-NEXT:    retl
34;
35; X64-LABEL: test2:
36; X64:       # %bb.0: # %entry
37; X64-NEXT:    imull $43691, %esi, %eax # imm = 0xAAAB
38; X64-NEXT:    shrl $17, %eax
39; X64-NEXT:    # kill: def $ax killed $ax killed $eax
40; X64-NEXT:    retq
41entry:
42  %div = udiv i16 %c, 3
43  ret i16 %div
44
45}
46
47define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) nounwind readnone ssp noredzone {
48; X32-LABEL: test3:
49; X32:       # %bb.0: # %entry
50; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
51; X32-NEXT:    imull $171, %eax, %eax
52; X32-NEXT:    shrl $9, %eax
53; X32-NEXT:    # kill: def $al killed $al killed $eax
54; X32-NEXT:    retl
55;
56; X64-LABEL: test3:
57; X64:       # %bb.0: # %entry
58; X64-NEXT:    imull $171, %esi, %eax
59; X64-NEXT:    shrl $9, %eax
60; X64-NEXT:    # kill: def $al killed $al killed $eax
61; X64-NEXT:    retq
62entry:
63  %div = udiv i8 %c, 3
64  ret i8 %div
65}
66
67define signext i16 @test4(i16 signext %x) nounwind {
68; X32-LABEL: test4:
69; X32:       # %bb.0: # %entry
70; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
71; X32-NEXT:    imull $1986, %eax, %eax # imm = 0x7C2
72; X32-NEXT:    movl %eax, %ecx
73; X32-NEXT:    shrl $31, %ecx
74; X32-NEXT:    shrl $16, %eax
75; X32-NEXT:    addl %ecx, %eax
76; X32-NEXT:    # kill: def $ax killed $ax killed $eax
77; X32-NEXT:    retl
78;
79; X64-LABEL: test4:
80; X64:       # %bb.0: # %entry
81; X64-NEXT:    imull $1986, %edi, %eax # imm = 0x7C2
82; X64-NEXT:    movl %eax, %ecx
83; X64-NEXT:    shrl $31, %ecx
84; X64-NEXT:    shrl $16, %eax
85; X64-NEXT:    addl %ecx, %eax
86; X64-NEXT:    # kill: def $ax killed $ax killed $eax
87; X64-NEXT:    retq
88entry:
89	%div = sdiv i16 %x, 33		; <i32> [#uses=1]
90	ret i16 %div
91}
92
93define i32 @test5(i32 %A) nounwind {
94; X32-LABEL: test5:
95; X32:       # %bb.0:
96; X32-NEXT:    movl $365384439, %eax # imm = 0x15C752F7
97; X32-NEXT:    mull {{[0-9]+}}(%esp)
98; X32-NEXT:    movl %edx, %eax
99; X32-NEXT:    shrl $27, %eax
100; X32-NEXT:    retl
101;
102; X64-LABEL: test5:
103; X64:       # %bb.0:
104; X64-NEXT:    movl %edi, %eax
105; X64-NEXT:    imulq $365384439, %rax, %rax # imm = 0x15C752F7
106; X64-NEXT:    shrq $59, %rax
107; X64-NEXT:    # kill: def $eax killed $eax killed $rax
108; X64-NEXT:    retq
109        %tmp1 = udiv i32 %A, 1577682821         ; <i32> [#uses=1]
110        ret i32 %tmp1
111}
112
113define signext i16 @test6(i16 signext %x) nounwind {
114; X32-LABEL: test6:
115; X32:       # %bb.0: # %entry
116; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
117; X32-NEXT:    imull $26215, %eax, %eax # imm = 0x6667
118; X32-NEXT:    movl %eax, %ecx
119; X32-NEXT:    shrl $31, %ecx
120; X32-NEXT:    sarl $18, %eax
121; X32-NEXT:    addl %ecx, %eax
122; X32-NEXT:    # kill: def $ax killed $ax killed $eax
123; X32-NEXT:    retl
124;
125; X64-LABEL: test6:
126; X64:       # %bb.0: # %entry
127; X64-NEXT:    imull $26215, %edi, %eax # imm = 0x6667
128; X64-NEXT:    movl %eax, %ecx
129; X64-NEXT:    shrl $31, %ecx
130; X64-NEXT:    sarl $18, %eax
131; X64-NEXT:    addl %ecx, %eax
132; X64-NEXT:    # kill: def $ax killed $ax killed $eax
133; X64-NEXT:    retq
134entry:
135  %div = sdiv i16 %x, 10
136  ret i16 %div
137}
138
139define i32 @test7(i32 %x) nounwind {
140; X32-LABEL: test7:
141; X32:       # %bb.0:
142; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
143; X32-NEXT:    shrl $2, %eax
144; X32-NEXT:    movl $613566757, %ecx # imm = 0x24924925
145; X32-NEXT:    mull %ecx
146; X32-NEXT:    movl %edx, %eax
147; X32-NEXT:    retl
148;
149; X64-LABEL: test7:
150; X64:       # %bb.0:
151; X64-NEXT:    # kill: def $edi killed $edi def $rdi
152; X64-NEXT:    shrl $2, %edi
153; X64-NEXT:    imulq $613566757, %rdi, %rax # imm = 0x24924925
154; X64-NEXT:    shrq $32, %rax
155; X64-NEXT:    # kill: def $eax killed $eax killed $rax
156; X64-NEXT:    retq
157  %div = udiv i32 %x, 28
158  ret i32 %div
159}
160
161; PR13326
162define i8 @test8(i8 %x) nounwind {
163; X32-LABEL: test8:
164; X32:       # %bb.0:
165; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
166; X32-NEXT:    shrb %al
167; X32-NEXT:    movzbl %al, %eax
168; X32-NEXT:    imull $211, %eax, %eax
169; X32-NEXT:    shrl $13, %eax
170; X32-NEXT:    # kill: def $al killed $al killed $eax
171; X32-NEXT:    retl
172;
173; X64-LABEL: test8:
174; X64:       # %bb.0:
175; X64-NEXT:    shrb %dil
176; X64-NEXT:    movzbl %dil, %eax
177; X64-NEXT:    imull $211, %eax, %eax
178; X64-NEXT:    shrl $13, %eax
179; X64-NEXT:    # kill: def $al killed $al killed $eax
180; X64-NEXT:    retq
181  %div = udiv i8 %x, 78
182  ret i8 %div
183}
184
185define i8 @test9(i8 %x) nounwind {
186; X32-LABEL: test9:
187; X32:       # %bb.0:
188; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
189; X32-NEXT:    shrb $2, %al
190; X32-NEXT:    movzbl %al, %eax
191; X32-NEXT:    imull $71, %eax, %eax
192; X32-NEXT:    shrl $11, %eax
193; X32-NEXT:    # kill: def $al killed $al killed $eax
194; X32-NEXT:    retl
195;
196; X64-LABEL: test9:
197; X64:       # %bb.0:
198; X64-NEXT:    shrb $2, %dil
199; X64-NEXT:    movzbl %dil, %eax
200; X64-NEXT:    imull $71, %eax, %eax
201; X64-NEXT:    shrl $11, %eax
202; X64-NEXT:    # kill: def $al killed $al killed $eax
203; X64-NEXT:    retq
204  %div = udiv i8 %x, 116
205  ret i8 %div
206}
207
208define i32 @testsize1(i32 %x) minsize nounwind {
209; X32-LABEL: testsize1:
210; X32:       # %bb.0: # %entry
211; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
212; X32-NEXT:    pushl $32
213; X32-NEXT:    popl %ecx
214; X32-NEXT:    cltd
215; X32-NEXT:    idivl %ecx
216; X32-NEXT:    retl
217;
218; X64-LABEL: testsize1:
219; X64:       # %bb.0: # %entry
220; X64-NEXT:    movl %edi, %eax
221; X64-NEXT:    pushq $32
222; X64-NEXT:    popq %rcx
223; X64-NEXT:    cltd
224; X64-NEXT:    idivl %ecx
225; X64-NEXT:    retq
226entry:
227	%div = sdiv i32 %x, 32
228	ret i32 %div
229}
230
231define i32 @testsize2(i32 %x) minsize nounwind {
232; X32-LABEL: testsize2:
233; X32:       # %bb.0: # %entry
234; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
235; X32-NEXT:    pushl $33
236; X32-NEXT:    popl %ecx
237; X32-NEXT:    cltd
238; X32-NEXT:    idivl %ecx
239; X32-NEXT:    retl
240;
241; X64-LABEL: testsize2:
242; X64:       # %bb.0: # %entry
243; X64-NEXT:    movl %edi, %eax
244; X64-NEXT:    pushq $33
245; X64-NEXT:    popq %rcx
246; X64-NEXT:    cltd
247; X64-NEXT:    idivl %ecx
248; X64-NEXT:    retq
249entry:
250	%div = sdiv i32 %x, 33
251	ret i32 %div
252}
253
254define i32 @testsize3(i32 %x) minsize nounwind {
255; X32-LABEL: testsize3:
256; X32:       # %bb.0: # %entry
257; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
258; X32-NEXT:    shrl $5, %eax
259; X32-NEXT:    retl
260;
261; X64-LABEL: testsize3:
262; X64:       # %bb.0: # %entry
263; X64-NEXT:    movl %edi, %eax
264; X64-NEXT:    shrl $5, %eax
265; X64-NEXT:    retq
266entry:
267	%div = udiv i32 %x, 32
268	ret i32 %div
269}
270
271define i32 @testsize4(i32 %x) minsize nounwind {
272; X32-LABEL: testsize4:
273; X32:       # %bb.0: # %entry
274; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
275; X32-NEXT:    pushl $33
276; X32-NEXT:    popl %ecx
277; X32-NEXT:    xorl %edx, %edx
278; X32-NEXT:    divl %ecx
279; X32-NEXT:    retl
280;
281; X64-LABEL: testsize4:
282; X64:       # %bb.0: # %entry
283; X64-NEXT:    movl %edi, %eax
284; X64-NEXT:    pushq $33
285; X64-NEXT:    popq %rcx
286; X64-NEXT:    xorl %edx, %edx
287; X64-NEXT:    divl %ecx
288; X64-NEXT:    retq
289entry:
290	%div = udiv i32 %x, 33
291	ret i32 %div
292}
293
294define i64 @PR23590(i64 %x) nounwind {
295; X32-LABEL: PR23590:
296; X32:       # %bb.0: # %entry
297; X32-NEXT:    subl $12, %esp
298; X32-NEXT:    pushl $0
299; X32-NEXT:    pushl $12345 # imm = 0x3039
300; X32-NEXT:    pushl {{[0-9]+}}(%esp)
301; X32-NEXT:    pushl {{[0-9]+}}(%esp)
302; X32-NEXT:    calll __umoddi3
303; X32-NEXT:    addl $16, %esp
304; X32-NEXT:    pushl $0
305; X32-NEXT:    pushl $7
306; X32-NEXT:    pushl %edx
307; X32-NEXT:    pushl %eax
308; X32-NEXT:    calll __udivdi3
309; X32-NEXT:    addl $28, %esp
310; X32-NEXT:    retl
311;
312; X64-FAST-LABEL: PR23590:
313; X64-FAST:       # %bb.0: # %entry
314; X64-FAST-NEXT:    movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
315; X64-FAST-NEXT:    movq %rdi, %rax
316; X64-FAST-NEXT:    mulq %rcx
317; X64-FAST-NEXT:    shrq $12, %rdx
318; X64-FAST-NEXT:    imulq $12345, %rdx, %rax # imm = 0x3039
319; X64-FAST-NEXT:    subq %rax, %rdi
320; X64-FAST-NEXT:    movabsq $2635249153387078803, %rcx # imm = 0x2492492492492493
321; X64-FAST-NEXT:    movq %rdi, %rax
322; X64-FAST-NEXT:    mulq %rcx
323; X64-FAST-NEXT:    subq %rdx, %rdi
324; X64-FAST-NEXT:    shrq %rdi
325; X64-FAST-NEXT:    leaq (%rdi,%rdx), %rax
326; X64-FAST-NEXT:    shrq $2, %rax
327; X64-FAST-NEXT:    retq
328;
329; X64-SLOW-LABEL: PR23590:
330; X64-SLOW:       # %bb.0: # %entry
331; X64-SLOW-NEXT:    movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
332; X64-SLOW-NEXT:    movq %rdi, %rax
333; X64-SLOW-NEXT:    mulq %rcx
334; X64-SLOW-NEXT:    shrq $12, %rdx
335; X64-SLOW-NEXT:    imulq $12345, %rdx, %rax # imm = 0x3039
336; X64-SLOW-NEXT:    subq %rax, %rdi
337; X64-SLOW-NEXT:    imulq $613566757, %rdi, %rax # imm = 0x24924925
338; X64-SLOW-NEXT:    shrq $32, %rax
339; X64-SLOW-NEXT:    subl %eax, %edi
340; X64-SLOW-NEXT:    shrl %edi
341; X64-SLOW-NEXT:    addl %eax, %edi
342; X64-SLOW-NEXT:    shrl $2, %edi
343; X64-SLOW-NEXT:    movq %rdi, %rax
344; X64-SLOW-NEXT:    retq
345entry:
346	%rem = urem i64 %x, 12345
347	%div = udiv i64 %rem, 7
348	ret i64 %div
349}
350
351define { i64, i32 } @PR38622(i64) nounwind {
352; X32-LABEL: PR38622:
353; X32:       # %bb.0:
354; X32-NEXT:    pushl %ebp
355; X32-NEXT:    pushl %ebx
356; X32-NEXT:    pushl %edi
357; X32-NEXT:    pushl %esi
358; X32-NEXT:    subl $12, %esp
359; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
360; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
361; X32-NEXT:    pushl $0
362; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
363; X32-NEXT:    pushl %ebp
364; X32-NEXT:    pushl %ebx
365; X32-NEXT:    calll __udivdi3
366; X32-NEXT:    addl $16, %esp
367; X32-NEXT:    movl %eax, %esi
368; X32-NEXT:    movl %edx, %edi
369; X32-NEXT:    pushl $0
370; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
371; X32-NEXT:    pushl %ebp
372; X32-NEXT:    pushl %ebx
373; X32-NEXT:    calll __umoddi3
374; X32-NEXT:    addl $16, %esp
375; X32-NEXT:    movl %eax, %ecx
376; X32-NEXT:    movl %esi, %eax
377; X32-NEXT:    movl %edi, %edx
378; X32-NEXT:    addl $12, %esp
379; X32-NEXT:    popl %esi
380; X32-NEXT:    popl %edi
381; X32-NEXT:    popl %ebx
382; X32-NEXT:    popl %ebp
383; X32-NEXT:    retl
384;
385; X64-LABEL: PR38622:
386; X64:       # %bb.0:
387; X64-NEXT:    movq %rdi, %rax
388; X64-NEXT:    shrq $11, %rax
389; X64-NEXT:    movabsq $4835703278458517, %rcx # imm = 0x112E0BE826D695
390; X64-NEXT:    mulq %rcx
391; X64-NEXT:    movq %rdx, %rax
392; X64-NEXT:    shrq $9, %rax
393; X64-NEXT:    imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
394; X64-NEXT:    subl %ecx, %edi
395; X64-NEXT:    movl %edi, %edx
396; X64-NEXT:    retq
397  %2 = udiv i64 %0, 4000000000
398  %3 = urem i64 %0, 4000000000
399  %4 = trunc i64 %3 to i32
400  %5 = insertvalue { i64, i32 } undef, i64 %2, 0
401  %6 = insertvalue { i64, i32 } %5, i32 %4, 1
402  ret { i64, i32 } %6
403}
404
405define { i64, i32 } @PR38622_signed(i64) nounwind {
406; X32-LABEL: PR38622_signed:
407; X32:       # %bb.0:
408; X32-NEXT:    pushl %ebp
409; X32-NEXT:    pushl %ebx
410; X32-NEXT:    pushl %edi
411; X32-NEXT:    pushl %esi
412; X32-NEXT:    subl $12, %esp
413; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
414; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
415; X32-NEXT:    pushl $0
416; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
417; X32-NEXT:    pushl %ebp
418; X32-NEXT:    pushl %ebx
419; X32-NEXT:    calll __divdi3
420; X32-NEXT:    addl $16, %esp
421; X32-NEXT:    movl %eax, %esi
422; X32-NEXT:    movl %edx, %edi
423; X32-NEXT:    pushl $0
424; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
425; X32-NEXT:    pushl %ebp
426; X32-NEXT:    pushl %ebx
427; X32-NEXT:    calll __moddi3
428; X32-NEXT:    addl $16, %esp
429; X32-NEXT:    movl %eax, %ecx
430; X32-NEXT:    movl %esi, %eax
431; X32-NEXT:    movl %edi, %edx
432; X32-NEXT:    addl $12, %esp
433; X32-NEXT:    popl %esi
434; X32-NEXT:    popl %edi
435; X32-NEXT:    popl %ebx
436; X32-NEXT:    popl %ebp
437; X32-NEXT:    retl
438;
439; X64-LABEL: PR38622_signed:
440; X64:       # %bb.0:
441; X64-NEXT:    movabsq $1237940039285380275, %rcx # imm = 0x112E0BE826D694B3
442; X64-NEXT:    movq %rdi, %rax
443; X64-NEXT:    imulq %rcx
444; X64-NEXT:    movq %rdx, %rax
445; X64-NEXT:    movq %rdx, %rcx
446; X64-NEXT:    shrq $63, %rcx
447; X64-NEXT:    sarq $28, %rax
448; X64-NEXT:    addq %rcx, %rax
449; X64-NEXT:    imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
450; X64-NEXT:    subl %ecx, %edi
451; X64-NEXT:    movl %edi, %edx
452; X64-NEXT:    retq
453  %2 = sdiv i64 %0, 4000000000
454  %3 = srem i64 %0, 4000000000
455  %4 = trunc i64 %3 to i32
456  %5 = insertvalue { i64, i32 } undef, i64 %2, 0
457  %6 = insertvalue { i64, i32 } %5, i32 %4, 1
458  ret { i64, i32 } %6
459}
460