mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
X86: Add patterns for the various rounding ops for SSE4.1 and AVX.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146257 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a73fb9adbb
commit
b653397dcd
@ -914,6 +914,17 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Subtarget->hasSSE41orAVX()) {
|
if (Subtarget->hasSSE41orAVX()) {
|
||||||
|
setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::FCEIL, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::FTRUNC, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::FRINT, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal);
|
||||||
|
setOperationAction(ISD::FFLOOR, MVT::f64, Legal);
|
||||||
|
setOperationAction(ISD::FCEIL, MVT::f64, Legal);
|
||||||
|
setOperationAction(ISD::FTRUNC, MVT::f64, Legal);
|
||||||
|
setOperationAction(ISD::FRINT, MVT::f64, Legal);
|
||||||
|
setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal);
|
||||||
|
|
||||||
// FIXME: Do we need to handle scalar-to-vector here?
|
// FIXME: Do we need to handle scalar-to-vector here?
|
||||||
setOperationAction(ISD::MUL, MVT::v4i32, Legal);
|
setOperationAction(ISD::MUL, MVT::v4i32, Legal);
|
||||||
|
|
||||||
|
@ -6134,6 +6134,27 @@ let Predicates = [HasAVX] in {
|
|||||||
defm VROUND : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
|
defm VROUND : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
|
||||||
int_x86_sse41_round_ss,
|
int_x86_sse41_round_ss,
|
||||||
int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
|
int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
|
||||||
|
|
||||||
|
def : Pat<(ffloor FR32:$src),
|
||||||
|
(VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
|
||||||
|
def : Pat<(f64 (ffloor FR64:$src)),
|
||||||
|
(VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
|
||||||
|
def : Pat<(f32 (fnearbyint FR32:$src)),
|
||||||
|
(VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
|
||||||
|
def : Pat<(f64 (fnearbyint FR64:$src)),
|
||||||
|
(VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
|
||||||
|
def : Pat<(f32 (fceil FR32:$src)),
|
||||||
|
(VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
|
||||||
|
def : Pat<(f64 (fceil FR64:$src)),
|
||||||
|
(VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
|
||||||
|
def : Pat<(f32 (frint FR32:$src)),
|
||||||
|
(VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
|
||||||
|
def : Pat<(f64 (frint FR64:$src)),
|
||||||
|
(VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
|
||||||
|
def : Pat<(f32 (ftrunc FR32:$src)),
|
||||||
|
(VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
|
||||||
|
def : Pat<(f64 (ftrunc FR64:$src)),
|
||||||
|
(VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
|
||||||
}
|
}
|
||||||
|
|
||||||
defm ROUND : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
|
defm ROUND : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
|
||||||
@ -6143,6 +6164,27 @@ let Constraints = "$src1 = $dst" in
|
|||||||
defm ROUND : sse41_fp_binop_rm<0x0A, 0x0B, "round",
|
defm ROUND : sse41_fp_binop_rm<0x0A, 0x0B, "round",
|
||||||
int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
|
int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
|
||||||
|
|
||||||
|
def : Pat<(ffloor FR32:$src),
|
||||||
|
(ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
|
||||||
|
def : Pat<(f64 (ffloor FR64:$src)),
|
||||||
|
(ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
|
||||||
|
def : Pat<(f32 (fnearbyint FR32:$src)),
|
||||||
|
(ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
|
||||||
|
def : Pat<(f64 (fnearbyint FR64:$src)),
|
||||||
|
(ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
|
||||||
|
def : Pat<(f32 (fceil FR32:$src)),
|
||||||
|
(ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
|
||||||
|
def : Pat<(f64 (fceil FR64:$src)),
|
||||||
|
(ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
|
||||||
|
def : Pat<(f32 (frint FR32:$src)),
|
||||||
|
(ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
|
||||||
|
def : Pat<(f64 (frint FR64:$src)),
|
||||||
|
(ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
|
||||||
|
def : Pat<(f32 (ftrunc FR32:$src)),
|
||||||
|
(ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
|
||||||
|
def : Pat<(f64 (ftrunc FR64:$src)),
|
||||||
|
(ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SSE4.1 - Packed Bit Test
|
// SSE4.1 - Packed Bit Test
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
132
test/CodeGen/X86/rounding-ops.ll
Normal file
132
test/CodeGen/X86/rounding-ops.ll
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
; RUN: llc < %s -march=x86-64 -mattr=+sse41 | FileCheck -check-prefix=CHECK-SSE %s
|
||||||
|
; RUN: llc < %s -march=x86-64 -mattr=+avx | FileCheck -check-prefix=CHECK-AVX %s
|
||||||
|
|
||||||
|
define float @test1(float %x) nounwind {
|
||||||
|
%call = tail call float @floorf(float %x) nounwind readnone
|
||||||
|
ret float %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test1:
|
||||||
|
; CHECK-SSE: roundss $1
|
||||||
|
|
||||||
|
; CHECK-AVX: test1:
|
||||||
|
; CHECK-AVX: vroundss $1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare float @floorf(float) nounwind readnone
|
||||||
|
|
||||||
|
define double @test2(double %x) nounwind {
|
||||||
|
%call = tail call double @floor(double %x) nounwind readnone
|
||||||
|
ret double %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test2:
|
||||||
|
; CHECK-SSE: roundsd $1
|
||||||
|
|
||||||
|
; CHECK-AVX: test2:
|
||||||
|
; CHECK-AVX: vroundsd $1
|
||||||
|
}
|
||||||
|
|
||||||
|
declare double @floor(double) nounwind readnone
|
||||||
|
|
||||||
|
define float @test3(float %x) nounwind {
|
||||||
|
%call = tail call float @nearbyintf(float %x) nounwind readnone
|
||||||
|
ret float %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test3:
|
||||||
|
; CHECK-SSE: roundss $12
|
||||||
|
|
||||||
|
; CHECK-AVX: test3:
|
||||||
|
; CHECK-AVX: vroundss $12
|
||||||
|
}
|
||||||
|
|
||||||
|
declare float @nearbyintf(float) nounwind readnone
|
||||||
|
|
||||||
|
define double @test4(double %x) nounwind {
|
||||||
|
%call = tail call double @nearbyint(double %x) nounwind readnone
|
||||||
|
ret double %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test4:
|
||||||
|
; CHECK-SSE: roundsd $12
|
||||||
|
|
||||||
|
; CHECK-AVX: test4:
|
||||||
|
; CHECK-AVX: vroundsd $12
|
||||||
|
}
|
||||||
|
|
||||||
|
declare double @nearbyint(double) nounwind readnone
|
||||||
|
|
||||||
|
define float @test5(float %x) nounwind {
|
||||||
|
%call = tail call float @ceilf(float %x) nounwind readnone
|
||||||
|
ret float %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test5:
|
||||||
|
; CHECK-SSE: roundss $2
|
||||||
|
|
||||||
|
; CHECK-AVX: test5:
|
||||||
|
; CHECK-AVX: vroundss $2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare float @ceilf(float) nounwind readnone
|
||||||
|
|
||||||
|
define double @test6(double %x) nounwind {
|
||||||
|
%call = tail call double @ceil(double %x) nounwind readnone
|
||||||
|
ret double %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test6:
|
||||||
|
; CHECK-SSE: roundsd $2
|
||||||
|
|
||||||
|
; CHECK-AVX: test6:
|
||||||
|
; CHECK-AVX: vroundsd $2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare double @ceil(double) nounwind readnone
|
||||||
|
|
||||||
|
define float @test7(float %x) nounwind {
|
||||||
|
%call = tail call float @rintf(float %x) nounwind readnone
|
||||||
|
ret float %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test7:
|
||||||
|
; CHECK-SSE: roundss $4
|
||||||
|
|
||||||
|
; CHECK-AVX: test7:
|
||||||
|
; CHECK-AVX: vroundss $4
|
||||||
|
}
|
||||||
|
|
||||||
|
declare float @rintf(float) nounwind readnone
|
||||||
|
|
||||||
|
define double @test8(double %x) nounwind {
|
||||||
|
%call = tail call double @rint(double %x) nounwind readnone
|
||||||
|
ret double %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test8:
|
||||||
|
; CHECK-SSE: roundsd $4
|
||||||
|
|
||||||
|
; CHECK-AVX: test8:
|
||||||
|
; CHECK-AVX: vroundsd $4
|
||||||
|
}
|
||||||
|
|
||||||
|
declare double @rint(double) nounwind readnone
|
||||||
|
|
||||||
|
define float @test9(float %x) nounwind {
|
||||||
|
%call = tail call float @truncf(float %x) nounwind readnone
|
||||||
|
ret float %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test9:
|
||||||
|
; CHECK-SSE: roundss $3
|
||||||
|
|
||||||
|
; CHECK-AVX: test9:
|
||||||
|
; CHECK-AVX: vroundss $3
|
||||||
|
}
|
||||||
|
|
||||||
|
declare float @truncf(float) nounwind readnone
|
||||||
|
|
||||||
|
define double @test10(double %x) nounwind {
|
||||||
|
%call = tail call double @trunc(double %x) nounwind readnone
|
||||||
|
ret double %call
|
||||||
|
|
||||||
|
; CHECK-SSE: test10:
|
||||||
|
; CHECK-SSE: roundsd $3
|
||||||
|
|
||||||
|
; CHECK-AVX: test10:
|
||||||
|
; CHECK-AVX: vroundsd $3
|
||||||
|
}
|
||||||
|
|
||||||
|
declare double @trunc(double) nounwind readnone
|
Loading…
Reference in New Issue
Block a user