llvm-project/llvm/test/CodeGen/X86/divide-by-constant.ll
Guozhi Wei f1d8345a2a [TwoAddressInstructionPass] Create register mapping for registers with multiple uses in the current MBB
Currently we create register mappings for registers used only once in current
MBB. For registers with multiple uses, when all the uses are in the current MBB,
we can also create mappings for them similarly according to the last use.
For example

    %reg101 = ...
            = ... reg101
    %reg103 = ADD %reg101, %reg102

We can create mapping between %reg101 and %reg103.

Differential Revision: https://reviews.llvm.org/D113193
2021-11-29 19:01:59 -08:00

459 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: shrq $63, %rax
; X64-NEXT: sarq $28, %rdx
; X64-NEXT: addq %rdx, %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
}