From 490104720db9e1e0eb9cc27e88e2d7288ac27ff0 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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168025 91177308-0d34-0410-b5e6-96231b3b80d8
---
docs/LangRef.html | 141 ++++++++++++++++++
include/llvm/Intrinsics.td | 4 +
.../SelectionDAG/SelectionDAGBuilder.cpp | 20 +++
lib/Target/ARM/ARMISelLowering.cpp | 4 +
lib/Target/PowerPC/PPCISelLowering.cpp | 4 +
lib/Target/X86/X86ISelLowering.cpp | 6 +-
6 files changed, 178 insertions(+), 1 deletion(-)
diff --git a/docs/LangRef.html b/docs/LangRef.html
index cdb76848e2d..9c4c4eefd69 100644
--- a/docs/LangRef.html
+++ b/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.
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
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/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 26a05e1e16c..d3a548cd4e6 100644
--- a/include/llvm/Intrinsics.td
+++ b/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/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 0af7b9aa3fc..22a757d3d40 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/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/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index ff99b04078e..7b4d9fdaf95 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/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/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index aa0c77b808a..f7a7cfa890c 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/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/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 53a095f7180..d276353cca6 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/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);