1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02: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:
Bjorn Pettersson 2021-05-24 23:17:18 +02:00
parent 1603844caa
commit e9cfe99a84
5 changed files with 68 additions and 71 deletions

View File

@ -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);

View File

@ -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:

View File

@ -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,

View File

@ -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.

View File

@ -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;