mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-26 20:57:15 +00:00
Make default expansion for FP16 <-> FP32 nodes into libcalls
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98501 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be5b032e4b
commit
927411b7ce
@ -153,6 +153,8 @@ namespace RTLIB {
|
||||
|
||||
// CONVERSION
|
||||
FPEXT_F32_F64,
|
||||
FPEXT_F16_F32,
|
||||
FPROUND_F32_F16,
|
||||
FPROUND_F64_F32,
|
||||
FPROUND_F80_F32,
|
||||
FPROUND_PPCF128_F32,
|
||||
|
@ -345,6 +345,8 @@ def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
|
||||
def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
|
||||
def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
|
||||
def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
|
||||
def f16_to_f32 : SDNode<"ISD::FP16_TO_FP32", SDTIntToFPOp>;
|
||||
def f32_to_f16 : SDNode<"ISD::FP32_TO_FP16", SDTFPToIntOp>;
|
||||
|
||||
def setcc : SDNode<"ISD::SETCC" , SDTSetCC>;
|
||||
def select : SDNode<"ISD::SELECT" , SDTSelect>;
|
||||
|
@ -851,6 +851,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
case ISD::MERGE_VALUES:
|
||||
case ISD::EH_RETURN:
|
||||
case ISD::FRAME_TO_ARGS_OFFSET:
|
||||
case ISD::FP16_TO_FP32:
|
||||
case ISD::FP32_TO_FP16:
|
||||
// These operations lie about being legal: when they claim to be legal,
|
||||
// they should actually be expanded.
|
||||
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
|
||||
@ -2636,6 +2638,12 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
|
||||
Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
|
||||
RTLIB::REM_F80, RTLIB::REM_PPCF128));
|
||||
break;
|
||||
case ISD::FP16_TO_FP32:
|
||||
Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false));
|
||||
break;
|
||||
case ISD::FP32_TO_FP16:
|
||||
Results.push_back(ExpandLibCall(RTLIB::FPROUND_F32_F16, Node, false));
|
||||
break;
|
||||
case ISD::ConstantFP: {
|
||||
ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node);
|
||||
// Check to see if this FP immediate is already legal.
|
||||
|
@ -79,6 +79,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
|
||||
case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
|
||||
case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
|
||||
case ISD::FP16_TO_FP32:R = SoftenFloatRes_FP16_TO_FP32(N); break;
|
||||
case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break;
|
||||
case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break;
|
||||
case ISD::FREM: R = SoftenFloatRes_FREM(N); break;
|
||||
@ -332,6 +333,14 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
|
||||
return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
|
||||
}
|
||||
|
||||
// FIXME: Should we just use 'normal' FP_EXTEND / FP_TRUNC instead of special
|
||||
// nodes?
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FP16_TO_FP32(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
SDValue Op = N->getOperand(0);
|
||||
return MakeLibCall(RTLIB::FPEXT_F16_F32, NVT, &Op, 1, false, N->getDebugLoc());
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
SDValue Op = N->getOperand(0);
|
||||
@ -548,6 +557,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
|
||||
case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
|
||||
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
|
||||
case ISD::FP32_TO_FP16:Res = SoftenFloatOp_FP32_TO_FP16(N); break;
|
||||
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
|
||||
case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break;
|
||||
@ -704,6 +714,13 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
|
||||
return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP32_TO_FP16(SDNode *N) {
|
||||
EVT RVT = N->getValueType(0);
|
||||
RTLIB::Libcall LC = RTLIB::FPROUND_F32_F16;
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
|
||||
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||
|
@ -80,6 +80,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break;
|
||||
|
||||
case ISD::FP32_TO_FP16:Res = PromoteIntRes_FP32_TO_FP16(N); break;
|
||||
|
||||
case ISD::AND:
|
||||
case ISD::OR:
|
||||
case ISD::XOR:
|
||||
@ -324,6 +326,16 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
|
||||
NVT, Res, DAG.getValueType(N->getValueType(0)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_FP32_TO_FP16(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
|
||||
|
||||
return DAG.getNode(ISD::AssertZext, dl,
|
||||
NVT, Res, DAG.getValueType(N->getValueType(0)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
@ -634,6 +646,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
||||
OpNo); break;
|
||||
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
|
||||
case ISD::FP16_TO_FP32:
|
||||
case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
|
||||
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
|
||||
|
||||
|
@ -257,6 +257,7 @@ private:
|
||||
SDValue PromoteIntRes_CTTZ(SDNode *N);
|
||||
SDValue PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
|
||||
SDValue PromoteIntRes_FP_TO_XINT(SDNode *N);
|
||||
SDValue PromoteIntRes_FP32_TO_FP16(SDNode *N);
|
||||
SDValue PromoteIntRes_INT_EXTEND(SDNode *N);
|
||||
SDValue PromoteIntRes_LOAD(LoadSDNode *N);
|
||||
SDValue PromoteIntRes_Overflow(SDNode *N);
|
||||
@ -406,6 +407,7 @@ private:
|
||||
SDValue SoftenFloatRes_FNEARBYINT(SDNode *N);
|
||||
SDValue SoftenFloatRes_FNEG(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP_EXTEND(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP16_TO_FP32(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP_ROUND(SDNode *N);
|
||||
SDValue SoftenFloatRes_FPOW(SDNode *N);
|
||||
SDValue SoftenFloatRes_FPOWI(SDNode *N);
|
||||
@ -429,6 +431,7 @@ private:
|
||||
SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_SINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_UINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP32_TO_FP16(SDNode *N);
|
||||
SDValue SoftenFloatOp_SELECT_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_SETCC(SDNode *N);
|
||||
SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo);
|
||||
|
@ -5665,6 +5665,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::FP_TO_SINT: return "fp_to_sint";
|
||||
case ISD::FP_TO_UINT: return "fp_to_uint";
|
||||
case ISD::BIT_CONVERT: return "bit_convert";
|
||||
case ISD::FP16_TO_FP32: return "fp16_to_fp32";
|
||||
case ISD::FP32_TO_FP16: return "fp32_to_fp16";
|
||||
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
switch (cast<CvtRndSatSDNode>(this)->getCvtCode()) {
|
||||
|
@ -175,6 +175,8 @@ static void InitLibcallNames(const char **Names) {
|
||||
Names[RTLIB::FLOOR_F80] = "floorl";
|
||||
Names[RTLIB::FLOOR_PPCF128] = "floorl";
|
||||
Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2";
|
||||
Names[RTLIB::FPEXT_F16_F32] = "__gnu_h2f_ieee";
|
||||
Names[RTLIB::FPROUND_F32_F16] = "__gnu_f2h_ieee";
|
||||
Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2";
|
||||
Names[RTLIB::FPROUND_F80_F32] = "__truncxfsf2";
|
||||
Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2";
|
||||
@ -269,6 +271,7 @@ RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) {
|
||||
if (RetVT == MVT::f64)
|
||||
return FPEXT_F32_F64;
|
||||
}
|
||||
|
||||
return UNKNOWN_LIBCALL;
|
||||
}
|
||||
|
||||
@ -288,6 +291,7 @@ RTLIB::Libcall RTLIB::getFPROUND(EVT OpVT, EVT RetVT) {
|
||||
if (OpVT == MVT::ppcf128)
|
||||
return FPROUND_PPCF128_F64;
|
||||
}
|
||||
|
||||
return UNKNOWN_LIBCALL;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user