<div dir="ltr">I observe a leak report when running this test under lsan or valgrind (<a href="http://llvm.org/bugs/show_bug.cgi?id=19521">http://llvm.org/bugs/show_bug.cgi?id=19521</a>).<div>Please check. <br><div><br></div>
<div><div>Indirect leak of 136 byte(s) in 1 object(s) allocated from:                                                      </div><div>    #0 0x65f540 in operator new(unsigned long) projects/compiler-rt/lib/asan/asan_new_delete.cc:62               </div>
<div>    #1 0x20909d3 in llvm::User::operator new(unsigned long, unsigned int) lib/IR/User.cpp:60                     </div><div>    #2 0xa8bb12 in Twine include/llvm/IR/Function.h:131                                                          </div>
<div>    #3 0xa8bb12 in llvm::ARMFrameLowering::emitPrologue(llvm::MachineFunction&) const lib/Target/ARM/ARMFrameLowering.cpp:322</div><div>    #4 0x1c49990 in llvm::PEI::insertPrologEpilogCode(llvm::MachineFunction&) lib/CodeGen/PrologEpilogInserter.cpp:671</div>
<div>    #5 0x1c43127 in llvm::PEI::runOnMachineFunction(llvm::MachineFunction&) lib/CodeGen/PrologEpilogInserter.cpp:155</div><div>    #6 0x1b2cbfb in llvm::MachineFunctionPass::runOnFunction(llvm::Function&) lib/CodeGen/MachineFunctionPass.cpp:33</div>
<div>    #7 0x204ee04 in llvm::FPPassManager::runOnFunction(llvm::Function&) lib/IR/LegacyPassManager.cpp:1545        </div><div>    #8 0x204f315 in llvm::FPPassManager::runOnModule(llvm::Module&) lib/IR/LegacyPassManager.cpp:1567            </div>
<div>    #9 0x2050014 in runOnModule lib/IR/LegacyPassManager.cpp:1625                                                </div><div>    #10 0x2050014 in llvm::legacy::PassManagerImpl::run(llvm::Module&) lib/IR/LegacyPassManager.cpp:1734         </div>
<div>    #11 0x685d57 in compileModule tools/llc/llc.cpp:356                                                          </div><div>    #12 0x685d57 in main tools/llc/llc.cpp:202                                                                   </div>
<div>    #13 0x7fd3756f276c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226           </div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 30, 2014 at 11:05 AM, Saleem Abdulrasool <span dir="ltr"><<a href="mailto:compnerd@compnerd.org" target="_blank">compnerd@compnerd.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: compnerd<br>
Date: Wed Apr 30 02:05:07 2014<br>
New Revision: 207615<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=207615&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=207615&view=rev</a><br>
Log:<br>
ARM: support stack probe emission for Windows on ARM<br>
<br>
This introduces the stack lowering emission of the stack probe function for<br>
Windows on ARM. The stack on Windows on ARM is a dynamically paged stack where<br>
any page allocation which crosses a page boundary of the following guard page<br>
will cause a page fault. This page fault must be handled by the kernel to<br>
ensure that the page is faulted in. If this does not occur and a write access<br>
any memory beyond that, the page fault will go unserviced, resulting in an<br>
abnormal program termination.<br>
<br>
The watermark for the stack probe appears to be at 4080 bytes (for<br>
accommodating the stack guard canaries and stack alignment) when SSP is<br>
enabled.  Otherwise, the stack probe is emitted on the page size boundary of<br>
4096 bytes.<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll<br>
Modified:<br>
    llvm/trunk/docs/Extensions.rst<br>
    llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp<br>
<br>
Modified: llvm/trunk/docs/Extensions.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Extensions.rst?rev=207615&r1=207614&r2=207615&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Extensions.rst?rev=207615&r1=207614&r2=207615&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/docs/Extensions.rst (original)<br>
+++ llvm/trunk/docs/Extensions.rst Wed Apr 30 02:05:07 2014<br>
@@ -159,3 +159,34 @@ different COMDATs:<br>
   .globl Symbol2<br>
   Symbol2:<br>
   .long 1<br>
+<br>
+Target Specific Behaviour<br>
+=========================<br>
+<br>
+Windows on ARM<br>
+--------------<br>
+<br>
+Stack Probe Emission<br>
+^^^^^^^^^^^^^^^^^^^^<br>
+<br>
+The reference implementation (Microsoft Visual Studio 2012) emits stack probes<br>
+in the following fashion:<br>
+<br>
+.. code-block:: gas<br>
+<br>
+  movw r4, #constant<br>
+  bl __chkstk<br>
+  sub.w sp, sp, r4<br>
+<br>
+However, this has the limitation of 32 MiB (±16MiB).  In order to accomodate<br>
+larger binaries, LLVM supports the use of ``-mcode-model=large`` to allow a 4GiB<br>
+range via a slight deviation.  It will generate an indirect jump as follows:<br>
+<br>
+.. code-block:: gas<br>
+<br>
+  movw r4, #constant<br>
+  movw r12, :lower16:__chkstk<br>
+  movt r12, :upper16:__chkstk<br>
+  blx r12<br>
+  sub.w sp, sp, r4<br>
+<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=207615&r1=207614&r2=207615&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=207615&r1=207614&r2=207615&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp Wed Apr 30 02:05:07 2014<br>
@@ -25,6 +25,7 @@<br>
 #include "llvm/CodeGen/RegisterScavenging.h"<br>
 #include "llvm/IR/CallingConv.h"<br>
 #include "llvm/IR/Function.h"<br>
+#include "llvm/IR/Module.h"<br>
 #include "llvm/MC/MCContext.h"<br>
 #include "llvm/Support/CommandLine.h"<br>
 #include "llvm/Target/TargetOptions.h"<br>
@@ -142,6 +143,14 @@ static int sizeOfSPAdjustment(const Mach<br>
   return count;<br>
 }<br>
<br>
+static bool WindowsRequiresStackProbe(const MachineFunction &MF,<br>
+                                      size_t StackSizeInBytes) {<br>
+  const MachineFrameInfo *MFI = MF.getFrameInfo();<br>
+  if (MFI->getStackProtectorIndex() > 0)<br>
+    return StackSizeInBytes >= 4080;<br>
+  return StackSizeInBytes >= 4096;<br>
+}<br>
+<br>
 void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {<br>
   MachineBasicBlock &MBB = MF.front();<br>
   MachineBasicBlock::iterator MBBI = MBB.begin();<br>
@@ -149,15 +158,16 @@ void ARMFrameLowering::emitPrologue(Mach<br>
   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();<br>
   MachineModuleInfo &MMI = MF.getMMI();<br>
   MCContext &Context = MMI.getContext();<br>
+  const TargetMachine &TM = MF.getTarget();<br>
   const MCRegisterInfo *MRI = Context.getRegisterInfo();<br>
   const ARMBaseRegisterInfo *RegInfo =<br>
-    static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());<br>
+    static_cast<const ARMBaseRegisterInfo*>(TM.getRegisterInfo());<br>
   const ARMBaseInstrInfo &TII =<br>
-    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());<br>
+    *static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo());<br>
   assert(!AFI->isThumb1OnlyFunction() &&<br>
          "This emitPrologue does not support Thumb1!");<br>
   bool isARM = !AFI->isThumbFunction();<br>
-  unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();<br>
+  unsigned Align = TM.getFrameLowering()->getStackAlignment();<br>
   unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);<br>
   unsigned NumBytes = MFI->getStackSize();<br>
   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();<br>
@@ -187,7 +197,8 @@ void ARMFrameLowering::emitPrologue(Mach<br>
         .addCFIIndex(CFIIndex);<br>
   }<br>
<br>
-  if (!AFI->hasStackFrame()) {<br>
+  if (!AFI->hasStackFrame() &&<br>
+      (!STI.isTargetWindows() || !WindowsRequiresStackProbe(MF, NumBytes))) {<br>
     if (NumBytes - ArgRegsSaveSize != 0) {<br>
       emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes - ArgRegsSaveSize),<br>
                    MachineInstr::FrameSetup);<br>
@@ -284,6 +295,50 @@ void ARMFrameLowering::emitPrologue(Mach<br>
   } else<br>
     NumBytes = DPRCSOffset;<br>
<br>
+  if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, NumBytes)) {<br>
+    uint32_t NumWords = NumBytes >> 2;<br>
+<br>
+    if (NumWords < 65536)<br>
+      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), ARM::R4)<br>
+                     .addImm(NumWords));<br>
+    else<br>
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R4)<br>
+        .addImm(NumWords);<br>
+<br>
+    switch (TM.getCodeModel()) {<br>
+    case CodeModel::Small:<br>
+    case CodeModel::Medium:<br>
+    case CodeModel::Default:<br>
+    case CodeModel::Kernel:<br>
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))<br>
+        .addImm((unsigned)ARMCC::AL).addReg(0)<br>
+        .addExternalSymbol("__chkstk")<br>
+        .addReg(ARM::R4, RegState::Implicit);<br>
+      break;<br>
+    case CodeModel::Large:<br>
+    case CodeModel::JITDefault: {<br>
+      LLVMContext &Ctx = MF.getMMI().getModule()->getContext();<br>
+      const GlobalValue *F =<br>
+        Function::Create(FunctionType::get(Type::getVoidTy(Ctx), false),<br>
+                         GlobalValue::AvailableExternallyLinkage, "__chkstk");<br>
+<br>
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)<br>
+        .addGlobalAddress(F);<br>
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::BLX))<br>
+        .addReg(ARM::R12, RegState::Kill)<br>
+        .addReg(ARM::R4, RegState::Implicit);<br>
+      break;<br>
+    }<br>
+    }<br>
+<br>
+    AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr),<br>
+                                        ARM::SP)<br>
+                                .addReg(ARM::SP, RegState::Define)<br>
+                                .addReg(ARM::R4, RegState::Kill)<br>
+                                .setMIFlags(MachineInstr::FrameSetup)));<br>
+    NumBytes = 0;<br>
+  }<br>
+<br>
   unsigned adjustedGPRCS1Size = GPRCS1Size;<br>
   if (NumBytes) {<br>
     // Adjust SP after all the callee-save spills.<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll?rev=207615&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll?rev=207615&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll Wed Apr 30 02:05:07 2014<br>
@@ -0,0 +1,24 @@<br>
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 %s -o - \<br>
+; RUN:  | FileCheck -check-prefix CHECK-DEFAULT-CODE-MODEL %s<br>
+<br>
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -code-model=large %s -o - \<br>
+; RUN:  | FileCheck -check-prefix CHECK-LARGE-CODE-MODEL %s<br>
+<br>
+define arm_aapcs_vfpcc void @check_watermark() {<br>
+entry:<br>
+  %buffer = alloca [4096 x i8], align 1<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-DEFAULT-CODE-MODEL: check_watermark:<br>
+; CHECK-DEFAULT-CODE-MODEL:    movw r4, #1024<br>
+; CHECK-DEFAULT-CODE-MODEL:    bl __chkstk<br>
+; CHECK-DEFAULT-CODE-MODEL:    sub.w sp, sp, r4<br>
+<br>
+; CHECK-LARGE-CODE-MODEL: check_watermark:<br>
+; CHECK-LARGE-CODE-MODEL:      movw r4, #1024<br>
+; CHECK-LARGE-CODE-MODEL:      movw r12, :lower16:__chkstk<br>
+; CHECK-LARGE-CODE-MODEL:      movt r12, :upper16:__chkstk<br>
+; CHECK-LARGE-CODE-MODEL:      blx r12<br>
+; CHECK-LARGE-CODE-MODEL:      sub.w sp, sp, r4<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>