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
137 changes: 14 additions & 123 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
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