From: Nicolai Hähnle <nicolai.haeh...@amd.com> This is enabled automatically if shader printing is enabled, or separately by R600_DEBUG=checkir. Catch mal-formed IR before it crashes in a later pass. --- src/gallium/drivers/radeon/r600_pipe_common.c | 7 ++++++ src/gallium/drivers/radeon/r600_pipe_common.h | 3 +++ src/gallium/drivers/radeon/radeon_llvm.h | 3 ++- .../drivers/radeon/radeon_setup_tgsi_llvm.c | 6 ++++- src/gallium/drivers/radeonsi/si_shader.c | 28 ++++++++++++++++------ 5 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 5b1ce04..e7bf7f2 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -632,20 +632,21 @@ static const struct debug_named_value common_debug_options[] = { { "vs", DBG_VS, "Print vertex shaders" }, { "gs", DBG_GS, "Print geometry shaders" }, { "ps", DBG_PS, "Print pixel shaders" }, { "cs", DBG_CS, "Print compute shaders" }, { "tcs", DBG_TCS, "Print tessellation control shaders" }, { "tes", DBG_TES, "Print tessellation evaluation shaders" }, { "noir", DBG_NO_IR, "Don't print the LLVM IR"}, { "notgsi", DBG_NO_TGSI, "Don't print the TGSI"}, { "noasm", DBG_NO_ASM, "Don't print disassembled shaders"}, { "preoptir", DBG_PREOPT_IR, "Print the LLVM IR before initial optimizations" }, + { "checkir", DBG_CHECK_IR, "Enable additional sanity checks on shader IR" }, { "testdma", DBG_TEST_DMA, "Invoke SDMA tests and exit." }, /* features */ { "nodma", DBG_NO_ASYNC_DMA, "Disable asynchronous DMA" }, { "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" }, /* GL uses the word INVALIDATE, gallium uses the word DISCARD */ { "noinvalrange", DBG_NO_DISCARD_RANGE, "Disable handling of INVALIDATE_RANGE map flags" }, { "no2d", DBG_NO_2D_TILING, "Disable 2D tiling" }, { "notiling", DBG_NO_TILING, "Disable tiling" }, @@ -1276,20 +1277,26 @@ bool r600_can_dump_shader(struct r600_common_screen *rscreen, return (rscreen->debug_flags & DBG_GS) != 0; case PIPE_SHADER_FRAGMENT: return (rscreen->debug_flags & DBG_PS) != 0; case PIPE_SHADER_COMPUTE: return (rscreen->debug_flags & DBG_CS) != 0; default: return false; } } +bool r600_extra_shader_checks(struct r600_common_screen *rscreen, unsigned processor) +{ + return (rscreen->debug_flags & DBG_CHECK_IR) || + r600_can_dump_shader(rscreen, processor); +} + void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_resource *dst, uint64_t offset, uint64_t size, unsigned value, enum r600_coherency coher) { struct r600_common_context *rctx = (struct r600_common_context*)rscreen->aux_context; pipe_mutex_lock(rscreen->aux_context_lock); rctx->clear_buffer(&rctx->b, dst, offset, size, value, coher); rscreen->aux_context->flush(rscreen->aux_context, NULL, 0); pipe_mutex_unlock(rscreen->aux_context_lock); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index f23f1c4..c836ab1 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -71,20 +71,21 @@ #define DBG_VS (1 << 6) #define DBG_GS (1 << 7) #define DBG_PS (1 << 8) #define DBG_CS (1 << 9) #define DBG_TCS (1 << 10) #define DBG_TES (1 << 11) #define DBG_NO_IR (1 << 12) #define DBG_NO_TGSI (1 << 13) #define DBG_NO_ASM (1 << 14) #define DBG_PREOPT_IR (1 << 15) +#define DBG_CHECK_IR (1 << 16) /* gaps */ #define DBG_TEST_DMA (1 << 20) /* Bits 21-31 are reserved for the r600g driver. */ /* features */ #define DBG_NO_ASYNC_DMA (1llu << 32) #define DBG_NO_HYPERZ (1llu << 33) #define DBG_NO_DISCARD_RANGE (1llu << 34) #define DBG_NO_2D_TILING (1llu << 35) #define DBG_NO_TILING (1llu << 36) #define DBG_SWITCH_ON_EOP (1llu << 37) @@ -714,20 +715,22 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, void r600_destroy_common_screen(struct r600_common_screen *rscreen); void r600_preflush_suspend_features(struct r600_common_context *ctx); void r600_postflush_resume_features(struct r600_common_context *ctx); bool r600_common_context_init(struct r600_common_context *rctx, struct r600_common_screen *rscreen, unsigned context_flags); void r600_common_context_cleanup(struct r600_common_context *rctx); void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resource *r); bool r600_can_dump_shader(struct r600_common_screen *rscreen, unsigned processor); +bool r600_extra_shader_checks(struct r600_common_screen *rscreen, + unsigned processor); void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_resource *dst, uint64_t offset, uint64_t size, unsigned value, enum r600_coherency coher); struct pipe_resource *r600_resource_create_common(struct pipe_screen *screen, const struct pipe_resource *templ); const char *r600_get_llvm_processor_name(enum radeon_family family); void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw, struct r600_resource *dst, struct r600_resource *src); void r600_dma_emit_wait_idle(struct r600_common_context *rctx); void radeon_save_cs(struct radeon_winsys *ws, struct radeon_winsys_cs *cs, diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h index 2f9572a..6010254 100644 --- a/src/gallium/drivers/radeon/radeon_llvm.h +++ b/src/gallium/drivers/radeon/radeon_llvm.h @@ -121,21 +121,22 @@ void radeon_llvm_context_init(struct radeon_llvm_context *ctx, const struct tgsi_token *tokens); void radeon_llvm_create_func(struct radeon_llvm_context *ctx, LLVMTypeRef *return_types, unsigned num_return_elems, LLVMTypeRef *ParamTypes, unsigned ParamCount); void radeon_llvm_dispose(struct radeon_llvm_context *ctx); unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan); -void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx); +void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx, + bool run_verifier); void build_tgsi_intrinsic_nomem(const struct lp_build_tgsi_action *action, struct lp_build_tgsi_context *bld_base, struct lp_build_emit_data *emit_data); LLVMValueRef radeon_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base, enum tgsi_opcode_type type, LLVMValueRef ptr, LLVMValueRef ptr2); diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c index 80e9707..8e364c9 100644 --- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c +++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c @@ -2107,33 +2107,37 @@ void radeon_llvm_create_func(struct radeon_llvm_context *ctx, /* Setup the function */ ctx->return_type = ret_type; main_fn_type = LLVMFunctionType(ret_type, ParamTypes, ParamCount, 0); ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type); main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context, ctx->main_fn, "main_body"); LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body); } -void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx) +void radeon_llvm_finalize_module(struct radeon_llvm_context *ctx, + bool run_verifier) { struct gallivm_state *gallivm = ctx->soa.bld_base.base.gallivm; const char *triple = LLVMGetTarget(gallivm->module); LLVMTargetLibraryInfoRef target_library_info; /* Create the pass manager */ gallivm->passmgr = LLVMCreateFunctionPassManagerForModule( gallivm->module); target_library_info = gallivm_create_target_library_info(triple); LLVMAddTargetLibraryInfo(target_library_info, gallivm->passmgr); + if (run_verifier) + LLVMAddVerifierPass(gallivm->passmgr); + /* This pass should eliminate all the load and store instructions */ LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr); /* Add some optimization passes */ LLVMAddScalarReplAggregatesPass(gallivm->passmgr); LLVMAddLICMPass(gallivm->passmgr); LLVMAddAggressiveDCEPass(gallivm->passmgr); LLVMAddCFGSimplificationPass(gallivm->passmgr); LLVMAddInstructionCombiningPass(gallivm->passmgr); diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 3ccff7a..2cabff6 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -6424,21 +6424,23 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen, si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs); LLVMBuildRetVoid(gallivm->builder); /* Dump LLVM IR before any optimization passes */ if (sscreen->b.debug_flags & DBG_PREOPT_IR && r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY)) LLVMDumpModule(bld_base->base.gallivm->module); - radeon_llvm_finalize_module(&ctx->radeon_bld); + radeon_llvm_finalize_module( + &ctx->radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY)); r = si_compile_llvm(sscreen, &ctx->shader->binary, &ctx->shader->config, ctx->tm, bld_base->base.gallivm->module, debug, PIPE_SHADER_GEOMETRY, "GS Copy Shader"); if (!r) { if (r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY)) fprintf(stderr, "GS Copy Shader:\n"); si_shader_dump(sscreen, ctx->shader, debug, @@ -6708,21 +6710,23 @@ int si_compile_tgsi_shader(struct si_screen *sscreen, } si_llvm_build_ret(&ctx, ctx.return_value); mod = bld_base->base.gallivm->module; /* Dump LLVM IR before any optimization passes */ if (sscreen->b.debug_flags & DBG_PREOPT_IR && r600_can_dump_shader(&sscreen->b, ctx.type)) LLVMDumpModule(mod); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, ctx.type)); r = si_compile_llvm(sscreen, &shader->binary, &shader->config, tm, mod, debug, ctx.type, "TGSI shader"); if (r) { fprintf(stderr, "LLVM failed to compile shader\n"); goto out; } radeon_llvm_dispose(&ctx.radeon_bld); @@ -6969,21 +6973,23 @@ static bool si_compile_vs_prolog(struct si_screen *sscreen, LLVMGetParam(func, SI_SGPR_BASE_VERTEX), ""); } index = LLVMBuildBitCast(gallivm->builder, index, ctx.f32, ""); ret = LLVMBuildInsertValue(gallivm->builder, ret, index, num_params++, ""); } /* Compile. */ si_llvm_build_ret(&ctx, ret); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_VERTEX)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Vertex Shader Prolog")) status = false; radeon_llvm_dispose(&ctx.radeon_bld); return status; } @@ -7041,21 +7047,23 @@ static bool si_compile_vs_epilog(struct si_screen *sscreen, args[7] = uint->undef; /* Z */ args[8] = uint->undef; /* W */ lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export", LLVMVoidTypeInContext(base->gallivm->context), args, 9, 0); } /* Compile. */ LLVMBuildRetVoid(gallivm->builder); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_VERTEX)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Vertex Shader Epilog")) status = false; radeon_llvm_dispose(&ctx.radeon_bld); return status; } @@ -7194,21 +7202,23 @@ static bool si_compile_tcs_epilog(struct si_screen *sscreen, declare_tess_lds(&ctx); func = ctx.radeon_bld.main_fn; si_write_tess_factors(bld_base, LLVMGetParam(func, last_sgpr + 1), LLVMGetParam(func, last_sgpr + 2), LLVMGetParam(func, last_sgpr + 3)); /* Compile. */ LLVMBuildRetVoid(gallivm->builder); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_TESS_CTRL)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Tessellation Control Shader Epilog")) status = false; radeon_llvm_dispose(&ctx.radeon_bld); return status; } @@ -7478,21 +7488,23 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen, } /* Tell LLVM to insert WQM instruction sequence when needed. */ if (key->ps_prolog.wqm) { LLVMAddTargetDependentFunctionAttr(func, "amdgpu-ps-wqm-outputs", ""); } /* Compile. */ si_llvm_build_ret(&ctx, ret); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Fragment Shader Prolog")) status = false; radeon_llvm_dispose(&ctx.radeon_bld); return status; } @@ -7598,21 +7610,23 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen, if (depth || stencil || samplemask) si_export_mrt_z(bld_base, depth, stencil, samplemask, &exp); else if (last_color_export == -1) si_export_null(bld_base); if (exp.num) si_emit_ps_exports(&ctx, &exp); /* Compile. */ LLVMBuildRetVoid(gallivm->builder); - radeon_llvm_finalize_module(&ctx.radeon_bld); + radeon_llvm_finalize_module( + &ctx.radeon_bld, + r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT)); if (si_compile_llvm(sscreen, &out->binary, &out->config, tm, gallivm->module, debug, ctx.type, "Fragment Shader Epilog")) status = false; radeon_llvm_dispose(&ctx.radeon_bld); return status; } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev