[llvm] r207615 - ARM: support stack probe emission for Windows on ARM

Saleem Abdulrasool compnerd at compnerd.org
Wed Apr 30 21:28:34 PDT 2014


On Wed, Apr 30, 2014 at 1:42 AM, Kostya Serebryany <kcc at google.com> wrote:

> I observe a leak report when running this test under lsan or valgrind (
> http://llvm.org/bugs/show_bug.cgi?id=19521).
> Please check.
>

Thank you for bringing this to my attention.  I believe that the leak
should be addressed by SVN  r207737.  At the very least, valgrind seems to
be happy with it now.

Indirect leak of 136 byte(s) in 1 object(s) allocated from:
>
>     #0 0x65f540 in operator new(unsigned long)
> projects/compiler-rt/lib/asan/asan_new_delete.cc:62
>     #1 0x20909d3 in llvm::User::operator new(unsigned long, unsigned int)
> lib/IR/User.cpp:60
>     #2 0xa8bb12 in Twine include/llvm/IR/Function.h:131
>
>     #3 0xa8bb12 in
> llvm::ARMFrameLowering::emitPrologue(llvm::MachineFunction&) const
> lib/Target/ARM/ARMFrameLowering.cpp:322
>     #4 0x1c49990 in
> llvm::PEI::insertPrologEpilogCode(llvm::MachineFunction&)
> lib/CodeGen/PrologEpilogInserter.cpp:671
>     #5 0x1c43127 in
> llvm::PEI::runOnMachineFunction(llvm::MachineFunction&)
> lib/CodeGen/PrologEpilogInserter.cpp:155
>     #6 0x1b2cbfb in
> llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
> lib/CodeGen/MachineFunctionPass.cpp:33
>     #7 0x204ee04 in llvm::FPPassManager::runOnFunction(llvm::Function&)
> lib/IR/LegacyPassManager.cpp:1545
>     #8 0x204f315 in llvm::FPPassManager::runOnModule(llvm::Module&)
> lib/IR/LegacyPassManager.cpp:1567
>     #9 0x2050014 in runOnModule lib/IR/LegacyPassManager.cpp:1625
>
>     #10 0x2050014 in llvm::legacy::PassManagerImpl::run(llvm::Module&)
> lib/IR/LegacyPassManager.cpp:1734
>     #11 0x685d57 in compileModule tools/llc/llc.cpp:356
>
>     #12 0x685d57 in main tools/llc/llc.cpp:202
>
>     #13 0x7fd3756f276c in __libc_start_main
> /build/buildd/eglibc-2.15/csu/libc-start.c:226
>
>
> On Wed, Apr 30, 2014 at 11:05 AM, Saleem Abdulrasool <
> compnerd at compnerd.org> wrote:
>
>> Author: compnerd
>> Date: Wed Apr 30 02:05:07 2014
>> New Revision: 207615
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=207615&view=rev
>> Log:
>> ARM: support stack probe emission for Windows on ARM
>>
>> This introduces the stack lowering emission of the stack probe function
>> for
>> Windows on ARM. The stack on Windows on ARM is a dynamically paged stack
>> where
>> any page allocation which crosses a page boundary of the following guard
>> page
>> will cause a page fault. This page fault must be handled by the kernel to
>> ensure that the page is faulted in. If this does not occur and a write
>> access
>> any memory beyond that, the page fault will go unserviced, resulting in an
>> abnormal program termination.
>>
>> The watermark for the stack probe appears to be at 4080 bytes (for
>> accommodating the stack guard canaries and stack alignment) when SSP is
>> enabled.  Otherwise, the stack probe is emitted on the page size boundary
>> of
>> 4096 bytes.
>>
>> Added:
>>     llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll
>> Modified:
>>     llvm/trunk/docs/Extensions.rst
>>     llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
>>
>> Modified: llvm/trunk/docs/Extensions.rst
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Extensions.rst?rev=207615&r1=207614&r2=207615&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/docs/Extensions.rst (original)
>> +++ llvm/trunk/docs/Extensions.rst Wed Apr 30 02:05:07 2014
>> @@ -159,3 +159,34 @@ different COMDATs:
>>    .globl Symbol2
>>    Symbol2:
>>    .long 1
>> +
>> +Target Specific Behaviour
>> +=========================
>> +
>> +Windows on ARM
>> +--------------
>> +
>> +Stack Probe Emission
>> +^^^^^^^^^^^^^^^^^^^^
>> +
>> +The reference implementation (Microsoft Visual Studio 2012) emits stack
>> probes
>> +in the following fashion:
>> +
>> +.. code-block:: gas
>> +
>> +  movw r4, #constant
>> +  bl __chkstk
>> +  sub.w sp, sp, r4
>> +
>> +However, this has the limitation of 32 MiB (±16MiB).  In order to
>> accomodate
>> +larger binaries, LLVM supports the use of ``-mcode-model=large`` to
>> allow a 4GiB
>> +range via a slight deviation.  It will generate an indirect jump as
>> follows:
>> +
>> +.. code-block:: gas
>> +
>> +  movw r4, #constant
>> +  movw r12, :lower16:__chkstk
>> +  movt r12, :upper16:__chkstk
>> +  blx r12
>> +  sub.w sp, sp, r4
>> +
>>
>> Modified: llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp?rev=207615&r1=207614&r2=207615&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/ARM/ARMFrameLowering.cpp Wed Apr 30 02:05:07
>> 2014
>> @@ -25,6 +25,7 @@
>>  #include "llvm/CodeGen/RegisterScavenging.h"
>>  #include "llvm/IR/CallingConv.h"
>>  #include "llvm/IR/Function.h"
>> +#include "llvm/IR/Module.h"
>>  #include "llvm/MC/MCContext.h"
>>  #include "llvm/Support/CommandLine.h"
>>  #include "llvm/Target/TargetOptions.h"
>> @@ -142,6 +143,14 @@ static int sizeOfSPAdjustment(const Mach
>>    return count;
>>  }
>>
>> +static bool WindowsRequiresStackProbe(const MachineFunction &MF,
>> +                                      size_t StackSizeInBytes) {
>> +  const MachineFrameInfo *MFI = MF.getFrameInfo();
>> +  if (MFI->getStackProtectorIndex() > 0)
>> +    return StackSizeInBytes >= 4080;
>> +  return StackSizeInBytes >= 4096;
>> +}
>> +
>>  void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
>>    MachineBasicBlock &MBB = MF.front();
>>    MachineBasicBlock::iterator MBBI = MBB.begin();
>> @@ -149,15 +158,16 @@ void ARMFrameLowering::emitPrologue(Mach
>>    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
>>    MachineModuleInfo &MMI = MF.getMMI();
>>    MCContext &Context = MMI.getContext();
>> +  const TargetMachine &TM = MF.getTarget();
>>    const MCRegisterInfo *MRI = Context.getRegisterInfo();
>>    const ARMBaseRegisterInfo *RegInfo =
>> -    static_cast<const
>> ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
>> +    static_cast<const ARMBaseRegisterInfo*>(TM.getRegisterInfo());
>>    const ARMBaseInstrInfo &TII =
>> -    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
>> +    *static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo());
>>    assert(!AFI->isThumb1OnlyFunction() &&
>>           "This emitPrologue does not support Thumb1!");
>>    bool isARM = !AFI->isThumbFunction();
>> -  unsigned Align =
>> MF.getTarget().getFrameLowering()->getStackAlignment();
>> +  unsigned Align = TM.getFrameLowering()->getStackAlignment();
>>    unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
>>    unsigned NumBytes = MFI->getStackSize();
>>    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
>> @@ -187,7 +197,8 @@ void ARMFrameLowering::emitPrologue(Mach
>>          .addCFIIndex(CFIIndex);
>>    }
>>
>> -  if (!AFI->hasStackFrame()) {
>> +  if (!AFI->hasStackFrame() &&
>> +      (!STI.isTargetWindows() || !WindowsRequiresStackProbe(MF,
>> NumBytes))) {
>>      if (NumBytes - ArgRegsSaveSize != 0) {
>>        emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes -
>> ArgRegsSaveSize),
>>                     MachineInstr::FrameSetup);
>> @@ -284,6 +295,50 @@ void ARMFrameLowering::emitPrologue(Mach
>>    } else
>>      NumBytes = DPRCSOffset;
>>
>> +  if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, NumBytes)) {
>> +    uint32_t NumWords = NumBytes >> 2;
>> +
>> +    if (NumWords < 65536)
>> +      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16),
>> ARM::R4)
>> +                     .addImm(NumWords));
>> +    else
>> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R4)
>> +        .addImm(NumWords);
>> +
>> +    switch (TM.getCodeModel()) {
>> +    case CodeModel::Small:
>> +    case CodeModel::Medium:
>> +    case CodeModel::Default:
>> +    case CodeModel::Kernel:
>> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))
>> +        .addImm((unsigned)ARMCC::AL).addReg(0)
>> +        .addExternalSymbol("__chkstk")
>> +        .addReg(ARM::R4, RegState::Implicit);
>> +      break;
>> +    case CodeModel::Large:
>> +    case CodeModel::JITDefault: {
>> +      LLVMContext &Ctx = MF.getMMI().getModule()->getContext();
>> +      const GlobalValue *F =
>> +        Function::Create(FunctionType::get(Type::getVoidTy(Ctx), false),
>> +                         GlobalValue::AvailableExternallyLinkage,
>> "__chkstk");
>> +
>> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)
>> +        .addGlobalAddress(F);
>> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::BLX))
>> +        .addReg(ARM::R12, RegState::Kill)
>> +        .addReg(ARM::R4, RegState::Implicit);
>> +      break;
>> +    }
>> +    }
>> +
>> +    AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
>> TII.get(ARM::t2SUBrr),
>> +                                        ARM::SP)
>> +                                .addReg(ARM::SP, RegState::Define)
>> +                                .addReg(ARM::R4, RegState::Kill)
>> +                                .setMIFlags(MachineInstr::FrameSetup)));
>> +    NumBytes = 0;
>> +  }
>> +
>>    unsigned adjustedGPRCS1Size = GPRCS1Size;
>>    if (NumBytes) {
>>      // Adjust SP after all the callee-save spills.
>>
>> Added: llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll?rev=207615&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll (added)
>> +++ llvm/trunk/test/CodeGen/ARM/Windows/chkstk.ll Wed Apr 30 02:05:07 2014
>> @@ -0,0 +1,24 @@
>> +; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 %s -o - \
>> +; RUN:  | FileCheck -check-prefix CHECK-DEFAULT-CODE-MODEL %s
>> +
>> +; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -code-model=large %s
>> -o - \
>> +; RUN:  | FileCheck -check-prefix CHECK-LARGE-CODE-MODEL %s
>> +
>> +define arm_aapcs_vfpcc void @check_watermark() {
>> +entry:
>> +  %buffer = alloca [4096 x i8], align 1
>> +  ret void
>> +}
>> +
>> +; CHECK-DEFAULT-CODE-MODEL: check_watermark:
>> +; CHECK-DEFAULT-CODE-MODEL:    movw r4, #1024
>> +; CHECK-DEFAULT-CODE-MODEL:    bl __chkstk
>> +; CHECK-DEFAULT-CODE-MODEL:    sub.w sp, sp, r4
>> +
>> +; CHECK-LARGE-CODE-MODEL: check_watermark:
>> +; CHECK-LARGE-CODE-MODEL:      movw r4, #1024
>> +; CHECK-LARGE-CODE-MODEL:      movw r12, :lower16:__chkstk
>> +; CHECK-LARGE-CODE-MODEL:      movt r12, :upper16:__chkstk
>> +; CHECK-LARGE-CODE-MODEL:      blx r12
>> +; CHECK-LARGE-CODE-MODEL:      sub.w sp, sp, r4
>> +
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>


-- 
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140430/1ac35905/attachment.html>


More information about the llvm-commits mailing list