Index: include/clang/Driver/CLCompatOptions.td =================================================================== --- include/clang/Driver/CLCompatOptions.td +++ include/clang/Driver/CLCompatOptions.td @@ -62,6 +62,8 @@ def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">; def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, Alias; +def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">, + Alias; def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, Alias; def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">, @@ -252,7 +254,6 @@ def _SLASH_Gm_ : CLFlag<"Gm-">; def _SLASH_Gr : CLFlag<"Gr">; def _SLASH_GS : CLFlag<"GS">; -def _SLASH_Gs : CLJoined<"Gs">; def _SLASH_GT : CLFlag<"GT">; def _SLASH_GX : CLFlag<"GX">; def _SLASH_Gv : CLFlag<"Gv">; Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1106,6 +1106,8 @@ HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; +def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group, Flags<[CC1Option]>, + HelpText<"Set the stack probe size">; def mthread_model : Separate<["-"], "mthread-model">, Group, Flags<[CC1Option]>, HelpText<"The thread model to use, e.g. posix, single (posix by default)">; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -138,6 +138,11 @@ ///< .ctors. VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack ///< alignment, if not 0. +CODEGENOPT(IsStackProbeSizeOverridden, 1, 0) ///< Controls whether to use the + ///< overridden or the default + ///< stack probe size. +VALUE_CODEGENOPT(StackProbeSize , 32, 0) ///< Overrides default stack + ///< probe size, even if 0. CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1317,18 +1317,22 @@ llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { if (const FunctionDecl *FD = dyn_cast(D)) { + // Get the LLVM function. + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B; + if (FD->hasAttr()) { - // Get the LLVM function. - llvm::Function *Fn = cast(GV); - // Now add the 'alignstack' attribute with a value of 16. - llvm::AttrBuilder B; B.addStackAlignmentAttr(16); - Fn->addAttributes(llvm::AttributeSet::FunctionIndex, - llvm::AttributeSet::get(CGM.getLLVMContext(), - llvm::AttributeSet::FunctionIndex, - B)); } + + if (CGM.getCodeGenOpts().IsStackProbeSizeOverridden) + B.addStackProbeSizeAttr(CGM.getCodeGenOpts().StackProbeSize); + + Fn->addAttributes(llvm::AttributeSet::FunctionIndex, + llvm::AttributeSet::get(CGM.getLLVMContext(), + llvm::AttributeSet::FunctionIndex, + B)); } } @@ -1539,6 +1543,9 @@ X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX) : TargetCodeGenInfo(new X86_64ABIInfo(CGT, HasAVX)), HasAVX(HasAVX) {} + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override; + const X86_64ABIInfo &getABIInfo() const { return static_cast(TargetCodeGenInfo::getABIInfo()); } @@ -1602,6 +1609,24 @@ } }; +void X86_64TargetCodeGenInfo::SetTargetAttributes(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const { + if (const FunctionDecl *FD = dyn_cast(D)) { + if (CGM.getCodeGenOpts().IsStackProbeSizeOverridden) { + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B; + + B.addStackProbeSizeAttr(CGM.getCodeGenOpts().StackProbeSize); + + Fn->addAttributes(llvm::AttributeSet::FunctionIndex, + llvm::AttributeSet::get(CGM.getLLVMContext(), + llvm::AttributeSet::FunctionIndex, + B)); + } + } +} + static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { // If the argument does not end in .lib, automatically add the suffix. This // matches the behavior of MSVC. Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3711,6 +3711,15 @@ CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment)); } + if (Args.hasArg(options::OPT_mstack_probe_size)) { + StringRef size = Args.getLastArgValue(options::OPT_mstack_probe_size); + + if(!size.empty()) + CmdArgs.push_back(Args.MakeArgString("-mstack-probe-size=" + size)); + else + CmdArgs.push_back("-mstack-probe-size=0"); + } + if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 || getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be) CmdArgs.push_back("-fallow-half-arguments-and-returns"); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -508,6 +508,18 @@ Opts.StackAlignment = StackAlignment; } + if (Arg *A = Args.getLastArg(OPT_mstack_probe_size)) { + StringRef Val = A->getValue(); + unsigned StackProbeSize = Opts.StackProbeSize; + Val.getAsInteger(0, StackProbeSize); + Opts.StackProbeSize = StackProbeSize; + Opts.IsStackProbeSizeOverridden = true; + } + else + { + Opts.IsStackProbeSizeOverridden = false; + } + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(); unsigned Method = llvm::StringSwitch(Name) Index: test/Driver/cl-options.c =================================================================== --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -42,6 +42,13 @@ // RUN: %clang_cl /Gy /Gy- -### -- %s 2>&1 | FileCheck -check-prefix=Gy_ %s // Gy_-NOT: -ffunction-sections +// RUN: %clang_cl /Gs -### -- %s 2>&1 | FileCheck -check-prefix=Gs %s +// Gs: "-mstack-probe-size=0" +// RUN: %clang_cl /Gs0 -### -- %s 2>&1 | FileCheck -check-prefix=Gs0 %s +// Gs0: "-mstack-probe-size=0" +// RUN: %clang_cl /Gs4096 -### -- %s 2>&1 | FileCheck -check-prefix=Gs4096 %s +// Gs4096: "-mstack-probe-size=4096" + // RUN: %clang_cl /Gw -### -- %s 2>&1 | FileCheck -check-prefix=Gw %s // Gw: -fdata-sections @@ -249,7 +256,6 @@ // RUN: /Gm- \ // RUN: /Gr \ // RUN: /GS \ -// RUN: /Gs1000 \ // RUN: /GT \ // RUN: /GX \ // RUN: /Gv \