diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-02-25 21:13:37 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-02-25 21:13:37 +0000 |
commit | e1bbad9eb2eababecc21ace975bb25129891da38 (patch) | |
tree | 80aa5ae77b05c016172f75c23f697ba8a440ac89 /llvm/lib/Target/X86/X86FrameLowering.cpp | |
parent | 0db567f2adf7cc3bf7cfba39817245bb245c6f1f (diff) | |
download | bcm5719-llvm-e1bbad9eb2eababecc21ace975bb25129891da38.tar.gz bcm5719-llvm-e1bbad9eb2eababecc21ace975bb25129891da38.zip |
X86, Win64: Allow 'mov' to restore the stack pointer if we have a FP
The Win64 epilogue structure is very restrictive, it permits a very
small number of opcodes and none of them are 'mov'.
This means that given:
mov %rbp, %rsp
pop %rbp
The mov isn't the epilogue, only the pop is. This is problematic unless
a frame pointer is present in which case we are free to do whatever we'd
like in the "body" of the function. If a frame pointer is present,
unwinding will undo the prologue operations in reverse order regardless
of the fact that we are at an instruction which is reseting the stack
pointer.
llvm-svn: 230543
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 040b91a4e1d..cead0995330 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1074,21 +1074,20 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, if (RegInfo->needsStackRealignment(MF) || MFI->hasVarSizedObjects()) { if (RegInfo->needsStackRealignment(MF)) MBBI = FirstCSPop; - if (IsWinEH) { - // There are only two legal forms of epilogue: - // - add SEHAllocationSize, %rsp - // - lea SEHAllocationSize(%FramePtr), %rsp - // - // We are *not* permitted to use 'mov %FramePtr, %rsp' because the Win64 - // unwinder will not recognize 'mov' as an epilogue instruction. - unsigned SEHFrameOffset = calculateSetFPREG(SEHStackAllocAmt); - addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), StackPtr), - FramePtr, false, SEHStackAllocAmt - SEHFrameOffset); - --MBBI; - } else if (CSSize != 0) { + unsigned SEHFrameOffset = calculateSetFPREG(SEHStackAllocAmt); + uint64_t LEAAmount = IsWinEH ? SEHStackAllocAmt - SEHFrameOffset : -CSSize; + + // There are only two legal forms of epilogue: + // - add SEHAllocationSize, %rsp + // - lea SEHAllocationSize(%FramePtr), %rsp + // + // 'mov %FramePtr, %rsp' will not be recognized as an epilogue sequence. + // However, we may use this sequence if we have a frame pointer because the + // effects of the prologue can safely be undone. + if (LEAAmount != 0) { unsigned Opc = getLEArOpcode(Uses64BitFramePtr); addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), - FramePtr, false, -CSSize); + FramePtr, false, LEAAmount); --MBBI; } else { unsigned Opc = (Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr); |