From: Nicolai Hähnle <nicolai.haeh...@amd.com> SimplifyCFG generates a switch instruction anyway when all four streams are present, but is simultaneously not smart enough to eliminate some redundant jumps that it generates.
The generated assembly is still a bit silly, probably because the control flow annotation doesn't know how to handle a switch with uniform condition. --- src/gallium/drivers/radeonsi/si_shader.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 6aaf318..0eeff19 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -6256,35 +6256,38 @@ si_generate_gs_copy_shader(struct si_screen *sscreen, for (i = 0; i < gsinfo->num_outputs; ++i) { outputs[i].semantic_name = gsinfo->output_semantic_name[i]; outputs[i].semantic_index = gsinfo->output_semantic_index[i]; for (int chan = 0; chan < 4; chan++) { outputs[i].vertex_stream[chan] = (gsinfo->output_streams[i] >> (2 * chan)) & 3; } } + LLVMBasicBlockRef end_bb; + LLVMValueRef switch_inst; + + end_bb = LLVMAppendBasicBlockInContext(gallivm->context, ctx.main_fn, "end"); + switch_inst = LLVMBuildSwitch(builder, stream_id, end_bb, 4); + for (int stream = 0; stream < 4; stream++) { - struct lp_build_if_state if_ctx_stream; + LLVMBasicBlockRef bb; if (!gsinfo->num_stream_output_components[stream]) continue; if (stream > 0 && !gs_selector->so.num_outputs) continue; - LLVMValueRef is_stream = - LLVMBuildICmp(builder, LLVMIntEQ, - stream_id, - lp_build_const_int32(gallivm, stream), ""); - - lp_build_if(&if_ctx_stream, gallivm, is_stream); + bb = LLVMInsertBasicBlockInContext(gallivm->context, end_bb, "out"); + LLVMAddCase(switch_inst, lp_build_const_int32(gallivm, stream), bb); + LLVMPositionBuilderAtEnd(builder, bb); /* Fetch vertex data from GSVS ring */ for (i = 0; i < gsinfo->num_outputs; ++i) { for (unsigned chan = 0; chan < 4; chan++) { if (outputs[i].vertex_stream[chan] != stream) { outputs[i].values[chan] = ctx.soa.bld_base.base.undef; continue; } args[2] = lp_build_const_int32( @@ -6304,23 +6307,25 @@ si_generate_gs_copy_shader(struct si_screen *sscreen, /* Streamout and exports. */ if (gs_selector->so.num_outputs) { si_llvm_emit_streamout(&ctx, outputs, gsinfo->num_outputs, stream); } if (stream == 0) si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs); - lp_build_endif(&if_ctx_stream); + LLVMBuildBr(builder, end_bb); } + LLVMPositionBuilderAtEnd(builder, end_bb); + 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); si_llvm_finalize_module(&ctx, r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY)); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev