1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; Check that a division is bypassed when appropriate only.
3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=atom < %s | FileCheck -check-prefixes=CHECK,ATOM %s
4 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64 < %s | FileCheck -check-prefixes=CHECK,REST,X64 %s
5 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=silvermont < %s | FileCheck -check-prefixes=CHECK,REST,SLM %s
6 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake < %s | FileCheck -check-prefixes=CHECK,REST,SKL %s
7 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=goldmont < %s | FileCheck -check-prefixes=CHECK,REST,GMT %s
8 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=gracemont < %s | FileCheck -check-prefixes=CHECK,REST,GMT %s
9 ; RUN: llc -profile-summary-huge-working-set-size-threshold=1 -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake < %s | FileCheck -check-prefixes=HUGEWS %s
11 ; Verify that div32 is bypassed only for Atoms.
12 define i32 @div32(i32 %a, i32 %b) {
14 ; ATOM: # %bb.0: # %entry
15 ; ATOM-NEXT: movl %edi, %eax
16 ; ATOM-NEXT: orl %esi, %eax
17 ; ATOM-NEXT: testl $-256, %eax
18 ; ATOM-NEXT: je .LBB0_1
20 ; ATOM-NEXT: movl %edi, %eax
22 ; ATOM-NEXT: idivl %esi
25 ; ATOM-NEXT: movzbl %dil, %eax
26 ; ATOM-NEXT: divb %sil
27 ; ATOM-NEXT: movzbl %al, %eax
31 ; REST: # %bb.0: # %entry
32 ; REST-NEXT: movl %edi, %eax
34 ; REST-NEXT: idivl %esi
37 ; HUGEWS-LABEL: div32:
38 ; HUGEWS: # %bb.0: # %entry
39 ; HUGEWS-NEXT: movl %edi, %eax
41 ; HUGEWS-NEXT: idivl %esi
44 %div = sdiv i32 %a, %b
48 ; Verify that div64 is always bypassed.
49 define i64 @div64(i64 %a, i64 %b) {
51 ; ATOM: # %bb.0: # %entry
52 ; ATOM-NEXT: movq %rdi, %rcx
53 ; ATOM-NEXT: movq %rdi, %rax
54 ; ATOM-NEXT: orq %rsi, %rcx
55 ; ATOM-NEXT: shrq $32, %rcx
56 ; ATOM-NEXT: je .LBB1_1
59 ; ATOM-NEXT: idivq %rsi
62 ; ATOM-NEXT: # kill: def $eax killed $eax killed $rax
63 ; ATOM-NEXT: xorl %edx, %edx
64 ; ATOM-NEXT: divl %esi
65 ; ATOM-NEXT: # kill: def $eax killed $eax def $rax
69 ; X64: # %bb.0: # %entry
70 ; X64-NEXT: movq %rdi, %rax
71 ; X64-NEXT: movq %rdi, %rcx
72 ; X64-NEXT: orq %rsi, %rcx
73 ; X64-NEXT: shrq $32, %rcx
74 ; X64-NEXT: je .LBB1_1
77 ; X64-NEXT: idivq %rsi
80 ; X64-NEXT: # kill: def $eax killed $eax killed $rax
81 ; X64-NEXT: xorl %edx, %edx
83 ; X64-NEXT: # kill: def $eax killed $eax def $rax
87 ; SLM: # %bb.0: # %entry
88 ; SLM-NEXT: movq %rdi, %rcx
89 ; SLM-NEXT: movq %rdi, %rax
90 ; SLM-NEXT: orq %rsi, %rcx
91 ; SLM-NEXT: shrq $32, %rcx
92 ; SLM-NEXT: je .LBB1_1
95 ; SLM-NEXT: idivq %rsi
98 ; SLM-NEXT: xorl %edx, %edx
99 ; SLM-NEXT: # kill: def $eax killed $eax killed $rax
100 ; SLM-NEXT: divl %esi
101 ; SLM-NEXT: # kill: def $eax killed $eax def $rax
105 ; SKL: # %bb.0: # %entry
106 ; SKL-NEXT: movq %rdi, %rax
107 ; SKL-NEXT: movq %rdi, %rcx
108 ; SKL-NEXT: orq %rsi, %rcx
109 ; SKL-NEXT: shrq $32, %rcx
110 ; SKL-NEXT: je .LBB1_1
113 ; SKL-NEXT: idivq %rsi
116 ; SKL-NEXT: # kill: def $eax killed $eax killed $rax
117 ; SKL-NEXT: xorl %edx, %edx
118 ; SKL-NEXT: divl %esi
119 ; SKL-NEXT: # kill: def $eax killed $eax def $rax
123 ; GMT: # %bb.0: # %entry
124 ; GMT-NEXT: movq %rdi, %rax
126 ; GMT-NEXT: idivq %rsi
129 ; HUGEWS-LABEL: div64:
130 ; HUGEWS: # %bb.0: # %entry
131 ; HUGEWS-NEXT: movq %rdi, %rax
133 ; HUGEWS-NEXT: idivq %rsi
136 %div = sdiv i64 %a, %b
141 ; Verify that no extra code is generated when optimizing for size.
143 define i64 @div64_optsize(i64 %a, i64 %b) optsize {
144 ; CHECK-LABEL: div64_optsize:
146 ; CHECK-NEXT: movq %rdi, %rax
148 ; CHECK-NEXT: idivq %rsi
151 ; HUGEWS-LABEL: div64_optsize:
153 ; HUGEWS-NEXT: movq %rdi, %rax
155 ; HUGEWS-NEXT: idivq %rsi
157 %div = sdiv i64 %a, %b
161 define i64 @div64_pgso(i64 %a, i64 %b) !prof !15 {
162 ; CHECK-LABEL: div64_pgso:
164 ; CHECK-NEXT: movq %rdi, %rax
166 ; CHECK-NEXT: idivq %rsi
169 ; HUGEWS-LABEL: div64_pgso:
171 ; HUGEWS-NEXT: movq %rdi, %rax
173 ; HUGEWS-NEXT: idivq %rsi
175 %div = sdiv i64 %a, %b
179 define i64 @div64_hugews(i64 %a, i64 %b) {
180 ; ATOM-LABEL: div64_hugews:
182 ; ATOM-NEXT: movq %rdi, %rcx
183 ; ATOM-NEXT: movq %rdi, %rax
184 ; ATOM-NEXT: orq %rsi, %rcx
185 ; ATOM-NEXT: shrq $32, %rcx
186 ; ATOM-NEXT: je .LBB4_1
187 ; ATOM-NEXT: # %bb.2:
189 ; ATOM-NEXT: idivq %rsi
191 ; ATOM-NEXT: .LBB4_1:
192 ; ATOM-NEXT: # kill: def $eax killed $eax killed $rax
193 ; ATOM-NEXT: xorl %edx, %edx
194 ; ATOM-NEXT: divl %esi
195 ; ATOM-NEXT: # kill: def $eax killed $eax def $rax
198 ; X64-LABEL: div64_hugews:
200 ; X64-NEXT: movq %rdi, %rax
201 ; X64-NEXT: movq %rdi, %rcx
202 ; X64-NEXT: orq %rsi, %rcx
203 ; X64-NEXT: shrq $32, %rcx
204 ; X64-NEXT: je .LBB4_1
207 ; X64-NEXT: idivq %rsi
210 ; X64-NEXT: # kill: def $eax killed $eax killed $rax
211 ; X64-NEXT: xorl %edx, %edx
212 ; X64-NEXT: divl %esi
213 ; X64-NEXT: # kill: def $eax killed $eax def $rax
216 ; SLM-LABEL: div64_hugews:
218 ; SLM-NEXT: movq %rdi, %rcx
219 ; SLM-NEXT: movq %rdi, %rax
220 ; SLM-NEXT: orq %rsi, %rcx
221 ; SLM-NEXT: shrq $32, %rcx
222 ; SLM-NEXT: je .LBB4_1
225 ; SLM-NEXT: idivq %rsi
228 ; SLM-NEXT: xorl %edx, %edx
229 ; SLM-NEXT: # kill: def $eax killed $eax killed $rax
230 ; SLM-NEXT: divl %esi
231 ; SLM-NEXT: # kill: def $eax killed $eax def $rax
234 ; SKL-LABEL: div64_hugews:
236 ; SKL-NEXT: movq %rdi, %rax
237 ; SKL-NEXT: movq %rdi, %rcx
238 ; SKL-NEXT: orq %rsi, %rcx
239 ; SKL-NEXT: shrq $32, %rcx
240 ; SKL-NEXT: je .LBB4_1
243 ; SKL-NEXT: idivq %rsi
246 ; SKL-NEXT: # kill: def $eax killed $eax killed $rax
247 ; SKL-NEXT: xorl %edx, %edx
248 ; SKL-NEXT: divl %esi
249 ; SKL-NEXT: # kill: def $eax killed $eax def $rax
252 ; GMT-LABEL: div64_hugews:
254 ; GMT-NEXT: movq %rdi, %rax
256 ; GMT-NEXT: idivq %rsi
259 ; HUGEWS-LABEL: div64_hugews:
261 ; HUGEWS-NEXT: movq %rdi, %rax
263 ; HUGEWS-NEXT: idivq %rsi
265 %div = sdiv i64 %a, %b
269 define i32 @div32_optsize(i32 %a, i32 %b) optsize {
270 ; CHECK-LABEL: div32_optsize:
272 ; CHECK-NEXT: movl %edi, %eax
274 ; CHECK-NEXT: idivl %esi
277 ; HUGEWS-LABEL: div32_optsize:
279 ; HUGEWS-NEXT: movl %edi, %eax
281 ; HUGEWS-NEXT: idivl %esi
283 %div = sdiv i32 %a, %b
287 define i32 @div32_pgso(i32 %a, i32 %b) !prof !15 {
288 ; CHECK-LABEL: div32_pgso:
290 ; CHECK-NEXT: movl %edi, %eax
292 ; CHECK-NEXT: idivl %esi
295 ; HUGEWS-LABEL: div32_pgso:
297 ; HUGEWS-NEXT: movl %edi, %eax
299 ; HUGEWS-NEXT: idivl %esi
301 %div = sdiv i32 %a, %b
305 define i32 @div32_minsize(i32 %a, i32 %b) minsize {
306 ; CHECK-LABEL: div32_minsize:
308 ; CHECK-NEXT: movl %edi, %eax
310 ; CHECK-NEXT: idivl %esi
313 ; HUGEWS-LABEL: div32_minsize:
315 ; HUGEWS-NEXT: movl %edi, %eax
317 ; HUGEWS-NEXT: idivl %esi
319 %div = sdiv i32 %a, %b
323 !llvm.module.flags = !{!1}
324 !1 = !{i32 1, !"ProfileSummary", !2}
325 !2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
326 !3 = !{!"ProfileFormat", !"InstrProf"}
327 !4 = !{!"TotalCount", i64 10000}
328 !5 = !{!"MaxCount", i64 1000}
329 !6 = !{!"MaxInternalCount", i64 1}
330 !7 = !{!"MaxFunctionCount", i64 1000}
331 !8 = !{!"NumCounts", i64 3}
332 !9 = !{!"NumFunctions", i64 3}
333 !10 = !{!"DetailedSummary", !11}
334 !11 = !{!12, !13, !14}
335 !12 = !{i32 10000, i64 1000, i32 1}
336 !13 = !{i32 999000, i64 1000, i32 3}
337 !14 = !{i32 999999, i64 5, i32 3}
338 !15 = !{!"function_entry_count", i64 0}