@@ -2514,18 +2514,20 @@ static bool canFoldStoreIntoLibCallOutputPointers(StoreSDNode *StoreNode,
25142514
25152515bool SelectionDAG::expandMultipleResultFPLibCall(
25162516 RTLIB::Libcall LC, SDNode *Node, SmallVectorImpl<SDValue> &Results,
2517- std::optional<unsigned> CallRetResNo) {
2518- LLVMContext &Ctx = *getContext();
2519- EVT VT = Node->getValueType(0);
2520- unsigned NumResults = Node->getNumValues();
2521-
2517+ EVT CallVT, std::optional<unsigned> CallRetResNo) {
25222518 if (LC == RTLIB::UNKNOWN_LIBCALL)
25232519 return false;
25242520
2525- const char *LCName = TLI->getLibcallName(LC);
2526- if (!LCName)
2521+ EVT VT = Node->getValueType(0);
2522+
2523+ RTLIB::LibcallImpl Impl = TLI->getLibcallImpl(LC);
2524+ if (Impl == RTLIB::Unsupported)
25272525 return false;
25282526
2527+ StringRef LCName = TLI->getLibcallImplName(Impl);
2528+
2529+ // FIXME: This should not use TargetLibraryInfo. There should be
2530+ // RTLIB::Libcall entries for each used vector type, and directly matched.
25292531 auto getVecDesc = [&]() -> VecDesc const * {
25302532 for (bool Masked : {false, true}) {
25312533 if (VecDesc const *VD = getLibInfo().getVectorMappingInfo(
@@ -2538,9 +2540,34 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
25382540
25392541 // For vector types, we must find a vector mapping for the libcall.
25402542 VecDesc const *VD = nullptr;
2541- if (VT.isVector() && !(VD = getVecDesc()))
2543+ if (VT.isVector() && !CallVT.isVector() && ! (VD = getVecDesc()))
25422544 return false;
25432545
2546+ bool IsMasked = (VD && VD->isMasked()) ||
2547+ RTLIB::RuntimeLibcallsInfo::hasVectorMaskArgument(Impl);
2548+
2549+ // This wrapper function exists because getVectorMappingInfo works in terms of
2550+ // function names instead of RTLIB enums.
2551+
2552+ // FIXME: If we used a vector mapping, this assumes the calling convention of
2553+ // the vector function is the same as the scalar.
2554+
2555+ StringRef Name = VD ? VD->getVectorFnName() : LCName;
2556+
2557+ return expandMultipleResultFPLibCall(Name,
2558+ TLI->getLibcallImplCallingConv(Impl),
2559+ Node, Results, CallRetResNo, IsMasked);
2560+ }
2561+
2562+ // FIXME: This belongs in TargetLowering
2563+ bool SelectionDAG::expandMultipleResultFPLibCall(
2564+ StringRef Name, CallingConv::ID CC, SDNode *Node,
2565+ SmallVectorImpl<SDValue> &Results, std::optional<unsigned> CallRetResNo,
2566+ bool IsMasked) {
2567+ LLVMContext &Ctx = *getContext();
2568+ EVT VT = Node->getValueType(0);
2569+ unsigned NumResults = Node->getNumValues();
2570+
25442571 // Find users of the node that store the results (and share input chains). The
25452572 // destination pointers can be used instead of creating stack allocations.
25462573 SDValue StoresInChain;
@@ -2598,7 +2625,7 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
25982625 SDLoc DL(Node);
25992626
26002627 // Pass the vector mask (if required).
2601- if (VD && VD->isMasked() ) {
2628+ if (IsMasked ) {
26022629 EVT MaskVT = TLI->getSetCCResultType(getDataLayout(), Ctx, VT);
26032630 SDValue Mask = getBoolConstant(true, DL, MaskVT, VT);
26042631 Args.emplace_back(Mask, MaskVT.getTypeForEVT(Ctx));
@@ -2608,11 +2635,11 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
26082635 ? Node->getValueType(*CallRetResNo).getTypeForEVT(Ctx)
26092636 : Type::getVoidTy(Ctx);
26102637 SDValue InChain = StoresInChain ? StoresInChain : getEntryNode();
2611- SDValue Callee = getExternalSymbol(VD ? VD->getVectorFnName().data() : LCName,
2612- TLI->getPointerTy(getDataLayout()));
2638+ SDValue Callee =
2639+ getExternalSymbol(Name.data(), TLI->getPointerTy(getDataLayout()));
26132640 TargetLowering::CallLoweringInfo CLI(*this);
2614- CLI.setDebugLoc(DL).setChain(InChain).setLibCallee(
2615- TLI->getLibcallCallingConv(LC), RetType, Callee, std::move(Args));
2641+ CLI.setDebugLoc(DL).setChain(InChain).setLibCallee(CC, RetType, Callee,
2642+ std::move(Args));
26162643
26172644 auto [Call, CallChain] = TLI->LowerCallTo(CLI);
26182645
0 commit comments