Properly emit __chkstk call instead of __alloca on non-mingw windows targets.
authorAnton Korobeynikov <asl@math.spbu.ru>
Thu, 2 Sep 2010 23:03:46 +0000 (23:03 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Thu, 2 Sep 2010 23:03:46 +0000 (23:03 +0000)
Patch by Cameron Esfahani!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112902 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86RegisterInfo.cpp
lib/Target/X86/X86Subtarget.h
test/CodeGen/X86/win_chkstk.ll [new file with mode: 0644]

index 03c7ffc2bc2de1cc38aaf0d6a609ba2b5d041ef1..fedd49ebb5403d794eafbce2488fb987d89763fc 100644 (file)
@@ -764,7 +764,7 @@ void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
   }
 }
 
-/// mergeSPUpdatesUp - Merge two stack-manipulating instructions lower iterator.
+/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower iterator.
 static
 void mergeSPUpdatesDown(MachineBasicBlock &MBB,
                         MachineBasicBlock::iterator &MBBI,
@@ -1087,7 +1087,17 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
   DL = MBB.findDebugLoc(MBBI);
 
   // Adjust stack pointer: ESP -= numbytes.
-  if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
+
+  // Windows and cygwin/mingw require a prologue helper routine when allocating
+  // more than 4K bytes on the stack.  Windows uses __chkstk and cygwin/mingw
+  // uses __alloca.  __alloca and the 32-bit version of __chkstk will probe
+  // the stack and adjust the stack pointer in one go.  The 64-bit version
+  // of __chkstk is only responsible for probing the stack.  The 64-bit
+  // prologue is responsible for adjusting the stack pointer.  Touching the
+  // stack at 4K increments is necessary to ensure that the guard pages used
+  // by the OS virtual memory manager are allocated in correct sequence.
+  if (NumBytes >= 4096 &&
+     (Subtarget->isTargetCygMing() || Subtarget->isTargetWin32())) {
     // Check, whether EAX is livein for this function.
     bool isEAXAlive = false;
     for (MachineRegisterInfo::livein_iterator
@@ -1098,15 +1108,14 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
                     Reg == X86::AH || Reg == X86::AL);
     }
 
-    // Function prologue calls _alloca to probe the stack when allocating more
-    // than 4k bytes in one go. Touching the stack at 4K increments is necessary
-    // to ensure that the guard pages used by the OS virtual memory manager are
-    // allocated in correct sequence.
+
+    const char *StackProbeSymbol =
+      Subtarget->isTargetWindows() ? "_chkstk" : "_alloca";
     if (!isEAXAlive) {
       BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
         .addImm(NumBytes);
       BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
-        .addExternalSymbol("_alloca")
+        .addExternalSymbol(StackProbeSymbol)
         .addReg(StackPtr,    RegState::Define | RegState::Implicit)
         .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
     } else {
@@ -1119,7 +1128,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
       BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
         .addImm(NumBytes - 4);
       BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
-        .addExternalSymbol("_alloca")
+        .addExternalSymbol(StackProbeSymbol)
         .addReg(StackPtr,    RegState::Define | RegState::Implicit)
         .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
 
index 531fb04bd601c9661184573f5749a3a4f4defbb4..0ee91abe21f4ea949af47689b6b534fb19b3be3f 100644 (file)
@@ -186,6 +186,10 @@ public:
     return Is64Bit && (isTargetMingw() || isTargetWindows());
   }
 
+  bool isTargetWin32() const {
+    return !Is64Bit && (isTargetMingw() || isTargetWindows());
+  }
+
   std::string getDataLayout() const {
     const char *p;
     if (is64Bit())
diff --git a/test/CodeGen/X86/win_chkstk.ll b/test/CodeGen/X86/win_chkstk.ll
new file mode 100644 (file)
index 0000000..27d3358
--- /dev/null
@@ -0,0 +1,45 @@
+; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
+; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
+; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X64
+; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
+
+; Windows and mingw require a prologue helper routine if more than 4096 bytes area
+; allocated on the stack.  Windows uses __chkstk and mingw uses __alloca.  __alloca
+; and the 32-bit version of __chkstk will probe the stack and adjust the stack pointer.
+; The 64-bit version of __chkstk is only responsible for probing the stack.  The 64-bit
+; prologue is responsible for adjusting the stack pointer.
+
+; Stack allocation >= 4096 bytes will require call to __chkstk in the Windows ABI.
+define i32 @main4k() nounwind {
+entry:
+; WIN_X32:    call __chkstk
+; WIN_X64:    call __chkstk
+; MINGW_X32:  call __alloca
+; MINGW_X64:  call _alloca
+; LINUX-NOT:  call __chkstk
+  %array4096 = alloca [4096 x i8], align 16       ; <[4096 x i8]*> [#uses=0]
+  ret i32 0
+}
+
+; Make sure we don't call __chkstk or __alloca when we have less than a 4096 stack
+; allocation.
+define i32 @main128() nounwind {
+entry:
+; WIN_X32:       # BB#0:
+; WIN_X32-NOT:   call __chkstk
+; WIN_X32:       ret
+
+; WIN_X64:       # BB#0:
+; WIN_X64-NOT:   call __chkstk
+; WIN_X64:       ret
+
+; MINGW_X64:     # BB#0:
+; MINGW_X64-NOT: call _alloca
+; MINGW_X64:     ret
+
+; LINUX:         # BB#0:
+; LINUX-NOT:     call __chkstk
+; LINUX:         ret
+  %array128 = alloca [128 x i8], align 16         ; <[128 x i8]*> [#uses=0]
+  ret i32 0
+}