mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[CodeGen] Refactor libcall lookups for RTLIB::POWI_*
Use RuntimeLibcalls to get a common way to pick correct RTLIB::POWI_* libcall for a given value type. This includes a small refactoring of ExpandFPLibCall and ExpandArgFPLibCall in SelectionDAGLegalize to share a bit of code, plus adding an ExpandFPLibCall version that can be called directly when expanding FPOWI/STRICT_FPOWI to ensure that we actually use the same RTLIB::Libcall when expanding the libcall as we used when checking the legality of such a call by doing a getLibcallName check. Differential Revision: https://reviews.llvm.org/D103050
This commit is contained in:
parent
1603844caa
commit
e9cfe99a84
@ -33,6 +33,15 @@ namespace RTLIB {
|
||||
#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 @@ namespace RTLIB {
|
||||
/// 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);
|
||||
|
@ -135,6 +135,8 @@ private:
|
||||
|
||||
SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned);
|
||||
|
||||
void ExpandFPLibCall(SDNode *Node, RTLIB::Libcall LC,
|
||||
SmallVectorImpl<SDValue> &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 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
|
||||
}
|
||||
|
||||
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<SDValue> &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 @@ void SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<SDValue> &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 @@ void SelectionDAGLegalize::ExpandArgFPLibCall(SDNode* Node,
|
||||
RTLIB::Libcall Call_PPCF128,
|
||||
SmallVectorImpl<SDValue> &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<SDValue, 4> Ops(Node->op_begin() + 1, Node->op_end());
|
||||
TargetLowering::MakeLibCallOptions CallOptions;
|
||||
// FIXME: This doesn't support tail calls.
|
||||
std::pair<SDValue, SDValue> 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 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
||||
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 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
|
||||
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:
|
||||
|
@ -26,6 +26,8 @@ using namespace llvm;
|
||||
#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 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
|
||||
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_FPOW(SDNode *N,
|
||||
|
||||
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,
|
||||
|
@ -1998,15 +1998,8 @@ SDValue DAGTypeLegalizer::PromoteIntOp_FPOWI(SDNode *N) {
|
||||
// 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.
|
||||
|
@ -211,6 +211,23 @@ void TargetLoweringBase::InitLibcalls(const Triple &TT) {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user