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:
Benjamin Kramer 2011-12-09 15:44:03 +00:00
parent a73fb9adbb
commit b653397dcd
3 changed files with 185 additions and 0 deletions

View File

@ -914,6 +914,17 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
}
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?
setOperationAction(ISD::MUL, MVT::v4i32, Legal);

View File

@ -6134,6 +6134,27 @@ let Predicates = [HasAVX] in {
defm VROUND : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
int_x86_sse41_round_ss,
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,
@ -6143,6 +6164,27 @@ let Constraints = "$src1 = $dst" in
defm ROUND : sse41_fp_binop_rm<0x0A, 0x0B, "round",
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
//===----------------------------------------------------------------------===//

View 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