From: David Majnemer Date: Wed, 25 Feb 2015 21:13:37 +0000 (+0000) Subject: X86, Win64: Allow 'mov' to restore the stack pointer if we have a FP X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=92d1637e2f4310d1512e93f669d02741c9b45dcd 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230543 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 040b91a4e1d..cead0995330 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/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); diff --git a/test/CodeGen/X86/win64_eh.ll b/test/CodeGen/X86/win64_eh.ll index 597127a6998..b67ad58e0d0 100644 --- a/test/CodeGen/X86/win64_eh.ll +++ b/test/CodeGen/X86/win64_eh.ll @@ -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