Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / bypass-slow-division-64.ll
blobb0ca0069a526b7d14a4b038579106d177ab9397a
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
26 ; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver5          | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ
28 ; Additional tests for 64-bit divide bypass
31 ; SDIV
34 define i64 @sdiv_quotient(i64 %a, i64 %b) nounwind {
35 ; FAST-DIVQ-LABEL: sdiv_quotient:
36 ; FAST-DIVQ:       # %bb.0:
37 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
38 ; FAST-DIVQ-NEXT:    cqto
39 ; FAST-DIVQ-NEXT:    idivq %rsi
40 ; FAST-DIVQ-NEXT:    retq
42 ; SLOW-DIVQ-LABEL: sdiv_quotient:
43 ; SLOW-DIVQ:       # %bb.0:
44 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
45 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
46 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
47 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
48 ; SLOW-DIVQ-NEXT:    je .LBB0_1
49 ; SLOW-DIVQ-NEXT:  # %bb.2:
50 ; SLOW-DIVQ-NEXT:    cqto
51 ; SLOW-DIVQ-NEXT:    idivq %rsi
52 ; SLOW-DIVQ-NEXT:    retq
53 ; SLOW-DIVQ-NEXT:  .LBB0_1:
54 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
55 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
56 ; SLOW-DIVQ-NEXT:    divl %esi
57 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
58 ; SLOW-DIVQ-NEXT:    retq
59   %result = sdiv i64 %a, %b
60   ret i64 %result
63 define i64 @sdiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
64 ; CHECK-LABEL: sdiv_quotient_optsize:
65 ; CHECK:       # %bb.0:
66 ; CHECK-NEXT:    movq %rdi, %rax
67 ; CHECK-NEXT:    cqto
68 ; CHECK-NEXT:    idivq %rsi
69 ; CHECK-NEXT:    retq
70   %result = sdiv i64 %a, %b
71   ret i64 %result
74 define i64 @sdiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
75 ; CHECK-LABEL: sdiv_quotient_minsize:
76 ; CHECK:       # %bb.0:
77 ; CHECK-NEXT:    movq %rdi, %rax
78 ; CHECK-NEXT:    cqto
79 ; CHECK-NEXT:    idivq %rsi
80 ; CHECK-NEXT:    retq
81   %result = sdiv i64 %a, %b
82   ret i64 %result
85 define i64 @sdiv_remainder(i64 %a, i64 %b) nounwind {
86 ; FAST-DIVQ-LABEL: sdiv_remainder:
87 ; FAST-DIVQ:       # %bb.0:
88 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
89 ; FAST-DIVQ-NEXT:    cqto
90 ; FAST-DIVQ-NEXT:    idivq %rsi
91 ; FAST-DIVQ-NEXT:    movq %rdx, %rax
92 ; FAST-DIVQ-NEXT:    retq
94 ; SLOW-DIVQ-LABEL: sdiv_remainder:
95 ; SLOW-DIVQ:       # %bb.0:
96 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
97 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
98 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
99 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
100 ; SLOW-DIVQ-NEXT:    je .LBB3_1
101 ; SLOW-DIVQ-NEXT:  # %bb.2:
102 ; SLOW-DIVQ-NEXT:    cqto
103 ; SLOW-DIVQ-NEXT:    idivq %rsi
104 ; SLOW-DIVQ-NEXT:    movq %rdx, %rax
105 ; SLOW-DIVQ-NEXT:    retq
106 ; SLOW-DIVQ-NEXT:  .LBB3_1:
107 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
108 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
109 ; SLOW-DIVQ-NEXT:    divl %esi
110 ; SLOW-DIVQ-NEXT:    movl %edx, %eax
111 ; SLOW-DIVQ-NEXT:    retq
112   %result = srem i64 %a, %b
113   ret i64 %result
116 define i64 @sdiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
117 ; CHECK-LABEL: sdiv_remainder_optsize:
118 ; CHECK:       # %bb.0:
119 ; CHECK-NEXT:    movq %rdi, %rax
120 ; CHECK-NEXT:    cqto
121 ; CHECK-NEXT:    idivq %rsi
122 ; CHECK-NEXT:    movq %rdx, %rax
123 ; CHECK-NEXT:    retq
124   %result = srem i64 %a, %b
125   ret i64 %result
128 define i64 @sdiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
129 ; CHECK-LABEL: sdiv_remainder_minsize:
130 ; CHECK:       # %bb.0:
131 ; CHECK-NEXT:    movq %rdi, %rax
132 ; CHECK-NEXT:    cqto
133 ; CHECK-NEXT:    idivq %rsi
134 ; CHECK-NEXT:    movq %rdx, %rax
135 ; CHECK-NEXT:    retq
136   %result = srem i64 %a, %b
137   ret i64 %result
140 define i64 @sdiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {
141 ; FAST-DIVQ-LABEL: sdiv_quotient_and_remainder:
142 ; FAST-DIVQ:       # %bb.0:
143 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
144 ; FAST-DIVQ-NEXT:    cqto
145 ; FAST-DIVQ-NEXT:    idivq %rsi
146 ; FAST-DIVQ-NEXT:    addq %rdx, %rax
147 ; FAST-DIVQ-NEXT:    retq
149 ; SLOW-DIVQ-LABEL: sdiv_quotient_and_remainder:
150 ; SLOW-DIVQ:       # %bb.0:
151 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
152 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
153 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
154 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
155 ; SLOW-DIVQ-NEXT:    je .LBB6_1
156 ; SLOW-DIVQ-NEXT:  # %bb.2:
157 ; SLOW-DIVQ-NEXT:    cqto
158 ; SLOW-DIVQ-NEXT:    idivq %rsi
159 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
160 ; SLOW-DIVQ-NEXT:    retq
161 ; SLOW-DIVQ-NEXT:  .LBB6_1:
162 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
163 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
164 ; SLOW-DIVQ-NEXT:    divl %esi
165 ; SLOW-DIVQ-NEXT:    # kill: def $edx killed $edx def $rdx
166 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
167 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
168 ; SLOW-DIVQ-NEXT:    retq
169   %resultdiv = sdiv i64 %a, %b
170   %resultrem = srem i64 %a, %b
171   %result = add i64 %resultdiv, %resultrem
172   ret i64 %result
175 define i64 @sdiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
176 ; CHECK-LABEL: sdiv_quotient_and_remainder_optsize:
177 ; CHECK:       # %bb.0:
178 ; CHECK-NEXT:    movq %rdi, %rax
179 ; CHECK-NEXT:    cqto
180 ; CHECK-NEXT:    idivq %rsi
181 ; CHECK-NEXT:    addq %rdx, %rax
182 ; CHECK-NEXT:    retq
183   %resultdiv = sdiv i64 %a, %b
184   %resultrem = srem i64 %a, %b
185   %result = add i64 %resultdiv, %resultrem
186   ret i64 %result
189 define i64 @sdiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
190 ; CHECK-LABEL: sdiv_quotient_and_remainder_minsize:
191 ; CHECK:       # %bb.0:
192 ; CHECK-NEXT:    movq %rdi, %rax
193 ; CHECK-NEXT:    cqto
194 ; CHECK-NEXT:    idivq %rsi
195 ; CHECK-NEXT:    addq %rdx, %rax
196 ; CHECK-NEXT:    retq
197   %resultdiv = sdiv i64 %a, %b
198   %resultrem = srem i64 %a, %b
199   %result = add i64 %resultdiv, %resultrem
200   ret i64 %result
204 ; UDIV
207 define i64 @udiv_quotient(i64 %a, i64 %b) nounwind {
208 ; FAST-DIVQ-LABEL: udiv_quotient:
209 ; FAST-DIVQ:       # %bb.0:
210 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
211 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
212 ; FAST-DIVQ-NEXT:    divq %rsi
213 ; FAST-DIVQ-NEXT:    retq
215 ; SLOW-DIVQ-LABEL: udiv_quotient:
216 ; SLOW-DIVQ:       # %bb.0:
217 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
218 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
219 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
220 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
221 ; SLOW-DIVQ-NEXT:    je .LBB9_1
222 ; SLOW-DIVQ-NEXT:  # %bb.2:
223 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
224 ; SLOW-DIVQ-NEXT:    divq %rsi
225 ; SLOW-DIVQ-NEXT:    retq
226 ; SLOW-DIVQ-NEXT:  .LBB9_1:
227 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
228 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
229 ; SLOW-DIVQ-NEXT:    divl %esi
230 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
231 ; SLOW-DIVQ-NEXT:    retq
232   %result = udiv i64 %a, %b
233   ret i64 %result
236 define i64 @udiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
237 ; CHECK-LABEL: udiv_quotient_optsize:
238 ; CHECK:       # %bb.0:
239 ; CHECK-NEXT:    movq %rdi, %rax
240 ; CHECK-NEXT:    xorl %edx, %edx
241 ; CHECK-NEXT:    divq %rsi
242 ; CHECK-NEXT:    retq
243   %result = udiv i64 %a, %b
244   ret i64 %result
247 define i64 @udiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
248 ; CHECK-LABEL: udiv_quotient_minsize:
249 ; CHECK:       # %bb.0:
250 ; CHECK-NEXT:    movq %rdi, %rax
251 ; CHECK-NEXT:    xorl %edx, %edx
252 ; CHECK-NEXT:    divq %rsi
253 ; CHECK-NEXT:    retq
254   %result = udiv i64 %a, %b
255   ret i64 %result
258 define i64 @udiv_remainder(i64 %a, i64 %b) nounwind {
259 ; FAST-DIVQ-LABEL: udiv_remainder:
260 ; FAST-DIVQ:       # %bb.0:
261 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
262 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
263 ; FAST-DIVQ-NEXT:    divq %rsi
264 ; FAST-DIVQ-NEXT:    movq %rdx, %rax
265 ; FAST-DIVQ-NEXT:    retq
267 ; SLOW-DIVQ-LABEL: udiv_remainder:
268 ; SLOW-DIVQ:       # %bb.0:
269 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
270 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
271 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
272 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
273 ; SLOW-DIVQ-NEXT:    je .LBB12_1
274 ; SLOW-DIVQ-NEXT:  # %bb.2:
275 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
276 ; SLOW-DIVQ-NEXT:    divq %rsi
277 ; SLOW-DIVQ-NEXT:    movq %rdx, %rax
278 ; SLOW-DIVQ-NEXT:    retq
279 ; SLOW-DIVQ-NEXT:  .LBB12_1:
280 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
281 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
282 ; SLOW-DIVQ-NEXT:    divl %esi
283 ; SLOW-DIVQ-NEXT:    movl %edx, %eax
284 ; SLOW-DIVQ-NEXT:    retq
285   %result = urem i64 %a, %b
286   ret i64 %result
289 define i64 @udiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
290 ; CHECK-LABEL: udiv_remainder_optsize:
291 ; CHECK:       # %bb.0:
292 ; CHECK-NEXT:    movq %rdi, %rax
293 ; CHECK-NEXT:    xorl %edx, %edx
294 ; CHECK-NEXT:    divq %rsi
295 ; CHECK-NEXT:    movq %rdx, %rax
296 ; CHECK-NEXT:    retq
297   %result = urem i64 %a, %b
298   ret i64 %result
301 define i64 @udiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
302 ; CHECK-LABEL: udiv_remainder_minsize:
303 ; CHECK:       # %bb.0:
304 ; CHECK-NEXT:    movq %rdi, %rax
305 ; CHECK-NEXT:    xorl %edx, %edx
306 ; CHECK-NEXT:    divq %rsi
307 ; CHECK-NEXT:    movq %rdx, %rax
308 ; CHECK-NEXT:    retq
309   %result = urem i64 %a, %b
310   ret i64 %result
313 define i64 @udiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {
314 ; FAST-DIVQ-LABEL: udiv_quotient_and_remainder:
315 ; FAST-DIVQ:       # %bb.0:
316 ; FAST-DIVQ-NEXT:    movq %rdi, %rax
317 ; FAST-DIVQ-NEXT:    xorl %edx, %edx
318 ; FAST-DIVQ-NEXT:    divq %rsi
319 ; FAST-DIVQ-NEXT:    addq %rdx, %rax
320 ; FAST-DIVQ-NEXT:    retq
322 ; SLOW-DIVQ-LABEL: udiv_quotient_and_remainder:
323 ; SLOW-DIVQ:       # %bb.0:
324 ; SLOW-DIVQ-DAG:     movq %rdi, %rax
325 ; SLOW-DIVQ-DAG:     movq %rdi, %rcx
326 ; SLOW-DIVQ-DAG:     orq %rsi, %rcx
327 ; SLOW-DIVQ-DAG:     shrq $32, %rcx
328 ; SLOW-DIVQ-NEXT:    je .LBB15_1
329 ; SLOW-DIVQ-NEXT:  # %bb.2:
330 ; SLOW-DIVQ-NEXT:    xorl %edx, %edx
331 ; SLOW-DIVQ-NEXT:    divq %rsi
332 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
333 ; SLOW-DIVQ-NEXT:    retq
334 ; SLOW-DIVQ-NEXT:  .LBB15_1:
335 ; SLOW-DIVQ-DAG:     # kill: def $eax killed $eax killed $rax
336 ; SLOW-DIVQ-DAG:     xorl %edx, %edx
337 ; SLOW-DIVQ-NEXT:    divl %esi
338 ; SLOW-DIVQ-NEXT:    # kill: def $edx killed $edx def $rdx
339 ; SLOW-DIVQ-NEXT:    # kill: def $eax killed $eax def $rax
340 ; SLOW-DIVQ-NEXT:    addq %rdx, %rax
341 ; SLOW-DIVQ-NEXT:    retq
342   %resultdiv = udiv i64 %a, %b
343   %resultrem = urem i64 %a, %b
344   %result = add i64 %resultdiv, %resultrem
345   ret i64 %result
348 define i64 @udiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
349 ; CHECK-LABEL: udiv_quotient_and_remainder_optsize:
350 ; CHECK:       # %bb.0:
351 ; CHECK-NEXT:    movq %rdi, %rax
352 ; CHECK-NEXT:    xorl %edx, %edx
353 ; CHECK-NEXT:    divq %rsi
354 ; CHECK-NEXT:    addq %rdx, %rax
355 ; CHECK-NEXT:    retq
356   %resultdiv = udiv i64 %a, %b
357   %resultrem = urem i64 %a, %b
358   %result = add i64 %resultdiv, %resultrem
359   ret i64 %result
362 define i64 @udiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
363 ; CHECK-LABEL: udiv_quotient_and_remainder_minsize:
364 ; CHECK:       # %bb.0:
365 ; CHECK-NEXT:    movq %rdi, %rax
366 ; CHECK-NEXT:    xorl %edx, %edx
367 ; CHECK-NEXT:    divq %rsi
368 ; CHECK-NEXT:    addq %rdx, %rax
369 ; CHECK-NEXT:    retq
370   %resultdiv = udiv i64 %a, %b
371   %resultrem = urem i64 %a, %b
372   %result = add i64 %resultdiv, %resultrem
373   ret i64 %result
376 define void @PR43514(i32 %x, i32 %y) {
377 ; CHECK-LABEL: PR43514:
378 ; CHECK:       # %bb.0:
379 ; CHECK-NEXT:    retq
380   %z1 = zext i32 %x to i64
381   %z2 = zext i32 %y to i64
382   %s = srem i64 %z1, %z2
383   ret void