mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-07 01:54:50 +00:00
This obviously helps a lot if the division would be turned into a libcall (think i64 udiv on i386), but div is also one of the few remaining instructions on modern CPUs that become more expensive when the bitwidth gets bigger. This also helps register pressure on i386 when dividing chars, divb needs two 8-bit parts of a 16 bit register as input where divl uses two registers. int foo(unsigned char a) { return a/10; } int bar(unsigned char a, unsigned char b) { return a/b; } compiles into (x86_64) _foo: imull $205, %edi, %eax shrl $11, %eax ret _bar: movzbl %dil, %eax divb %sil, %al movzbl %al, %eax ret git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130615 91177308-0d34-0410-b5e6-96231b3b80d8
63 lines
1.4 KiB
LLVM
63 lines
1.4 KiB
LLVM
; RUN: opt < %s -instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
|
|
|
; PR4548
|
|
define i8 @udiv_i8(i8 %a, i8 %b) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%conv2 = zext i8 %b to i32
|
|
%div = udiv i32 %conv, %conv2
|
|
%conv3 = trunc i32 %div to i8
|
|
ret i8 %conv3
|
|
; CHECK: @udiv_i8
|
|
; CHECK: udiv i8 %a, %b
|
|
}
|
|
|
|
define i8 @urem_i8(i8 %a, i8 %b) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%conv2 = zext i8 %b to i32
|
|
%div = urem i32 %conv, %conv2
|
|
%conv3 = trunc i32 %div to i8
|
|
ret i8 %conv3
|
|
; CHECK: @urem_i8
|
|
; CHECK: urem i8 %a, %b
|
|
}
|
|
|
|
define i32 @udiv_i32(i8 %a, i8 %b) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%conv2 = zext i8 %b to i32
|
|
%div = udiv i32 %conv, %conv2
|
|
ret i32 %div
|
|
; CHECK: @udiv_i32
|
|
; CHECK: udiv i8 %a, %b
|
|
; CHECK: zext
|
|
}
|
|
|
|
define i32 @urem_i32(i8 %a, i8 %b) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%conv2 = zext i8 %b to i32
|
|
%div = urem i32 %conv, %conv2
|
|
ret i32 %div
|
|
; CHECK: @urem_i32
|
|
; CHECK: urem i8 %a, %b
|
|
; CHECK: zext
|
|
}
|
|
|
|
define i32 @udiv_i32_c(i8 %a) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%div = udiv i32 %conv, 10
|
|
ret i32 %div
|
|
; CHECK: @udiv_i32_c
|
|
; CHECK: udiv i8 %a, 10
|
|
; CHECK: zext
|
|
}
|
|
|
|
define i32 @urem_i32_c(i8 %a) nounwind {
|
|
%conv = zext i8 %a to i32
|
|
%div = urem i32 %conv, 10
|
|
ret i32 %div
|
|
; CHECK: @urem_i32_c
|
|
; CHECK: urem i8 %a, 10
|
|
; CHECK: zext
|
|
}
|