Skip to content
Open
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
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ LLVM_ABI Libcall getSINCOS_STRET(EVT RetVT);
/// UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT VT);

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

/// \return the LROUND_* value for the given types, or UNKNOWN_LIBCALL if there
/// is none.
LLVM_ABI Libcall getLROUND(EVT VT);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ class SelectionDAG {
// to provide debug info for the BB at that time, so keep this one around.
LLVM_ABI SDValue getBasicBlock(MachineBasicBlock *MBB);
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT);
LLVM_ABI SDValue getExternalSymbol(RTLIB::LibcallImpl LCImpl, EVT VT);
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT,
unsigned TargetFlags = 0);
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT);
Expand Down
22 changes: 11 additions & 11 deletions llvm/include/llvm/IR/RuntimeLibcalls.td
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ foreach S = !listconcat(F32VectorSuffixes, F64VectorSuffixes) in {
def FMA_#S : RuntimeLibcall;
def FMAX_#S : RuntimeLibcall;
def FMIN_#S : RuntimeLibcall;
def FMOD_#S : RuntimeLibcall;
def REM_#S : RuntimeLibcall; // "fmod"
def HYPOT_#S : RuntimeLibcall;
def ILOGB_#S : RuntimeLibcall;
def LDEXP_#S : RuntimeLibcall;
Expand Down Expand Up @@ -3919,7 +3919,7 @@ defset list<RuntimeLibcallImpl> SLEEFGNUABI_VF2_VECFUNCS = {
def _ZGVnN2vv_fdim : RuntimeLibcallImpl<FDIM_V2F64>;
def _ZGVnN2vv_fmax : RuntimeLibcallImpl<FMAX_V2F64>;
def _ZGVnN2vv_fmin : RuntimeLibcallImpl<FMIN_V2F64>;
def _ZGVnN2vv_fmod : RuntimeLibcallImpl<FMOD_V2F64>;
def _ZGVnN2vv_fmod : RuntimeLibcallImpl<REM_V2F64>;
def _ZGVnN2vv_hypot : RuntimeLibcallImpl<HYPOT_V2F64>;
def _ZGVnN2vv_ldexp : RuntimeLibcallImpl<LDEXP_V2F64>;
def _ZGVnN2vv_nextafter : RuntimeLibcallImpl<NEXTAFTER_V2F64>;
Expand Down Expand Up @@ -3965,7 +3965,7 @@ defset list<RuntimeLibcallImpl> SLEEFGNUABI_VF4_VECFUNCS = {
def _ZGVnN4vv_fdimf : RuntimeLibcallImpl<FDIM_V4F32>;
def _ZGVnN4vv_fmaxf : RuntimeLibcallImpl<FMAX_V4F32>;
def _ZGVnN4vv_fminf : RuntimeLibcallImpl<FMIN_V4F32>;
def _ZGVnN4vv_fmodf : RuntimeLibcallImpl<FMOD_V4F32>;
def _ZGVnN4vv_fmodf : RuntimeLibcallImpl<REM_V4F32>;
def _ZGVnN4vv_hypotf : RuntimeLibcallImpl<HYPOT_V4F32>;
def _ZGVnN4vv_ldexpf : RuntimeLibcallImpl<LDEXP_V4F32>;
def _ZGVnN4vv_nextafterf : RuntimeLibcallImpl<NEXTAFTER_V4F32>;
Expand Down Expand Up @@ -4042,8 +4042,8 @@ defset list<RuntimeLibcallImpl> SLEEFGNUABI_SCALABLE_VECFUNCS = {
def _ZGVsMxvv_fmaxf : RuntimeLibcallImpl<FMAX_NXV4F32>;
def _ZGVsMxvv_fmin : RuntimeLibcallImpl<FMIN_NXV2F64>;
def _ZGVsMxvv_fminf : RuntimeLibcallImpl<FMIN_NXV4F32>;
def _ZGVsMxvv_fmod : RuntimeLibcallImpl<FMOD_NXV2F64>;
def _ZGVsMxvv_fmodf : RuntimeLibcallImpl<FMOD_NXV4F32>;
def _ZGVsMxvv_fmod : RuntimeLibcallImpl<REM_NXV2F64>;
def _ZGVsMxvv_fmodf : RuntimeLibcallImpl<REM_NXV4F32>;
def _ZGVsMxvv_hypot : RuntimeLibcallImpl<HYPOT_NXV2F64>;
def _ZGVsMxvv_hypotf : RuntimeLibcallImpl<HYPOT_NXV4F32>;
def _ZGVsMxvv_ldexp : RuntimeLibcallImpl<LDEXP_NXV2F64>;
Expand Down Expand Up @@ -4107,8 +4107,8 @@ defset list<RuntimeLibcallImpl> SLEEFGNUABI_SCALABLE_VECFUNCS_RISCV = {
def Sleef_fmaxfx_rvvm2 : RuntimeLibcallImpl<FMAX_NXV4F32>;
def Sleef_fmindx_u10rvvm2 : RuntimeLibcallImpl<FMIN_NXV2F64>;
def Sleef_fminfx_u10rvvm2 : RuntimeLibcallImpl<FMIN_NXV4F32>;
def Sleef_fmoddx_rvvm2 : RuntimeLibcallImpl<FMOD_NXV2F64>;
def Sleef_fmodfx_rvvm2 : RuntimeLibcallImpl<FMOD_NXV4F32>;
def Sleef_fmoddx_rvvm2 : RuntimeLibcallImpl<REM_NXV2F64>;
def Sleef_fmodfx_rvvm2 : RuntimeLibcallImpl<REM_NXV4F32>;
def Sleef_hypotdx_u05rvvm2 : RuntimeLibcallImpl<HYPOT_NXV2F64>;
def Sleef_hypotfx_u05rvvm2 : RuntimeLibcallImpl<HYPOT_NXV4F32>;
def Sleef_ilogbdx_rvvm2 : RuntimeLibcallImpl<ILOGB_NXV2F64>;
Expand Down Expand Up @@ -4200,8 +4200,8 @@ defset list<RuntimeLibcallImpl> ARMPL_VECFUNCS = {
def armpl_svfmax_f64_x : RuntimeLibcallImpl<FMAX_NXV2F64>;
def armpl_svfmin_f32_x : RuntimeLibcallImpl<FMIN_NXV4F32>;
def armpl_svfmin_f64_x : RuntimeLibcallImpl<FMIN_NXV2F64>;
def armpl_svfmod_f32_x : RuntimeLibcallImpl<FMOD_NXV4F32>;
def armpl_svfmod_f64_x : RuntimeLibcallImpl<FMOD_NXV2F64>;
def armpl_svfmod_f32_x : RuntimeLibcallImpl<REM_NXV4F32>;
def armpl_svfmod_f64_x : RuntimeLibcallImpl<REM_NXV2F64>;
def armpl_svhypot_f32_x : RuntimeLibcallImpl<HYPOT_NXV4F32>;
def armpl_svhypot_f64_x : RuntimeLibcallImpl<HYPOT_NXV2F64>;
def armpl_svilogb_f32_x : RuntimeLibcallImpl<ILOGB_NXV4F32>;
Expand Down Expand Up @@ -4286,8 +4286,8 @@ defset list<RuntimeLibcallImpl> ARMPL_VECFUNCS = {
def armpl_vfmaxq_f64 : RuntimeLibcallImpl<FMAX_V2F64>;
def armpl_vfminq_f32 : RuntimeLibcallImpl<FMIN_V4F32>;
def armpl_vfminq_f64 : RuntimeLibcallImpl<FMIN_V2F64>;
def armpl_vfmodq_f32 : RuntimeLibcallImpl<FMOD_V4F32>;
def armpl_vfmodq_f64 : RuntimeLibcallImpl<FMOD_V2F64>;
def armpl_vfmodq_f32 : RuntimeLibcallImpl<REM_V4F32>;
def armpl_vfmodq_f64 : RuntimeLibcallImpl<REM_V2F64>;
def armpl_vhypotq_f32 : RuntimeLibcallImpl<HYPOT_V4F32>;
def armpl_vhypotq_f64 : RuntimeLibcallImpl<HYPOT_V2F64>;
def armpl_vilogbq_f32 : RuntimeLibcallImpl<ILOGB_V4F32>;
Expand Down
15 changes: 7 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2127,8 +2127,9 @@ SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
bool IsSigned, EVT RetVT) {
EVT CodePtrTy = TLI.getPointerTy(DAG.getDataLayout());
SDValue Callee;
if (const char *LibcallName = TLI.getLibcallName(LC))
Callee = DAG.getExternalSymbol(LibcallName, CodePtrTy);
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl != RTLIB::Unsupported)
Callee = DAG.getExternalSymbol(LCImpl, CodePtrTy);
else {
Callee = DAG.getPOISON(CodePtrTy);
DAG.getContext()->emitError(Twine("no libcall available for ") +
Expand Down Expand Up @@ -2157,7 +2158,7 @@ SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
bool signExtend = TLI.shouldSignExtendTypeInLibCall(RetTy, IsSigned);
CLI.setDebugLoc(SDLoc(Node))
.setChain(InChain)
.setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
.setLibCallee(TLI.getLibcallImplCallingConv(LCImpl), RetTy, Callee,
std::move(Args))
.setTailCall(isTailCall)
.setSExtResult(signExtend)
Expand Down Expand Up @@ -2392,8 +2393,7 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
}

SDValue Callee =
DAG.getExternalSymbol(TLI.getLibcallImplName(LibcallImpl).data(),
TLI.getPointerTy(DAG.getDataLayout()));
DAG.getExternalSymbol(LibcallImpl, TLI.getPointerTy(DAG.getDataLayout()));

SDLoc dl(Node);
TargetLowering::CallLoweringInfo CLI(DAG);
Expand Down Expand Up @@ -2461,10 +2461,9 @@ SDValue SelectionDAGLegalize::ExpandSincosStretLibCall(SDNode *Node) const {

Type *SincosStretRetTy = FuncTy->getReturnType();
CallingConv::ID CallConv = CallsInfo.getLibcallImplCallingConv(SincosStret);
StringRef LibcallImplName = CallsInfo.getLibcallImplName(SincosStret);

SDValue Callee = DAG.getExternalSymbol(LibcallImplName.data(),
TLI.getProgramPointerTy(DL));
SDValue Callee =
DAG.getExternalSymbol(SincosStret, TLI.getProgramPointerTy(DL));

TargetLowering::ArgListTy Args;
SDValue SRet;
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5213,8 +5213,7 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
Entry.IsZExt = false;
Args.push_back(Entry);

SDValue Func =
DAG.getExternalSymbol(TLI.getLibcallImplName(LCImpl).data(), PtrVT);
SDValue Func = DAG.getExternalSymbol(LCImpl, PtrVT);

TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(dl)
Expand Down
114 changes: 35 additions & 79 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,6 @@ class VectorLegalizer {

bool tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
SmallVectorImpl<SDValue> &Results);
bool tryExpandVecMathCall(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);

void UnrollStrictFPOp(SDNode *Node, SmallVectorImpl<SDValue> &Results);

Expand Down Expand Up @@ -1261,13 +1256,13 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
return;
}
break;
case ISD::FREM:
if (tryExpandVecMathCall(Node, RTLIB::REM_F32, RTLIB::REM_F64,
RTLIB::REM_F80, RTLIB::REM_F128,
RTLIB::REM_PPCF128, Results))
case ISD::FREM: {
RTLIB::Libcall LC = RTLIB::getREM(Node->getValueType(0));
if (tryExpandVecMathCall(Node, LC, Results))
return;

break;
}
case ISD::FSINCOS:
case ISD::FSINCOSPI: {
EVT VT = Node->getValueType(0);
Expand Down Expand Up @@ -2233,99 +2228,60 @@ bool VectorLegalizer::tryExpandVecMathCall(SDNode *Node, RTLIB::Libcall LC,
// converted to their none strict counterpart.
assert(!Node->isStrictFPOpcode() && "Unexpected strict fp operation!");

const char *LCName = TLI.getLibcallName(LC);
if (!LCName)
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl == RTLIB::Unsupported)
return false;
LLVM_DEBUG(dbgs() << "Looking for vector variant of " << LCName << "\n");

EVT VT = Node->getValueType(0);
ElementCount VL = VT.getVectorElementCount();

// Lookup a vector function equivalent to the specified libcall. Prefer
// unmasked variants but we will generate a mask if need be.
const TargetLibraryInfo &TLibInfo = DAG.getLibInfo();
const VecDesc *VD = TLibInfo.getVectorMappingInfo(LCName, VL, false);
if (!VD)
VD = TLibInfo.getVectorMappingInfo(LCName, VL, /*Masked=*/true);
if (!VD)
return false;

LLVMContext *Ctx = DAG.getContext();
Type *Ty = VT.getTypeForEVT(*Ctx);
Type *ScalarTy = Ty->getScalarType();
const RTLIB::RuntimeLibcallsInfo &RTLCI = TLI.getRuntimeLibcallsInfo();
LLVMContext &Ctx = *DAG.getContext();

// Construct a scalar function type based on Node's operands.
SmallVector<Type *, 8> ArgTys;
for (unsigned i = 0; i < Node->getNumOperands(); ++i) {
assert(Node->getOperand(i).getValueType() == VT &&
"Expected matching vector types!");
ArgTys.push_back(ScalarTy);
}
FunctionType *ScalarFTy = FunctionType::get(ScalarTy, ArgTys, false);
auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(
Ctx, DAG.getSubtarget().getTargetTriple(), DAG.getDataLayout(), LCImpl);

// Generate call information for the vector function.
const std::string MangledName = VD->getVectorFunctionABIVariantString();
auto OptVFInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy);
if (!OptVFInfo)
return false;
SDLoc DL(Node);
TargetLowering::ArgListTy Args;

LLVM_DEBUG(dbgs() << "Found vector variant " << VD->getVectorFnName()
<< "\n");
bool HasMaskArg = RTLCI.hasVectorMaskArgument(LCImpl);

// Sanity check just in case OptVFInfo has unexpected parameters.
if (OptVFInfo->Shape.Parameters.size() !=
Node->getNumOperands() + VD->isMasked())
return false;
// Sanity check just in case function has unexpected parameters.
assert(FuncTy->getNumParams() == Node->getNumOperands() + HasMaskArg &&
EVT::getEVT(FuncTy->getReturnType(), true) == VT &&
"mismatch in value type and call signature type");

// Collect vector call operands.
for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) {
Type *ParamTy = FuncTy->getParamType(I);

SDLoc DL(Node);
TargetLowering::ArgListTy Args;

unsigned OpNum = 0;
for (auto &VFParam : OptVFInfo->Shape.Parameters) {
if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), *Ctx, VT);
if (HasMaskArg && I == E - 1) {
assert(cast<VectorType>(ParamTy)->getElementType()->isIntegerTy(1) &&
"unexpected vector mask type");
EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), Ctx, VT);
Args.emplace_back(DAG.getBoolConstant(true, DL, MaskVT, VT),
MaskVT.getTypeForEVT(*Ctx));
continue;
}

// Only vector operands are supported.
if (VFParam.ParamKind != VFParamKind::Vector)
return false;
MaskVT.getTypeForEVT(Ctx));

Args.emplace_back(Node->getOperand(OpNum++), Ty);
} else {
SDValue Op = Node->getOperand(I);
assert(Op.getValueType() == EVT::getEVT(ParamTy, true) &&
"mismatch in value type and call argument type");
Args.emplace_back(Op, ParamTy);
}
}

// Emit a call to the vector function.
SDValue Callee = DAG.getExternalSymbol(VD->getVectorFnName().data(),
TLI.getPointerTy(DAG.getDataLayout()));
SDValue Callee =
DAG.getExternalSymbol(LCImpl, TLI.getPointerTy(DAG.getDataLayout()));
CallingConv::ID CC = RTLCI.getLibcallImplCallingConv(LCImpl);

TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(DL)
.setChain(DAG.getEntryNode())
.setLibCallee(CallingConv::C, Ty, Callee, std::move(Args));
.setLibCallee(CC, FuncTy->getReturnType(), Callee, std::move(Args));

std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
Results.push_back(CallResult.first);
return true;
}

/// Try to expand the node to a vector libcall based on the result type.
bool VectorLegalizer::tryExpandVecMathCall(
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->getValueType(0).getVectorElementType(), Call_F32, Call_F64,
Call_F80, Call_F128, Call_PPCF128);

if (LC == RTLIB::UNKNOWN_LIBCALL)
return false;

return tryExpandVecMathCall(Node, LC, Results);
}

void VectorLegalizer::UnrollStrictFPOp(SDNode *Node,
SmallVectorImpl<SDValue> &Results) {
EVT VT = Node->getValueType(0);
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,11 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) {
return SDValue(N, 0);
}

SDValue SelectionDAG::getExternalSymbol(RTLIB::LibcallImpl Libcall, EVT VT) {
StringRef SymName = TLI->getLibcallImplName(Libcall);
return getExternalSymbol(SymName.data(), VT);
}

SDValue SelectionDAG::getMCSymbol(MCSymbol *Sym, EVT VT) {
SDNode *&N = MCSymbols[Sym];
if (N)
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl,
Args.push_back(Entry);
}

SDValue Callee = DAG.getExternalSymbol(getLibcallImplName(LibcallImpl).data(),
getPointerTy(DAG.getDataLayout()));
SDValue Callee =
DAG.getExternalSymbol(LibcallImpl, getPointerTy(DAG.getDataLayout()));

Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
Type *OrigRetTy = RetTy;
Expand Down Expand Up @@ -12261,8 +12261,8 @@ bool TargetLowering::expandMultipleResultFPLibCall(
? Node->getValueType(*CallRetResNo).getTypeForEVT(Ctx)
: Type::getVoidTy(Ctx);
SDValue InChain = StoresInChain ? StoresInChain : DAG.getEntryNode();
SDValue Callee = DAG.getExternalSymbol(getLibcallImplName(LibcallImpl).data(),
getPointerTy(DAG.getDataLayout()));
SDValue Callee =
DAG.getExternalSymbol(LibcallImpl, getPointerTy(DAG.getDataLayout()));
TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(DL).setChain(InChain).setLibCallee(
getLibcallImplCallingConv(LibcallImpl), RetType, Callee, std::move(Args));
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,28 @@ RTLIB::Libcall RTLIB::getSINCOS_STRET(EVT RetVT) {
UNKNOWN_LIBCALL, UNKNOWN_LIBCALL, UNKNOWN_LIBCALL);
}

RTLIB::Libcall RTLIB::getREM(EVT VT) {
// TODO: Tablegen should generate this function
if (VT.isVector()) {
if (!VT.isSimple())
return RTLIB::UNKNOWN_LIBCALL;
switch (VT.getSimpleVT().SimpleTy) {
case MVT::v4f32:
return RTLIB::REM_V4F32;
case MVT::v2f64:
return RTLIB::REM_V2F64;
case MVT::nxv4f32:
return RTLIB::REM_NXV4F32;
case MVT::nxv2f64:
return RTLIB::REM_NXV2F64;
default:
return RTLIB::UNKNOWN_LIBCALL;
}
}

return getFPLibCall(VT, REM_F32, REM_F64, REM_F80, REM_F128, REM_PPCF128);
}

RTLIB::Libcall RTLIB::getMODF(EVT RetVT) {
// TODO: Tablegen should generate this function
if (RetVT.isVector()) {
Expand Down
Loading
Loading