Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / X86 / bypass-slow-division-64.ll
blob6e0cfdd26a7866cbf87f6255b451749ec07f6ae1
1 ; Check that 64-bit division is bypassed correctly.
2 ; RUN: llc < %s -mtriple=x86_64-- -mattr=-idivq-to-divl | FileCheck %s --check-prefixes=CHECK,FAST-DIVQ
3 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+idivq-to-divl | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
4 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
5 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2       | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
6 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3       | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
7 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4       | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
8 ; Intel
9 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=nehalem         | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
10 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=sandybridge     | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
11 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=haswell         | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
12 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=skylake         | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
13 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=alderlake       | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
14 ; AMD
15 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=barcelona       | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
16 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=btver1          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
17 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=btver2          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
18 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver1          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
19 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver2          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
20 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver3          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
21 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver4          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
22 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver1          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
23 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver2          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
24 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver3          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
25 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver4          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
27 ; Additional tests for 64-bit divide bypass
30 ; SDIV
33 define i64 @sdiv_quotient(i64 %a, i64 %b) nounwind {
34 ; FAST-DIVQ-LABEL: sdiv_quotient:
35 ; FAST-DIVQ:       # %bb.0:
36 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
37 ; FAST-DIVQ-NEXT:    cqto
38 ; FAST-DIVQ-NEXT:    idivq %rsi
39 ; FAST-DIVQ-NEXT:    retq
41 ; SLOW-DIVQ-LABEL: sdiv_quotient:
42 ; SLOW-DIVQ:       # %bb.0:
43 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
44 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
45 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
46 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
47 ; SLOW-DIVQ-NEXT:    je .LBB0_1
48 ; SLOW-DIVQ-NEXT:  # %bb.2:
49 ; SLOW-DIVQ-NEXT:    cqto
50 ; SLOW-DIVQ-NEXT:    idivq %rsi
51 ; SLOW-DIVQ-NEXT:    retq
52 ; SLOW-DIVQ-NEXT:  .LBB0_1:
53 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
54 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
55 ; SLOW-DIVQ-NEXT:    divl %esi
56 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
57 ; SLOW-DIVQ-NEXT:    retq
58   %result = sdiv i64 %a, %b
59   ret i64 %result
62 define i64 @sdiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
63 ; CHECK-LABEL: sdiv_quotient_optsize:
64 ; CHECK:       # %bb.0:
65 ; CHECK-NEXT:    movq %rdi, %rax
66 ; CHECK-NEXT:    cqto
67 ; CHECK-NEXT:    idivq %rsi
68 ; CHECK-NEXT:    retq
69   %result = sdiv i64 %a, %b
70   ret i64 %result
73 define i64 @sdiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
74 ; CHECK-LABEL: sdiv_quotient_minsize:
75 ; CHECK:       # %bb.0:
76 ; CHECK-NEXT:    movq %rdi, %rax
77 ; CHECK-NEXT:    cqto
78 ; CHECK-NEXT:    idivq %rsi
79 ; CHECK-NEXT:    retq
80   %result = sdiv i64 %a, %b
81   ret i64 %result
84 define i64 @sdiv_remainder(i64 %a, i64 %b) nounwind {
85 ; FAST-DIVQ-LABEL: sdiv_remainder:
86 ; FAST-DIVQ:       # %bb.0:
87 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
88 ; FAST-DIVQ-NEXT:    cqto
89 ; FAST-DIVQ-NEXT:    idivq %rsi
90 ; FAST-DIVQ-NEXT:    movq %rdx, %rax
91 ; FAST-DIVQ-NEXT:    retq
93 ; SLOW-DIVQ-LABEL: sdiv_remainder:
94 ; SLOW-DIVQ:       # %bb.0:
95 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
96 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
97 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
98 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
99 ; SLOW-DIVQ-NEXT:    je .LBB3_1
100 ; SLOW-DIVQ-NEXT:  # %bb.2:
101 ; SLOW-DIVQ-NEXT:    cqto
102 ; SLOW-DIVQ-NEXT:    idivq %rsi
103 ; SLOW-DIVQ-NEXT:    movq %rdx, %rax
104 ; SLOW-DIVQ-NEXT:    retq
105 ; SLOW-DIVQ-NEXT:  .LBB3_1:
106 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
107 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
108 ; SLOW-DIVQ-NEXT:    divl %esi
109 ; SLOW-DIVQ-NEXT:    movl %edx, %eax
110 ; SLOW-DIVQ-NEXT:    retq
111   %result = srem i64 %a, %b
112   ret i64 %result
115 define i64 @sdiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
116 ; CHECK-LABEL: sdiv_remainder_optsize:
117 ; CHECK:       # %bb.0:
118 ; CHECK-NEXT:    movq %rdi, %rax
119 ; CHECK-NEXT:    cqto
120 ; CHECK-NEXT:    idivq %rsi
121 ; CHECK-NEXT:    movq %rdx, %rax
122 ; CHECK-NEXT:    retq
123   %result = srem i64 %a, %b
124   ret i64 %result
127 define i64 @sdiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
128 ; CHECK-LABEL: sdiv_remainder_minsize:
129 ; CHECK:       # %bb.0:
130 ; CHECK-NEXT:    movq %rdi, %rax
131 ; CHECK-NEXT:    cqto
132 ; CHECK-NEXT:    idivq %rsi
133 ; CHECK-NEXT:    movq %rdx, %rax
134 ; CHECK-NEXT:    retq
135   %result = srem i64 %a, %b
136   ret i64 %result
139 define i64 @sdiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {
140 ; FAST-DIVQ-LABEL: sdiv_quotient_and_remainder:
141 ; FAST-DIVQ:       # %bb.0:
142 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
143 ; FAST-DIVQ-NEXT:    cqto
144 ; FAST-DIVQ-NEXT:    idivq %rsi
145 ; FAST-DIVQ-NEXT:    addq %rdx, %rax
146 ; FAST-DIVQ-NEXT:    retq
148 ; SLOW-DIVQ-LABEL: sdiv_quotient_and_remainder:
149 ; SLOW-DIVQ:       # %bb.0:
150 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
151 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
152 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
153 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
154 ; SLOW-DIVQ-NEXT:    je .LBB6_1
155 ; SLOW-DIVQ-NEXT:  # %bb.2:
156 ; SLOW-DIVQ-NEXT:    cqto
157 ; SLOW-DIVQ-NEXT:    idivq %rsi
158 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
159 ; SLOW-DIVQ-NEXT:    retq
160 ; SLOW-DIVQ-NEXT:  .LBB6_1:
161 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
162 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
163 ; SLOW-DIVQ-NEXT:    divl %esi
164 ; SLOW-DIVQ-NEXT:    # kill: def $edx killed $edx def $rdx
165 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
166 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
167 ; SLOW-DIVQ-NEXT:    retq
168   %resultdiv = sdiv i64 %a, %b
169   %resultrem = srem i64 %a, %b
170   %result = add i64 %resultdiv, %resultrem
171   ret i64 %result
174 define i64 @sdiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
175 ; CHECK-LABEL: sdiv_quotient_and_remainder_optsize:
176 ; CHECK:       # %bb.0:
177 ; CHECK-NEXT:    movq %rdi, %rax
178 ; CHECK-NEXT:    cqto
179 ; CHECK-NEXT:    idivq %rsi
180 ; CHECK-NEXT:    addq %rdx, %rax
181 ; CHECK-NEXT:    retq
182   %resultdiv = sdiv i64 %a, %b
183   %resultrem = srem i64 %a, %b
184   %result = add i64 %resultdiv, %resultrem
185   ret i64 %result
188 define i64 @sdiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
189 ; CHECK-LABEL: sdiv_quotient_and_remainder_minsize:
190 ; CHECK:       # %bb.0:
191 ; CHECK-NEXT:    movq %rdi, %rax
192 ; CHECK-NEXT:    cqto
193 ; CHECK-NEXT:    idivq %rsi
194 ; CHECK-NEXT:    addq %rdx, %rax
195 ; CHECK-NEXT:    retq
196   %resultdiv = sdiv i64 %a, %b
197   %resultrem = srem i64 %a, %b
198   %result = add i64 %resultdiv, %resultrem
199   ret i64 %result
203 ; UDIV
206 define i64 @udiv_quotient(i64 %a, i64 %b) nounwind {
207 ; FAST-DIVQ-LABEL: udiv_quotient:
208 ; FAST-DIVQ:       # %bb.0:
209 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
210 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
211 ; FAST-DIVQ-NEXT:    divq %rsi
212 ; FAST-DIVQ-NEXT:    retq
214 ; SLOW-DIVQ-LABEL: udiv_quotient:
215 ; SLOW-DIVQ:       # %bb.0:
216 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
217 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
218 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
219 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
220 ; SLOW-DIVQ-NEXT:    je .LBB9_1
221 ; SLOW-DIVQ-NEXT:  # %bb.2:
222 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
223 ; SLOW-DIVQ-NEXT:    divq %rsi
224 ; SLOW-DIVQ-NEXT:    retq
225 ; SLOW-DIVQ-NEXT:  .LBB9_1:
226 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
227 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
228 ; SLOW-DIVQ-NEXT:    divl %esi
229 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
230 ; SLOW-DIVQ-NEXT:    retq
231   %result = udiv i64 %a, %b
232   ret i64 %result
235 define i64 @udiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
236 ; CHECK-LABEL: udiv_quotient_optsize:
237 ; CHECK:       # %bb.0:
238 ; CHECK-NEXT:    movq %rdi, %rax
239 ; CHECK-NEXT:    xorl %edx, %edx
240 ; CHECK-NEXT:    divq %rsi
241 ; CHECK-NEXT:    retq
242   %result = udiv i64 %a, %b
243   ret i64 %result
246 define i64 @udiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
247 ; CHECK-LABEL: udiv_quotient_minsize:
248 ; CHECK:       # %bb.0:
249 ; CHECK-NEXT:    movq %rdi, %rax
250 ; CHECK-NEXT:    xorl %edx, %edx
251 ; CHECK-NEXT:    divq %rsi
252 ; CHECK-NEXT:    retq
253   %result = udiv i64 %a, %b
254   ret i64 %result
257 define i64 @udiv_remainder(i64 %a, i64 %b) nounwind {
258 ; FAST-DIVQ-LABEL: udiv_remainder:
259 ; FAST-DIVQ:       # %bb.0:
260 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
261 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
262 ; FAST-DIVQ-NEXT:    divq %rsi
263 ; FAST-DIVQ-NEXT:    movq %rdx, %rax
264 ; FAST-DIVQ-NEXT:    retq
266 ; SLOW-DIVQ-LABEL: udiv_remainder:
267 ; SLOW-DIVQ:       # %bb.0:
268 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
269 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
270 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
271 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
272 ; SLOW-DIVQ-NEXT:    je .LBB12_1
273 ; SLOW-DIVQ-NEXT:  # %bb.2:
274 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
275 ; SLOW-DIVQ-NEXT:    divq %rsi
276 ; SLOW-DIVQ-NEXT:    movq %rdx, %rax
277 ; SLOW-DIVQ-NEXT:    retq
278 ; SLOW-DIVQ-NEXT:  .LBB12_1:
279 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
280 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
281 ; SLOW-DIVQ-NEXT:    divl %esi
282 ; SLOW-DIVQ-NEXT:    movl %edx, %eax
283 ; SLOW-DIVQ-NEXT:    retq
284   %result = urem i64 %a, %b
285   ret i64 %result
288 define i64 @udiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
289 ; CHECK-LABEL: udiv_remainder_optsize:
290 ; CHECK:       # %bb.0:
291 ; CHECK-NEXT:    movq %rdi, %rax
292 ; CHECK-NEXT:    xorl %edx, %edx
293 ; CHECK-NEXT:    divq %rsi
294 ; CHECK-NEXT:    movq %rdx, %rax
295 ; CHECK-NEXT:    retq
296   %result = urem i64 %a, %b
297   ret i64 %result
300 define i64 @udiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
301 ; CHECK-LABEL: udiv_remainder_minsize:
302 ; CHECK:       # %bb.0:
303 ; CHECK-NEXT:    movq %rdi, %rax
304 ; CHECK-NEXT:    xorl %edx, %edx
305 ; CHECK-NEXT:    divq %rsi
306 ; CHECK-NEXT:    movq %rdx, %rax
307 ; CHECK-NEXT:    retq
308   %result = urem i64 %a, %b
309   ret i64 %result
312 define i64 @udiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {
313 ; FAST-DIVQ-LABEL: udiv_quotient_and_remainder:
314 ; FAST-DIVQ:       # %bb.0:
315 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
316 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
317 ; FAST-DIVQ-NEXT:    divq %rsi
318 ; FAST-DIVQ-NEXT:    addq %rdx, %rax
319 ; FAST-DIVQ-NEXT:    retq
321 ; SLOW-DIVQ-LABEL: udiv_quotient_and_remainder:
322 ; SLOW-DIVQ:       # %bb.0:
323 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
324 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
325 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
326 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
327 ; SLOW-DIVQ-NEXT:    je .LBB15_1
328 ; SLOW-DIVQ-NEXT:  # %bb.2:
329 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
330 ; SLOW-DIVQ-NEXT:    divq %rsi
331 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
332 ; SLOW-DIVQ-NEXT:    retq
333 ; SLOW-DIVQ-NEXT:  .LBB15_1:
334 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
335 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
336 ; SLOW-DIVQ-NEXT:    divl %esi
337 ; SLOW-DIVQ-NEXT:    # kill: def $edx killed $edx def $rdx
338 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
339 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
340 ; SLOW-DIVQ-NEXT:    retq
341   %resultdiv = udiv i64 %a, %b
342   %resultrem = urem i64 %a, %b
343   %result = add i64 %resultdiv, %resultrem
344   ret i64 %result
347 define i64 @udiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
348 ; CHECK-LABEL: udiv_quotient_and_remainder_optsize:
349 ; CHECK:       # %bb.0:
350 ; CHECK-NEXT:    movq %rdi, %rax
351 ; CHECK-NEXT:    xorl %edx, %edx
352 ; CHECK-NEXT:    divq %rsi
353 ; CHECK-NEXT:    addq %rdx, %rax
354 ; CHECK-NEXT:    retq
355   %resultdiv = udiv i64 %a, %b
356   %resultrem = urem i64 %a, %b
357   %result = add i64 %resultdiv, %resultrem
358   ret i64 %result
361 define i64 @udiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
362 ; CHECK-LABEL: udiv_quotient_and_remainder_minsize:
363 ; CHECK:       # %bb.0:
364 ; CHECK-NEXT:    movq %rdi, %rax
365 ; CHECK-NEXT:    xorl %edx, %edx
366 ; CHECK-NEXT:    divq %rsi
367 ; CHECK-NEXT:    addq %rdx, %rax
368 ; CHECK-NEXT:    retq
369   %resultdiv = udiv i64 %a, %b
370   %resultrem = urem i64 %a, %b
371   %result = add i64 %resultdiv, %resultrem
372   ret i64 %result
375 define void @PR43514(i32 %x, i32 %y) {
376 ; CHECK-LABEL: PR43514:
377 ; CHECK:       # %bb.0:
378 ; CHECK-NEXT:    retq
379   %z1 = zext i32 %x to i64
380   %z2 = zext i32 %y to i64
381   %s = srem i64 %z1, %z2
382   ret void