[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / divide-by-constant.ll
blob23a3d1e095ca793436ab7059eb1e70d9d414bc88
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-pc-linux-gnu | FileCheck %s --check-prefix=X32
3 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64 --check-prefix=X64-FAST
4 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mattr=idivq-to-divl | FileCheck %s --check-prefix=X64 --check-prefix=X64-SLOW
6 define zeroext i16 @test1(i16 zeroext %x) nounwind {
7 ; X32-LABEL: test1:
8 ; X32:       # %bb.0: # %entry
9 ; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
10 ; X32-NEXT:    imull $63551, %eax, %eax # imm = 0xF83F
11 ; X32-NEXT:    shrl $21, %eax
12 ; X32-NEXT:    # kill: def $ax killed $ax killed $eax
13 ; X32-NEXT:    retl
15 ; X64-LABEL: test1:
16 ; X64:       # %bb.0: # %entry
17 ; X64-NEXT:    imull $63551, %edi, %eax # imm = 0xF83F
18 ; X64-NEXT:    shrl $21, %eax
19 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
20 ; X64-NEXT:    retq
21 entry:
22         %div = udiv i16 %x, 33
23         ret i16 %div
26 define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) nounwind readnone ssp noredzone {
27 ; X32-LABEL: test2:
28 ; X32:       # %bb.0: # %entry
29 ; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
30 ; X32-NEXT:    imull $43691, %eax, %eax # imm = 0xAAAB
31 ; X32-NEXT:    shrl $17, %eax
32 ; X32-NEXT:    # kill: def $ax killed $ax killed $eax
33 ; X32-NEXT:    retl
35 ; X64-LABEL: test2:
36 ; X64:       # %bb.0: # %entry
37 ; X64-NEXT:    imull $43691, %esi, %eax # imm = 0xAAAB
38 ; X64-NEXT:    shrl $17, %eax
39 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
40 ; X64-NEXT:    retq
41 entry:
42   %div = udiv i16 %c, 3
43   ret i16 %div
47 define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) nounwind readnone ssp noredzone {
48 ; X32-LABEL: test3:
49 ; X32:       # %bb.0: # %entry
50 ; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
51 ; X32-NEXT:    imull $171, %eax, %eax
52 ; X32-NEXT:    shrl $9, %eax
53 ; X32-NEXT:    # kill: def $al killed $al killed $eax
54 ; X32-NEXT:    retl
56 ; X64-LABEL: test3:
57 ; X64:       # %bb.0: # %entry
58 ; X64-NEXT:    imull $171, %esi, %eax
59 ; X64-NEXT:    shrl $9, %eax
60 ; X64-NEXT:    # kill: def $al killed $al killed $eax
61 ; X64-NEXT:    retq
62 entry:
63   %div = udiv i8 %c, 3
64   ret i8 %div
67 define signext i16 @test4(i16 signext %x) nounwind {
68 ; X32-LABEL: test4:
69 ; X32:       # %bb.0: # %entry
70 ; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
71 ; X32-NEXT:    imull $1986, %eax, %eax # imm = 0x7C2
72 ; X32-NEXT:    movl %eax, %ecx
73 ; X32-NEXT:    shrl $31, %ecx
74 ; X32-NEXT:    shrl $16, %eax
75 ; X32-NEXT:    addl %ecx, %eax
76 ; X32-NEXT:    # kill: def $ax killed $ax killed $eax
77 ; X32-NEXT:    retl
79 ; X64-LABEL: test4:
80 ; X64:       # %bb.0: # %entry
81 ; X64-NEXT:    imull $1986, %edi, %eax # imm = 0x7C2
82 ; X64-NEXT:    movl %eax, %ecx
83 ; X64-NEXT:    shrl $31, %ecx
84 ; X64-NEXT:    shrl $16, %eax
85 ; X64-NEXT:    addl %ecx, %eax
86 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
87 ; X64-NEXT:    retq
88 entry:
89         %div = sdiv i16 %x, 33          ; <i32> [#uses=1]
90         ret i16 %div
93 define i32 @test5(i32 %A) nounwind {
94 ; X32-LABEL: test5:
95 ; X32:       # %bb.0:
96 ; X32-NEXT:    movl $365384439, %eax # imm = 0x15C752F7
97 ; X32-NEXT:    mull {{[0-9]+}}(%esp)
98 ; X32-NEXT:    movl %edx, %eax
99 ; X32-NEXT:    shrl $27, %eax
100 ; X32-NEXT:    retl
102 ; X64-LABEL: test5:
103 ; X64:       # %bb.0:
104 ; X64-NEXT:    movl %edi, %eax
105 ; X64-NEXT:    imulq $365384439, %rax, %rax # imm = 0x15C752F7
106 ; X64-NEXT:    shrq $59, %rax
107 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
108 ; X64-NEXT:    retq
109         %tmp1 = udiv i32 %A, 1577682821         ; <i32> [#uses=1]
110         ret i32 %tmp1
113 define signext i16 @test6(i16 signext %x) nounwind {
114 ; X32-LABEL: test6:
115 ; X32:       # %bb.0: # %entry
116 ; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
117 ; X32-NEXT:    imull $26215, %eax, %eax # imm = 0x6667
118 ; X32-NEXT:    movl %eax, %ecx
119 ; X32-NEXT:    shrl $31, %ecx
120 ; X32-NEXT:    sarl $18, %eax
121 ; X32-NEXT:    addl %ecx, %eax
122 ; X32-NEXT:    # kill: def $ax killed $ax killed $eax
123 ; X32-NEXT:    retl
125 ; X64-LABEL: test6:
126 ; X64:       # %bb.0: # %entry
127 ; X64-NEXT:    imull $26215, %edi, %eax # imm = 0x6667
128 ; X64-NEXT:    movl %eax, %ecx
129 ; X64-NEXT:    shrl $31, %ecx
130 ; X64-NEXT:    sarl $18, %eax
131 ; X64-NEXT:    addl %ecx, %eax
132 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
133 ; X64-NEXT:    retq
134 entry:
135   %div = sdiv i16 %x, 10
136   ret i16 %div
139 define i32 @test7(i32 %x) nounwind {
140 ; X32-LABEL: test7:
141 ; X32:       # %bb.0:
142 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
143 ; X32-NEXT:    shrl $2, %eax
144 ; X32-NEXT:    movl $613566757, %ecx # imm = 0x24924925
145 ; X32-NEXT:    mull %ecx
146 ; X32-NEXT:    movl %edx, %eax
147 ; X32-NEXT:    retl
149 ; X64-LABEL: test7:
150 ; X64:       # %bb.0:
151 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
152 ; X64-NEXT:    shrl $2, %edi
153 ; X64-NEXT:    imulq $613566757, %rdi, %rax # imm = 0x24924925
154 ; X64-NEXT:    shrq $32, %rax
155 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
156 ; X64-NEXT:    retq
157   %div = udiv i32 %x, 28
158   ret i32 %div
161 ; PR13326
162 define i8 @test8(i8 %x) nounwind {
163 ; X32-LABEL: test8:
164 ; X32:       # %bb.0:
165 ; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
166 ; X32-NEXT:    shrb %al
167 ; X32-NEXT:    movzbl %al, %eax
168 ; X32-NEXT:    imull $211, %eax, %eax
169 ; X32-NEXT:    shrl $13, %eax
170 ; X32-NEXT:    # kill: def $al killed $al killed $eax
171 ; X32-NEXT:    retl
173 ; X64-LABEL: test8:
174 ; X64:       # %bb.0:
175 ; X64-NEXT:    shrb %dil
176 ; X64-NEXT:    movzbl %dil, %eax
177 ; X64-NEXT:    imull $211, %eax, %eax
178 ; X64-NEXT:    shrl $13, %eax
179 ; X64-NEXT:    # kill: def $al killed $al killed $eax
180 ; X64-NEXT:    retq
181   %div = udiv i8 %x, 78
182   ret i8 %div
185 define i8 @test9(i8 %x) nounwind {
186 ; X32-LABEL: test9:
187 ; X32:       # %bb.0:
188 ; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
189 ; X32-NEXT:    shrb $2, %al
190 ; X32-NEXT:    movzbl %al, %eax
191 ; X32-NEXT:    imull $71, %eax, %eax
192 ; X32-NEXT:    shrl $11, %eax
193 ; X32-NEXT:    # kill: def $al killed $al killed $eax
194 ; X32-NEXT:    retl
196 ; X64-LABEL: test9:
197 ; X64:       # %bb.0:
198 ; X64-NEXT:    shrb $2, %dil
199 ; X64-NEXT:    movzbl %dil, %eax
200 ; X64-NEXT:    imull $71, %eax, %eax
201 ; X64-NEXT:    shrl $11, %eax
202 ; X64-NEXT:    # kill: def $al killed $al killed $eax
203 ; X64-NEXT:    retq
204   %div = udiv i8 %x, 116
205   ret i8 %div
208 define i32 @testsize1(i32 %x) minsize nounwind {
209 ; X32-LABEL: testsize1:
210 ; X32:       # %bb.0: # %entry
211 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
212 ; X32-NEXT:    pushl $32
213 ; X32-NEXT:    popl %ecx
214 ; X32-NEXT:    cltd
215 ; X32-NEXT:    idivl %ecx
216 ; X32-NEXT:    retl
218 ; X64-LABEL: testsize1:
219 ; X64:       # %bb.0: # %entry
220 ; X64-NEXT:    movl %edi, %eax
221 ; X64-NEXT:    pushq $32
222 ; X64-NEXT:    popq %rcx
223 ; X64-NEXT:    cltd
224 ; X64-NEXT:    idivl %ecx
225 ; X64-NEXT:    retq
226 entry:
227         %div = sdiv i32 %x, 32
228         ret i32 %div
231 define i32 @testsize2(i32 %x) minsize nounwind {
232 ; X32-LABEL: testsize2:
233 ; X32:       # %bb.0: # %entry
234 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
235 ; X32-NEXT:    pushl $33
236 ; X32-NEXT:    popl %ecx
237 ; X32-NEXT:    cltd
238 ; X32-NEXT:    idivl %ecx
239 ; X32-NEXT:    retl
241 ; X64-LABEL: testsize2:
242 ; X64:       # %bb.0: # %entry
243 ; X64-NEXT:    movl %edi, %eax
244 ; X64-NEXT:    pushq $33
245 ; X64-NEXT:    popq %rcx
246 ; X64-NEXT:    cltd
247 ; X64-NEXT:    idivl %ecx
248 ; X64-NEXT:    retq
249 entry:
250         %div = sdiv i32 %x, 33
251         ret i32 %div
254 define i32 @testsize3(i32 %x) minsize nounwind {
255 ; X32-LABEL: testsize3:
256 ; X32:       # %bb.0: # %entry
257 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
258 ; X32-NEXT:    shrl $5, %eax
259 ; X32-NEXT:    retl
261 ; X64-LABEL: testsize3:
262 ; X64:       # %bb.0: # %entry
263 ; X64-NEXT:    movl %edi, %eax
264 ; X64-NEXT:    shrl $5, %eax
265 ; X64-NEXT:    retq
266 entry:
267         %div = udiv i32 %x, 32
268         ret i32 %div
271 define i32 @testsize4(i32 %x) minsize nounwind {
272 ; X32-LABEL: testsize4:
273 ; X32:       # %bb.0: # %entry
274 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
275 ; X32-NEXT:    pushl $33
276 ; X32-NEXT:    popl %ecx
277 ; X32-NEXT:    xorl %edx, %edx
278 ; X32-NEXT:    divl %ecx
279 ; X32-NEXT:    retl
281 ; X64-LABEL: testsize4:
282 ; X64:       # %bb.0: # %entry
283 ; X64-NEXT:    movl %edi, %eax
284 ; X64-NEXT:    pushq $33
285 ; X64-NEXT:    popq %rcx
286 ; X64-NEXT:    xorl %edx, %edx
287 ; X64-NEXT:    divl %ecx
288 ; X64-NEXT:    retq
289 entry:
290         %div = udiv i32 %x, 33
291         ret i32 %div
294 define i64 @PR23590(i64 %x) nounwind {
295 ; X32-LABEL: PR23590:
296 ; X32:       # %bb.0: # %entry
297 ; X32-NEXT:    subl $12, %esp
298 ; X32-NEXT:    pushl $0
299 ; X32-NEXT:    pushl $12345 # imm = 0x3039
300 ; X32-NEXT:    pushl {{[0-9]+}}(%esp)
301 ; X32-NEXT:    pushl {{[0-9]+}}(%esp)
302 ; X32-NEXT:    calll __umoddi3
303 ; X32-NEXT:    addl $16, %esp
304 ; X32-NEXT:    pushl $0
305 ; X32-NEXT:    pushl $7
306 ; X32-NEXT:    pushl %edx
307 ; X32-NEXT:    pushl %eax
308 ; X32-NEXT:    calll __udivdi3
309 ; X32-NEXT:    addl $28, %esp
310 ; X32-NEXT:    retl
312 ; X64-FAST-LABEL: PR23590:
313 ; X64-FAST:       # %bb.0: # %entry
314 ; X64-FAST-NEXT:    movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
315 ; X64-FAST-NEXT:    movq %rdi, %rax
316 ; X64-FAST-NEXT:    mulq %rcx
317 ; X64-FAST-NEXT:    shrq $12, %rdx
318 ; X64-FAST-NEXT:    imulq $12345, %rdx, %rax # imm = 0x3039
319 ; X64-FAST-NEXT:    subq %rax, %rdi
320 ; X64-FAST-NEXT:    movabsq $2635249153387078803, %rcx # imm = 0x2492492492492493
321 ; X64-FAST-NEXT:    movq %rdi, %rax
322 ; X64-FAST-NEXT:    mulq %rcx
323 ; X64-FAST-NEXT:    subq %rdx, %rdi
324 ; X64-FAST-NEXT:    shrq %rdi
325 ; X64-FAST-NEXT:    leaq (%rdi,%rdx), %rax
326 ; X64-FAST-NEXT:    shrq $2, %rax
327 ; X64-FAST-NEXT:    retq
329 ; X64-SLOW-LABEL: PR23590:
330 ; X64-SLOW:       # %bb.0: # %entry
331 ; X64-SLOW-NEXT:    movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
332 ; X64-SLOW-NEXT:    movq %rdi, %rax
333 ; X64-SLOW-NEXT:    mulq %rcx
334 ; X64-SLOW-NEXT:    shrq $12, %rdx
335 ; X64-SLOW-NEXT:    imulq $12345, %rdx, %rax # imm = 0x3039
336 ; X64-SLOW-NEXT:    subq %rax, %rdi
337 ; X64-SLOW-NEXT:    imulq $613566757, %rdi, %rax # imm = 0x24924925
338 ; X64-SLOW-NEXT:    shrq $32, %rax
339 ; X64-SLOW-NEXT:    subl %eax, %edi
340 ; X64-SLOW-NEXT:    shrl %edi
341 ; X64-SLOW-NEXT:    addl %eax, %edi
342 ; X64-SLOW-NEXT:    shrl $2, %edi
343 ; X64-SLOW-NEXT:    movq %rdi, %rax
344 ; X64-SLOW-NEXT:    retq
345 entry:
346         %rem = urem i64 %x, 12345
347         %div = udiv i64 %rem, 7
348         ret i64 %div
351 define { i64, i32 } @PR38622(i64) nounwind {
352 ; X32-LABEL: PR38622:
353 ; X32:       # %bb.0:
354 ; X32-NEXT:    pushl %ebp
355 ; X32-NEXT:    pushl %ebx
356 ; X32-NEXT:    pushl %edi
357 ; X32-NEXT:    pushl %esi
358 ; X32-NEXT:    subl $12, %esp
359 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
360 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
361 ; X32-NEXT:    pushl $0
362 ; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
363 ; X32-NEXT:    pushl %ebp
364 ; X32-NEXT:    pushl %ebx
365 ; X32-NEXT:    calll __udivdi3
366 ; X32-NEXT:    addl $16, %esp
367 ; X32-NEXT:    movl %eax, %esi
368 ; X32-NEXT:    movl %edx, %edi
369 ; X32-NEXT:    pushl $0
370 ; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
371 ; X32-NEXT:    pushl %ebp
372 ; X32-NEXT:    pushl %ebx
373 ; X32-NEXT:    calll __umoddi3
374 ; X32-NEXT:    addl $16, %esp
375 ; X32-NEXT:    movl %eax, %ecx
376 ; X32-NEXT:    movl %esi, %eax
377 ; X32-NEXT:    movl %edi, %edx
378 ; X32-NEXT:    addl $12, %esp
379 ; X32-NEXT:    popl %esi
380 ; X32-NEXT:    popl %edi
381 ; X32-NEXT:    popl %ebx
382 ; X32-NEXT:    popl %ebp
383 ; X32-NEXT:    retl
385 ; X64-LABEL: PR38622:
386 ; X64:       # %bb.0:
387 ; X64-NEXT:    movq %rdi, %rax
388 ; X64-NEXT:    shrq $11, %rax
389 ; X64-NEXT:    movabsq $4835703278458517, %rcx # imm = 0x112E0BE826D695
390 ; X64-NEXT:    mulq %rcx
391 ; X64-NEXT:    movq %rdx, %rax
392 ; X64-NEXT:    shrq $9, %rax
393 ; X64-NEXT:    imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
394 ; X64-NEXT:    subl %ecx, %edi
395 ; X64-NEXT:    movl %edi, %edx
396 ; X64-NEXT:    retq
397   %2 = udiv i64 %0, 4000000000
398   %3 = urem i64 %0, 4000000000
399   %4 = trunc i64 %3 to i32
400   %5 = insertvalue { i64, i32 } undef, i64 %2, 0
401   %6 = insertvalue { i64, i32 } %5, i32 %4, 1
402   ret { i64, i32 } %6
405 define { i64, i32 } @PR38622_signed(i64) nounwind {
406 ; X32-LABEL: PR38622_signed:
407 ; X32:       # %bb.0:
408 ; X32-NEXT:    pushl %ebp
409 ; X32-NEXT:    pushl %ebx
410 ; X32-NEXT:    pushl %edi
411 ; X32-NEXT:    pushl %esi
412 ; X32-NEXT:    subl $12, %esp
413 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
414 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
415 ; X32-NEXT:    pushl $0
416 ; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
417 ; X32-NEXT:    pushl %ebp
418 ; X32-NEXT:    pushl %ebx
419 ; X32-NEXT:    calll __divdi3
420 ; X32-NEXT:    addl $16, %esp
421 ; X32-NEXT:    movl %eax, %esi
422 ; X32-NEXT:    movl %edx, %edi
423 ; X32-NEXT:    pushl $0
424 ; X32-NEXT:    pushl $-294967296 # imm = 0xEE6B2800
425 ; X32-NEXT:    pushl %ebp
426 ; X32-NEXT:    pushl %ebx
427 ; X32-NEXT:    calll __moddi3
428 ; X32-NEXT:    addl $16, %esp
429 ; X32-NEXT:    movl %eax, %ecx
430 ; X32-NEXT:    movl %esi, %eax
431 ; X32-NEXT:    movl %edi, %edx
432 ; X32-NEXT:    addl $12, %esp
433 ; X32-NEXT:    popl %esi
434 ; X32-NEXT:    popl %edi
435 ; X32-NEXT:    popl %ebx
436 ; X32-NEXT:    popl %ebp
437 ; X32-NEXT:    retl
439 ; X64-LABEL: PR38622_signed:
440 ; X64:       # %bb.0:
441 ; X64-NEXT:    movabsq $1237940039285380275, %rcx # imm = 0x112E0BE826D694B3
442 ; X64-NEXT:    movq %rdi, %rax
443 ; X64-NEXT:    imulq %rcx
444 ; X64-NEXT:    movq %rdx, %rax
445 ; X64-NEXT:    movq %rdx, %rcx
446 ; X64-NEXT:    shrq $63, %rcx
447 ; X64-NEXT:    sarq $28, %rax
448 ; X64-NEXT:    addq %rcx, %rax
449 ; X64-NEXT:    imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
450 ; X64-NEXT:    subl %ecx, %edi
451 ; X64-NEXT:    movl %edi, %edx
452 ; X64-NEXT:    retq
453   %2 = sdiv i64 %0, 4000000000
454   %3 = srem i64 %0, 4000000000
455   %4 = trunc i64 %3 to i32
456   %5 = insertvalue { i64, i32 } undef, i64 %2, 0
457   %6 = insertvalue { i64, i32 } %5, i32 %4, 1
458   ret { i64, i32 } %6