diff --git a/llvm/include/llvm/CodeGen/RuntimeLibcalls.h b/llvm/include/llvm/CodeGen/RuntimeLibcalls.h --- a/llvm/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/llvm/include/llvm/CodeGen/RuntimeLibcalls.h @@ -33,6 +33,15 @@ #undef HANDLE_LIBCALL }; + /// GetFPLibCall - Helper to return the right libcall for the given floating + /// point type, or UNKNOWN_LIBCALL if there is none. + Libcall getFPLibCall(EVT VT, + Libcall Call_F32, + Libcall Call_F64, + Libcall Call_F80, + Libcall Call_F128, + Libcall Call_PPCF128); + /// getFPEXT - Return the FPEXT_*_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. Libcall getFPEXT(EVT OpVT, EVT RetVT); @@ -57,6 +66,10 @@ /// UNKNOWN_LIBCALL if there is none. Libcall getUINTTOFP(EVT OpVT, EVT RetVT); + /// getPOWI - Return the POWI_* value for the given types, or + /// UNKNOWN_LIBCALL if there is none. + Libcall getPOWI(EVT RetVT); + /// Return the SYNC_FETCH_AND_* value for the given opcode and type, or /// UNKNOWN_LIBCALL if there is none. Libcall getSYNC(unsigned Opc, MVT VT); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -135,6 +135,8 @@ SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); + void ExpandFPLibCall(SDNode *Node, RTLIB::Libcall LC, + SmallVectorImpl &Results); void ExpandFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128, @@ -2035,21 +2037,10 @@ } void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, - RTLIB::Libcall Call_F32, - RTLIB::Libcall Call_F64, - RTLIB::Libcall Call_F80, - RTLIB::Libcall Call_F128, - RTLIB::Libcall Call_PPCF128, + RTLIB::Libcall LC, SmallVectorImpl &Results) { - RTLIB::Libcall LC; - switch (Node->getSimpleValueType(0).SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); - case MVT::f32: LC = Call_F32; break; - case MVT::f64: LC = Call_F64; break; - case MVT::f80: LC = Call_F80; break; - case MVT::f128: LC = Call_F128; break; - case MVT::ppcf128: LC = Call_PPCF128; break; - } + if (LC == RTLIB::UNKNOWN_LIBCALL) + llvm_unreachable("Can't create an unknown libcall!"); if (Node->isStrictFPOpcode()) { EVT RetVT = Node->getValueType(0); @@ -2068,6 +2059,20 @@ } } +/// Expand the node to a libcall based on the result type. +void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, + RTLIB::Libcall Call_F32, + RTLIB::Libcall Call_F64, + RTLIB::Libcall Call_F80, + RTLIB::Libcall Call_F128, + RTLIB::Libcall Call_PPCF128, + SmallVectorImpl &Results) { + RTLIB::Libcall LC = RTLIB::getFPLibCall(Node->getSimpleValueType(0), + Call_F32, Call_F64, Call_F80, + Call_F128, Call_PPCF128); + ExpandFPLibCall(Node, LC, Results); +} + SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, RTLIB::Libcall Call_I8, RTLIB::Libcall Call_I16, @@ -2096,32 +2101,10 @@ RTLIB::Libcall Call_PPCF128, SmallVectorImpl &Results) { EVT InVT = Node->getOperand(Node->isStrictFPOpcode() ? 1 : 0).getValueType(); - - RTLIB::Libcall LC; - switch (InVT.getSimpleVT().SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); - case MVT::f32: LC = Call_F32; break; - case MVT::f64: LC = Call_F64; break; - case MVT::f80: LC = Call_F80; break; - case MVT::f128: LC = Call_F128; break; - case MVT::ppcf128: LC = Call_PPCF128; break; - } - - if (Node->isStrictFPOpcode()) { - EVT RetVT = Node->getValueType(0); - SmallVector Ops(Node->op_begin() + 1, Node->op_end()); - TargetLowering::MakeLibCallOptions CallOptions; - // FIXME: This doesn't support tail calls. - std::pair Tmp = TLI.makeLibCall(DAG, LC, RetVT, - Ops, CallOptions, - SDLoc(Node), - Node->getOperand(0)); - Results.push_back(Tmp.first); - Results.push_back(Tmp.second); - } else { - SDValue Tmp = ExpandLibCall(LC, Node, false); - Results.push_back(Tmp); - } + RTLIB::Libcall LC = RTLIB::getFPLibCall(InVT.getSimpleVT(), + Call_F32, Call_F64, Call_F80, + Call_F128, Call_PPCF128); + ExpandFPLibCall(Node, LC, Results); } /// Issue libcalls to __{u}divmod to compute div / rem pairs. @@ -4049,15 +4032,8 @@ break; case ISD::FPOWI: case ISD::STRICT_FPOWI: { - RTLIB::Libcall LC; - switch (Node->getSimpleValueType(0).SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); - case MVT::f32: LC = RTLIB::POWI_F32; break; - case MVT::f64: LC = RTLIB::POWI_F64; break; - case MVT::f80: LC = RTLIB::POWI_F80; break; - case MVT::f128: LC = RTLIB::POWI_F128; break; - case MVT::ppcf128: LC = RTLIB::POWI_PPCF128; break; - } + RTLIB::Libcall LC = RTLIB::getPOWI(Node->getSimpleValueType(0)); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi."); if (!TLI.getLibcallName(LC)) { // Some targets don't have a powi libcall; use pow instead. SDValue Exponent = DAG.getNode(ISD::SINT_TO_FP, SDLoc(Node), @@ -4068,9 +4044,7 @@ Exponent)); break; } - ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64, - RTLIB::POWI_F80, RTLIB::POWI_F128, - RTLIB::POWI_PPCF128, Results); + ExpandFPLibCall(Node, LC, Results); break; } case ISD::FPOW: diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -26,6 +26,8 @@ #define DEBUG_TYPE "legalize-types" /// GetFPLibCall - Return the right libcall for the given floating point type. +/// FIXME: This is a local version of RTLIB::getFPLibCall that should be +/// refactored away (see RTLIB::getPOWI for an example). static RTLIB::Libcall GetFPLibCall(EVT VT, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64, @@ -572,12 +574,8 @@ unsigned Offset = IsStrict ? 1 : 0; assert(N->getOperand(1 + Offset).getValueType() == MVT::i32 && "Unsupported power type!"); - RTLIB::Libcall LC = GetFPLibCall(N->getValueType(0), - RTLIB::POWI_F32, - RTLIB::POWI_F64, - RTLIB::POWI_F80, - RTLIB::POWI_F128, - RTLIB::POWI_PPCF128); + RTLIB::Libcall LC = RTLIB::getPOWI(N->getValueType(0)); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi."); if (!TLI.getLibcallName(LC)) { // Some targets don't have a powi libcall; use pow instead. // FIXME: Implement this if some target needs it. @@ -1515,10 +1513,7 @@ void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi) { - ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0), - RTLIB::POWI_F32, RTLIB::POWI_F64, - RTLIB::POWI_F80, RTLIB::POWI_F128, - RTLIB::POWI_PPCF128), Lo, Hi); + ExpandFloatRes_Binary(N, RTLIB::getPOWI(N->getValueType(0)), Lo, Hi); } void DAGTypeLegalizer::ExpandFloatRes_FREEZE(SDNode *N, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1998,15 +1998,8 @@ // sizeof(int) the libcall might not be according to the targets ABI. Instead // we rewrite to a libcall here directly, letting makeLibCall handle promotion // if the target accepts it according to shouldSignExtendTypeInLibCall. - RTLIB::Libcall LC; - switch (N->getSimpleValueType(0).SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); - case MVT::f32: LC = RTLIB::POWI_F32; break; - case MVT::f64: LC = RTLIB::POWI_F64; break; - case MVT::f80: LC = RTLIB::POWI_F80; break; - case MVT::f128: LC = RTLIB::POWI_F128; break; - case MVT::ppcf128: LC = RTLIB::POWI_PPCF128; break; - } + RTLIB::Libcall LC = RTLIB::getPOWI(N->getValueType(0)); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi."); if (!TLI.getLibcallName(LC)) { // Some targets don't have a powi libcall; use pow instead. // FIXME: Implement this if some target needs it. diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -211,6 +211,23 @@ } } +/// GetFPLibCall - Helper to return the right libcall for the given floating +/// point type, or UNKNOWN_LIBCALL if there is none. +RTLIB::Libcall RTLIB::getFPLibCall(EVT VT, + RTLIB::Libcall Call_F32, + RTLIB::Libcall Call_F64, + RTLIB::Libcall Call_F80, + RTLIB::Libcall Call_F128, + RTLIB::Libcall Call_PPCF128) { + return + VT == MVT::f32 ? Call_F32 : + VT == MVT::f64 ? Call_F64 : + VT == MVT::f80 ? Call_F80 : + VT == MVT::f128 ? Call_F128 : + VT == MVT::ppcf128 ? Call_PPCF128 : + RTLIB::UNKNOWN_LIBCALL; +} + /// getFPEXT - Return the FPEXT_*_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) { @@ -469,6 +486,11 @@ return UNKNOWN_LIBCALL; } +RTLIB::Libcall RTLIB::getPOWI(EVT RetVT) { + return getFPLibCall(RetVT, POWI_F32, POWI_F64, POWI_F80, POWI_F128, + POWI_PPCF128); +} + RTLIB::Libcall RTLIB::getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT) { unsigned ModeN, ModelN;