1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown   -mattr=+sse,+sse2 | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse,+sse2 | FileCheck %s --check-prefix=X64
4
5; If the target does not have a single div/rem operation,
6; -div-rem-pairs pass will decompose the remainder calculation as:
7;   X % Y --> X - ((X / Y) * Y)
8; But if the target does have a single div/rem operation,
9; the opposite transform is likely beneficial.
10
11define i8 @scalar_i8(i8 %x, i8 %y, ptr %divdst) nounwind {
12; X86-LABEL: scalar_i8:
13; X86:       # %bb.0:
14; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
15; X86-NEXT:    movb {{[0-9]+}}(%esp), %ch
16; X86-NEXT:    movb {{[0-9]+}}(%esp), %cl
17; X86-NEXT:    movzbl %cl, %eax
18; X86-NEXT:    divb %ch
19; X86-NEXT:    movb %al, (%edx)
20; X86-NEXT:    mulb %ch
21; X86-NEXT:    subb %al, %cl
22; X86-NEXT:    movl %ecx, %eax
23; X86-NEXT:    retl
24;
25; X64-LABEL: scalar_i8:
26; X64:       # %bb.0:
27; X64-NEXT:    movzbl %dil, %ecx
28; X64-NEXT:    movl %ecx, %eax
29; X64-NEXT:    divb %sil
30; X64-NEXT:    movb %al, (%rdx)
31; X64-NEXT:    mulb %sil
32; X64-NEXT:    subb %al, %cl
33; X64-NEXT:    movl %ecx, %eax
34; X64-NEXT:    retq
35  %div = udiv i8 %x, %y
36  store i8 %div, ptr %divdst, align 4
37  %t1 = mul i8 %div, %y
38  %t2 = sub i8 %x, %t1
39  ret i8 %t2
40}
41
42define i16 @scalar_i16(i16 %x, i16 %y, ptr %divdst) nounwind {
43; X86-LABEL: scalar_i16:
44; X86:       # %bb.0:
45; X86-NEXT:    pushl %edi
46; X86-NEXT:    pushl %esi
47; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
48; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
49; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
50; X86-NEXT:    movl %ecx, %eax
51; X86-NEXT:    xorl %edx, %edx
52; X86-NEXT:    divw %si
53; X86-NEXT:    # kill: def $ax killed $ax def $eax
54; X86-NEXT:    movw %ax, (%edi)
55; X86-NEXT:    imull %eax, %esi
56; X86-NEXT:    subl %esi, %ecx
57; X86-NEXT:    movl %ecx, %eax
58; X86-NEXT:    popl %esi
59; X86-NEXT:    popl %edi
60; X86-NEXT:    retl
61;
62; X64-LABEL: scalar_i16:
63; X64:       # %bb.0:
64; X64-NEXT:    movq %rdx, %rcx
65; X64-NEXT:    movl %edi, %eax
66; X64-NEXT:    xorl %edx, %edx
67; X64-NEXT:    divw %si
68; X64-NEXT:    # kill: def $ax killed $ax def $eax
69; X64-NEXT:    movw %ax, (%rcx)
70; X64-NEXT:    imull %eax, %esi
71; X64-NEXT:    subl %esi, %edi
72; X64-NEXT:    movl %edi, %eax
73; X64-NEXT:    retq
74  %div = udiv i16 %x, %y
75  store i16 %div, ptr %divdst, align 4
76  %t1 = mul i16 %div, %y
77  %t2 = sub i16 %x, %t1
78  ret i16 %t2
79}
80
81define i32 @scalar_i32(i32 %x, i32 %y, ptr %divdst) nounwind {
82; X86-LABEL: scalar_i32:
83; X86:       # %bb.0:
84; X86-NEXT:    pushl %edi
85; X86-NEXT:    pushl %esi
86; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
87; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
88; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
89; X86-NEXT:    movl %ecx, %eax
90; X86-NEXT:    xorl %edx, %edx
91; X86-NEXT:    divl %edi
92; X86-NEXT:    movl %eax, (%esi)
93; X86-NEXT:    imull %edi, %eax
94; X86-NEXT:    subl %eax, %ecx
95; X86-NEXT:    movl %ecx, %eax
96; X86-NEXT:    popl %esi
97; X86-NEXT:    popl %edi
98; X86-NEXT:    retl
99;
100; X64-LABEL: scalar_i32:
101; X64:       # %bb.0:
102; X64-NEXT:    movq %rdx, %rcx
103; X64-NEXT:    movl %edi, %eax
104; X64-NEXT:    xorl %edx, %edx
105; X64-NEXT:    divl %esi
106; X64-NEXT:    movl %eax, (%rcx)
107; X64-NEXT:    imull %esi, %eax
108; X64-NEXT:    subl %eax, %edi
109; X64-NEXT:    movl %edi, %eax
110; X64-NEXT:    retq
111  %div = udiv i32 %x, %y
112  store i32 %div, ptr %divdst, align 4
113  %t1 = mul i32 %div, %y
114  %t2 = sub i32 %x, %t1
115  ret i32 %t2
116}
117
118define i64 @scalar_i64(i64 %x, i64 %y, ptr %divdst) nounwind {
119; X86-LABEL: scalar_i64:
120; X86:       # %bb.0:
121; X86-NEXT:    pushl %ebp
122; X86-NEXT:    pushl %ebx
123; X86-NEXT:    pushl %edi
124; X86-NEXT:    pushl %esi
125; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
126; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
127; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
128; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
129; X86-NEXT:    pushl %ebp
130; X86-NEXT:    pushl %ebx
131; X86-NEXT:    pushl %edi
132; X86-NEXT:    pushl %esi
133; X86-NEXT:    calll __udivdi3
134; X86-NEXT:    addl $16, %esp
135; X86-NEXT:    movl %edx, %ecx
136; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
137; X86-NEXT:    movl %ecx, 4(%edx)
138; X86-NEXT:    movl %eax, (%edx)
139; X86-NEXT:    imull %eax, %ebp
140; X86-NEXT:    mull %ebx
141; X86-NEXT:    addl %ebp, %edx
142; X86-NEXT:    imull %ebx, %ecx
143; X86-NEXT:    addl %edx, %ecx
144; X86-NEXT:    subl %eax, %esi
145; X86-NEXT:    sbbl %ecx, %edi
146; X86-NEXT:    movl %esi, %eax
147; X86-NEXT:    movl %edi, %edx
148; X86-NEXT:    popl %esi
149; X86-NEXT:    popl %edi
150; X86-NEXT:    popl %ebx
151; X86-NEXT:    popl %ebp
152; X86-NEXT:    retl
153;
154; X64-LABEL: scalar_i64:
155; X64:       # %bb.0:
156; X64-NEXT:    movq %rdx, %rcx
157; X64-NEXT:    movq %rdi, %rax
158; X64-NEXT:    xorl %edx, %edx
159; X64-NEXT:    divq %rsi
160; X64-NEXT:    movq %rax, (%rcx)
161; X64-NEXT:    imulq %rsi, %rax
162; X64-NEXT:    subq %rax, %rdi
163; X64-NEXT:    movq %rdi, %rax
164; X64-NEXT:    retq
165  %div = udiv i64 %x, %y
166  store i64 %div, ptr %divdst, align 4
167  %t1 = mul i64 %div, %y
168  %t2 = sub i64 %x, %t1
169  ret i64 %t2
170}
171
172define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
173; X86-LABEL: scalar_i128:
174; X86:       # %bb.0:
175; X86-NEXT:    pushl %ebp
176; X86-NEXT:    movl %esp, %ebp
177; X86-NEXT:    pushl %ebx
178; X86-NEXT:    pushl %edi
179; X86-NEXT:    pushl %esi
180; X86-NEXT:    andl $-8, %esp
181; X86-NEXT:    subl $40, %esp
182; X86-NEXT:    movl 44(%ebp), %edi
183; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
184; X86-NEXT:    pushl 40(%ebp)
185; X86-NEXT:    pushl 36(%ebp)
186; X86-NEXT:    pushl 32(%ebp)
187; X86-NEXT:    pushl 28(%ebp)
188; X86-NEXT:    pushl 24(%ebp)
189; X86-NEXT:    pushl 20(%ebp)
190; X86-NEXT:    pushl 16(%ebp)
191; X86-NEXT:    pushl 12(%ebp)
192; X86-NEXT:    pushl %eax
193; X86-NEXT:    calll __udivti3
194; X86-NEXT:    addl $32, %esp
195; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
196; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
197; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
198; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
199; X86-NEXT:    movl %edi, %edx
200; X86-NEXT:    movl %ecx, 12(%edi)
201; X86-NEXT:    movl %esi, 8(%edi)
202; X86-NEXT:    movl %eax, 4(%edi)
203; X86-NEXT:    movl %eax, %edi
204; X86-NEXT:    movl %ebx, (%edx)
205; X86-NEXT:    movl 28(%ebp), %eax
206; X86-NEXT:    imull %eax, %ecx
207; X86-NEXT:    mull %esi
208; X86-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
209; X86-NEXT:    addl %ecx, %edx
210; X86-NEXT:    imull 32(%ebp), %esi
211; X86-NEXT:    addl %edx, %esi
212; X86-NEXT:    movl 36(%ebp), %eax
213; X86-NEXT:    movl %eax, %ecx
214; X86-NEXT:    imull %edi, %ecx
215; X86-NEXT:    mull %ebx
216; X86-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
217; X86-NEXT:    addl %ecx, %edx
218; X86-NEXT:    movl 40(%ebp), %eax
219; X86-NEXT:    imull %ebx, %eax
220; X86-NEXT:    addl %edx, %eax
221; X86-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
222; X86-NEXT:    addl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
223; X86-NEXT:    adcl %esi, %eax
224; X86-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
225; X86-NEXT:    movl %ebx, %eax
226; X86-NEXT:    movl 28(%ebp), %ecx
227; X86-NEXT:    mull %ecx
228; X86-NEXT:    movl %edx, (%esp) # 4-byte Spill
229; X86-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
230; X86-NEXT:    movl %edi, %eax
231; X86-NEXT:    mull %ecx
232; X86-NEXT:    movl %edx, %ecx
233; X86-NEXT:    movl %eax, %esi
234; X86-NEXT:    addl (%esp), %esi # 4-byte Folded Reload
235; X86-NEXT:    adcl $0, %ecx
236; X86-NEXT:    movl %ebx, %eax
237; X86-NEXT:    mull 32(%ebp)
238; X86-NEXT:    movl %edx, %ebx
239; X86-NEXT:    addl %esi, %eax
240; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
241; X86-NEXT:    adcl %ecx, %ebx
242; X86-NEXT:    setb %cl
243; X86-NEXT:    movl %edi, %eax
244; X86-NEXT:    mull 32(%ebp)
245; X86-NEXT:    addl %ebx, %eax
246; X86-NEXT:    movzbl %cl, %ecx
247; X86-NEXT:    adcl %ecx, %edx
248; X86-NEXT:    addl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Folded Reload
249; X86-NEXT:    adcl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload
250; X86-NEXT:    movl 12(%ebp), %ecx
251; X86-NEXT:    subl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload
252; X86-NEXT:    movl 16(%ebp), %esi
253; X86-NEXT:    sbbl (%esp), %esi # 4-byte Folded Reload
254; X86-NEXT:    movl 20(%ebp), %edi
255; X86-NEXT:    sbbl %eax, %edi
256; X86-NEXT:    movl 24(%ebp), %ebx
257; X86-NEXT:    sbbl %edx, %ebx
258; X86-NEXT:    movl 8(%ebp), %eax
259; X86-NEXT:    movl %ecx, (%eax)
260; X86-NEXT:    movl %esi, 4(%eax)
261; X86-NEXT:    movl %edi, 8(%eax)
262; X86-NEXT:    movl %ebx, 12(%eax)
263; X86-NEXT:    leal -12(%ebp), %esp
264; X86-NEXT:    popl %esi
265; X86-NEXT:    popl %edi
266; X86-NEXT:    popl %ebx
267; X86-NEXT:    popl %ebp
268; X86-NEXT:    retl $4
269;
270; X64-LABEL: scalar_i128:
271; X64:       # %bb.0:
272; X64-NEXT:    pushq %r15
273; X64-NEXT:    pushq %r14
274; X64-NEXT:    pushq %r13
275; X64-NEXT:    pushq %r12
276; X64-NEXT:    pushq %rbx
277; X64-NEXT:    movq %r8, %r14
278; X64-NEXT:    movq %rcx, %rbx
279; X64-NEXT:    movq %rdx, %r15
280; X64-NEXT:    movq %rsi, %r12
281; X64-NEXT:    movq %rdi, %r13
282; X64-NEXT:    callq __udivti3@PLT
283; X64-NEXT:    movq %rdx, %rcx
284; X64-NEXT:    movq %rdx, 8(%r14)
285; X64-NEXT:    movq %rax, (%r14)
286; X64-NEXT:    imulq %rax, %rbx
287; X64-NEXT:    mulq %r15
288; X64-NEXT:    addq %rbx, %rdx
289; X64-NEXT:    imulq %r15, %rcx
290; X64-NEXT:    addq %rdx, %rcx
291; X64-NEXT:    subq %rax, %r13
292; X64-NEXT:    sbbq %rcx, %r12
293; X64-NEXT:    movq %r13, %rax
294; X64-NEXT:    movq %r12, %rdx
295; X64-NEXT:    popq %rbx
296; X64-NEXT:    popq %r12
297; X64-NEXT:    popq %r13
298; X64-NEXT:    popq %r14
299; X64-NEXT:    popq %r15
300; X64-NEXT:    retq
301  %div = udiv i128 %x, %y
302  store i128 %div, ptr %divdst, align 4
303  %t1 = mul i128 %div, %y
304  %t2 = sub i128 %x, %t1
305  ret i128 %t2
306}
307
308define <16 x i8> @vector_i128_i8(<16 x i8> %x, <16 x i8> %y, ptr %divdst) nounwind {
309; X86-LABEL: vector_i128_i8:
310; X86:       # %bb.0:
311; X86-NEXT:    pushl %ebp
312; X86-NEXT:    movl %esp, %ebp
313; X86-NEXT:    pushl %ebx
314; X86-NEXT:    pushl %edi
315; X86-NEXT:    pushl %esi
316; X86-NEXT:    andl $-16, %esp
317; X86-NEXT:    subl $48, %esp
318; X86-NEXT:    movdqa %xmm0, (%esp)
319; X86-NEXT:    movdqa %xmm1, {{[0-9]+}}(%esp)
320; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
321; X86-NEXT:    divb {{[0-9]+}}(%esp)
322; X86-NEXT:    movzbl %al, %eax
323; X86-NEXT:    movd %eax, %xmm2
324; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
325; X86-NEXT:    divb {{[0-9]+}}(%esp)
326; X86-NEXT:    movzbl %al, %eax
327; X86-NEXT:    movd %eax, %xmm3
328; X86-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3],xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7]
329; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
330; X86-NEXT:    divb {{[0-9]+}}(%esp)
331; X86-NEXT:    movzbl %al, %eax
332; X86-NEXT:    movd %eax, %xmm4
333; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
334; X86-NEXT:    divb {{[0-9]+}}(%esp)
335; X86-NEXT:    movzbl %al, %eax
336; X86-NEXT:    movd %eax, %xmm2
337; X86-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3],xmm2[4],xmm4[4],xmm2[5],xmm4[5],xmm2[6],xmm4[6],xmm2[7],xmm4[7]
338; X86-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1],xmm2[2],xmm3[2],xmm2[3],xmm3[3]
339; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
340; X86-NEXT:    divb {{[0-9]+}}(%esp)
341; X86-NEXT:    movzbl %al, %eax
342; X86-NEXT:    movd %eax, %xmm3
343; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
344; X86-NEXT:    divb {{[0-9]+}}(%esp)
345; X86-NEXT:    movzbl %al, %eax
346; X86-NEXT:    movd %eax, %xmm4
347; X86-NEXT:    punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1],xmm4[2],xmm3[2],xmm4[3],xmm3[3],xmm4[4],xmm3[4],xmm4[5],xmm3[5],xmm4[6],xmm3[6],xmm4[7],xmm3[7]
348; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
349; X86-NEXT:    divb {{[0-9]+}}(%esp)
350; X86-NEXT:    movzbl %al, %eax
351; X86-NEXT:    movd %eax, %xmm5
352; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
353; X86-NEXT:    divb {{[0-9]+}}(%esp)
354; X86-NEXT:    movzbl %al, %eax
355; X86-NEXT:    movd %eax, %xmm3
356; X86-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1],xmm3[2],xmm5[2],xmm3[3],xmm5[3],xmm3[4],xmm5[4],xmm3[5],xmm5[5],xmm3[6],xmm5[6],xmm3[7],xmm5[7]
357; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
358; X86-NEXT:    divb {{[0-9]+}}(%esp)
359; X86-NEXT:    movzbl %al, %eax
360; X86-NEXT:    movd %eax, %xmm5
361; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
362; X86-NEXT:    divb {{[0-9]+}}(%esp)
363; X86-NEXT:    movzbl %al, %eax
364; X86-NEXT:    movd %eax, %xmm6
365; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
366; X86-NEXT:    divb {{[0-9]+}}(%esp)
367; X86-NEXT:    movzbl %al, %edx
368; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
369; X86-NEXT:    divb {{[0-9]+}}(%esp)
370; X86-NEXT:    movzbl %al, %esi
371; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
372; X86-NEXT:    divb {{[0-9]+}}(%esp)
373; X86-NEXT:    movzbl %al, %edi
374; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
375; X86-NEXT:    divb {{[0-9]+}}(%esp)
376; X86-NEXT:    movzbl %al, %ebx
377; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
378; X86-NEXT:    divb {{[0-9]+}}(%esp)
379; X86-NEXT:    movl %eax, %ecx
380; X86-NEXT:    movzbl (%esp), %eax
381; X86-NEXT:    divb {{[0-9]+}}(%esp)
382; X86-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3]
383; X86-NEXT:    movd %edx, %xmm4
384; X86-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
385; X86-NEXT:    movd %esi, %xmm7
386; X86-NEXT:    punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1],xmm6[2],xmm5[2],xmm6[3],xmm5[3],xmm6[4],xmm5[4],xmm6[5],xmm5[5],xmm6[6],xmm5[6],xmm6[7],xmm5[7]
387; X86-NEXT:    movd %edi, %xmm2
388; X86-NEXT:    punpcklbw {{.*#+}} xmm7 = xmm7[0],xmm4[0],xmm7[1],xmm4[1],xmm7[2],xmm4[2],xmm7[3],xmm4[3],xmm7[4],xmm4[4],xmm7[5],xmm4[5],xmm7[6],xmm4[6],xmm7[7],xmm4[7]
389; X86-NEXT:    punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm6[0],xmm7[1],xmm6[1],xmm7[2],xmm6[2],xmm7[3],xmm6[3]
390; X86-NEXT:    movd %ebx, %xmm4
391; X86-NEXT:    movzbl %cl, %ecx
392; X86-NEXT:    movd %ecx, %xmm5
393; X86-NEXT:    movl 8(%ebp), %ecx
394; X86-NEXT:    punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm2[0],xmm4[1],xmm2[1],xmm4[2],xmm2[2],xmm4[3],xmm2[3],xmm4[4],xmm2[4],xmm4[5],xmm2[5],xmm4[6],xmm2[6],xmm4[7],xmm2[7]
395; X86-NEXT:    movzbl %al, %eax
396; X86-NEXT:    movd %eax, %xmm2
397; X86-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm5[0],xmm2[1],xmm5[1],xmm2[2],xmm5[2],xmm2[3],xmm5[3],xmm2[4],xmm5[4],xmm2[5],xmm5[5],xmm2[6],xmm5[6],xmm2[7],xmm5[7]
398; X86-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]
399; X86-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm7[0],xmm2[1],xmm7[1]
400; X86-NEXT:    movdqa %xmm2, %xmm4
401; X86-NEXT:    punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm3[0]
402; X86-NEXT:    movdqa %xmm4, (%ecx)
403; X86-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
404; X86-NEXT:    movdqa %xmm1, %xmm4
405; X86-NEXT:    punpckhbw {{.*#+}} xmm4 = xmm4[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
406; X86-NEXT:    pmullw %xmm3, %xmm4
407; X86-NEXT:    movdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255]
408; X86-NEXT:    pand %xmm3, %xmm4
409; X86-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
410; X86-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
411; X86-NEXT:    pmullw %xmm2, %xmm1
412; X86-NEXT:    pand %xmm3, %xmm1
413; X86-NEXT:    packuswb %xmm4, %xmm1
414; X86-NEXT:    psubb %xmm1, %xmm0
415; X86-NEXT:    leal -12(%ebp), %esp
416; X86-NEXT:    popl %esi
417; X86-NEXT:    popl %edi
418; X86-NEXT:    popl %ebx
419; X86-NEXT:    popl %ebp
420; X86-NEXT:    retl
421;
422; X64-LABEL: vector_i128_i8:
423; X64:       # %bb.0:
424; X64-NEXT:    pushq %rbp
425; X64-NEXT:    pushq %r15
426; X64-NEXT:    pushq %r14
427; X64-NEXT:    pushq %r13
428; X64-NEXT:    pushq %r12
429; X64-NEXT:    pushq %rbx
430; X64-NEXT:    movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
431; X64-NEXT:    movdqa %xmm0, -{{[0-9]+}}(%rsp)
432; X64-NEXT:    movdqa %xmm1, -{{[0-9]+}}(%rsp)
433; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
434; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
435; X64-NEXT:    movzbl %al, %eax
436; X64-NEXT:    movd %eax, %xmm2
437; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
438; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
439; X64-NEXT:    movzbl %al, %r8d
440; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
441; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
442; X64-NEXT:    movzbl %al, %r9d
443; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
444; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
445; X64-NEXT:    movzbl %al, %r10d
446; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
447; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
448; X64-NEXT:    movzbl %al, %r11d
449; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
450; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
451; X64-NEXT:    movzbl %al, %r14d
452; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
453; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
454; X64-NEXT:    movzbl %al, %r15d
455; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
456; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
457; X64-NEXT:    movzbl %al, %r12d
458; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
459; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
460; X64-NEXT:    movzbl %al, %r13d
461; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
462; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
463; X64-NEXT:    movzbl %al, %edi
464; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
465; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
466; X64-NEXT:    movzbl %al, %esi
467; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
468; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
469; X64-NEXT:    movzbl %al, %ebx
470; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
471; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
472; X64-NEXT:    movzbl %al, %ebp
473; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
474; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
475; X64-NEXT:    movzbl %al, %edx
476; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
477; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
478; X64-NEXT:    movl %eax, %ecx
479; X64-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
480; X64-NEXT:    divb -{{[0-9]+}}(%rsp)
481; X64-NEXT:    movd %r8d, %xmm3
482; X64-NEXT:    movd %r9d, %xmm4
483; X64-NEXT:    movd %r10d, %xmm5
484; X64-NEXT:    movd %r11d, %xmm6
485; X64-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3],xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7]
486; X64-NEXT:    movd %r14d, %xmm2
487; X64-NEXT:    punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3],xmm5[4],xmm4[4],xmm5[5],xmm4[5],xmm5[6],xmm4[6],xmm5[7],xmm4[7]
488; X64-NEXT:    movd %r15d, %xmm4
489; X64-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1],xmm5[2],xmm3[2],xmm5[3],xmm3[3]
490; X64-NEXT:    movd %r12d, %xmm3
491; X64-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7]
492; X64-NEXT:    movd %r13d, %xmm6
493; X64-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3],xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7]
494; X64-NEXT:    movd %edi, %xmm4
495; X64-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3]
496; X64-NEXT:    movd %esi, %xmm2
497; X64-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm5[0],xmm3[1],xmm5[1]
498; X64-NEXT:    movd %ebx, %xmm5
499; X64-NEXT:    punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3],xmm4[4],xmm6[4],xmm4[5],xmm6[5],xmm4[6],xmm6[6],xmm4[7],xmm6[7]
500; X64-NEXT:    movd %ebp, %xmm6
501; X64-NEXT:    punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm2[0],xmm5[1],xmm2[1],xmm5[2],xmm2[2],xmm5[3],xmm2[3],xmm5[4],xmm2[4],xmm5[5],xmm2[5],xmm5[6],xmm2[6],xmm5[7],xmm2[7]
502; X64-NEXT:    movd %edx, %xmm2
503; X64-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3]
504; X64-NEXT:    movzbl %cl, %ecx
505; X64-NEXT:    movd %ecx, %xmm4
506; X64-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm6[0],xmm2[1],xmm6[1],xmm2[2],xmm6[2],xmm2[3],xmm6[3],xmm2[4],xmm6[4],xmm2[5],xmm6[5],xmm2[6],xmm6[6],xmm2[7],xmm6[7]
507; X64-NEXT:    movzbl %al, %eax
508; X64-NEXT:    movd %eax, %xmm6
509; X64-NEXT:    punpcklbw {{.*#+}} xmm6 = xmm6[0],xmm4[0],xmm6[1],xmm4[1],xmm6[2],xmm4[2],xmm6[3],xmm4[3],xmm6[4],xmm4[4],xmm6[5],xmm4[5],xmm6[6],xmm4[6],xmm6[7],xmm4[7]
510; X64-NEXT:    punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm2[0],xmm6[1],xmm2[1],xmm6[2],xmm2[2],xmm6[3],xmm2[3]
511; X64-NEXT:    punpckldq {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1]
512; X64-NEXT:    movdqa %xmm6, %xmm2
513; X64-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
514; X64-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
515; X64-NEXT:    movdqa %xmm2, (%rax)
516; X64-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
517; X64-NEXT:    movdqa %xmm1, %xmm2
518; X64-NEXT:    punpckhbw {{.*#+}} xmm2 = xmm2[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
519; X64-NEXT:    pmullw %xmm3, %xmm2
520; X64-NEXT:    movdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255]
521; X64-NEXT:    pand %xmm3, %xmm2
522; X64-NEXT:    punpcklbw {{.*#+}} xmm6 = xmm6[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
523; X64-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
524; X64-NEXT:    pmullw %xmm6, %xmm1
525; X64-NEXT:    pand %xmm3, %xmm1
526; X64-NEXT:    packuswb %xmm2, %xmm1
527; X64-NEXT:    psubb %xmm1, %xmm0
528; X64-NEXT:    popq %rbx
529; X64-NEXT:    popq %r12
530; X64-NEXT:    popq %r13
531; X64-NEXT:    popq %r14
532; X64-NEXT:    popq %r15
533; X64-NEXT:    popq %rbp
534; X64-NEXT:    retq
535  %div = udiv <16 x i8> %x, %y
536  store <16 x i8> %div, ptr %divdst, align 16
537  %t1 = mul <16 x i8> %div, %y
538  %t2 = sub <16 x i8> %x, %t1
539  ret <16 x i8> %t2
540}
541
542define <8 x i16> @vector_i128_i16(<8 x i16> %x, <8 x i16> %y, ptr %divdst) nounwind {
543; X86-LABEL: vector_i128_i16:
544; X86:       # %bb.0:
545; X86-NEXT:    pushl %esi
546; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
547; X86-NEXT:    pextrw $7, %xmm0, %eax
548; X86-NEXT:    pextrw $7, %xmm1, %esi
549; X86-NEXT:    # kill: def $ax killed $ax killed $eax
550; X86-NEXT:    xorl %edx, %edx
551; X86-NEXT:    divw %si
552; X86-NEXT:    # kill: def $ax killed $ax def $eax
553; X86-NEXT:    movd %eax, %xmm2
554; X86-NEXT:    pextrw $6, %xmm0, %eax
555; X86-NEXT:    pextrw $6, %xmm1, %esi
556; X86-NEXT:    # kill: def $ax killed $ax killed $eax
557; X86-NEXT:    xorl %edx, %edx
558; X86-NEXT:    divw %si
559; X86-NEXT:    # kill: def $ax killed $ax def $eax
560; X86-NEXT:    movd %eax, %xmm3
561; X86-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3]
562; X86-NEXT:    pextrw $5, %xmm0, %eax
563; X86-NEXT:    pextrw $5, %xmm1, %esi
564; X86-NEXT:    # kill: def $ax killed $ax killed $eax
565; X86-NEXT:    xorl %edx, %edx
566; X86-NEXT:    divw %si
567; X86-NEXT:    # kill: def $ax killed $ax def $eax
568; X86-NEXT:    movd %eax, %xmm4
569; X86-NEXT:    pextrw $4, %xmm0, %eax
570; X86-NEXT:    pextrw $4, %xmm1, %esi
571; X86-NEXT:    # kill: def $ax killed $ax killed $eax
572; X86-NEXT:    xorl %edx, %edx
573; X86-NEXT:    divw %si
574; X86-NEXT:    # kill: def $ax killed $ax def $eax
575; X86-NEXT:    movd %eax, %xmm2
576; X86-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]
577; X86-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
578; X86-NEXT:    pextrw $3, %xmm0, %eax
579; X86-NEXT:    pextrw $3, %xmm1, %esi
580; X86-NEXT:    # kill: def $ax killed $ax killed $eax
581; X86-NEXT:    xorl %edx, %edx
582; X86-NEXT:    divw %si
583; X86-NEXT:    # kill: def $ax killed $ax def $eax
584; X86-NEXT:    movd %eax, %xmm4
585; X86-NEXT:    pextrw $2, %xmm0, %eax
586; X86-NEXT:    pextrw $2, %xmm1, %esi
587; X86-NEXT:    # kill: def $ax killed $ax killed $eax
588; X86-NEXT:    xorl %edx, %edx
589; X86-NEXT:    divw %si
590; X86-NEXT:    # kill: def $ax killed $ax def $eax
591; X86-NEXT:    movd %eax, %xmm3
592; X86-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1],xmm3[2],xmm4[2],xmm3[3],xmm4[3]
593; X86-NEXT:    pextrw $1, %xmm0, %eax
594; X86-NEXT:    pextrw $1, %xmm1, %esi
595; X86-NEXT:    # kill: def $ax killed $ax killed $eax
596; X86-NEXT:    xorl %edx, %edx
597; X86-NEXT:    divw %si
598; X86-NEXT:    # kill: def $ax killed $ax def $eax
599; X86-NEXT:    movd %eax, %xmm4
600; X86-NEXT:    movd %xmm0, %eax
601; X86-NEXT:    movd %xmm1, %esi
602; X86-NEXT:    # kill: def $ax killed $ax killed $eax
603; X86-NEXT:    xorl %edx, %edx
604; X86-NEXT:    divw %si
605; X86-NEXT:    # kill: def $ax killed $ax def $eax
606; X86-NEXT:    movd %eax, %xmm5
607; X86-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3]
608; X86-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1]
609; X86-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm2[0]
610; X86-NEXT:    movdqa %xmm5, (%ecx)
611; X86-NEXT:    pmullw %xmm1, %xmm5
612; X86-NEXT:    psubw %xmm5, %xmm0
613; X86-NEXT:    popl %esi
614; X86-NEXT:    retl
615;
616; X64-LABEL: vector_i128_i16:
617; X64:       # %bb.0:
618; X64-NEXT:    pextrw $7, %xmm0, %eax
619; X64-NEXT:    pextrw $7, %xmm1, %ecx
620; X64-NEXT:    # kill: def $ax killed $ax killed $eax
621; X64-NEXT:    xorl %edx, %edx
622; X64-NEXT:    divw %cx
623; X64-NEXT:    # kill: def $ax killed $ax def $eax
624; X64-NEXT:    movd %eax, %xmm2
625; X64-NEXT:    pextrw $6, %xmm0, %eax
626; X64-NEXT:    pextrw $6, %xmm1, %ecx
627; X64-NEXT:    # kill: def $ax killed $ax killed $eax
628; X64-NEXT:    xorl %edx, %edx
629; X64-NEXT:    divw %cx
630; X64-NEXT:    # kill: def $ax killed $ax def $eax
631; X64-NEXT:    movd %eax, %xmm3
632; X64-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3]
633; X64-NEXT:    pextrw $5, %xmm0, %eax
634; X64-NEXT:    pextrw $5, %xmm1, %ecx
635; X64-NEXT:    # kill: def $ax killed $ax killed $eax
636; X64-NEXT:    xorl %edx, %edx
637; X64-NEXT:    divw %cx
638; X64-NEXT:    # kill: def $ax killed $ax def $eax
639; X64-NEXT:    movd %eax, %xmm4
640; X64-NEXT:    pextrw $4, %xmm0, %eax
641; X64-NEXT:    pextrw $4, %xmm1, %ecx
642; X64-NEXT:    # kill: def $ax killed $ax killed $eax
643; X64-NEXT:    xorl %edx, %edx
644; X64-NEXT:    divw %cx
645; X64-NEXT:    # kill: def $ax killed $ax def $eax
646; X64-NEXT:    movd %eax, %xmm2
647; X64-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]
648; X64-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
649; X64-NEXT:    pextrw $3, %xmm0, %eax
650; X64-NEXT:    pextrw $3, %xmm1, %ecx
651; X64-NEXT:    # kill: def $ax killed $ax killed $eax
652; X64-NEXT:    xorl %edx, %edx
653; X64-NEXT:    divw %cx
654; X64-NEXT:    # kill: def $ax killed $ax def $eax
655; X64-NEXT:    movd %eax, %xmm3
656; X64-NEXT:    pextrw $2, %xmm0, %eax
657; X64-NEXT:    pextrw $2, %xmm1, %ecx
658; X64-NEXT:    # kill: def $ax killed $ax killed $eax
659; X64-NEXT:    xorl %edx, %edx
660; X64-NEXT:    divw %cx
661; X64-NEXT:    # kill: def $ax killed $ax def $eax
662; X64-NEXT:    movd %eax, %xmm4
663; X64-NEXT:    punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1],xmm4[2],xmm3[2],xmm4[3],xmm3[3]
664; X64-NEXT:    pextrw $1, %xmm0, %eax
665; X64-NEXT:    pextrw $1, %xmm1, %ecx
666; X64-NEXT:    # kill: def $ax killed $ax killed $eax
667; X64-NEXT:    xorl %edx, %edx
668; X64-NEXT:    divw %cx
669; X64-NEXT:    # kill: def $ax killed $ax def $eax
670; X64-NEXT:    movd %eax, %xmm3
671; X64-NEXT:    movd %xmm0, %eax
672; X64-NEXT:    movd %xmm1, %ecx
673; X64-NEXT:    # kill: def $ax killed $ax killed $eax
674; X64-NEXT:    xorl %edx, %edx
675; X64-NEXT:    divw %cx
676; X64-NEXT:    # kill: def $ax killed $ax def $eax
677; X64-NEXT:    movd %eax, %xmm5
678; X64-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1],xmm5[2],xmm3[2],xmm5[3],xmm3[3]
679; X64-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1]
680; X64-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm2[0]
681; X64-NEXT:    movdqa %xmm5, (%rdi)
682; X64-NEXT:    pmullw %xmm1, %xmm5
683; X64-NEXT:    psubw %xmm5, %xmm0
684; X64-NEXT:    retq
685  %div = udiv <8 x i16> %x, %y
686  store <8 x i16> %div, ptr %divdst, align 16
687  %t1 = mul <8 x i16> %div, %y
688  %t2 = sub <8 x i16> %x, %t1
689  ret <8 x i16> %t2
690}
691
692define <4 x i32> @vector_i128_i32(<4 x i32> %x, <4 x i32> %y, ptr %divdst) nounwind {
693; X86-LABEL: vector_i128_i32:
694; X86:       # %bb.0:
695; X86-NEXT:    pushl %esi
696; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
697; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3]
698; X86-NEXT:    movd %xmm2, %eax
699; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3]
700; X86-NEXT:    movd %xmm2, %esi
701; X86-NEXT:    xorl %edx, %edx
702; X86-NEXT:    divl %esi
703; X86-NEXT:    movd %eax, %xmm3
704; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
705; X86-NEXT:    movd %xmm2, %eax
706; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
707; X86-NEXT:    movd %xmm2, %esi
708; X86-NEXT:    xorl %edx, %edx
709; X86-NEXT:    divl %esi
710; X86-NEXT:    movd %eax, %xmm2
711; X86-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
712; X86-NEXT:    movd %xmm0, %eax
713; X86-NEXT:    movd %xmm1, %esi
714; X86-NEXT:    xorl %edx, %edx
715; X86-NEXT:    divl %esi
716; X86-NEXT:    movd %eax, %xmm3
717; X86-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]
718; X86-NEXT:    movd %xmm4, %eax
719; X86-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1]
720; X86-NEXT:    movd %xmm4, %esi
721; X86-NEXT:    xorl %edx, %edx
722; X86-NEXT:    divl %esi
723; X86-NEXT:    movd %eax, %xmm4
724; X86-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
725; X86-NEXT:    punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm2[0]
726; X86-NEXT:    movdqa %xmm3, (%ecx)
727; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm3[1,1,3,3]
728; X86-NEXT:    pmuludq %xmm1, %xmm3
729; X86-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
730; X86-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
731; X86-NEXT:    pmuludq %xmm2, %xmm1
732; X86-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
733; X86-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1]
734; X86-NEXT:    psubd %xmm3, %xmm0
735; X86-NEXT:    popl %esi
736; X86-NEXT:    retl
737;
738; X64-LABEL: vector_i128_i32:
739; X64:       # %bb.0:
740; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,3,3,3]
741; X64-NEXT:    movd %xmm2, %eax
742; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3]
743; X64-NEXT:    movd %xmm2, %ecx
744; X64-NEXT:    xorl %edx, %edx
745; X64-NEXT:    divl %ecx
746; X64-NEXT:    movd %eax, %xmm2
747; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,2,3]
748; X64-NEXT:    movd %xmm3, %eax
749; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3]
750; X64-NEXT:    movd %xmm3, %ecx
751; X64-NEXT:    xorl %edx, %edx
752; X64-NEXT:    divl %ecx
753; X64-NEXT:    movd %eax, %xmm3
754; X64-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
755; X64-NEXT:    movd %xmm0, %eax
756; X64-NEXT:    movd %xmm1, %ecx
757; X64-NEXT:    xorl %edx, %edx
758; X64-NEXT:    divl %ecx
759; X64-NEXT:    movd %eax, %xmm2
760; X64-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,1,1]
761; X64-NEXT:    movd %xmm4, %eax
762; X64-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[1,1,1,1]
763; X64-NEXT:    movd %xmm4, %ecx
764; X64-NEXT:    xorl %edx, %edx
765; X64-NEXT:    divl %ecx
766; X64-NEXT:    movd %eax, %xmm4
767; X64-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
768; X64-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
769; X64-NEXT:    movdqa %xmm2, (%rdi)
770; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
771; X64-NEXT:    pmuludq %xmm1, %xmm2
772; X64-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
773; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
774; X64-NEXT:    pmuludq %xmm3, %xmm1
775; X64-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
776; X64-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
777; X64-NEXT:    psubd %xmm2, %xmm0
778; X64-NEXT:    retq
779  %div = udiv <4 x i32> %x, %y
780  store <4 x i32> %div, ptr %divdst, align 16
781  %t1 = mul <4 x i32> %div, %y
782  %t2 = sub <4 x i32> %x, %t1
783  ret <4 x i32> %t2
784}
785
786define <2 x i64> @vector_i128_i64(<2 x i64> %x, <2 x i64> %y, ptr %divdst) nounwind {
787; X86-LABEL: vector_i128_i64:
788; X86:       # %bb.0:
789; X86-NEXT:    pushl %esi
790; X86-NEXT:    subl $64, %esp
791; X86-NEXT:    movdqu %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
792; X86-NEXT:    movdqu %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
793; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
794; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3]
795; X86-NEXT:    movd %xmm2, {{[0-9]+}}(%esp)
796; X86-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[2,3,2,3]
797; X86-NEXT:    movd %xmm2, {{[0-9]+}}(%esp)
798; X86-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[3,3,3,3]
799; X86-NEXT:    movd %xmm1, {{[0-9]+}}(%esp)
800; X86-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
801; X86-NEXT:    movd %xmm1, (%esp)
802; X86-NEXT:    calll __udivdi3
803; X86-NEXT:    movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload
804; X86-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
805; X86-NEXT:    movd %xmm0, {{[0-9]+}}(%esp)
806; X86-NEXT:    movd %xmm1, {{[0-9]+}}(%esp)
807; X86-NEXT:    movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Reload
808; X86-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
809; X86-NEXT:    movd %xmm0, {{[0-9]+}}(%esp)
810; X86-NEXT:    movd %xmm1, (%esp)
811; X86-NEXT:    movd %edx, %xmm0
812; X86-NEXT:    movd %eax, %xmm1
813; X86-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
814; X86-NEXT:    movdqu %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
815; X86-NEXT:    calll __udivdi3
816; X86-NEXT:    movd %edx, %xmm1
817; X86-NEXT:    movd %eax, %xmm3
818; X86-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1]
819; X86-NEXT:    movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
820; X86-NEXT:    punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0]
821; X86-NEXT:    movdqa %xmm3, (%esi)
822; X86-NEXT:    movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
823; X86-NEXT:    movdqa %xmm0, %xmm1
824; X86-NEXT:    psrlq $32, %xmm1
825; X86-NEXT:    pmuludq %xmm3, %xmm1
826; X86-NEXT:    movdqa %xmm3, %xmm2
827; X86-NEXT:    psrlq $32, %xmm2
828; X86-NEXT:    pmuludq %xmm0, %xmm2
829; X86-NEXT:    paddq %xmm1, %xmm2
830; X86-NEXT:    psllq $32, %xmm2
831; X86-NEXT:    pmuludq %xmm0, %xmm3
832; X86-NEXT:    paddq %xmm2, %xmm3
833; X86-NEXT:    movdqu {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
834; X86-NEXT:    psubq %xmm3, %xmm0
835; X86-NEXT:    addl $64, %esp
836; X86-NEXT:    popl %esi
837; X86-NEXT:    retl
838;
839; X64-LABEL: vector_i128_i64:
840; X64:       # %bb.0:
841; X64-NEXT:    movq %xmm0, %rax
842; X64-NEXT:    movq %xmm1, %rcx
843; X64-NEXT:    xorl %edx, %edx
844; X64-NEXT:    divq %rcx
845; X64-NEXT:    movq %rax, %xmm2
846; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[2,3,2,3]
847; X64-NEXT:    movq %xmm3, %rax
848; X64-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[2,3,2,3]
849; X64-NEXT:    movq %xmm3, %rcx
850; X64-NEXT:    xorl %edx, %edx
851; X64-NEXT:    divq %rcx
852; X64-NEXT:    movq %rax, %xmm3
853; X64-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
854; X64-NEXT:    movdqa %xmm2, (%rdi)
855; X64-NEXT:    movdqa %xmm1, %xmm3
856; X64-NEXT:    psrlq $32, %xmm3
857; X64-NEXT:    pmuludq %xmm2, %xmm3
858; X64-NEXT:    movdqa %xmm2, %xmm4
859; X64-NEXT:    psrlq $32, %xmm4
860; X64-NEXT:    pmuludq %xmm1, %xmm4
861; X64-NEXT:    paddq %xmm3, %xmm4
862; X64-NEXT:    psllq $32, %xmm4
863; X64-NEXT:    pmuludq %xmm1, %xmm2
864; X64-NEXT:    paddq %xmm4, %xmm2
865; X64-NEXT:    psubq %xmm2, %xmm0
866; X64-NEXT:    retq
867  %div = udiv <2 x i64> %x, %y
868  store <2 x i64> %div, ptr %divdst, align 16
869  %t1 = mul <2 x i64> %div, %y
870  %t2 = sub <2 x i64> %x, %t1
871  ret <2 x i64> %t2
872}
873
874; Special tests.
875
876define i32 @scalar_i32_commutative(i32 %x, ptr %ysrc, ptr %divdst) nounwind {
877; X86-LABEL: scalar_i32_commutative:
878; X86:       # %bb.0:
879; X86-NEXT:    pushl %edi
880; X86-NEXT:    pushl %esi
881; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
882; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
883; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
884; X86-NEXT:    movl (%eax), %edi
885; X86-NEXT:    movl %ecx, %eax
886; X86-NEXT:    xorl %edx, %edx
887; X86-NEXT:    divl %edi
888; X86-NEXT:    movl %eax, (%esi)
889; X86-NEXT:    imull %eax, %edi
890; X86-NEXT:    subl %edi, %ecx
891; X86-NEXT:    movl %ecx, %eax
892; X86-NEXT:    popl %esi
893; X86-NEXT:    popl %edi
894; X86-NEXT:    retl
895;
896; X64-LABEL: scalar_i32_commutative:
897; X64:       # %bb.0:
898; X64-NEXT:    movq %rdx, %rcx
899; X64-NEXT:    movl (%rsi), %esi
900; X64-NEXT:    movl %edi, %eax
901; X64-NEXT:    xorl %edx, %edx
902; X64-NEXT:    divl %esi
903; X64-NEXT:    movl %eax, (%rcx)
904; X64-NEXT:    imull %eax, %esi
905; X64-NEXT:    subl %esi, %edi
906; X64-NEXT:    movl %edi, %eax
907; X64-NEXT:    retq
908  %y = load i32, ptr %ysrc, align 4
909  %div = udiv i32 %x, %y
910  store i32 %div, ptr %divdst, align 4
911  %t1 = mul i32 %y, %div ; commutative
912  %t2 = sub i32 %x, %t1
913  ret i32 %t2
914}
915
916; We do not care about extra uses.
917define i32 @extrause(i32 %x, i32 %y, ptr %divdst, ptr %t1dst) nounwind {
918; X86-LABEL: extrause:
919; X86:       # %bb.0:
920; X86-NEXT:    pushl %ebx
921; X86-NEXT:    pushl %edi
922; X86-NEXT:    pushl %esi
923; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
924; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
925; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
926; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
927; X86-NEXT:    movl %ecx, %eax
928; X86-NEXT:    xorl %edx, %edx
929; X86-NEXT:    divl %ebx
930; X86-NEXT:    movl %eax, (%edi)
931; X86-NEXT:    imull %ebx, %eax
932; X86-NEXT:    movl %eax, (%esi)
933; X86-NEXT:    subl %eax, %ecx
934; X86-NEXT:    movl %ecx, %eax
935; X86-NEXT:    popl %esi
936; X86-NEXT:    popl %edi
937; X86-NEXT:    popl %ebx
938; X86-NEXT:    retl
939;
940; X64-LABEL: extrause:
941; X64:       # %bb.0:
942; X64-NEXT:    movq %rdx, %r8
943; X64-NEXT:    movl %edi, %eax
944; X64-NEXT:    xorl %edx, %edx
945; X64-NEXT:    divl %esi
946; X64-NEXT:    movl %eax, (%r8)
947; X64-NEXT:    imull %esi, %eax
948; X64-NEXT:    movl %eax, (%rcx)
949; X64-NEXT:    subl %eax, %edi
950; X64-NEXT:    movl %edi, %eax
951; X64-NEXT:    retq
952  %div = udiv i32 %x, %y
953  store i32 %div, ptr %divdst, align 4
954  %t1 = mul i32 %div, %y
955  store i32 %t1, ptr %t1dst, align 4
956  %t2 = sub i32 %x, %t1
957  ret i32 %t2
958}
959
960; 'rem' should appear next to 'div'.
961define i32 @multiple_bb(i32 %x, i32 %y, ptr %divdst, i1 zeroext %store_urem, ptr %uremdst) nounwind {
962; X86-LABEL: multiple_bb:
963; X86:       # %bb.0:
964; X86-NEXT:    pushl %ebx
965; X86-NEXT:    pushl %edi
966; X86-NEXT:    pushl %esi
967; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
968; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
969; X86-NEXT:    movb {{[0-9]+}}(%esp), %bl
970; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
971; X86-NEXT:    movl %ecx, %eax
972; X86-NEXT:    xorl %edx, %edx
973; X86-NEXT:    divl %esi
974; X86-NEXT:    movl %eax, (%edi)
975; X86-NEXT:    testb %bl, %bl
976; X86-NEXT:    je .LBB11_2
977; X86-NEXT:  # %bb.1: # %do_urem
978; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
979; X86-NEXT:    movl %eax, %edi
980; X86-NEXT:    imull %esi, %edi
981; X86-NEXT:    subl %edi, %ecx
982; X86-NEXT:    movl %ecx, (%edx)
983; X86-NEXT:  .LBB11_2: # %end
984; X86-NEXT:    popl %esi
985; X86-NEXT:    popl %edi
986; X86-NEXT:    popl %ebx
987; X86-NEXT:    retl
988;
989; X64-LABEL: multiple_bb:
990; X64:       # %bb.0:
991; X64-NEXT:    movq %rdx, %r9
992; X64-NEXT:    movl %edi, %eax
993; X64-NEXT:    xorl %edx, %edx
994; X64-NEXT:    divl %esi
995; X64-NEXT:    movl %eax, (%r9)
996; X64-NEXT:    testl %ecx, %ecx
997; X64-NEXT:    je .LBB11_2
998; X64-NEXT:  # %bb.1: # %do_urem
999; X64-NEXT:    movl %eax, %ecx
1000; X64-NEXT:    imull %esi, %ecx
1001; X64-NEXT:    subl %ecx, %edi
1002; X64-NEXT:    movl %edi, (%r8)
1003; X64-NEXT:  .LBB11_2: # %end
1004; X64-NEXT:    retq
1005  %div = udiv i32 %x, %y
1006  store i32 %div, ptr %divdst, align 4
1007  br i1 %store_urem, label %do_urem, label %end
1008do_urem:
1009  %t1 = mul i32 %div, %y
1010  %t2 = sub i32 %x, %t1
1011  store i32 %t2, ptr %uremdst, align 4
1012  br label %end
1013end:
1014  ret i32 %div
1015}
1016
1017define i32 @negative_different_x(i32 %x0, i32 %x1, i32 %y, ptr %divdst) nounwind {
1018; X86-LABEL: negative_different_x:
1019; X86:       # %bb.0:
1020; X86-NEXT:    pushl %edi
1021; X86-NEXT:    pushl %esi
1022; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1023; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1024; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1025; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
1026; X86-NEXT:    xorl %edx, %edx
1027; X86-NEXT:    divl %edi
1028; X86-NEXT:    movl %eax, (%esi)
1029; X86-NEXT:    imull %edi, %eax
1030; X86-NEXT:    subl %eax, %ecx
1031; X86-NEXT:    movl %ecx, %eax
1032; X86-NEXT:    popl %esi
1033; X86-NEXT:    popl %edi
1034; X86-NEXT:    retl
1035;
1036; X64-LABEL: negative_different_x:
1037; X64:       # %bb.0:
1038; X64-NEXT:    movl %edx, %r8d
1039; X64-NEXT:    movl %edi, %eax
1040; X64-NEXT:    xorl %edx, %edx
1041; X64-NEXT:    divl %r8d
1042; X64-NEXT:    movl %eax, (%rcx)
1043; X64-NEXT:    imull %r8d, %eax
1044; X64-NEXT:    subl %eax, %esi
1045; X64-NEXT:    movl %esi, %eax
1046; X64-NEXT:    retq
1047  %div = udiv i32 %x0, %y ; not %x1
1048  store i32 %div, ptr %divdst, align 4
1049  %t1 = mul i32 %div, %y
1050  %t2 = sub i32 %x1, %t1 ; not %x0
1051  ret i32 %t2
1052}
1053
1054define i32 @negative_different_y(i32 %x0, i32 %x1, i32 %y, i32 %z, ptr %divdst) nounwind {
1055; X86-LABEL: negative_different_y:
1056; X86:       # %bb.0:
1057; X86-NEXT:    pushl %esi
1058; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1059; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1060; X86-NEXT:    movl %ecx, %eax
1061; X86-NEXT:    xorl %edx, %edx
1062; X86-NEXT:    divl {{[0-9]+}}(%esp)
1063; X86-NEXT:    movl %eax, (%esi)
1064; X86-NEXT:    imull {{[0-9]+}}(%esp), %eax
1065; X86-NEXT:    subl %eax, %ecx
1066; X86-NEXT:    movl %ecx, %eax
1067; X86-NEXT:    popl %esi
1068; X86-NEXT:    retl
1069;
1070; X64-LABEL: negative_different_y:
1071; X64:       # %bb.0:
1072; X64-NEXT:    movl %edx, %edi
1073; X64-NEXT:    movl %esi, %eax
1074; X64-NEXT:    xorl %edx, %edx
1075; X64-NEXT:    divl %ecx
1076; X64-NEXT:    movl %eax, (%r8)
1077; X64-NEXT:    imull %eax, %edi
1078; X64-NEXT:    subl %edi, %esi
1079; X64-NEXT:    movl %esi, %eax
1080; X64-NEXT:    retq
1081  %div = udiv i32 %x1, %z ; not %x0
1082  store i32 %div, ptr %divdst, align 4
1083  %t1 = mul i32 %div, %y
1084  %t2 = sub i32 %x1, %t1
1085  ret i32 %t2
1086}
1087
1088define i32 @negative_inverted_division(i32 %x0, i32 %x1, i32 %y, ptr %divdst) nounwind {
1089; X86-LABEL: negative_inverted_division:
1090; X86:       # %bb.0:
1091; X86-NEXT:    pushl %esi
1092; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1093; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1094; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1095; X86-NEXT:    xorl %edx, %edx
1096; X86-NEXT:    divl %ecx
1097; X86-NEXT:    movl %eax, (%esi)
1098; X86-NEXT:    imull %ecx, %eax
1099; X86-NEXT:    subl %eax, %ecx
1100; X86-NEXT:    movl %ecx, %eax
1101; X86-NEXT:    popl %esi
1102; X86-NEXT:    retl
1103;
1104; X64-LABEL: negative_inverted_division:
1105; X64:       # %bb.0:
1106; X64-NEXT:    movl %edi, %eax
1107; X64-NEXT:    xorl %edx, %edx
1108; X64-NEXT:    divl %esi
1109; X64-NEXT:    movl %eax, (%rcx)
1110; X64-NEXT:    imull %esi, %eax
1111; X64-NEXT:    subl %eax, %esi
1112; X64-NEXT:    movl %esi, %eax
1113; X64-NEXT:    retq
1114  %div = udiv i32 %x0, %x1 ; inverted division
1115  store i32 %div, ptr %divdst, align 4
1116  %t1 = mul i32 %div, %x1
1117  %t2 = sub i32 %x1, %t1
1118  ret i32 %t2
1119}
1120