From 9f0889bc211c165b522c39fc3331206ed5c67ef5 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 3 Nov 2025 22:53:16 -0800 Subject: [PATCH 1/3] DAG: Use LibcallImpl in various getLibFunc helpers Avoid using getLibcallName in favor of querying the libcall impl, and getting the ABI details from that. --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 109 ++++++++++-------- .../CodeGen/SelectionDAG/TargetLowering.cpp | 12 +- 2 files changed, 70 insertions(+), 51 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 7cf05cf99b6a8..b009e6a3d5f5f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -9061,8 +9061,8 @@ static bool isInTailCallPositionWrapper(const CallInst *CI, std::pair SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0, SDValue Mem1, SDValue Size, const CallInst *CI) { - const char *LibCallName = TLI->getLibcallName(RTLIB::MEMCMP); - if (!LibCallName) + RTLIB::LibcallImpl MemcmpImpl = TLI->getLibcallImpl(RTLIB::MEMCMP); + if (MemcmpImpl == RTLIB::Unsupported) return {}; PointerType *PT = PointerType::getUnqual(*getContext()); @@ -9075,13 +9075,14 @@ SelectionDAG::getMemcmp(SDValue Chain, const SDLoc &dl, SDValue Mem0, bool IsTailCall = isInTailCallPositionWrapper(CI, this, /*AllowReturnsFirstArg*/ true); + StringRef LibCallName = TLI->getLibcallImplName(MemcmpImpl); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee( - TLI->getLibcallCallingConv(RTLIB::MEMCMP), - Type::getInt32Ty(*getContext()), - getExternalSymbol(LibCallName, TLI->getPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee(TLI->getLibcallImplCallingConv(MemcmpImpl), + Type::getInt32Ty(*getContext()), + getExternalSymbol(LibCallName.data(), + TLI->getPointerTy(getDataLayout())), + std::move(Args)) .setTailCall(IsTailCall); return TLI->LowerCallTo(CLI); @@ -9091,8 +9092,8 @@ std::pair SelectionDAG::getStrlen(SDValue Chain, const SDLoc &dl, SDValue Src, const CallInst *CI) { - const char *LibCallName = TLI->getLibcallName(RTLIB::STRLEN); - if (!LibCallName) + RTLIB::LibcallImpl StrlenImpl = TLI->getLibcallImpl(RTLIB::STRLEN); + if (StrlenImpl == RTLIB::Unsupported) return {}; // Emit a library call. @@ -9102,13 +9103,15 @@ std::pair SelectionDAG::getStrlen(SDValue Chain, TargetLowering::CallLoweringInfo CLI(*this); bool IsTailCall = isInTailCallPositionWrapper(CI, this, /*AllowReturnsFirstArg*/ true); + StringRef LibcallName = TLI->getLibcallImplName(StrlenImpl); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI->getLibcallCallingConv(RTLIB::STRLEN), CI->getType(), - getExternalSymbol( - LibCallName, TLI->getProgramPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee( + TLI->getLibcallImplCallingConv(StrlenImpl), CI->getType(), + getExternalSymbol(LibcallName.data(), + TLI->getProgramPointerTy(getDataLayout())), + std::move(Args)) .setTailCall(IsTailCall); return TLI->LowerCallTo(CLI); @@ -9211,17 +9214,19 @@ SDValue SelectionDAG::getAtomicMemcpy(SDValue Chain, const SDLoc &dl, RTLIB::Libcall LibraryCall = RTLIB::getMEMCPY_ELEMENT_UNORDERED_ATOMIC(ElemSz); - if (LibraryCall == RTLIB::UNKNOWN_LIBCALL) + RTLIB::LibcallImpl LibcallImpl = TLI->getLibcallImpl(LibraryCall); + if (LibcallImpl == RTLIB::Unsupported) report_fatal_error("Unsupported element size"); TargetLowering::CallLoweringInfo CLI(*this); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI->getLibcallCallingConv(LibraryCall), - Type::getVoidTy(*getContext()), - getExternalSymbol(TLI->getLibcallName(LibraryCall), - TLI->getPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee( + TLI->getLibcallImplCallingConv(LibcallImpl), + Type::getVoidTy(*getContext()), + getExternalSymbol(TLI->getLibcallImplName(LibcallImpl).data(), + TLI->getPointerTy(getDataLayout())), + std::move(Args)) .setDiscardResult() .setTailCall(isTailCall); @@ -9317,17 +9322,19 @@ SDValue SelectionDAG::getAtomicMemmove(SDValue Chain, const SDLoc &dl, RTLIB::Libcall LibraryCall = RTLIB::getMEMMOVE_ELEMENT_UNORDERED_ATOMIC(ElemSz); - if (LibraryCall == RTLIB::UNKNOWN_LIBCALL) + RTLIB::LibcallImpl LibcallImpl = TLI->getLibcallImpl(LibraryCall); + if (LibcallImpl == RTLIB::Unsupported) report_fatal_error("Unsupported element size"); TargetLowering::CallLoweringInfo CLI(*this); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI->getLibcallCallingConv(LibraryCall), - Type::getVoidTy(*getContext()), - getExternalSymbol(TLI->getLibcallName(LibraryCall), - TLI->getPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee( + TLI->getLibcallImplCallingConv(LibcallImpl), + Type::getVoidTy(*getContext()), + getExternalSymbol(TLI->getLibcallImplName(LibcallImpl).data(), + TLI->getPointerTy(getDataLayout())), + std::move(Args)) .setDiscardResult() .setTailCall(isTailCall); @@ -9388,27 +9395,32 @@ SDValue SelectionDAG::getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, // FIXME: pass in SDLoc CLI.setDebugLoc(dl).setChain(Chain); - const char *BzeroName = getTargetLoweringInfo().getLibcallName(RTLIB::BZERO); + RTLIB::LibcallImpl BzeroImpl = TLI->getLibcallImpl(RTLIB::BZERO); + bool UseBZero = BzeroImpl != RTLIB::Unsupported && isNullConstant(Src); - bool UseBZero = isNullConstant(Src) && BzeroName; // If zeroing out and bzero is present, use it. if (UseBZero) { TargetLowering::ArgListTy Args; Args.emplace_back(Dst, PointerType::getUnqual(Ctx)); Args.emplace_back(Size, DL.getIntPtrType(Ctx)); CLI.setLibCallee( - TLI->getLibcallCallingConv(RTLIB::BZERO), Type::getVoidTy(Ctx), - getExternalSymbol(BzeroName, TLI->getPointerTy(DL)), std::move(Args)); + TLI->getLibcallImplCallingConv(BzeroImpl), Type::getVoidTy(Ctx), + getExternalSymbol(TLI->getLibcallImplName(BzeroImpl).data(), + TLI->getPointerTy(DL)), + std::move(Args)); } else { + RTLIB::LibcallImpl MemsetImpl = TLI->getLibcallImpl(RTLIB::MEMSET); + TargetLowering::ArgListTy Args; Args.emplace_back(Dst, PointerType::getUnqual(Ctx)); Args.emplace_back(Src, Src.getValueType().getTypeForEVT(Ctx)); Args.emplace_back(Size, DL.getIntPtrType(Ctx)); - CLI.setLibCallee(TLI->getLibcallCallingConv(RTLIB::MEMSET), - Dst.getValueType().getTypeForEVT(Ctx), - getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET), - TLI->getPointerTy(DL)), - std::move(Args)); + CLI.setLibCallee( + TLI->getLibcallImplCallingConv(MemsetImpl), + Dst.getValueType().getTypeForEVT(Ctx), + getExternalSymbol(TLI->getLibcallImplName(MemsetImpl).data(), + TLI->getPointerTy(DL)), + std::move(Args)); } RTLIB::LibcallImpl MemsetImpl = TLI->getLibcallImpl(RTLIB::MEMSET); @@ -9440,17 +9452,19 @@ SDValue SelectionDAG::getAtomicMemset(SDValue Chain, const SDLoc &dl, RTLIB::Libcall LibraryCall = RTLIB::getMEMSET_ELEMENT_UNORDERED_ATOMIC(ElemSz); - if (LibraryCall == RTLIB::UNKNOWN_LIBCALL) + RTLIB::LibcallImpl LibcallImpl = TLI->getLibcallImpl(LibraryCall); + if (LibcallImpl == RTLIB::Unsupported) report_fatal_error("Unsupported element size"); TargetLowering::CallLoweringInfo CLI(*this); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI->getLibcallCallingConv(LibraryCall), - Type::getVoidTy(*getContext()), - getExternalSymbol(TLI->getLibcallName(LibraryCall), - TLI->getPointerTy(getDataLayout())), - std::move(Args)) + .setLibCallee( + TLI->getLibcallImplCallingConv(LibcallImpl), + Type::getVoidTy(*getContext()), + getExternalSymbol(TLI->getLibcallImplName(LibcallImpl).data(), + TLI->getPointerTy(getDataLayout())), + std::move(Args)) .setDiscardResult() .setTailCall(isTailCall); @@ -14177,13 +14191,18 @@ SDValue SelectionDAG::makeStateFunctionCall(unsigned LibFunc, SDValue Ptr, assert(InChain.getValueType() == MVT::Other && "Expected token chain"); TargetLowering::ArgListTy Args; Args.emplace_back(Ptr, Ptr.getValueType().getTypeForEVT(*getContext())); - RTLIB::Libcall LC = static_cast(LibFunc); - SDValue Callee = getExternalSymbol(TLI->getLibcallName(LC), - TLI->getPointerTy(getDataLayout())); + RTLIB::LibcallImpl LibcallImpl = + TLI->getLibcallImpl(static_cast(LibFunc)); + if (LibcallImpl == RTLIB::Unsupported) + reportFatalUsageError("emitting call to unsupported libcall"); + + SDValue Callee = + getExternalSymbol(TLI->getLibcallImplName(LibcallImpl).data(), + TLI->getPointerTy(getDataLayout())); TargetLowering::CallLoweringInfo CLI(*this); CLI.setDebugLoc(DLoc).setChain(InChain).setLibCallee( - TLI->getLibcallCallingConv(LC), Type::getVoidTy(*getContext()), Callee, - std::move(Args)); + TLI->getLibcallImplCallingConv(LibcallImpl), + Type::getVoidTy(*getContext()), Callee, std::move(Args)); return TLI->LowerCallTo(CLI).second; } diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 783ec4b0bd211..3564cbebed5c2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -185,12 +185,12 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, Args.push_back(Entry); } - const char *LibcallName = getLibcallName(LC); - if (LC == RTLIB::UNKNOWN_LIBCALL || !LibcallName) + RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC); + if (LibcallImpl == RTLIB::Unsupported) reportFatalInternalError("unsupported library call operation"); - SDValue Callee = - DAG.getExternalSymbol(LibcallName, getPointerTy(DAG.getDataLayout())); + SDValue Callee = DAG.getExternalSymbol(getLibcallImplName(LibcallImpl).data(), + getPointerTy(DAG.getDataLayout())); Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); Type *OrigRetTy = RetTy; @@ -206,8 +206,8 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, CLI.setDebugLoc(dl) .setChain(InChain) - .setLibCallee(getLibcallCallingConv(LC), RetTy, OrigRetTy, Callee, - std::move(Args)) + .setLibCallee(getLibcallImplCallingConv(LibcallImpl), RetTy, OrigRetTy, + Callee, std::move(Args)) .setNoReturn(CallOptions.DoesNotReturn) .setDiscardResult(!CallOptions.IsReturnValueUsed) .setIsPostTypeLegalization(CallOptions.IsPostTypeLegalization) From 77249d0059b431c93dcb35424696f31b87ff635f Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 2 Dec 2025 20:41:15 -0500 Subject: [PATCH 2/3] DAG: Avoid more uses of getLibcallName --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 70950084ee6b7..0e52f0516b09a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4983,7 +4983,7 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned, case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; } - return TLI.getLibcallName(LC) != nullptr; + return TLI.getLibcallImpl(LC) != RTLIB::Unsupported; } /// Issue divrem if both quotient and remainder are needed. diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 3564cbebed5c2..0ba8816bf1e82 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -11121,7 +11121,8 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl, else if (WideVT == MVT::i128) LC = RTLIB::MUL_I128; - if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName(LC)) { + RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC); + if (LibcallImpl == RTLIB::Unsupported) { forceExpandMultiply(DAG, dl, Signed, Lo, Hi, LHS, RHS); return; } From b5ef5ed3e65584020a039a2fa8cd98c4d7ce31f9 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 2 Dec 2025 21:03:00 -0500 Subject: [PATCH 3/3] DAG: Avoid using getLibcallName when looking for a divrem call Also introduce an error if it's not available, which is not yet testable. --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 99d14a60c6ed1..8336e1d1f4134 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2381,8 +2381,19 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, Entry.IsZExt = !isSigned; Args.push_back(Entry); - SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), - TLI.getPointerTy(DAG.getDataLayout())); + RTLIB::LibcallImpl LibcallImpl = TLI.getLibcallImpl(LC); + if (LibcallImpl == RTLIB::Unsupported) { + DAG.getContext()->emitError(Twine("no libcall available for ") + + Node->getOperationName(&DAG)); + SDValue Poison = DAG.getPOISON(RetVT); + Results.push_back(Poison); + Results.push_back(Poison); + return; + } + + SDValue Callee = + DAG.getExternalSymbol(TLI.getLibcallImplName(LibcallImpl).data(), + TLI.getPointerTy(DAG.getDataLayout())); SDLoc dl(Node); TargetLowering::CallLoweringInfo CLI(DAG);