[llvm] r230286 - X86: Only use 'lea' in Win64 epilogues if a frame pointer exists

David Majnemer david.majnemer at gmail.com
Mon Feb 23 16:13:25 PST 2015


Author: majnemer
Date: Mon Feb 23 18:11:32 2015
New Revision: 230286

URL: http://llvm.org/viewvc/llvm-project?rev=230286&view=rev
Log:
X86: Only use 'lea' in Win64 epilogues if a frame pointer exists

We can only use 'add' in epilogues, 'lea' is not permitted unless we've
established a frame pointer in the prologue.

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=230286&r1=230285&r2=230286&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Mon Feb 23 18:11:32 2015
@@ -250,7 +250,7 @@ void emitSPUpdate(MachineBasicBlock &MBB
       }
     }
 
-    uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
+    uint64_t ThisVal = std::min(Offset, Chunk);
     if (ThisVal == (Is64BitTarget ? 8 : 4)) {
       // Use push / pop instead.
       unsigned Reg = isSub
@@ -980,8 +980,8 @@ void X86FrameLowering::emitEpilogue(Mach
   bool Is64Bit = STI.is64Bit();
   // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit.
   const bool Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64();
+  bool HasFP = hasFP(MF);
   const bool Is64BitILP32 = STI.isTarget64BitILP32();
-  bool UseLEA = STI.useLeaForSP();
   unsigned SlotSize = RegInfo->getSlotSize();
   unsigned FramePtr = RegInfo->getFrameRegister(MF);
   unsigned MachineFramePtr =
@@ -991,6 +991,20 @@ void X86FrameLowering::emitEpilogue(Mach
 
   bool IsWinEH = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
   bool NeedsWinEH = IsWinEH && MF.getFunction()->needsUnwindTableEntry();
+  bool UseLEAForSP = false;
+
+  // We can't use LEA instructions for adjusting the stack pointer if this is a
+  // leaf function in the Win64 ABI.  Only ADD instructions may be used to
+  // deallocate the stack.
+  if (STI.useLeaForSP()) {
+    if (!IsWinEH) {
+      // We *aren't* using the Win64 ABI which means we are free to use LEA.
+      UseLEAForSP = true;
+    } else if (HasFP) {
+      // We *have* a frame pointer which means we are permitted to use LEA.
+      UseLEAForSP = true;
+    }
+  }
 
   switch (RetOpcode) {
   default:
@@ -1084,8 +1098,8 @@ void X86FrameLowering::emitEpilogue(Mach
     }
   } else if (NumBytes) {
     // Adjust stack pointer back: ESP += numbytes.
-    emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, Uses64BitFramePtr, UseLEA,
-                 TII, *RegInfo);
+    emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, Uses64BitFramePtr,
+                 UseLEAForSP, TII, *RegInfo);
     --MBBI;
   }
 
@@ -1131,7 +1145,7 @@ void X86FrameLowering::emitEpilogue(Mach
       // Check for possible merge with preceding ADD instruction.
       Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true);
       emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, Uses64BitFramePtr,
-                   UseLEA, TII, *RegInfo);
+                   UseLEAForSP, TII, *RegInfo);
     }
 
     // Jump to label or value in register.
@@ -1179,8 +1193,8 @@ void X86FrameLowering::emitEpilogue(Mach
 
     // Check for possible merge with preceding ADD instruction.
     delta += mergeSPUpdates(MBB, MBBI, StackPtr, true);
-    emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, Uses64BitFramePtr, UseLEA, TII,
-                 *RegInfo);
+    emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, Uses64BitFramePtr,
+                 UseLEAForSP, TII, *RegInfo);
   }
 }
 

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=230286&r1=230285&r2=230286&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win64_eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win64_eh.ll Mon Feb 23 18:11:32 2015
@@ -1,5 +1,6 @@
-; RUN: llc < %s -O0 -mattr=sse2 -mtriple=x86_64-pc-windows-itanium | FileCheck %s -check-prefix=WIN64
-; RUN: llc < %s -O0 -mattr=sse2 -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=WIN64
+; RUN: llc < %s -O0 -mattr=sse2 -mtriple=x86_64-pc-windows-itanium | FileCheck %s -check-prefix=WIN64 -check-prefix=NORM
+; RUN: llc < %s -O0 -mattr=sse2 -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=WIN64 -check-prefix=NORM
+; RUN: llc < %s -O0 -mattr=sse2 -mtriple=x86_64-pc-mingw32 -mcpu=atom | FileCheck %s -check-prefix=WIN64 -check-prefix=ATOM
 
 ; Check function without prolog
 define void @foo0() uwtable {
@@ -20,7 +21,8 @@ entry:
 }
 ; WIN64-LABEL: foo1:
 ; WIN64: .seh_proc foo1
-; WIN64: subq $4000, %rsp
+; NORM:  subq $4000, %rsp
+; ATOM:  leaq -4000(%rsp), %rsp
 ; WIN64: .seh_stackalloc 4000
 ; WIN64: .seh_endprologue
 ; WIN64: addq $4000, %rsp
@@ -83,7 +85,8 @@ entry:
 ; WIN64: .seh_proc foo3
 ; WIN64: pushq %rsi
 ; WIN64: .seh_pushreg 6
-; WIN64: subq $24, %rsp
+; NORM:  subq $24, %rsp
+; ATOM:  leaq -24(%rsp), %rsp
 ; WIN64: .seh_stackalloc 24
 ; WIN64: .seh_endprologue
 ; WIN64: addq $24, %rsp
@@ -126,7 +129,8 @@ endtryfinally:
 ; WIN64-LABEL: foo4:
 ; WIN64: .seh_proc foo4
 ; WIN64: .seh_handler _d_eh_personality, @unwind, @except
-; WIN64: subq $56, %rsp
+; NORM:  subq $56, %rsp
+; ATOM:  leaq -56(%rsp), %rsp
 ; WIN64: .seh_stackalloc 56
 ; WIN64: .seh_endprologue
 ; WIN64: addq $56, %rsp
@@ -150,7 +154,8 @@ entry:
 ; WIN64: .seh_pushreg 7
 ; WIN64: pushq %rbx
 ; WIN64: .seh_pushreg 3
-; WIN64: subq  $96, %rsp
+; NORM:  subq  $96, %rsp
+; ATOM:  leaq -96(%rsp), %rsp
 ; WIN64: .seh_stackalloc 96
 ; WIN64: leaq  96(%rsp), %rbp
 ; WIN64: .seh_setframe 5, 96





More information about the llvm-commits mailing list