[llvm] r284061 - Create llvm.addressofreturnaddress intrinsic
Albert Gutowski via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 12 15:13:20 PDT 2016
Author: agutowski
Date: Wed Oct 12 17:13:19 2016
New Revision: 284061
URL: http://llvm.org/viewvc/llvm-project?rev=284061&view=rev
Log:
Create llvm.addressofreturnaddress intrinsic
Summary: We need a new LLVM intrinsic to implement MS _AddressOfReturnAddress builtin on 64-bit Windows.
Reviewers: majnemer, rnk
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D25293
Added:
llvm/trunk/test/CodeGen/X86/addr-of-ret-addr.ll
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
llvm/trunk/include/llvm/IR/Intrinsics.td
llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp
llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
llvm/trunk/test/CodeGen/X86/win64_frame.ll
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Wed Oct 12 17:13:19 2016
@@ -9294,6 +9294,32 @@ Note that calling this intrinsic does no
other aggressive transformations, so the value returned may not be that
of the obvious source-language caller.
+'``llvm.addressofreturnaddress``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+ declare i8 *@llvm.addressofreturnaddress()
+
+Overview:
+"""""""""
+
+The '``llvm.addressofreturnaddress``' intrinsic returns a target-specific
+pointer to the place in the stack frame where the return address of the
+current function is stored.
+
+Semantics:
+""""""""""
+
+Note that calling this intrinsic does not prevent function inlining or
+other aggressive transformations, so the value returned may not be that
+of the obvious source-language caller.
+
+This intrinsic is only implemented for x86.
+
'``llvm.frameaddress``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Wed Oct 12 17:13:19 2016
@@ -70,7 +70,7 @@ namespace ISD {
/// of the frame or return address to return. An index of zero corresponds
/// to the current function's frame or return address, an index of one to
/// the parent's frame or return address, and so on.
- FRAMEADDR, RETURNADDR,
+ FRAMEADDR, RETURNADDR, ADDROFRETURNADDR,
/// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
/// Materializes the offset from the local object pointer of another
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Wed Oct 12 17:13:19 2016
@@ -290,6 +290,7 @@ def int_gcwrite : Intrinsic<[],
//===--------------------- Code Generator Intrinsics ----------------------===//
//
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_addressofreturnaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrReadMem], "llvm.read_register">;
Modified: llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp Wed Oct 12 17:13:19 2016
@@ -184,6 +184,7 @@ static bool isInertIntrinsic(unsigned ID
// TODO: Make this into a covered switch.
switch (ID) {
case Intrinsic::returnaddress:
+ case Intrinsic::addressofreturnaddress:
case Intrinsic::frameaddress:
case Intrinsic::stacksave:
case Intrinsic::stackrestore:
Modified: llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/IntrinsicLowering.cpp Wed Oct 12 17:13:19 2016
@@ -436,8 +436,14 @@ void IntrinsicLowering::LowerIntrinsicCa
errs() << "WARNING: this target does not support the llvm."
<< (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
"return" : "frame") << "address intrinsic.\n";
- CI->replaceAllUsesWith(ConstantPointerNull::get(
- cast<PointerType>(CI->getType())));
+ CI->replaceAllUsesWith(
+ ConstantPointerNull::get(cast<PointerType>(CI->getType())));
+ break;
+ case Intrinsic::addressofreturnaddress:
+ errs() << "WARNING: this target does not support the "
+ "llvm.addressofreturnaddress intrinsic.\n";
+ CI->replaceAllUsesWith(
+ ConstantPointerNull::get(cast<PointerType>(CI->getType())));
break;
case Intrinsic::prefetch:
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Oct 12 17:13:19 2016
@@ -1019,6 +1019,7 @@ void SelectionDAGLegalize::LegalizeOp(SD
case ISD::ADJUST_TRAMPOLINE:
case ISD::FRAMEADDR:
case ISD::RETURNADDR:
+ case ISD::ADDROFRETURNADDR:
// These operations lie about being legal: when they claim to be legal,
// they should actually be custom-lowered.
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Oct 12 17:13:19 2016
@@ -4770,6 +4770,10 @@ SelectionDAGBuilder::visitIntrinsicCall(
TLI.getPointerTy(DAG.getDataLayout()),
getValue(I.getArgOperand(0))));
return nullptr;
+ case Intrinsic::addressofreturnaddress:
+ setValue(&I, DAG.getNode(ISD::ADDROFRETURNADDR, sdl,
+ TLI.getPointerTy(DAG.getDataLayout())));
+ return nullptr;
case Intrinsic::frameaddress:
setValue(&I, DAG.getNode(ISD::FRAMEADDR, sdl,
TLI.getPointerTy(DAG.getDataLayout()),
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp Wed Oct 12 17:13:19 2016
@@ -100,6 +100,7 @@ std::string SDNode::getOperationName(con
case ISD::JumpTable: return "JumpTable";
case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
case ISD::RETURNADDR: return "RETURNADDR";
+ case ISD::ADDROFRETURNADDR: return "ADDROFRETURNADDR";
case ISD::FRAMEADDR: return "FRAMEADDR";
case ISD::LOCAL_RECOVER: return "LOCAL_RECOVER";
case ISD::READ_REGISTER: return "READ_REGISTER";
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Oct 12 17:13:19 2016
@@ -18931,6 +18931,12 @@ SDValue X86TargetLowering::LowerRETURNAD
MachinePointerInfo());
}
+SDValue X86TargetLowering::LowerADDROFRETURNADDR(SDValue Op,
+ SelectionDAG &DAG) const {
+ DAG.getMachineFunction().getFrameInfo().setReturnAddressIsTaken(true);
+ return getReturnAddressFrameIndex(DAG);
+}
+
SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -22056,6 +22062,7 @@ SDValue X86TargetLowering::LowerOperatio
case ISD::INTRINSIC_VOID:
case ISD::INTRINSIC_W_CHAIN: return LowerINTRINSIC_W_CHAIN(Op, Subtarget, DAG);
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
+ case ISD::ADDROFRETURNADDR: return LowerADDROFRETURNADDR(Op, DAG);
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::FRAME_TO_ARGS_OFFSET:
return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Oct 12 17:13:19 2016
@@ -1130,6 +1130,7 @@ namespace llvm {
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerADDROFRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
Added: llvm/trunk/test/CodeGen/X86/addr-of-ret-addr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/addr-of-ret-addr.ll?rev=284061&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/addr-of-ret-addr.ll (added)
+++ llvm/trunk/test/CodeGen/X86/addr-of-ret-addr.ll Wed Oct 12 17:13:19 2016
@@ -0,0 +1,19 @@
+; RUN: llc < %s -disable-fp-elim -march=x86 | FileCheck %s --check-prefix=CHECK-X86
+; RUN: llc < %s -disable-fp-elim -march=x86-64 | FileCheck %s --check-prefix=CHECK-X64
+
+define i8* @f() nounwind readnone optsize {
+entry:
+ %0 = tail call i8* @llvm.addressofreturnaddress() ; <i8*> [#uses=1]
+ ret i8* %0
+ ; CHECK-X86-LABEL: _f:
+ ; CHECK-X86: pushl %ebp
+ ; CHECK-X86: movl %esp, %ebp
+ ; CHECK-X86: leal 4(%ebp), %eax
+
+ ; CHECK-X64-LABEL: f:
+ ; CHECK-X64: pushq %rbp
+ ; CHECK-X64: movq %rsp, %rbp
+ ; CHECK-X64: leaq 8(%rbp), %rax
+}
+
+declare i8* @llvm.addressofreturnaddress() nounwind readnone
Modified: llvm/trunk/test/CodeGen/X86/win64_frame.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win64_frame.ll?rev=284061&r1=284060&r2=284061&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win64_frame.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win64_frame.ll Wed Oct 12 17:13:19 2016
@@ -184,7 +184,26 @@ define i64 @f10(i64* %foo, i64 %bar, i64
; CHECK-NEXT: popq %rbp
}
+define i8* @f11() "no-frame-pointer-elim"="true" {
+ ; CHECK-LABEL: f11:
+ ; CHECK: pushq %rbp
+ ; CHECK: movq %rsp, %rbp
+ ; CHECK: .seh_setframe 5, 0
+ ; CHECK: leaq 8(%rbp), %rax
+ %aora = call i8* @llvm.addressofreturnaddress()
+ ret i8* %aora
+}
+
+define i8* @f12() {
+ ; CHECK-LABEL: f12:
+ ; CHECK-NOT: push
+ ; CHECK: movq %rsp, %rax
+ %aora = call i8* @llvm.addressofreturnaddress()
+ ret i8* %aora
+}
+
declare i8* @llvm.returnaddress(i32) nounwind readnone
+declare i8* @llvm.addressofreturnaddress() nounwind readnone
declare i64 @llvm.x86.flags.read.u64()
declare void @llvm.va_start(i8*) nounwind
More information about the llvm-commits
mailing list