[llvm] r345892 - [COFF, ARM64] Implement llvm.addressofreturnaddress intrinsic

Mandeep Singh Grang via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 1 14:23:47 PDT 2018


Author: mgrang
Date: Thu Nov  1 14:23:47 2018
New Revision: 345892

URL: http://llvm.org/viewvc/llvm-project?rev=345892&view=rev
Log:
[COFF, ARM64] Implement llvm.addressofreturnaddress intrinsic

Reviewers: rnk, mstorsjo, efriedma, TomTan

Reviewed By: efriedma

Subscribers: javed.absar, kristof.beyls, chrib, llvm-commits

Differential Revision: https://reviews.llvm.org/D53962

Added:
    llvm/trunk/test/CodeGen/AArch64/addr-of-ret-addr.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=345892&r1=345891&r2=345892&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Nov  1 14:23:47 2018
@@ -10328,7 +10328,7 @@ Note that calling this intrinsic does no
 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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=345892&r1=345891&r2=345892&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu Nov  1 14:23:47 2018
@@ -2865,6 +2865,8 @@ SDValue AArch64TargetLowering::LowerOper
     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,20 @@ unsigned AArch64TargetLowering::getRegis
                               + StringRef(RegName)  + "\"."));
 }
 
+SDValue AArch64TargetLowering::LowerADDROFRETURNADDR(SDValue Op,
+                                                     SelectionDAG &DAG) const {
+  DAG.getMachineFunction().getFrameInfo().setFrameAddressIsTaken(true);
+
+  EVT VT = Op.getValueType();
+  SDLoc DL(Op);
+
+  SDValue FrameAddr =
+      DAG.getCopyFromReg(DAG.getEntryNode(), DL, AArch64::FP, VT);
+  SDValue Offset = DAG.getConstant(8, DL, getPointerTy(DAG.getDataLayout()));
+
+  return DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset);
+}
+
 SDValue AArch64TargetLowering::LowerRETURNADDR(SDValue Op,
                                                SelectionDAG &DAG) const {
   MachineFunction &MF = DAG.getMachineFunction();

Added: llvm/trunk/test/CodeGen/AArch64/addr-of-ret-addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/addr-of-ret-addr.ll?rev=345892&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/addr-of-ret-addr.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/addr-of-ret-addr.ll Thu Nov  1 14:23:47 2018
@@ -0,0 +1,51 @@
+; RUN: llc < %s -disable-fp-elim -mtriple=arm64-windows | FileCheck %s
+
+; Test generated from C code:
+; #include <stdarg.h>
+; void *foo() {
+;   return _AddressOfReturnAddress();
+; }
+; int bar(int x(va_list, void*), ...) {
+;   va_list y;
+;   va_start(y, x);
+;   return x(y, _AddressOfReturnAddress()) + 1;
+; }
+
+declare void @llvm.va_start(i8*)
+declare i8* @llvm.addressofreturnaddress()
+
+define dso_local i8* @"foo"() {
+entry:
+  %0 = call i8* @llvm.addressofreturnaddress()
+  ret i8* %0
+
+; CHECK-LABEL: foo
+; CHECK: stp x29, x30, [sp, #-16]!
+; CHECK: mov x29, sp
+; CHECK: add x0, x29, #8
+; CHECK: ldp x29, x30, [sp], #16
+}
+
+define dso_local i32 @"bar"(i32 (i8*, i8*)* %x, ...) {
+entry:
+  %x.addr = alloca i32 (i8*, i8*)*, align 8
+  %y = alloca i8*, align 8
+  store i32 (i8*, i8*)* %x, i32 (i8*, i8*)** %x.addr, align 8
+  %y1 = bitcast i8** %y to i8*
+  call void @llvm.va_start(i8* %y1)
+  %0 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %x.addr, align 8
+  %1 = call i8* @llvm.addressofreturnaddress()
+  %2 = load i8*, i8** %y, align 8
+  %call = call i32 %0(i8* %2, i8* %1)
+  %add = add nsw i32 %call, 1
+  ret i32 %add
+
+; CHECK-LABEL: bar
+; CHECK: sub sp, sp, #96
+; CHECK: stp x29, x30, [sp, #16]
+; CHECK: add x29, sp, #16
+; CHECK: str x1, [x29, #24]
+; CHECK: add x1, x29, #8
+; CHECK: ldp x29, x30, [sp, #16]
+; CHECK: add sp, sp, #96
+}




More information about the llvm-commits mailing list