From 82eb871e99995946c6f0a60d04ba8e282c8056e9 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 16 Mar 2021 16:37:00 -0400 Subject: [PATCH] add stack-probes to make stack-overflow detection more reliable Supported platforms are currently X86, PowerPC, and SystemZ. Fixes #25523 Fixes #36170 Closes #28577 Closes #30892 --- src/codegen.cpp | 35 +++++++++++++++-------------------- test/llvmpasses/noinline.jl | 2 +- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index f0edf7b19fa29..b3acb943b3150 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1719,6 +1719,14 @@ static void jl_init_function(Function *F) F->addFnAttr("no-frame-pointer-elim", "true"); #endif #endif +#if JL_LLVM_VERSION >= 110000 && !defined(JL_ASAN_ENABLED) && !defined(_OS_WINDOWS_) + // ASAN won't like us accessing undefined memory causing spurious issues, + // and Windows has platform-specific handling which causes it to mishandle + // this annotation. Other platforms should just ignore this if they don't + // implement it. + F->addFnAttr("probe-stack", "inline-asm"); + //F->addFnAttr("stack-probe-size", 4096); // can use this to change the default +#endif } static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) @@ -6297,20 +6305,7 @@ static std::pair, jl_llvm_functions_t> } } - /* - // step 6. (optional) check for stack overflow (the slower way) - Value *cur_sp = - ctx.builder.CreateCall(Intrinsic::getDeclaration(M, - Intrinsic::frameaddress), - ConstantInt::get(T_int32, 0)); - Value *sp_ok = - ctx.builder.CreateICmpUGT(cur_sp, - ConstantInt::get(T_size, - (uptrint_t)jl_stack_lo)); - error_unless(ctx, sp_ok, "stack overflow"); - */ - - // step 7. set up GC frame + // step 6. set up GC frame allocate_gc_frame(ctx, b0); Value *last_age = NULL; emit_last_age_field(ctx); @@ -6318,7 +6313,7 @@ static std::pair, jl_llvm_functions_t> last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))); } - // step 8. allocate local variables slots + // step 7. allocate local variables slots // must be in the first basic block for the llvm mem2reg pass to work auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) { jl_value_t *jt = varinfo.value.typ; @@ -6436,7 +6431,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 9. move args into local variables + // step 8. move args into local variables Function::arg_iterator AI = f->arg_begin(); auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) { @@ -6566,7 +6561,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 10. allocate rest argument + // step 9. allocate rest argument CallInst *restTuple = NULL; if (va && ctx.vaSlot != -1) { jl_varinfo_t &vi = ctx.slots[ctx.vaSlot]; @@ -6608,7 +6603,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 11. Compute properties for each statements + // step 10. Compute properties for each statements // This needs to be computed by iterating in the IR order // instead of control flow order. auto in_user_mod = [] (jl_module_t *mod) { @@ -6730,7 +6725,7 @@ static std::pair, jl_llvm_functions_t> Instruction &prologue_end = ctx.builder.GetInsertBlock()->back(); - // step 12. Do codegen in control flow order + // step 11. Do codegen in control flow order std::vector workstack; std::map BB; std::map come_from_bb; @@ -7288,7 +7283,7 @@ static std::pair, jl_llvm_functions_t> PN->eraseFromParent(); } - // step 13. Perform any delayed instantiations + // step 12. Perform any delayed instantiations if (ctx.debug_enabled) { bool in_prologue = true; for (auto &BB : *ctx.f) { diff --git a/test/llvmpasses/noinline.jl b/test/llvmpasses/noinline.jl index f542968b21979..c4aa22bf80a71 100644 --- a/test/llvmpasses/noinline.jl +++ b/test/llvmpasses/noinline.jl @@ -17,5 +17,5 @@ include(joinpath("..", "testhelpers", "llvmpasses.jl")) return A + B end -# CHECK: attributes #{{[0-9]+}} = {{{([a-z]+ )*}} noinline {{([a-z]+ )*}}} +# CHECK: attributes #{{[0-9]+}} = {{{[^}]*}} noinline {{[^}]*}}} emit(simple_noinline, Float64, Float64)