1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00
llvm-mirror/test/CodeGen/X86/divide-by-constant.ll
Craig Topper 54cbcebb97 [DAGCombiner] After performing the division by constant optimization for a DIV or REM node, replace the users of the corresponding REM or DIV node if it exists.
Currently we expand the two nodes separately. This gives DAG combiner an opportunity to optimize the expanded sequence taking into account only one set of users. When we expand the other node we'll create the expansion again, but might not be able to optimize it the same way. So the nodes won't CSE and we'll have two similarish sequences in the same basic block. By expanding both nodes at the same time we'll avoid prematurely optimizing the expansion until both the division and remainder have been replaced.

Improves the test case from PR38217. There may be additional opportunities after this.

Differential Revision: https://reviews.llvm.org/D56145

llvm-svn: 350239
2019-01-02 18:19:07 +00:00

460 lines
13 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-pc-linux-gnu | FileCheck %s --check-prefix=X32
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=X64 --check-prefix=X64-FAST
; RUN: llc < %s -mtriple=x86_64-pc-linux-gnu -mattr=idivq-to-divl | FileCheck %s --check-prefix=X64 --check-prefix=X64-SLOW
define zeroext i16 @test1(i16 zeroext %x) nounwind {
; X32-LABEL: test1:
; X32: # %bb.0: # %entry
; X32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
; X32-NEXT: imull $63551, %eax, %eax # imm = 0xF83F
; X32-NEXT: shrl $21, %eax
; X32-NEXT: # kill: def $ax killed $ax killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test1:
; X64: # %bb.0: # %entry
; X64-NEXT: imull $63551, %edi, %eax # imm = 0xF83F
; X64-NEXT: shrl $21, %eax
; X64-NEXT: # kill: def $ax killed $ax killed $eax
; X64-NEXT: retq
entry:
%div = udiv i16 %x, 33
ret i16 %div
}
define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) nounwind readnone ssp noredzone {
; X32-LABEL: test2:
; X32: # %bb.0: # %entry
; X32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
; X32-NEXT: imull $43691, %eax, %eax # imm = 0xAAAB
; X32-NEXT: shrl $17, %eax
; X32-NEXT: # kill: def $ax killed $ax killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test2:
; X64: # %bb.0: # %entry
; X64-NEXT: imull $43691, %esi, %eax # imm = 0xAAAB
; X64-NEXT: shrl $17, %eax
; X64-NEXT: # kill: def $ax killed $ax killed $eax
; X64-NEXT: retq
entry:
%div = udiv i16 %c, 3
ret i16 %div
}
define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) nounwind readnone ssp noredzone {
; X32-LABEL: test3:
; X32: # %bb.0: # %entry
; X32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
; X32-NEXT: imull $171, %eax, %eax
; X32-NEXT: shrl $9, %eax
; X32-NEXT: # kill: def $al killed $al killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test3:
; X64: # %bb.0: # %entry
; X64-NEXT: imull $171, %esi, %eax
; X64-NEXT: shrl $9, %eax
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: retq
entry:
%div = udiv i8 %c, 3
ret i8 %div
}
define signext i16 @test4(i16 signext %x) nounwind {
; X32-LABEL: test4:
; X32: # %bb.0: # %entry
; X32-NEXT: movswl {{[0-9]+}}(%esp), %eax
; X32-NEXT: imull $1986, %eax, %eax # imm = 0x7C2
; X32-NEXT: movl %eax, %ecx
; X32-NEXT: shrl $31, %ecx
; X32-NEXT: shrl $16, %eax
; X32-NEXT: addl %ecx, %eax
; X32-NEXT: # kill: def $ax killed $ax killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test4:
; X64: # %bb.0: # %entry
; X64-NEXT: imull $1986, %edi, %eax # imm = 0x7C2
; X64-NEXT: movl %eax, %ecx
; X64-NEXT: shrl $31, %ecx
; X64-NEXT: shrl $16, %eax
; X64-NEXT: addl %ecx, %eax
; X64-NEXT: # kill: def $ax killed $ax killed $eax
; X64-NEXT: retq
entry:
%div = sdiv i16 %x, 33 ; <i32> [#uses=1]
ret i16 %div
}
define i32 @test5(i32 %A) nounwind {
; X32-LABEL: test5:
; X32: # %bb.0:
; X32-NEXT: movl $365384439, %eax # imm = 0x15C752F7
; X32-NEXT: mull {{[0-9]+}}(%esp)
; X32-NEXT: movl %edx, %eax
; X32-NEXT: shrl $27, %eax
; X32-NEXT: retl
;
; X64-LABEL: test5:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: imulq $365384439, %rax, %rax # imm = 0x15C752F7
; X64-NEXT: shrq $59, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%tmp1 = udiv i32 %A, 1577682821 ; <i32> [#uses=1]
ret i32 %tmp1
}
define signext i16 @test6(i16 signext %x) nounwind {
; X32-LABEL: test6:
; X32: # %bb.0: # %entry
; X32-NEXT: movswl {{[0-9]+}}(%esp), %eax
; X32-NEXT: imull $26215, %eax, %eax # imm = 0x6667
; X32-NEXT: movl %eax, %ecx
; X32-NEXT: shrl $31, %ecx
; X32-NEXT: sarl $18, %eax
; X32-NEXT: addl %ecx, %eax
; X32-NEXT: # kill: def $ax killed $ax killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test6:
; X64: # %bb.0: # %entry
; X64-NEXT: imull $26215, %edi, %eax # imm = 0x6667
; X64-NEXT: movl %eax, %ecx
; X64-NEXT: shrl $31, %ecx
; X64-NEXT: sarl $18, %eax
; X64-NEXT: addl %ecx, %eax
; X64-NEXT: # kill: def $ax killed $ax killed $eax
; X64-NEXT: retq
entry:
%div = sdiv i16 %x, 10
ret i16 %div
}
define i32 @test7(i32 %x) nounwind {
; X32-LABEL: test7:
; X32: # %bb.0:
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: shrl $2, %eax
; X32-NEXT: movl $613566757, %ecx # imm = 0x24924925
; X32-NEXT: mull %ecx
; X32-NEXT: movl %edx, %eax
; X32-NEXT: retl
;
; X64-LABEL: test7:
; X64: # %bb.0:
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: shrl $2, %edi
; X64-NEXT: imulq $613566757, %rdi, %rax # imm = 0x24924925
; X64-NEXT: shrq $32, %rax
; X64-NEXT: # kill: def $eax killed $eax killed $rax
; X64-NEXT: retq
%div = udiv i32 %x, 28
ret i32 %div
}
; PR13326
define i8 @test8(i8 %x) nounwind {
; X32-LABEL: test8:
; X32: # %bb.0:
; X32-NEXT: movb {{[0-9]+}}(%esp), %al
; X32-NEXT: shrb %al
; X32-NEXT: movzbl %al, %eax
; X32-NEXT: imull $211, %eax, %eax
; X32-NEXT: shrl $13, %eax
; X32-NEXT: # kill: def $al killed $al killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test8:
; X64: # %bb.0:
; X64-NEXT: shrb %dil
; X64-NEXT: movzbl %dil, %eax
; X64-NEXT: imull $211, %eax, %eax
; X64-NEXT: shrl $13, %eax
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: retq
%div = udiv i8 %x, 78
ret i8 %div
}
define i8 @test9(i8 %x) nounwind {
; X32-LABEL: test9:
; X32: # %bb.0:
; X32-NEXT: movb {{[0-9]+}}(%esp), %al
; X32-NEXT: shrb $2, %al
; X32-NEXT: movzbl %al, %eax
; X32-NEXT: imull $71, %eax, %eax
; X32-NEXT: shrl $11, %eax
; X32-NEXT: # kill: def $al killed $al killed $eax
; X32-NEXT: retl
;
; X64-LABEL: test9:
; X64: # %bb.0:
; X64-NEXT: shrb $2, %dil
; X64-NEXT: movzbl %dil, %eax
; X64-NEXT: imull $71, %eax, %eax
; X64-NEXT: shrl $11, %eax
; X64-NEXT: # kill: def $al killed $al killed $eax
; X64-NEXT: retq
%div = udiv i8 %x, 116
ret i8 %div
}
define i32 @testsize1(i32 %x) minsize nounwind {
; X32-LABEL: testsize1:
; X32: # %bb.0: # %entry
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: pushl $32
; X32-NEXT: popl %ecx
; X32-NEXT: cltd
; X32-NEXT: idivl %ecx
; X32-NEXT: retl
;
; X64-LABEL: testsize1:
; X64: # %bb.0: # %entry
; X64-NEXT: movl %edi, %eax
; X64-NEXT: pushq $32
; X64-NEXT: popq %rcx
; X64-NEXT: cltd
; X64-NEXT: idivl %ecx
; X64-NEXT: retq
entry:
%div = sdiv i32 %x, 32
ret i32 %div
}
define i32 @testsize2(i32 %x) minsize nounwind {
; X32-LABEL: testsize2:
; X32: # %bb.0: # %entry
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: pushl $33
; X32-NEXT: popl %ecx
; X32-NEXT: cltd
; X32-NEXT: idivl %ecx
; X32-NEXT: retl
;
; X64-LABEL: testsize2:
; X64: # %bb.0: # %entry
; X64-NEXT: movl %edi, %eax
; X64-NEXT: pushq $33
; X64-NEXT: popq %rcx
; X64-NEXT: cltd
; X64-NEXT: idivl %ecx
; X64-NEXT: retq
entry:
%div = sdiv i32 %x, 33
ret i32 %div
}
define i32 @testsize3(i32 %x) minsize nounwind {
; X32-LABEL: testsize3:
; X32: # %bb.0: # %entry
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: shrl $5, %eax
; X32-NEXT: retl
;
; X64-LABEL: testsize3:
; X64: # %bb.0: # %entry
; X64-NEXT: movl %edi, %eax
; X64-NEXT: shrl $5, %eax
; X64-NEXT: retq
entry:
%div = udiv i32 %x, 32
ret i32 %div
}
define i32 @testsize4(i32 %x) minsize nounwind {
; X32-LABEL: testsize4:
; X32: # %bb.0: # %entry
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: pushl $33
; X32-NEXT: popl %ecx
; X32-NEXT: xorl %edx, %edx
; X32-NEXT: divl %ecx
; X32-NEXT: retl
;
; X64-LABEL: testsize4:
; X64: # %bb.0: # %entry
; X64-NEXT: movl %edi, %eax
; X64-NEXT: pushq $33
; X64-NEXT: popq %rcx
; X64-NEXT: xorl %edx, %edx
; X64-NEXT: divl %ecx
; X64-NEXT: retq
entry:
%div = udiv i32 %x, 33
ret i32 %div
}
define i64 @PR23590(i64 %x) nounwind {
; X32-LABEL: PR23590:
; X32: # %bb.0: # %entry
; X32-NEXT: subl $12, %esp
; X32-NEXT: pushl $0
; X32-NEXT: pushl $12345 # imm = 0x3039
; X32-NEXT: pushl {{[0-9]+}}(%esp)
; X32-NEXT: pushl {{[0-9]+}}(%esp)
; X32-NEXT: calll __umoddi3
; X32-NEXT: addl $16, %esp
; X32-NEXT: pushl $0
; X32-NEXT: pushl $7
; X32-NEXT: pushl %edx
; X32-NEXT: pushl %eax
; X32-NEXT: calll __udivdi3
; X32-NEXT: addl $28, %esp
; X32-NEXT: retl
;
; X64-FAST-LABEL: PR23590:
; X64-FAST: # %bb.0: # %entry
; X64-FAST-NEXT: movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
; X64-FAST-NEXT: movq %rdi, %rax
; X64-FAST-NEXT: mulq %rcx
; X64-FAST-NEXT: shrq $12, %rdx
; X64-FAST-NEXT: imulq $12345, %rdx, %rax # imm = 0x3039
; X64-FAST-NEXT: subq %rax, %rdi
; X64-FAST-NEXT: movabsq $2635249153387078803, %rcx # imm = 0x2492492492492493
; X64-FAST-NEXT: movq %rdi, %rax
; X64-FAST-NEXT: mulq %rcx
; X64-FAST-NEXT: subq %rdx, %rdi
; X64-FAST-NEXT: shrq %rdi
; X64-FAST-NEXT: leaq (%rdi,%rdx), %rax
; X64-FAST-NEXT: shrq $2, %rax
; X64-FAST-NEXT: retq
;
; X64-SLOW-LABEL: PR23590:
; X64-SLOW: # %bb.0: # %entry
; X64-SLOW-NEXT: movabsq $6120523590596543007, %rcx # imm = 0x54F077C718E7C21F
; X64-SLOW-NEXT: movq %rdi, %rax
; X64-SLOW-NEXT: mulq %rcx
; X64-SLOW-NEXT: shrq $12, %rdx
; X64-SLOW-NEXT: imulq $12345, %rdx, %rax # imm = 0x3039
; X64-SLOW-NEXT: subq %rax, %rdi
; X64-SLOW-NEXT: imulq $613566757, %rdi, %rax # imm = 0x24924925
; X64-SLOW-NEXT: shrq $32, %rax
; X64-SLOW-NEXT: subl %eax, %edi
; X64-SLOW-NEXT: shrl %edi
; X64-SLOW-NEXT: addl %eax, %edi
; X64-SLOW-NEXT: shrl $2, %edi
; X64-SLOW-NEXT: movq %rdi, %rax
; X64-SLOW-NEXT: retq
entry:
%rem = urem i64 %x, 12345
%div = udiv i64 %rem, 7
ret i64 %div
}
define { i64, i32 } @PR38622(i64) nounwind {
; X32-LABEL: PR38622:
; X32: # %bb.0:
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: pushl %edi
; X32-NEXT: pushl %esi
; X32-NEXT: subl $12, %esp
; X32-NEXT: movl {{[0-9]+}}(%esp), %ebx
; X32-NEXT: movl {{[0-9]+}}(%esp), %ebp
; X32-NEXT: pushl $0
; X32-NEXT: pushl $-294967296 # imm = 0xEE6B2800
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: calll __udivdi3
; X32-NEXT: addl $16, %esp
; X32-NEXT: movl %eax, %esi
; X32-NEXT: movl %edx, %edi
; X32-NEXT: pushl $0
; X32-NEXT: pushl $-294967296 # imm = 0xEE6B2800
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: calll __umoddi3
; X32-NEXT: addl $16, %esp
; X32-NEXT: movl %eax, %ecx
; X32-NEXT: movl %esi, %eax
; X32-NEXT: movl %edi, %edx
; X32-NEXT: addl $12, %esp
; X32-NEXT: popl %esi
; X32-NEXT: popl %edi
; X32-NEXT: popl %ebx
; X32-NEXT: popl %ebp
; X32-NEXT: retl
;
; X64-LABEL: PR38622:
; X64: # %bb.0:
; X64-NEXT: movq %rdi, %rax
; X64-NEXT: shrq $11, %rax
; X64-NEXT: movabsq $4835703278458517, %rcx # imm = 0x112E0BE826D695
; X64-NEXT: mulq %rcx
; X64-NEXT: movq %rdx, %rax
; X64-NEXT: shrq $9, %rax
; X64-NEXT: imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
; X64-NEXT: subl %ecx, %edi
; X64-NEXT: movl %edi, %edx
; X64-NEXT: retq
%2 = udiv i64 %0, 4000000000
%3 = urem i64 %0, 4000000000
%4 = trunc i64 %3 to i32
%5 = insertvalue { i64, i32 } undef, i64 %2, 0
%6 = insertvalue { i64, i32 } %5, i32 %4, 1
ret { i64, i32 } %6
}
define { i64, i32 } @PR38622_signed(i64) nounwind {
; X32-LABEL: PR38622_signed:
; X32: # %bb.0:
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: pushl %edi
; X32-NEXT: pushl %esi
; X32-NEXT: subl $12, %esp
; X32-NEXT: movl {{[0-9]+}}(%esp), %ebx
; X32-NEXT: movl {{[0-9]+}}(%esp), %ebp
; X32-NEXT: pushl $0
; X32-NEXT: pushl $-294967296 # imm = 0xEE6B2800
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: calll __divdi3
; X32-NEXT: addl $16, %esp
; X32-NEXT: movl %eax, %esi
; X32-NEXT: movl %edx, %edi
; X32-NEXT: pushl $0
; X32-NEXT: pushl $-294967296 # imm = 0xEE6B2800
; X32-NEXT: pushl %ebp
; X32-NEXT: pushl %ebx
; X32-NEXT: calll __moddi3
; X32-NEXT: addl $16, %esp
; X32-NEXT: movl %eax, %ecx
; X32-NEXT: movl %esi, %eax
; X32-NEXT: movl %edi, %edx
; X32-NEXT: addl $12, %esp
; X32-NEXT: popl %esi
; X32-NEXT: popl %edi
; X32-NEXT: popl %ebx
; X32-NEXT: popl %ebp
; X32-NEXT: retl
;
; X64-LABEL: PR38622_signed:
; X64: # %bb.0:
; X64-NEXT: movabsq $1237940039285380275, %rcx # imm = 0x112E0BE826D694B3
; X64-NEXT: movq %rdi, %rax
; X64-NEXT: imulq %rcx
; X64-NEXT: movq %rdx, %rax
; X64-NEXT: movq %rdx, %rcx
; X64-NEXT: shrq $63, %rcx
; X64-NEXT: sarq $28, %rax
; X64-NEXT: addq %rcx, %rax
; X64-NEXT: imull $-294967296, %eax, %ecx # imm = 0xEE6B2800
; X64-NEXT: subl %ecx, %edi
; X64-NEXT: movl %edi, %edx
; X64-NEXT: retq
%2 = sdiv i64 %0, 4000000000
%3 = srem i64 %0, 4000000000
%4 = trunc i64 %3 to i32
%5 = insertvalue { i64, i32 } undef, i64 %2, 0
%6 = insertvalue { i64, i32 } %5, i32 %4, 1
ret { i64, i32 } %6
}