Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -1561,6 +1561,8 @@ inlined into a function that has no ``"stack-probe-size"`` attribute at all, the resulting function has the ``"stack-probe-size"`` attribute of the callee. +``"no-stack-arg-probe"`` + This attribute disables ABI-required stack probes, if any. ``writeonly`` On a function, this attribute indicates that the function may write to but does not read from memory. Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -369,7 +369,8 @@ F.getFnAttribute("stack-probe-size") .getValueAsString() .getAsInteger(0, StackProbeSize); - return StackSizeInBytes >= StackProbeSize; + return (StackSizeInBytes >= StackProbeSize) && + !F.hasFnAttribute("no-stack-arg-probe"); } bool AArch64FrameLowering::shouldCombineCSRLocalStackBump( Index: lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- lib/Target/ARM/ARMFrameLowering.cpp +++ lib/Target/ARM/ARMFrameLowering.cpp @@ -209,7 +209,8 @@ F.getFnAttribute("stack-probe-size") .getValueAsString() .getAsInteger(0, StackProbeSize); - return StackSizeInBytes >= StackProbeSize; + return (StackSizeInBytes >= StackProbeSize) && + !F.hasFnAttribute("no-stack-arg-probe"); } namespace { Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -38919,7 +38919,8 @@ // Generally, if we aren't on Windows, the platform ABI does not include // support for stack probes, so don't emit them. - if (!Subtarget.isOSWindows() || Subtarget.isTargetMachO()) + if (!Subtarget.isOSWindows() || Subtarget.isTargetMachO() || + MF.getFunction()->hasFnAttribute("no-stack-arg-probe")) return ""; // We need a stack probe to conform to the Windows ABI. Choose the right Index: lib/Target/X86/X86WinAllocaExpander.cpp =================================================================== --- lib/Target/X86/X86WinAllocaExpander.cpp +++ lib/Target/X86/X86WinAllocaExpander.cpp @@ -62,6 +62,7 @@ unsigned StackPtr; unsigned SlotSize; int64_t StackProbeSize; + bool NoStackArgProbe; StringRef getPassName() const override { return "X86 WinAlloca Expander"; } static char ID; @@ -240,13 +241,21 @@ } break; case Probe: - // The probe lowering expects the amount in RAX/EAX. - BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA) - .addReg(MI->getOperand(0).getReg()); - - // Do the probe. - STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL, - /*InPrologue=*/false); + if (!NoStackArgProbe) { + // The probe lowering expects the amount in RAX/EAX. + BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA) + .addReg(MI->getOperand(0).getReg()); + + // Do the probe. + STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL, + /*InPrologue=*/false); + } else { + // Sub + BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::SUB64rr : X86::SUB32rr), + StackPtr) + .addReg(StackPtr) + .addReg(MI->getOperand(0).getReg()); + } break; } @@ -278,6 +287,7 @@ StackPtr = TRI->getStackRegister(); SlotSize = TRI->getSlotSize(); + NoStackArgProbe = MF.getFunction()->hasFnAttribute("no-stack-arg-probe"); StackProbeSize = 4096; if (MF.getFunction().hasFnAttribute("stack-probe-size")) { MF.getFunction()