summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-07-17 10:51:23 +0000
committerTim Northover <tnorthover@apple.com>2014-07-17 10:51:23 +0000
commitfd7e4249359f510d21c2b682176cdb28dfa4e7e4 (patch)
treec6f154b34d59f3708bea28534939101fdc74b37d /llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
parent2355066e4303a8c948ee9c7b8e3f28d778eb2180 (diff)
downloadbcm5719-llvm-fd7e4249359f510d21c2b682176cdb28dfa4e7e4.tar.gz
bcm5719-llvm-fd7e4249359f510d21c2b682176cdb28dfa4e7e4.zip
CodeGen: extend f16 conversions to permit types > float.
This makes the two intrinsics @llvm.convert.from.f16 and @llvm.convert.to.f16 accept types other than simple "float". This is only strictly needed for the truncate operation, since otherwise double rounding occurs and there's no way to represent the strict IEEE conversion. However, for symmetry we allow larger types in the extend too. During legalization, we can expand an "fp16_to_double" operation into two extends for convenience, but abort when the truncate isn't legal. A new libcall is probably needed here. Even after this commit, various target tweaks are needed to actually use the extended intrinsics. I've put these into separate commits for clarity, so there are no actual tests of f64 conversion here. llvm-svn: 213248
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index bff540ad174..58f290e1137 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1186,6 +1186,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
if (Action != TargetLowering::Promote)
Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other);
break;
+ case ISD::FP_TO_FP16:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
case ISD::EXTRACT_VECTOR_ELT:
@@ -3513,10 +3514,26 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
RTLIB::FMA_F80, RTLIB::FMA_F128,
RTLIB::FMA_PPCF128));
break;
- case ISD::FP16_TO_FP32:
- Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false));
+ case ISD::FP16_TO_FP: {
+ if (Node->getValueType(0) == MVT::f32) {
+ Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false));
+ break;
+ }
+
+ // We can extend to types bigger than f32 in two steps without changing the
+ // result. Since "f16 -> f32" is much more commonly available, give CodeGen
+ // the option of emitting that before resorting to a libcall.
+ SDValue Res =
+ DAG.getNode(ISD::FP16_TO_FP, dl, MVT::f32, Node->getOperand(0));
+ Results.push_back(
+ DAG.getNode(ISD::FP_EXTEND, dl, Node->getValueType(0), Res));
break;
- case ISD::FP32_TO_FP16:
+ }
+ case ISD::FP_TO_FP16:
+ // Can't use two-step truncation here because the rounding may be
+ // significant.
+ assert(Node->getOperand(0).getValueType() == MVT::f32 &&
+ "Don't know libcall for FPROUND_F64_F16");
Results.push_back(ExpandLibCall(RTLIB::FPROUND_F32_F16, Node, false));
break;
case ISD::ConstantFP: {
OpenPOWER on IntegriCloud