Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -10328,7 +10328,7 @@ other aggressive transformations, so the value returned may not be that of the obvious source-language caller. -This intrinsic is only implemented for x86. +This intrinsic is only implemented for x86 and aarch64. '``llvm.frameaddress``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2865,6 +2865,8 @@ return LowerFRAMEADDR(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); + case ISD::ADDROFRETURNADDR: + return LowerADDROFRETURNADDR(Op, DAG); case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG); case ISD::EXTRACT_VECTOR_ELT: @@ -5221,6 +5223,25 @@ + StringRef(RegName) + "\".")); } +SDValue AArch64TargetLowering::LowerADDROFRETURNADDR(SDValue Op, + SelectionDAG &DAG) const { + DAG.getMachineFunction().getFrameInfo().setReturnAddressIsTaken(true); + + MachineFunction &MF = DAG.getMachineFunction(); + AArch64FunctionInfo *FI = MF.getInfo(); + int ReturnAddrIndex = FI->getRAIndex(); + + if (ReturnAddrIndex == 0) { + // Set up a frame object for the return address. + uint64_t SlotSize = MF.getDataLayout().getPointerSize(); + ReturnAddrIndex = + MF.getFrameInfo().CreateFixedObject(SlotSize, -(uint64_t)SlotSize, false); + FI->setRAIndex(ReturnAddrIndex); + } + + return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy(DAG.getDataLayout())); +} + SDValue AArch64TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); Index: lib/Target/AArch64/AArch64MachineFunctionInfo.h =================================================================== --- lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -101,6 +101,10 @@ /// ForwardedMustTailRegParms - A list of virtual and physical registers /// that must be forwarded to every musttail call. SmallVector ForwardedMustTailRegParms; + + /// FrameIndex for return slot. + int ReturnAddrIndex = 0; + public: AArch64FunctionInfo() = default; @@ -183,6 +187,9 @@ const SetOfInstructions &getLOHRelated() const { return LOHRelated; } + int getRAIndex() const { return ReturnAddrIndex; } + void setRAIndex(int Index) { ReturnAddrIndex = Index; } + // Shortcuts for LOH related types. class MILOHDirective { MCLOHType Kind; Index: test/CodeGen/AArch64/addr-of-ret-addr.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/addr-of-ret-addr.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -disable-fp-elim -mtriple=arm64-windows | FileCheck %s + +define i8* @f() nounwind readnone optsize { +entry: + %0 = tail call i8* @llvm.addressofreturnaddress() + ret i8* %0 + ; CHECK-LABEL: f: + ; CHECK: sp, sp, #16 + ; CHECK: add x0, sp, #8 + ; CHECK: add, sp, #16 +} + +declare i8* @llvm.addressofreturnaddress() nounwind readnone