xref: /llvm-project/llvm/test/CodeGen/X86/bypass-slow-division-32.ll (revision f1d8345a2ab3c343929212d1c62174cfaa46e71a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; Check that 32-bit division is bypassed correctly.
3; RUN: llc < %s -mattr=+idivl-to-divb -mtriple=i686-linux | FileCheck %s
4
5define i32 @Test_get_quotient(i32 %a, i32 %b) nounwind {
6; CHECK-LABEL: Test_get_quotient:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
9; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
10; CHECK-NEXT:    movl %eax, %edx
11; CHECK-NEXT:    orl %ecx, %edx
12; CHECK-NEXT:    testl $-256, %edx
13; CHECK-NEXT:    je .LBB0_1
14; CHECK-NEXT:  # %bb.2:
15; CHECK-NEXT:    cltd
16; CHECK-NEXT:    idivl %ecx
17; CHECK-NEXT:    retl
18; CHECK-NEXT:  .LBB0_1:
19; CHECK-NEXT:    movzbl %al, %eax
20; CHECK-NEXT:    divb %cl
21; CHECK-NEXT:    movzbl %al, %eax
22; CHECK-NEXT:    retl
23  %result = sdiv i32 %a, %b
24  ret i32 %result
25}
26
27define i32 @Test_get_remainder(i32 %a, i32 %b) nounwind {
28; CHECK-LABEL: Test_get_remainder:
29; CHECK:       # %bb.0:
30; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
31; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
32; CHECK-NEXT:    movl %eax, %edx
33; CHECK-NEXT:    orl %ecx, %edx
34; CHECK-NEXT:    testl $-256, %edx
35; CHECK-NEXT:    je .LBB1_1
36; CHECK-NEXT:  # %bb.2:
37; CHECK-NEXT:    cltd
38; CHECK-NEXT:    idivl %ecx
39; CHECK-NEXT:    movl %edx, %eax
40; CHECK-NEXT:    retl
41; CHECK-NEXT:  .LBB1_1:
42; CHECK-NEXT:    movzbl %al, %eax
43; CHECK-NEXT:    divb %cl
44; CHECK-NEXT:    movzbl %ah, %eax
45; CHECK-NEXT:    retl
46  %result = srem i32 %a, %b
47  ret i32 %result
48}
49
50define i32 @Test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind {
51; CHECK-LABEL: Test_get_quotient_and_remainder:
52; CHECK:       # %bb.0:
53; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
54; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
55; CHECK-NEXT:    movl %eax, %edx
56; CHECK-NEXT:    orl %ecx, %edx
57; CHECK-NEXT:    testl $-256, %edx
58; CHECK-NEXT:    je .LBB2_1
59; CHECK-NEXT:  # %bb.2:
60; CHECK-NEXT:    cltd
61; CHECK-NEXT:    idivl %ecx
62; CHECK-NEXT:    addl %edx, %eax
63; CHECK-NEXT:    retl
64; CHECK-NEXT:  .LBB2_1:
65; CHECK-NEXT:    movzbl %al, %eax
66; CHECK-NEXT:    divb %cl
67; CHECK-NEXT:    movzbl %ah, %edx
68; CHECK-NEXT:    movzbl %al, %eax
69; CHECK-NEXT:    addl %edx, %eax
70; CHECK-NEXT:    retl
71  %resultdiv = sdiv i32 %a, %b
72  %resultrem = srem i32 %a, %b
73  %result = add i32 %resultdiv, %resultrem
74  ret i32 %result
75}
76
77define i32 @Test_use_div_and_idiv(i32 %a, i32 %b) nounwind {
78; CHECK-LABEL: Test_use_div_and_idiv:
79; CHECK:       # %bb.0:
80; CHECK-NEXT:    pushl %ebx
81; CHECK-NEXT:    pushl %edi
82; CHECK-NEXT:    pushl %esi
83; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ebx
84; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
85; CHECK-NEXT:    movl %ecx, %edi
86; CHECK-NEXT:    orl %ebx, %edi
87; CHECK-NEXT:    testl $-256, %edi
88; CHECK-NEXT:    je .LBB3_1
89; CHECK-NEXT:  # %bb.2:
90; CHECK-NEXT:    movl %ecx, %eax
91; CHECK-NEXT:    cltd
92; CHECK-NEXT:    idivl %ebx
93; CHECK-NEXT:    movl %eax, %esi
94; CHECK-NEXT:    testl $-256, %edi
95; CHECK-NEXT:    je .LBB3_4
96; CHECK-NEXT:  .LBB3_5:
97; CHECK-NEXT:    movl %ecx, %eax
98; CHECK-NEXT:    xorl %edx, %edx
99; CHECK-NEXT:    divl %ebx
100; CHECK-NEXT:    jmp .LBB3_6
101; CHECK-NEXT:  .LBB3_1:
102; CHECK-NEXT:    movzbl %cl, %eax
103; CHECK-NEXT:    divb %bl
104; CHECK-NEXT:    movzbl %al, %esi
105; CHECK-NEXT:    testl $-256, %edi
106; CHECK-NEXT:    jne .LBB3_5
107; CHECK-NEXT:  .LBB3_4:
108; CHECK-NEXT:    movzbl %cl, %eax
109; CHECK-NEXT:    divb %bl
110; CHECK-NEXT:    movzbl %al, %eax
111; CHECK-NEXT:  .LBB3_6:
112; CHECK-NEXT:    addl %eax, %esi
113; CHECK-NEXT:    movl %esi, %eax
114; CHECK-NEXT:    popl %esi
115; CHECK-NEXT:    popl %edi
116; CHECK-NEXT:    popl %ebx
117; CHECK-NEXT:    retl
118  %resultidiv = sdiv i32 %a, %b
119  %resultdiv = udiv i32 %a, %b
120  %result = add i32 %resultidiv, %resultdiv
121  ret i32 %result
122}
123
124define i32 @Test_use_div_imm_imm() nounwind {
125; CHECK-LABEL: Test_use_div_imm_imm:
126; CHECK:       # %bb.0:
127; CHECK-NEXT:    movl $64, %eax
128; CHECK-NEXT:    retl
129  %resultdiv = sdiv i32 256, 4
130  ret i32 %resultdiv
131}
132
133define i32 @Test_use_div_reg_imm(i32 %a) nounwind {
134; CHECK-LABEL: Test_use_div_reg_imm:
135; CHECK:       # %bb.0:
136; CHECK-NEXT:    movl $1041204193, %eax # imm = 0x3E0F83E1
137; CHECK-NEXT:    imull {{[0-9]+}}(%esp)
138; CHECK-NEXT:    movl %edx, %eax
139; CHECK-NEXT:    shrl $31, %eax
140; CHECK-NEXT:    sarl $3, %edx
141; CHECK-NEXT:    addl %edx, %eax
142; CHECK-NEXT:    retl
143  %resultdiv = sdiv i32 %a, 33
144  ret i32 %resultdiv
145}
146
147define i32 @Test_use_rem_reg_imm(i32 %a) nounwind {
148; CHECK-LABEL: Test_use_rem_reg_imm:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
151; CHECK-NEXT:    movl $1041204193, %edx # imm = 0x3E0F83E1
152; CHECK-NEXT:    movl %ecx, %eax
153; CHECK-NEXT:    imull %edx
154; CHECK-NEXT:    movl %edx, %eax
155; CHECK-NEXT:    shrl $31, %eax
156; CHECK-NEXT:    sarl $3, %edx
157; CHECK-NEXT:    addl %eax, %edx
158; CHECK-NEXT:    movl %edx, %eax
159; CHECK-NEXT:    shll $5, %eax
160; CHECK-NEXT:    addl %edx, %eax
161; CHECK-NEXT:    subl %eax, %ecx
162; CHECK-NEXT:    movl %ecx, %eax
163; CHECK-NEXT:    retl
164  %resultrem = srem i32 %a, 33
165  ret i32 %resultrem
166}
167
168define i32 @Test_use_divrem_reg_imm(i32 %a) nounwind {
169; CHECK-LABEL: Test_use_divrem_reg_imm:
170; CHECK:       # %bb.0:
171; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
172; CHECK-NEXT:    movl $1041204193, %edx # imm = 0x3E0F83E1
173; CHECK-NEXT:    movl %ecx, %eax
174; CHECK-NEXT:    imull %edx
175; CHECK-NEXT:    movl %edx, %eax
176; CHECK-NEXT:    shrl $31, %eax
177; CHECK-NEXT:    sarl $3, %edx
178; CHECK-NEXT:    addl %edx, %eax
179; CHECK-NEXT:    movl %eax, %edx
180; CHECK-NEXT:    shll $5, %edx
181; CHECK-NEXT:    addl %eax, %edx
182; CHECK-NEXT:    subl %edx, %ecx
183; CHECK-NEXT:    addl %eax, %ecx
184; CHECK-NEXT:    movl %ecx, %eax
185; CHECK-NEXT:    retl
186  %resultdiv = sdiv i32 %a, 33
187  %resultrem = srem i32 %a, 33
188  %result = add i32 %resultdiv, %resultrem
189  ret i32 %result
190}
191
192define i32 @Test_use_div_imm_reg(i32 %a) nounwind {
193; CHECK-LABEL: Test_use_div_imm_reg:
194; CHECK:       # %bb.0:
195; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
196; CHECK-NEXT:    testl $-256, %ecx
197; CHECK-NEXT:    je .LBB8_1
198; CHECK-NEXT:  # %bb.2:
199; CHECK-NEXT:    movl $4, %eax
200; CHECK-NEXT:    xorl %edx, %edx
201; CHECK-NEXT:    idivl %ecx
202; CHECK-NEXT:    retl
203; CHECK-NEXT:  .LBB8_1:
204; CHECK-NEXT:    movb $4, %al
205; CHECK-NEXT:    movzbl %al, %eax
206; CHECK-NEXT:    divb %cl
207; CHECK-NEXT:    movzbl %al, %eax
208; CHECK-NEXT:    retl
209  %resultdiv = sdiv i32 4, %a
210  ret i32 %resultdiv
211}
212
213define i32 @Test_use_rem_imm_reg(i32 %a) nounwind {
214; CHECK-LABEL: Test_use_rem_imm_reg:
215; CHECK:       # %bb.0:
216; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
217; CHECK-NEXT:    testl $-256, %ecx
218; CHECK-NEXT:    je .LBB9_1
219; CHECK-NEXT:  # %bb.2:
220; CHECK-NEXT:    movl $4, %eax
221; CHECK-NEXT:    xorl %edx, %edx
222; CHECK-NEXT:    idivl %ecx
223; CHECK-NEXT:    retl
224; CHECK-NEXT:  .LBB9_1:
225; CHECK-NEXT:    movb $4, %al
226; CHECK-NEXT:    movzbl %al, %eax
227; CHECK-NEXT:    divb %cl
228; CHECK-NEXT:    movzbl %al, %eax
229; CHECK-NEXT:    retl
230  %resultdiv = sdiv i32 4, %a
231  ret i32 %resultdiv
232}
233