From 3db09b74cdf881df9e36cf222ecabd6f492eb5ef Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 3 Dec 2025 23:23:38 +0100 Subject: [PATCH] DAG: Add overload of makeLibCall which calls an RTLIB::LibcallImpl Logically the concrete implementation is what's being called, not the abstract libcall. Many uses conditionalize emitting the call on whether the call is available, so the caller and makeLibCall would both be checking that. --- llvm/include/llvm/CodeGen/TargetLowering.h | 11 +++++- .../SelectionDAG/LegalizeFloatTypes.cpp | 8 ++-- .../SelectionDAG/LegalizeIntegerTypes.cpp | 37 ++++++++++++------- .../CodeGen/SelectionDAG/TargetLowering.cpp | 14 +++---- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 149366c69bdcc..621cef5ef6230 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4116,12 +4116,21 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase { } /// Returns a pair of (return value, chain). + /// It is an error to pass RTLIB::Unsupported as \p LibcallImpl + std::pair + makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, + ArrayRef Ops, MakeLibCallOptions CallOptions, + const SDLoc &dl, SDValue Chain = SDValue()) const; + /// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC. std::pair makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, - SDValue Chain = SDValue()) const; + SDValue Chain = SDValue()) const { + return makeLibCall(DAG, getLibcallImpl(LC), RetVT, Ops, CallOptions, dl, + Chain); + } /// Check whether parameters to a call that are passed in callee saved /// registers are the same as from the calling function. This needs to be diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index dbdd913fccdb2..545b7f5120d35 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -802,7 +802,8 @@ bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults( assert(VT == N->getValueType(1) && "expected both return values to have the same type"); - if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) + RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC); + if (LCImpl == RTLIB::Unsupported) return false; EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); @@ -831,8 +832,9 @@ bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults( CallOptions.setTypeListBeforeSoften({OpsVT}, VT) .setOpsTypeOverrides(CallOpsTypeOverrides); - auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, DL, - /*Chain=*/SDValue()); + auto [ReturnVal, Chain] = + TLI.makeLibCall(DAG, LCImpl, NVT, Ops, CallOptions, DL, + /*Chain=*/SDValue()); auto CreateStackLoad = [&, Chain = Chain](SDValue StackSlot) { int FrameIdx = cast(StackSlot)->getIndex(); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 8c9f5eeebd26c..94a3386e75394 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -2692,7 +2692,8 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) { RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0)) : RTLIB::getLDEXP(N->getValueType(0)); - if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) { + RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC); + if (LCImpl == 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. @@ -2719,7 +2720,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) { CallOptions.setIsSigned(true); SDValue Ops[2] = {N->getOperand(0 + OpOffset), N->getOperand(1 + OpOffset)}; std::pair Tmp = TLI.makeLibCall( - DAG, LC, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain); + DAG, LCImpl, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain); ReplaceValueWith(SDValue(N, 0), Tmp.first); if (IsStrict) ReplaceValueWith(SDValue(N, 1), Tmp.second); @@ -3187,7 +3188,9 @@ std::pair DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { EVT RetVT = Node->getValueType(0); TargetLowering::MakeLibCallOptions CallOptions; SmallVector Ops; - if (TLI.getLibcallName(LC)) { + + RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC); + if (LCImpl != RTLIB::Unsupported) { Ops.append(Node->op_begin() + 2, Node->op_end()); Ops.push_back(Node->getOperand(1)); } else { @@ -3195,8 +3198,9 @@ std::pair DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected atomic op or value type!"); Ops.append(Node->op_begin() + 1, Node->op_end()); + LCImpl = TLI.getLibcallImpl(LC); } - return TLI.makeLibCall(DAG, LC, RetVT, Ops, CallOptions, SDLoc(Node), + return TLI.makeLibCall(DAG, LCImpl, RetVT, Ops, CallOptions, SDLoc(Node), Node->getOperand(0)); } @@ -4403,8 +4407,8 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, // If nothing else, we can make a libcall. RTLIB::Libcall LC = RTLIB::getMUL(VT); - - if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) { + RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC); + if (LCImpl == RTLIB::Unsupported) { // Perform a wide multiplication where the wide type is the original VT and // the 4 parts are the split arguments. TLI.forceExpandMultiply(DAG, dl, /*Signed=*/false, Lo, Hi, LL, RL, LH, RH); @@ -4416,8 +4420,8 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; TargetLowering::MakeLibCallOptions CallOptions; CallOptions.setIsSigned(true); - SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, - Lo, Hi); + SplitInteger(TLI.makeLibCall(DAG, LCImpl, VT, Ops, CallOptions, dl).first, Lo, + Hi); } void DAGTypeLegalizer::ExpandIntRes_READCOUNTER(SDNode *N, SDValue &Lo, @@ -4991,14 +4995,16 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, LC = RTLIB::getSRA(VT); } - if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) { + if (RTLIB::LibcallImpl LibcallImpl = TLI.getLibcallImpl(LC)) { EVT ShAmtTy = EVT::getIntegerVT(*DAG.getContext(), DAG.getLibInfo().getIntSize()); SDValue ShAmt = DAG.getZExtOrTrunc(N->getOperand(1), dl, ShAmtTy); SDValue Ops[2] = {N->getOperand(0), ShAmt}; TargetLowering::MakeLibCallOptions CallOptions; CallOptions.setIsSigned(isSigned); - SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi); + SplitInteger( + TLI.makeLibCall(DAG, LibcallImpl, VT, Ops, CallOptions, dl).first, Lo, + Hi); return; } @@ -5158,11 +5164,12 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N, // Replace this with a libcall that will check overflow. RTLIB::Libcall LC = RTLIB::getMULO(VT); + RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC); // 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. - if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC) || - TLI.getLibcallName(LC) == DAG.getMachineFunction().getName()) { + if (LCImpl == RTLIB::Unsupported || + TLI.getLibcallImplName(LCImpl) == DAG.getMachineFunction().getName()) { // FIXME: This is not an optimal expansion, but better than crashing. SDValue MulLo, MulHi; TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, N->getOperand(0), @@ -5200,12 +5207,14 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N, Entry.IsZExt = false; Args.push_back(Entry); - SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT); + SDValue Func = + DAG.getExternalSymbol(TLI.getLibcallImplName(LCImpl).data(), PtrVT); TargetLowering::CallLoweringInfo CLI(DAG); CLI.setDebugLoc(dl) .setChain(Chain) - .setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Func, std::move(Args)) + .setLibCallee(TLI.getLibcallImplCallingConv(LCImpl), RetTy, Func, + std::move(Args)) .setSExtResult(); std::pair CallInfo = TLI.LowerCallTo(CLI); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index b698ef4fcf0cc..172c7485e108b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -152,11 +152,13 @@ void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call, /// Generate a libcall taking the given operands as arguments and returning a /// result of type RetVT. std::pair -TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, - ArrayRef Ops, - MakeLibCallOptions CallOptions, - const SDLoc &dl, +TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, + EVT RetVT, ArrayRef Ops, + MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue InChain) const { + if (LibcallImpl == RTLIB::Unsupported) + reportFatalInternalError("unsupported library call operation"); + if (!InChain) InChain = DAG.getEntryNode(); @@ -185,10 +187,6 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, Args.push_back(Entry); } - RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC); - if (LibcallImpl == RTLIB::Unsupported) - reportFatalInternalError("unsupported library call operation"); - SDValue Callee = DAG.getExternalSymbol(getLibcallImplName(LibcallImpl).data(), getPointerTy(DAG.getDataLayout()));