Index: llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp =================================================================== --- llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp +++ llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp @@ -79,8 +79,8 @@ const Function &F = MF.getFunction(); MachineRegisterInfo &MRI = MF.getRegInfo(); const M68kTargetLowering &TLI = *getTLI(); - CCAssignFn *AssignFn = - TLI.getCCAssignFn(F.getCallingConv(), true, F.isVarArg()); + CCAssignFn *AssignFn = TLI.getCCAssignFn(F.getCallingConv(), true, + F.isVarArg(), F.getReturnType()); auto &DL = F.getParent()->getDataLayout(); if (!VRegs.empty()) { SmallVector SplitArgs; @@ -115,8 +115,8 @@ ++I; } - CCAssignFn *AssignFn = - TLI.getCCAssignFn(F.getCallingConv(), false, F.isVarArg()); + CCAssignFn *AssignFn = TLI.getCCAssignFn(F.getCallingConv(), false, + F.isVarArg(), F.getReturnType()); IncomingValueAssigner ArgAssigner(AssignFn); FormalArgHandler ArgHandler(MIRBuilder, MRI); return determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgs, @@ -196,7 +196,8 @@ .add(Info.Callee) .addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv)); - CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg); + CCAssignFn *AssignFn = + TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg, F.getReturnType()); OutgoingValueAssigner Assigner(AssignFn); M68kOutgoingArgHandler Handler(MIRBuilder, MRI, MIB); if (!determineAndHandleAssignments(Handler, Assigner, OutArgs, MIRBuilder, @@ -211,8 +212,8 @@ MIRBuilder.insertInstr(MIB); if (!Info.OrigRet.Ty->isVoidTy()) { - CCAssignFn *RetAssignFn = - TLI.getCCAssignFn(Info.CallConv, true, Info.IsVarArg); + CCAssignFn *RetAssignFn = TLI.getCCAssignFn( + Info.CallConv, true, Info.IsVarArg, F.getReturnType()); OutgoingValueAssigner Assigner(RetAssignFn, RetAssignFn); CallReturnHandler Handler(MIRBuilder, MRI, MIB); Index: llvm/lib/Target/M68k/M68kCallingConv.td =================================================================== --- llvm/lib/Target/M68k/M68kCallingConv.td +++ llvm/lib/Target/M68k/M68kCallingConv.td @@ -27,7 +27,6 @@ ]>; /// M68k C return convention. -/// TODO: Return via address register def RetCC_M68k_C : CallingConv<[ CCIfType<[i1], CCPromoteToType>, CCIfType<[i8], CCAssignToReg<[BD0, BD1]>>, @@ -36,6 +35,11 @@ CCDelegateTo ]>; +def RetCC_M68k_C_PTRRET : CallingConv<[ + CCIfType<[i32], CCAssignToReg<[A0]>>, + CCDelegateTo +]>; + /// M68k fastcc return convention. /// This convention allows to return up to 16 bytes in registers which can be /// split among 16 1-byte values or used for a single 16-byte value. Index: llvm/lib/Target/M68k/M68kISelLowering.h =================================================================== --- llvm/lib/Target/M68k/M68kISelLowering.h +++ llvm/lib/Target/M68k/M68kISelLowering.h @@ -171,8 +171,8 @@ EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override; - CCAssignFn *getCCAssignFn(CallingConv::ID CC, bool Return, - bool IsVarArg) const; + CCAssignFn *getCCAssignFn(CallingConv::ID CC, bool IsReturn, bool IsVarArg, + Type *ReturnType) const; AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override; Index: llvm/lib/Target/M68k/M68kISelLowering.cpp =================================================================== --- llvm/lib/Target/M68k/M68kISelLowering.cpp +++ llvm/lib/Target/M68k/M68kISelLowering.cpp @@ -864,11 +864,15 @@ const SmallVectorImpl &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const { + MachineFunction &MF = DAG.getMachineFunction(); // Assign locations to each value returned by this call. SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(Ins, RetCC_M68k); + + CCInfo.AnalyzeCallResult(Ins, + getCCAssignFn(CallConv, /*IsReturn=*/true, IsVarArg, + MF.getFunction().getReturnType())); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { @@ -1048,7 +1052,9 @@ SmallVector RVLocs; CCState CCInfo(CCID, IsVarArg, MF, RVLocs, *DAG.getContext()); - CCInfo.AnalyzeReturn(Outs, RetCC_M68k); + + CCInfo.AnalyzeReturn(Outs, getCCAssignFn(CCID, /*IsReturn=*/true, IsVarArg, + MF.getFunction().getReturnType())); SDValue Flag; SmallVector RetOps; @@ -3546,10 +3552,11 @@ } } -CCAssignFn *M68kTargetLowering::getCCAssignFn(CallingConv::ID CC, bool Return, - bool IsVarArg) const { - if (Return) - return RetCC_M68k_C; - else - return CC_M68k_C; +CCAssignFn *M68kTargetLowering::getCCAssignFn(CallingConv::ID CC, bool IsReturn, + bool IsVarArg, + Type *ReturnType) const { + if (IsReturn) + return isa(ReturnType) ? RetCC_M68k_C_PTRRET : RetCC_M68k_C; + + return CC_M68k_C; } Index: llvm/test/CodeGen/M68k/CConv/ret-addr-reg.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/M68k/CConv/ret-addr-reg.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=m68k -o - %s | FileCheck %s + +@getA.a = internal global i32 0, align 4 + +; Function Attrs: noinline nounwind optnone +define ptr @getA() #0 { +; CHECK-LABEL: getA: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: lea (getA.a,%pc), %a0 +; CHECK-NEXT: rts + ret ptr @getA.a +} + +define ptr @get_addr() { +; CHECK-LABEL: get_addr: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.l #0, %a0 +; CHECK-NEXT: rts + ret ptr null +}