[llvm] r207615 - ARM: support stack probe emission for Windows on ARM
Kostya Serebryany
kcc at google.com
Wed Apr 30 01:42:01 PDT 2014
I observe a leak report when running this test under lsan or valgrind (
http://llvm.org/bugs/show_bug.cgi?id=19521).
Please check.
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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140430/914c8c80/attachment.html>
More information about the llvm-commits
mailing list