Update comments to use unreachable instead of llvm.trap, as implemented now
authorReid Kleckner <reid@kleckner.net>
Thu, 29 Jan 2015 22:33:00 +0000 (22:33 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 29 Jan 2015 22:33:00 +0000 (22:33 +0000)
win64: Call __chkstk through a register with the large code model

Fixes half of PR18582. True dynamic allocas will still have a
CALL64pcrel32 which will fail.

Reviewers: majnemer

Differential Revision: http://reviews.llvm.org/D7267

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

lib/Target/X86/X86FrameLowering.cpp
lib/Target/X86/X86FrameLowering.h
lib/Target/X86/X86InstrControl.td
test/CodeGen/X86/win_chkstk.ll

index bb2007dd68211a3163c3b041d5fe33c4ea8507fe..4cccfa26be4f7846a240ff39dc239bb5e095d2da 100644 (file)
@@ -408,10 +408,16 @@ static bool usesTheStack(const MachineFunction &MF) {
   return false;
 }
 
-void X86FrameLowering::getStackProbeFunction(const X86Subtarget &STI,
+void X86FrameLowering::getStackProbeFunction(const MachineFunction &MF,
+                                             const X86Subtarget &STI,
                                              unsigned &CallOp,
                                              const char *&Symbol) {
-  CallOp = STI.is64Bit() ? X86::W64ALLOCA : X86::CALLpcrel32;
+  if (STI.is64Bit())
+    CallOp = MF.getTarget().getCodeModel() == CodeModel::Large
+                 ? X86::CALL64r
+                 : X86::W64ALLOCA;
+  else
+    CallOp = X86::CALLpcrel32;
 
   if (STI.is64Bit()) {
     if (STI.isTargetCygMing()) {
@@ -758,7 +764,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
     const char *StackProbeSymbol;
     unsigned CallOp;
 
-    getStackProbeFunction(STI, CallOp, StackProbeSymbol);
+    getStackProbeFunction(MF, STI, CallOp, StackProbeSymbol);
 
     // Check whether EAX is livein for this function.
     bool isEAXAlive = isEAXLiveIn(MF);
@@ -788,12 +794,23 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
         .setMIFlag(MachineInstr::FrameSetup);
     }
 
-    BuildMI(MBB, MBBI, DL,
-            TII.get(CallOp))
-      .addExternalSymbol(StackProbeSymbol)
-      .addReg(StackPtr,    RegState::Define | RegState::Implicit)
-      .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
-      .setMIFlag(MachineInstr::FrameSetup);
+    if (Is64Bit && MF.getTarget().getCodeModel() == CodeModel::Large) {
+      // For the large code model, we have to call through a register. Use R11,
+      // as it is unused and clobbered by all probe functions.
+      BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::R11)
+          .addExternalSymbol(StackProbeSymbol);
+      BuildMI(MBB, MBBI, DL, TII.get(CallOp))
+          .addReg(X86::R11)
+          .addReg(StackPtr, RegState::Define | RegState::Implicit)
+          .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
+          .setMIFlag(MachineInstr::FrameSetup);
+    } else {
+      BuildMI(MBB, MBBI, DL, TII.get(CallOp))
+          .addExternalSymbol(StackProbeSymbol)
+          .addReg(StackPtr, RegState::Define | RegState::Implicit)
+          .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
+          .setMIFlag(MachineInstr::FrameSetup);
+    }
 
     if (Is64Bit) {
       // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp
index ee0ee227cad862058d126b205489f3cd9b50a225..7b1b5e470c88184d0ea56d872b41bb0b56ee76f2 100644 (file)
@@ -27,8 +27,8 @@ public:
   explicit X86FrameLowering(StackDirection D, unsigned StackAl, int LAO)
     : TargetFrameLowering(StackGrowsDown, StackAl, LAO) {}
 
-  static void getStackProbeFunction(const X86Subtarget &STI,
-                                    unsigned &CallOp,
+  static void getStackProbeFunction(const MachineFunction &MF,
+                                    const X86Subtarget &STI, unsigned &CallOp,
                                     const char *&Symbol);
 
   void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
index 71415c6fde8ed7cbb1da6532a9483a013d005d86..7baff19e51a9296394a8e8596da9f7ab360f47ec 100644 (file)
@@ -279,7 +279,8 @@ let isCall = 1, Uses = [RSP], SchedRW = [WriteJump] in {
 }
 
 let isCall = 1, isCodeGenOnly = 1 in
-  // __chkstk(MSVC):     clobber R10, R11 and EFLAGS.
+  // __chkstk(MSVC):     clobber R10, R11 and EFLAGS
+  // ___chkstk_ms(Mingw64): clobber R10, R11 and EFLAGS
   // ___chkstk(Mingw64): clobber R10, R11, RAX and EFLAGS, and update RSP.
   let Defs = [RAX, R10, R11, RSP, EFLAGS],
       Uses = [RSP] in {
index 0c02c1a11d18154def208c022cc845322c735f17..4edc89f623ad4dd0031a3c29bd386956c4306c8b 100644 (file)
@@ -1,5 +1,6 @@
 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=WIN_X64
+; RUN: llc < %s -mtriple=x86_64-pc-win32 -code-model=large | FileCheck %s -check-prefix=WIN64_LARGE
 ; 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
@@ -16,6 +17,8 @@ define i32 @main4k() nounwind {
 entry:
 ; WIN_X32:    calll __chkstk
 ; WIN_X64:    callq __chkstk
+; WIN64_LARGE: movabsq $__chkstk, %r11
+; WIN64_LARGE: callq *%r11
 ; MINGW_X32:  calll __alloca
 ; MINGW_X64:  callq ___chkstk_ms
 ; LINUX-NOT:  call __chkstk
@@ -52,6 +55,8 @@ define x86_64_win64cc i32 @main4k_win64() nounwind {
 entry:
 ; WIN_X32:    calll __chkstk
 ; WIN_X64:    callq __chkstk
+; WIN64_LARGE: movabsq $__chkstk, %r11
+; WIN64_LARGE: callq *%r11
 ; MINGW_X32:  calll __alloca
 ; MINGW_X64:  callq ___chkstk_ms
 ; LINUX-NOT:  call __chkstk