[llvm] r230543 - X86, Win64: Allow 'mov' to restore the stack pointer if we have a FP
David Majnemer
david.majnemer at gmail.com
Wed Feb 25 13:13:37 PST 2015
Author: majnemer
Date: Wed Feb 25 15:13:37 2015
New Revision: 230543
URL: http://llvm.org/viewvc/llvm-project?rev=230543&view=rev
Log:
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.
Modified:
llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
llvm/trunk/test/CodeGen/X86/win64_eh.ll
Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=230543&r1=230542&r2=230543&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Wed Feb 25 15:13:37 2015
@@ -1074,21 +1074,20 @@ void X86FrameLowering::emitEpilogue(Mach
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);
Modified: llvm/trunk/test/CodeGen/X86/win64_eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win64_eh.ll?rev=230543&r1=230542&r2=230543&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win64_eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win64_eh.ll Wed Feb 25 15:13:37 2015
@@ -167,7 +167,7 @@ entry:
; WIN64: andq $-64, %rsp
; WIN64: movaps -32(%rbp), %xmm6 # 16-byte Reload
; WIN64: movaps -16(%rbp), %xmm7 # 16-byte Reload
-; WIN64: leaq (%rbp), %rsp
+; WIN64: movq %rbp, %rsp
; WIN64: popq %rbx
; WIN64: popq %rdi
; WIN64: popq %rbp
More information about the llvm-commits
mailing list