diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index adeb46df8d5..d049c02da77 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1242,6 +1242,9 @@ int X86FrameLowering::getFrameIndexOffset(const MachineFunction &MF, NumBytes = FrameSize - CSSize; } uint64_t SEHFrameOffset = calculateSetFPREG(NumBytes); + if (FI && FI == X86FI->getFAIndex()) + return -SEHFrameOffset; + // FPDelta is the offset from the "traditional" FP location of the old base // pointer followed by return address and the location required by the // restricted Win64 prologue. diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 7c950a5a716..c36db5a4931 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -17953,15 +17953,33 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op, } SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { - MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + X86MachineFunctionInfo *FuncInfo = MF.getInfo(); + const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo(); + EVT VT = Op.getValueType(); + MFI->setFrameAddressIsTaken(true); - EVT VT = Op.getValueType(); + if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI()) { + // Depth > 0 makes no sense on targets which use Windows unwind codes. It + // is not possible to crawl up the stack without looking at the unwind codes + // simultaneously. + int FrameAddrIndex = FuncInfo->getFAIndex(); + if (!FrameAddrIndex) { + // Set up a frame object for the return address. + unsigned SlotSize = RegInfo->getSlotSize(); + FrameAddrIndex = MF.getFrameInfo()->CreateFixedObject( + SlotSize, /*Offset=*/INT64_MIN, /*IsImmutable=*/false); + FuncInfo->setFAIndex(FrameAddrIndex); + } + return DAG.getFrameIndex(FrameAddrIndex, VT); + } + + unsigned FrameReg = + RegInfo->getPtrSizedFrameRegister(DAG.getMachineFunction()); SDLoc dl(Op); // FIXME probably not meaningful unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); - const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo(); - unsigned FrameReg = RegInfo->getPtrSizedFrameRegister( - DAG.getMachineFunction()); assert(((FrameReg == X86::RBP && VT == MVT::i64) || (FrameReg == X86::EBP && VT == MVT::i32)) && "Invalid Frame Register!"); diff --git a/lib/Target/X86/X86MachineFunctionInfo.h b/lib/Target/X86/X86MachineFunctionInfo.h index 9fd03a7059c..d598b55aae3 100644 --- a/lib/Target/X86/X86MachineFunctionInfo.h +++ b/lib/Target/X86/X86MachineFunctionInfo.h @@ -50,6 +50,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo { /// ReturnAddrIndex - FrameIndex for return slot. int ReturnAddrIndex; + /// \brief FrameIndex for return slot. + int FrameAddrIndex; + /// TailCallReturnAddrDelta - The number of bytes by which return address /// stack slot is moved as the result of tail call optimization. int TailCallReturnAddrDelta; @@ -92,6 +95,7 @@ public: CalleeSavedFrameSize(0), BytesToPopOnReturn(0), ReturnAddrIndex(0), + FrameAddrIndex(0), TailCallReturnAddrDelta(0), SRetReturnReg(0), GlobalBaseReg(0), @@ -109,6 +113,7 @@ public: CalleeSavedFrameSize(0), BytesToPopOnReturn(0), ReturnAddrIndex(0), + FrameAddrIndex(0), TailCallReturnAddrDelta(0), SRetReturnReg(0), GlobalBaseReg(0), @@ -139,6 +144,9 @@ public: int getRAIndex() const { return ReturnAddrIndex; } void setRAIndex(int Index) { ReturnAddrIndex = Index; } + int getFAIndex() const { return FrameAddrIndex; } + void setFAIndex(int Index) { FrameAddrIndex = Index; } + int getTCReturnAddrDelta() const { return TailCallReturnAddrDelta; } void setTCReturnAddrDelta(int delta) {TailCallReturnAddrDelta = delta;} diff --git a/test/CodeGen/X86/frameallocate.ll b/test/CodeGen/X86/frameallocate.ll index 13d35b91937..7a2f9e3eb74 100644 --- a/test/CodeGen/X86/frameallocate.ll +++ b/test/CodeGen/X86/frameallocate.ll @@ -32,8 +32,12 @@ define void @alloc_func(i32* %s, i32* %d) { } ; CHECK-LABEL: alloc_func: +; CHECK: subq $48, %rsp +; CHECK: .seh_stackalloc 48 +; CHECK: leaq 48(%rsp), %rbp +; CHECK: .seh_setframe 5, 48 ; CHECK: .Lframeallocation_alloc_func = -[[offs:[0-9]+]] ; CHECK: movl $42, -[[offs]](%rbp) -; CHECK: movq %rbp, %rcx +; CHECK: leaq -48(%rbp), %rcx ; CHECK: callq print_framealloc_from_fp ; CHECK: retq