Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,46 @@
namespace llvm {
namespace RTLIB {

/// \return The SHL_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getSHL(EVT VT);

/// \return The SRL_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getSRL(EVT VT);

/// \return The SRA_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getSRA(EVT VT);

/// \return The MUL_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getMUL(EVT VT);

/// \return The MULO_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getMULO(EVT VT);

/// \return The SDIV_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getSDIV(EVT VT);

/// \return The UDIV_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getUDIV(EVT VT);

/// \return The SREM_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getSREM(EVT VT);

/// \return The UREM_* value for the given types, or UNKNOWN_LIBCALL if there is
/// none.
LLVM_ABI Libcall getUREM(EVT VT);

/// \return The CTPOP_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getCTPOP(EVT VT);

/// GetFPLibCall - Helper to return the right libcall for the given floating
/// point type, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64,
Expand Down Expand Up @@ -90,7 +130,23 @@ LLVM_ABI Libcall getSINCOS_STRET(EVT RetVT);

/// getMODF - Return the MODF_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT RetVT);
LLVM_ABI Libcall getMODF(EVT VT);

/// \return the LROUND_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getLROUND(EVT VT);

/// \return the LLROUND_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getLLROUND(EVT VT);

/// \return the LRINT_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getLRINT(EVT RetVT);

/// \return the LLRINT_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getLLRINT(EVT RetVT);

/// Return the SYNC_FETCH_AND_* value for the given opcode and type, or
/// UNKNOWN_LIBCALL if there is none.
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3878,7 +3878,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
RTLIB::Libcall LC = RTLIB::getLDEXP(VT);
// Use the LibCall instead, it is very likely faster
// FIXME: Use separate LibCall action.
if (TLI.getLibcallName(LC))
if (TLI.getLibcallImpl(LC) != RTLIB::Unsupported)
break;

if (SDValue Expanded = expandLdexp(Node)) {
Expand All @@ -3893,7 +3893,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
RTLIB::Libcall LC = RTLIB::getFREXP(Node->getValueType(0));
// Use the LibCall instead, it is very likely faster
// FIXME: Use separate LibCall action.
if (TLI.getLibcallName(LC))
if (TLI.getLibcallImpl(LC) != RTLIB::Unsupported)
break;

if (SDValue Expanded = expandFrexp(Node)) {
Expand Down Expand Up @@ -4695,7 +4695,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
RTLIB::Libcall LC = RTLIB::getOUTLINE_ATOMIC(Opc, Order, VT);
EVT RetVT = Node->getValueType(0);
SmallVector<SDValue, 4> Ops;
if (TLI.getLibcallName(LC)) {
if (TLI.getLibcallImpl(LC) != RTLIB::Unsupported) {
// If outline atomic available, prepare its arguments and expand.
Ops.append(Node->op_begin() + 2, Node->op_end());
Ops.push_back(Node->getOperand(1));
Expand Down Expand Up @@ -4961,7 +4961,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
case ISD::STRICT_FPOWI: {
RTLIB::Libcall LC = RTLIB::getPOWI(Node->getSimpleValueType(0));
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi.");
if (!TLI.getLibcallName(LC)) {
if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) {
// Some targets don't have a powi libcall; use pow instead.
if (Node->isStrictFPOpcode()) {
SDValue Exponent =
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ExpOp(SDNode *N) {
RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
: RTLIB::getLDEXP(N->getValueType(0));
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi.");
if (!TLI.getLibcallName(LC)) {
if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) {
// Some targets don't have a powi libcall; use pow instead.
// FIXME: Implement this if some target needs it.
DAG.getContext()->emitError("do not know how to soften fpowi to fpow");
Expand Down Expand Up @@ -802,7 +802,7 @@ bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
assert(VT == N->getValueType(1) &&
"expected both return values to have the same type");

if (!TLI.getLibcallName(LC))
if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported)
return false;

EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
Expand Down Expand Up @@ -862,7 +862,8 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
RTLIB::Libcall CosLC = RTLIB::getCOS(VT);

SDValue SoftSin, SoftCos;
if (!TLI.getLibcallName(SinLC) || !TLI.getLibcallName(CosLC)) {
if (TLI.getLibcallImpl(SinLC) == RTLIB::Unsupported ||
TLI.getLibcallImpl(CosLC) == RTLIB::Unsupported) {
DAG.getContext()->emitError("do not know how to soften fsincos");

EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
Expand Down
139 changes: 15 additions & 124 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2692,7 +2692,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
: RTLIB::getLDEXP(N->getValueType(0));

if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) {
// Scalarize vector FPOWI instead of promoting the type. This allows the
// scalar FPOWIs to be visited and converted to libcalls before promoting
// the type.
Expand Down Expand Up @@ -4097,13 +4097,7 @@ void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDLoc DL(N);

if (TLI.getOperationAction(ISD::CTPOP, VT) == TargetLoweringBase::LibCall) {
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
LC = RTLIB::CTPOP_I32;
else if (VT == MVT::i64)
LC = RTLIB::CTPOP_I64;
else if (VT == MVT::i128)
LC = RTLIB::CTPOP_I128;
RTLIB::Libcall LC = RTLIB::getCTPOP(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC) &&
"LibCall explicitly requested, but not available");
TargetLowering::MakeLibCallOptions CallOptions;
Expand Down Expand Up @@ -4236,55 +4230,19 @@ void DAGTypeLegalizer::ExpandIntRes_XROUND_XRINT(SDNode *N, SDValue &Lo,
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (N->getOpcode() == ISD::LROUND ||
N->getOpcode() == ISD::STRICT_LROUND) {
if (VT == MVT::f32)
LC = RTLIB::LROUND_F32;
else if (VT == MVT::f64)
LC = RTLIB::LROUND_F64;
else if (VT == MVT::f80)
LC = RTLIB::LROUND_F80;
else if (VT == MVT::f128)
LC = RTLIB::LROUND_F128;
else if (VT == MVT::ppcf128)
LC = RTLIB::LROUND_PPCF128;
LC = RTLIB::getLROUND(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lround input type!");
} else if (N->getOpcode() == ISD::LRINT ||
N->getOpcode() == ISD::STRICT_LRINT) {
if (VT == MVT::f32)
LC = RTLIB::LRINT_F32;
else if (VT == MVT::f64)
LC = RTLIB::LRINT_F64;
else if (VT == MVT::f80)
LC = RTLIB::LRINT_F80;
else if (VT == MVT::f128)
LC = RTLIB::LRINT_F128;
else if (VT == MVT::ppcf128)
LC = RTLIB::LRINT_PPCF128;
LC = RTLIB::getLRINT(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected lrint input type!");
} else if (N->getOpcode() == ISD::LLROUND ||
N->getOpcode() == ISD::STRICT_LLROUND) {
if (VT == MVT::f32)
LC = RTLIB::LLROUND_F32;
else if (VT == MVT::f64)
LC = RTLIB::LLROUND_F64;
else if (VT == MVT::f80)
LC = RTLIB::LLROUND_F80;
else if (VT == MVT::f128)
LC = RTLIB::LLROUND_F128;
else if (VT == MVT::ppcf128)
LC = RTLIB::LLROUND_PPCF128;
LC = RTLIB::getLLROUND(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llround input type!");
} else if (N->getOpcode() == ISD::LLRINT ||
N->getOpcode() == ISD::STRICT_LLRINT) {
if (VT == MVT::f32)
LC = RTLIB::LLRINT_F32;
else if (VT == MVT::f64)
LC = RTLIB::LLRINT_F64;
else if (VT == MVT::f80)
LC = RTLIB::LLRINT_F80;
else if (VT == MVT::f128)
LC = RTLIB::LLRINT_F128;
else if (VT == MVT::ppcf128)
LC = RTLIB::LLRINT_PPCF128;
LC = RTLIB::getLLRINT(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected llrint input type!");
} else
llvm_unreachable("Unexpected opcode!");
Expand Down Expand Up @@ -4444,15 +4402,7 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
return;

// If nothing else, we can make a libcall.
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i16)
LC = RTLIB::MUL_I16;
else if (VT == MVT::i32)
LC = RTLIB::MUL_I32;
else if (VT == MVT::i64)
LC = RTLIB::MUL_I64;
else if (VT == MVT::i128)
LC = RTLIB::MUL_I128;
RTLIB::Libcall LC = RTLIB::getMUL(VT);

if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
// Perform a wide multiplication where the wide type is the original VT and
Expand Down Expand Up @@ -4824,15 +4774,7 @@ void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
return;
}

RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i16)
LC = RTLIB::SDIV_I16;
else if (VT == MVT::i32)
LC = RTLIB::SDIV_I32;
else if (VT == MVT::i64)
LC = RTLIB::SDIV_I64;
else if (VT == MVT::i128)
LC = RTLIB::SDIV_I128;
RTLIB::Libcall LC = RTLIB::getSDIV(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");

TargetLowering::MakeLibCallOptions CallOptions;
Expand Down Expand Up @@ -5039,35 +4981,14 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
bool isSigned;
if (Opc == ISD::SHL) {
isSigned = false; /*sign irrelevant*/
if (VT == MVT::i16)
LC = RTLIB::SHL_I16;
else if (VT == MVT::i32)
LC = RTLIB::SHL_I32;
else if (VT == MVT::i64)
LC = RTLIB::SHL_I64;
else if (VT == MVT::i128)
LC = RTLIB::SHL_I128;
LC = RTLIB::getSHL(VT);
} else if (Opc == ISD::SRL) {
isSigned = false;
if (VT == MVT::i16)
LC = RTLIB::SRL_I16;
else if (VT == MVT::i32)
LC = RTLIB::SRL_I32;
else if (VT == MVT::i64)
LC = RTLIB::SRL_I64;
else if (VT == MVT::i128)
LC = RTLIB::SRL_I128;
LC = RTLIB::getSRL(VT);
} else {
assert(Opc == ISD::SRA && "Unknown shift!");
isSigned = true;
if (VT == MVT::i16)
LC = RTLIB::SRA_I16;
else if (VT == MVT::i32)
LC = RTLIB::SRA_I32;
else if (VT == MVT::i64)
LC = RTLIB::SRA_I64;
else if (VT == MVT::i128)
LC = RTLIB::SRA_I128;
LC = RTLIB::getSRA(VT);
}

if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
Expand Down Expand Up @@ -5153,15 +5074,7 @@ void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
return;
}

RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i16)
LC = RTLIB::SREM_I16;
else if (VT == MVT::i32)
LC = RTLIB::SREM_I32;
else if (VT == MVT::i64)
LC = RTLIB::SREM_I64;
else if (VT == MVT::i128)
LC = RTLIB::SREM_I128;
RTLIB::Libcall LC = RTLIB::getSREM(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");

TargetLowering::MakeLibCallOptions CallOptions;
Expand Down Expand Up @@ -5244,13 +5157,7 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());

// Replace this with a libcall that will check overflow.
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
LC = RTLIB::MULO_I32;
else if (VT == MVT::i64)
LC = RTLIB::MULO_I64;
else if (VT == MVT::i128)
LC = RTLIB::MULO_I128;
RTLIB::Libcall LC = RTLIB::getMULO(VT);

// If we don't have the libcall or if the function we are compiling is the
// implementation of the expected libcall (avoid inf-loop), expand inline.
Expand Down Expand Up @@ -5341,15 +5248,7 @@ void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
}
}

RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i16)
LC = RTLIB::UDIV_I16;
else if (VT == MVT::i32)
LC = RTLIB::UDIV_I32;
else if (VT == MVT::i64)
LC = RTLIB::UDIV_I64;
else if (VT == MVT::i128)
LC = RTLIB::UDIV_I128;
RTLIB::Libcall LC = RTLIB::getUDIV(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");

TargetLowering::MakeLibCallOptions CallOptions;
Expand Down Expand Up @@ -5384,15 +5283,7 @@ void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
}
}

RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i16)
LC = RTLIB::UREM_I16;
else if (VT == MVT::i32)
LC = RTLIB::UREM_I32;
else if (VT == MVT::i64)
LC = RTLIB::UREM_I64;
else if (VT == MVT::i128)
LC = RTLIB::UREM_I128;
RTLIB::Libcall LC = RTLIB::getUREM(VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");

TargetLowering::MakeLibCallOptions CallOptions;
Expand Down
Loading