From a12072868d3ff71cfa7d124d1e0984d5723a00b4 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 30 May 2023 11:46:10 +0200 Subject: [PATCH] r600/sfn: assert that group barrier is not emitted in divergent code flow Also rename emit_barrier to emit_group_barrier Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/sfn/sfn_shader.cpp | 33 ++++++++++++++++++++- src/gallium/drivers/r600/sfn/sfn_shader.h | 3 +- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.cpp b/src/gallium/drivers/r600/sfn/sfn_shader.cpp index fe21c03ccc1..fabb9594c10 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader.cpp @@ -724,6 +724,29 @@ child_block_empty(const exec_list& list) return result; } +static bool value_has_non_const_source(VirtualValue *value) +{ + auto reg = value->as_register(); + if (reg) { + // Non-ssa registers are probably the result of some control flow + // that makes the values non-uniform across the work group + if (!reg->has_flag(Register::ssa)) + return true; + + for (const auto& p : reg->parents()) { + auto alu = p->as_alu(); + if (alu) { + for (auto& s : p->as_alu()->sources()) { + return value_has_non_const_source(s); + } + } else { + return true; + } + } + } + return false; +} + bool Shader::process_if(nir_if *if_stmt) { @@ -731,6 +754,8 @@ Shader::process_if(nir_if *if_stmt) auto value = value_factory().src(if_stmt->condition, 0); + bool non_const_cond = value_has_non_const_source(value); + EAluOp op = child_block_empty(if_stmt->then_list) ? op2_prede_int : op2_pred_setne_int; @@ -745,6 +770,8 @@ Shader::process_if(nir_if *if_stmt) IfInstr *ir = new IfInstr(pred); emit_instruction(ir); + if (non_const_cond) + ++m_control_flow_depth; start_new_block(1); if (!child_block_empty(if_stmt->then_list)) { @@ -775,6 +802,9 @@ Shader::process_if(nir_if *if_stmt) if (!emit_control_flow(ControlFlowInstr::cf_endif)) return false; + if (non_const_cond) + --m_control_flow_depth; + return true; } @@ -1268,8 +1298,9 @@ Shader::emit_shader_clock(nir_intrinsic_instr *instr) } bool -Shader::emit_barrier(nir_intrinsic_instr *intr) +Shader::emit_group_barrier(nir_intrinsic_instr *intr) { + assert(m_control_flow_depth == 0); (void)intr; /* Put barrier into it's own block, so that optimizers and the * scheduler don't move code */ diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.h b/src/gallium/drivers/r600/sfn/sfn_shader.h index 8969a2b05f2..135a1179418 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader.h @@ -317,7 +317,7 @@ private: bool emit_local_store(nir_intrinsic_instr *intr); bool emit_local_load(nir_intrinsic_instr *instr); bool emit_load_tcs_param_base(nir_intrinsic_instr *instr, int offset); - bool emit_barrier(nir_intrinsic_instr *intr); + bool emit_group_barrier(nir_intrinsic_instr *intr); bool emit_shader_clock(nir_intrinsic_instr *instr); bool emit_wait_ack(); @@ -396,6 +396,7 @@ private: InstructionChain m_chain_instr; std::list> m_loops; + int m_control_flow_depth{0}; }; std::pair