Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -156,6 +156,8 @@ /// This hook must be implemented to lower the given call instruction, /// including argument and return value marshalling. /// + /// \p CallConv is the calling convention to be used for the call. + /// /// \p Callee is the destination of the call. It should be either a register, /// globaladdress, or externalsymbol. /// @@ -171,7 +173,7 @@ /// needs to be passed. /// /// \return true if the lowering succeeded, false otherwise. - virtual bool lowerCall(MachineIRBuilder &MIRBuilder, + virtual bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef OrigArgs) const { return false; Index: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -52,7 +52,7 @@ if (!OrigRet.Ty->isVoidTy()) setArgFlags(OrigRet, AttributeSet::ReturnIndex, DL, CS); - return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs); + return lowerCall(MIRBuilder, CS.getCallingConv(), Callee, OrigRet, OrigArgs); } template Index: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -523,7 +523,8 @@ return false; } - return CLI->lowerCall(MIRBuilder, MachineOperand::CreateES(Callee), + return CLI->lowerCall(MIRBuilder, CI.getCallingConv(), + MachineOperand::CreateES(Callee), CallLowering::ArgInfo(0, CI.getType()), Args); } Index: llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -114,11 +114,12 @@ Type *Ty = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx); auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering(); auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); - const char *Name = TLI.getLibcallName(getRTLibDesc(MI.getOpcode(), Size)); + auto Libcall = getRTLibDesc(MI.getOpcode(), Size); + const char *Name = TLI.getLibcallName(Libcall); MIRBuilder.getMF().getFrameInfo().setHasCalls(true); CLI.lowerCall( - MIRBuilder, MachineOperand::CreateES(Name), - {MI.getOperand(0).getReg(), Ty}, + MIRBuilder, TLI.getLibcallCallingConv(Libcall), + MachineOperand::CreateES(Name), {MI.getOperand(0).getReg(), Ty}, {{MI.getOperand(1).getReg(), Ty}, {MI.getOperand(2).getReg(), Ty}}); MI.eraseFromParent(); return Legalized; Index: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.h @@ -34,8 +34,8 @@ bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef VRegs) const override; - bool lowerCall(MachineIRBuilder &MIRBuilder, const MachineOperand &Callee, - const ArgInfo &OrigRet, + bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, + const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef OrigArgs) const override; private: Index: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp @@ -302,6 +302,7 @@ } bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, + CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef OrigArgs) const { @@ -321,9 +322,9 @@ // Find out which ABI gets to decide where things go. const AArch64TargetLowering &TLI = *getTLI(); CCAssignFn *AssignFnFixed = - TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/false); + TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/false); CCAssignFn *AssignFnVarArg = - TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/true); + TLI.CCAssignFnForCall(CallConv, /*IsVarArg=*/true); auto CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN); Index: llvm/trunk/lib/Target/ARM/ARMCallLowering.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMCallLowering.h +++ llvm/trunk/lib/Target/ARM/ARMCallLowering.h @@ -34,8 +34,8 @@ bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef VRegs) const override; - bool lowerCall(MachineIRBuilder &MIRBuilder, const MachineOperand &Callee, - const ArgInfo &OrigRet, + bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, + const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef OrigArgs) const override; private: Index: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp @@ -373,6 +373,7 @@ } // End anonymous namespace. bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, + CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef OrigArgs) const { @@ -387,10 +388,6 @@ auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN); - // FIXME: This is the calling convention of the caller - we should use the - // calling convention of the callee instead. - auto CallConv = MF.getFunction()->getCallingConv(); - // Create the call instruction so we can add the implicit uses of arg // registers, but don't insert it yet. auto MIB = MIRBuilder.buildInstrNoInsert(ARM::BLX).add(Callee).addRegMask( Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1401,3 +1401,13 @@ %res = extractelement <1 x i32> %add, i32 0 ret i32 %res } + +declare ghccc float @different_call_conv_target(float %x) +define float @test_different_call_conv_target(float %x) { +; CHECK-LABEL: name: test_different_call_conv +; CHECK: [[X:%[0-9]+]](s32) = COPY %s0 +; CHECK: %s8 = COPY [[X]] +; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %s8, implicit-def %s0 + %res = call ghccc float @different_call_conv_target(float %x) + ret float %res +} Index: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -526,3 +526,20 @@ %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a, float %b, double %a) ret double %r } + +declare arm_aapcscc float @different_call_conv_target(float) + +define arm_aapcs_vfpcc float @test_call_different_call_conv(float %x) { +; CHECK-LABEL: name: test_call_different_call_conv +; CHECK: [[X:%[0-9]+]](s32) = COPY %s0 +; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp +; CHECK: %r0 = COPY [[X]] +; CHECK: BLX @different_call_conv_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit-def %r0 +; CHECK: [[R:%[0-9]+]](s32) = COPY %r0 +; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp +; CHECK: %s0 = COPY [[R]] +; CHECK: BX_RET 14, _, implicit %s0 +entry: + %r = notail call arm_aapcscc float @different_call_conv_target(float %x) + ret float %r +}