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
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
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
34 define i64 @sdiv_quotient(i64 %a, i64 %b) nounwind {
35 ; FAST-DIVQ-LABEL: sdiv_quotient:
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:
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
63 define i64 @sdiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
64 ; CHECK-LABEL: sdiv_quotient_optsize:
66 ; CHECK-NEXT: movq %rdi, %rax
68 ; CHECK-NEXT: idivq %rsi
70 %result = sdiv i64 %a, %b
74 define i64 @sdiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
75 ; CHECK-LABEL: sdiv_quotient_minsize:
77 ; CHECK-NEXT: movq %rdi, %rax
79 ; CHECK-NEXT: idivq %rsi
81 %result = sdiv i64 %a, %b
85 define i64 @sdiv_remainder(i64 %a, i64 %b) nounwind {
86 ; FAST-DIVQ-LABEL: sdiv_remainder:
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:
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
116 define i64 @sdiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
117 ; CHECK-LABEL: sdiv_remainder_optsize:
119 ; CHECK-NEXT: movq %rdi, %rax
121 ; CHECK-NEXT: idivq %rsi
122 ; CHECK-NEXT: movq %rdx, %rax
124 %result = srem i64 %a, %b
128 define i64 @sdiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
129 ; CHECK-LABEL: sdiv_remainder_minsize:
131 ; CHECK-NEXT: movq %rdi, %rax
133 ; CHECK-NEXT: idivq %rsi
134 ; CHECK-NEXT: movq %rdx, %rax
136 %result = srem i64 %a, %b
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
175 define i64 @sdiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
176 ; CHECK-LABEL: sdiv_quotient_and_remainder_optsize:
178 ; CHECK-NEXT: movq %rdi, %rax
180 ; CHECK-NEXT: idivq %rsi
181 ; CHECK-NEXT: addq %rdx, %rax
183 %resultdiv = sdiv i64 %a, %b
184 %resultrem = srem i64 %a, %b
185 %result = add i64 %resultdiv, %resultrem
189 define i64 @sdiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
190 ; CHECK-LABEL: sdiv_quotient_and_remainder_minsize:
192 ; CHECK-NEXT: movq %rdi, %rax
194 ; CHECK-NEXT: idivq %rsi
195 ; CHECK-NEXT: addq %rdx, %rax
197 %resultdiv = sdiv i64 %a, %b
198 %resultrem = srem i64 %a, %b
199 %result = add i64 %resultdiv, %resultrem
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
236 define i64 @udiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {
237 ; CHECK-LABEL: udiv_quotient_optsize:
239 ; CHECK-NEXT: movq %rdi, %rax
240 ; CHECK-NEXT: xorl %edx, %edx
241 ; CHECK-NEXT: divq %rsi
243 %result = udiv i64 %a, %b
247 define i64 @udiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {
248 ; CHECK-LABEL: udiv_quotient_minsize:
250 ; CHECK-NEXT: movq %rdi, %rax
251 ; CHECK-NEXT: xorl %edx, %edx
252 ; CHECK-NEXT: divq %rsi
254 %result = udiv i64 %a, %b
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
289 define i64 @udiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
290 ; CHECK-LABEL: udiv_remainder_optsize:
292 ; CHECK-NEXT: movq %rdi, %rax
293 ; CHECK-NEXT: xorl %edx, %edx
294 ; CHECK-NEXT: divq %rsi
295 ; CHECK-NEXT: movq %rdx, %rax
297 %result = urem i64 %a, %b
301 define i64 @udiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
302 ; CHECK-LABEL: udiv_remainder_minsize:
304 ; CHECK-NEXT: movq %rdi, %rax
305 ; CHECK-NEXT: xorl %edx, %edx
306 ; CHECK-NEXT: divq %rsi
307 ; CHECK-NEXT: movq %rdx, %rax
309 %result = urem i64 %a, %b
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
348 define i64 @udiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {
349 ; CHECK-LABEL: udiv_quotient_and_remainder_optsize:
351 ; CHECK-NEXT: movq %rdi, %rax
352 ; CHECK-NEXT: xorl %edx, %edx
353 ; CHECK-NEXT: divq %rsi
354 ; CHECK-NEXT: addq %rdx, %rax
356 %resultdiv = udiv i64 %a, %b
357 %resultrem = urem i64 %a, %b
358 %result = add i64 %resultdiv, %resultrem
362 define i64 @udiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {
363 ; CHECK-LABEL: udiv_quotient_and_remainder_minsize:
365 ; CHECK-NEXT: movq %rdi, %rax
366 ; CHECK-NEXT: xorl %edx, %edx
367 ; CHECK-NEXT: divq %rsi
368 ; CHECK-NEXT: addq %rdx, %rax
370 %resultdiv = udiv i64 %a, %b
371 %resultrem = urem i64 %a, %b
372 %result = add i64 %resultdiv, %resultrem
376 define void @PR43514(i32 %x, i32 %y) {
377 ; CHECK-LABEL: PR43514:
380 %z1 = zext i32 %x to i64
381 %z2 = zext i32 %y to i64
382 %s = srem i64 %z1, %z2