From 61d045781adc36c252f987ac6f91264be169d972 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 15 Nov 2012 06:51:10 +0000 Subject: [PATCH] Add llvm.ceil, llvm.trunc, llvm.rint, llvm.nearbyint intrinsics. llvm-svn: 168025 --- llvm/docs/LangRef.html | 141 +++++++++++++++++++++ llvm/include/llvm/Intrinsics.td | 4 + .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 20 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp | 4 + llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 + llvm/lib/Target/X86/X86ISelLowering.cpp | 6 +- 6 files changed, 178 insertions(+), 1 deletion(-) diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index cdb7684..9c4c4ee 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/docs/LangRef.html @@ -260,6 +260,10 @@
  • 'llvm.fma.*' Intrinsic
  • 'llvm.fabs.*' Intrinsic
  • 'llvm.floor.*' Intrinsic
  • +
  • 'llvm.ceil.*' Intrinsic
  • +
  • 'llvm.trunc.*' Intrinsic
  • +
  • 'llvm.rint.*' Intrinsic
  • +
  • 'llvm.nearbyint.*' Intrinsic
  • Bit Manipulation Intrinsics @@ -7634,6 +7638,143 @@ LLVM.

    + +

    + 'llvm.ceil.*' Intrinsic +

    + +
    + +
    Syntax:
    +

    This is an overloaded intrinsic. You can use llvm.ceil on any + floating point or vector of floating point type. Not all targets support all + types however.

    + +
    +  declare float     @llvm.ceil.f32(float  %Val)
    +  declare double    @llvm.ceil.f64(double %Val)
    +  declare x86_fp80  @llvm.ceil.f80(x86_fp80  %Val)
    +  declare fp128     @llvm.ceil.f128(fp128 %Val)
    +  declare ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128  %Val)
    +
    + +
    Overview:
    +

    The 'llvm.ceil.*' intrinsics return the ceiling of + the operand.

    + +
    Arguments:
    +

    The argument and return value are floating point numbers of the same + type.

    + +
    Semantics:
    +

    This function returns the same values as the libm ceil functions + would, and handles error conditions in the same way.

    + +
    + + +

    + 'llvm.trunc.*' Intrinsic +

    + +
    + +
    Syntax:
    +

    This is an overloaded intrinsic. You can use llvm.trunc on any + floating point or vector of floating point type. Not all targets support all + types however.

    + +
    +  declare float     @llvm.trunc.f32(float  %Val)
    +  declare double    @llvm.trunc.f64(double %Val)
    +  declare x86_fp80  @llvm.trunc.f80(x86_fp80  %Val)
    +  declare fp128     @llvm.trunc.f128(fp128 %Val)
    +  declare ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128  %Val)
    +
    + +
    Overview:
    +

    The 'llvm.trunc.*' intrinsics returns the operand rounded to the + nearest integer not larger in magnitude than the operand.

    + +
    Arguments:
    +

    The argument and return value are floating point numbers of the same + type.

    + +
    Semantics:
    +

    This function returns the same values as the libm trunc functions + would, and handles error conditions in the same way.

    + +
    + + +

    + 'llvm.rint.*' Intrinsic +

    + +
    + +
    Syntax:
    +

    This is an overloaded intrinsic. You can use llvm.rint on any + floating point or vector of floating point type. Not all targets support all + types however.

    + +
    +  declare float     @llvm.rint.f32(float  %Val)
    +  declare double    @llvm.rint.f64(double %Val)
    +  declare x86_fp80  @llvm.rint.f80(x86_fp80  %Val)
    +  declare fp128     @llvm.rint.f128(fp128 %Val)
    +  declare ppc_fp128 @llvm.rint.ppcf128(ppc_fp128  %Val)
    +
    + +
    Overview:
    +

    The 'llvm.rint.*' intrinsics returns the operand rounded to the + nearest integer. It may raise an inexact floating-point exception if the + operand isn't an integer.

    + +
    Arguments:
    +

    The argument and return value are floating point numbers of the same + type.

    + +
    Semantics:
    +

    This function returns the same values as the libm rint functions + would, and handles error conditions in the same way.

    + +
    + + +

    + 'llvm.nearbyint.*' Intrinsic +

    + +
    + +
    Syntax:
    +

    This is an overloaded intrinsic. You can use llvm.nearbyint on any + floating point or vector of floating point type. Not all targets support all + types however.

    + +
    +  declare float     @llvm.nearbyint.f32(float  %Val)
    +  declare double    @llvm.nearbyint.f64(double %Val)
    +  declare x86_fp80  @llvm.nearbyint.f80(x86_fp80  %Val)
    +  declare fp128     @llvm.nearbyint.f128(fp128 %Val)
    +  declare ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128  %Val)
    +
    + +
    Overview:
    +

    The 'llvm.nearbyint.*' intrinsics returns the operand rounded to the + nearest integer.

    + +
    Arguments:
    +

    The argument and return value are floating point numbers of the same + type.

    + +
    Semantics:
    +

    This function returns the same values as the libm nearbyint + functions would, and handles error conditions in the same way.

    + +
    + diff --git a/llvm/include/llvm/Intrinsics.td b/llvm/include/llvm/Intrinsics.td index 26a05e1..d3a548c 100644 --- a/llvm/include/llvm/Intrinsics.td +++ b/llvm/include/llvm/Intrinsics.td @@ -271,6 +271,10 @@ let Properties = [IntrReadMem] in { def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_ceil : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; } let Properties = [IntrNoMem] in { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 0af7b9a..22a757d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4996,6 +4996,26 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { getValue(I.getArgOperand(0)).getValueType(), getValue(I.getArgOperand(0)))); return 0; + case Intrinsic::ceil: + setValue(&I, DAG.getNode(ISD::FCEIL, dl, + getValue(I.getArgOperand(0)).getValueType(), + getValue(I.getArgOperand(0)))); + return 0; + case Intrinsic::trunc: + setValue(&I, DAG.getNode(ISD::FTRUNC, dl, + getValue(I.getArgOperand(0)).getValueType(), + getValue(I.getArgOperand(0)))); + return 0; + case Intrinsic::rint: + setValue(&I, DAG.getNode(ISD::FRINT, dl, + getValue(I.getArgOperand(0)).getValueType(), + getValue(I.getArgOperand(0)))); + return 0; + case Intrinsic::nearbyint: + setValue(&I, DAG.getNode(ISD::FNEARBYINT, dl, + getValue(I.getArgOperand(0)).getValueType(), + getValue(I.getArgOperand(0)))); + return 0; case Intrinsic::fma: setValue(&I, DAG.getNode(ISD::FMA, dl, getValue(I.getArgOperand(0)).getValueType(), diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index ff99b04..7b4d9fd 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -515,6 +515,10 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::FLOG10, MVT::v4f32, Expand); setOperationAction(ISD::FEXP, MVT::v4f32, Expand); setOperationAction(ISD::FEXP2, MVT::v4f32, Expand); + setOperationAction(ISD::FCEIL, MVT::v4f32, Expand); + setOperationAction(ISD::FTRUNC, MVT::v4f32, Expand); + setOperationAction(ISD::FRINT, MVT::v4f32, Expand); + setOperationAction(ISD::FNEARBYINT, MVT::v4f32, Expand); setOperationAction(ISD::FFLOOR, MVT::v4f32, Expand); // Neon does not support some operations on v1i64 and v2i64 types. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index aa0c77b8..f7a7cfa 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -348,6 +348,10 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::FDIV, VT, Expand); setOperationAction(ISD::FNEG, VT, Expand); setOperationAction(ISD::FFLOOR, VT, Expand); + setOperationAction(ISD::FCEIL, VT, Expand); + setOperationAction(ISD::FTRUNC, VT, Expand); + setOperationAction(ISD::FRINT, VT, Expand); + setOperationAction(ISD::FNEARBYINT, VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Expand); setOperationAction(ISD::INSERT_VECTOR_ELT, VT, Expand); setOperationAction(ISD::BUILD_VECTOR, VT, Expand); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 53a095f..d276353 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -727,7 +727,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) // turn on ones that can be effectively codegen'd. for (int i = MVT::FIRST_VECTOR_VALUETYPE; i <= MVT::LAST_VECTOR_VALUETYPE; ++i) { - MVT::SimpleValueType VT = (MVT::SimpleValueType)i; + MVT VT = (MVT::SimpleValueType)i; setOperationAction(ISD::ADD , VT, Expand); setOperationAction(ISD::SUB , VT, Expand); setOperationAction(ISD::FADD, VT, Expand); @@ -755,6 +755,10 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setOperationAction(ISD::FSQRT, VT, Expand); setOperationAction(ISD::FCOPYSIGN, VT, Expand); setOperationAction(ISD::FFLOOR, VT, Expand); + setOperationAction(ISD::FCEIL, VT, Expand); + setOperationAction(ISD::FTRUNC, VT, Expand); + setOperationAction(ISD::FRINT, VT, Expand); + setOperationAction(ISD::FNEARBYINT, VT, Expand); setOperationAction(ISD::SMUL_LOHI, VT, Expand); setOperationAction(ISD::UMUL_LOHI, VT, Expand); setOperationAction(ISD::SDIVREM, VT, Expand); -- 2.7.4