diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -304,6 +304,13 @@ GISelChangeObserver &Observer; }; +/// Helper function that creates a libcall to the given \p Name using the given +/// calling convention \p CC. +LegalizerHelper::LegalizeResult +createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, + const CallLowering::ArgInfo &Result, + ArrayRef Args, CallingConv::ID CC); + /// Helper function that creates the given libcall. LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -489,15 +489,14 @@ } LegalizerHelper::LegalizeResult -llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, +llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, const CallLowering::ArgInfo &Result, - ArrayRef Args) { + ArrayRef Args, + const CallingConv::ID CC) { auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering(); - auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); - const char *Name = TLI.getLibcallName(Libcall); CallLowering::CallLoweringInfo Info; - Info.CallConv = TLI.getLibcallCallingConv(Libcall); + Info.CallConv = CC; Info.Callee = MachineOperand::CreateES(Name); Info.OrigRet = Result; std::copy(Args.begin(), Args.end(), std::back_inserter(Info.OrigArgs)); @@ -507,6 +506,16 @@ return LegalizerHelper::Legalized; } +LegalizerHelper::LegalizeResult +llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, + const CallLowering::ArgInfo &Result, + ArrayRef Args) { + auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); + const char *Name = TLI.getLibcallName(Libcall); + const CallingConv::ID CC = TLI.getLibcallCallingConv(Libcall); + return createLibcall(MIRBuilder, Name, Result, Args, CC); +} + // Useful for libcalls where all operands have the same type. static LegalizerHelper::LegalizeResult simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -2722,4 +2722,30 @@ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; } +TEST_F(AArch64GISelMITest, CreateLibcall) { + setUp(); + if (!TM) + return; + + DefineLegalizerInfo(A, {}); + + AInfo Info(MF->getSubtarget()); + DummyGISelObserver Observer; + + LLVMContext &Ctx = MF->getFunction().getContext(); + auto *RetTy = Type::getVoidTy(Ctx); + + EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized, + createLibcall(B, "abort", {{}, RetTy}, {}, CallingConv::C)); + + auto CheckStr = R"( + CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + CHECK: BL &abort + CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp + )"; + + // Check + EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; +} + } // namespace