diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index ff3785395a7..df0af331d0b 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -253,6 +253,9 @@ is_atomic_or_control_instr(Program* program, const Instruction* instr, memory_sy if (is_pops_end_export(program, instr) || is_ordered_ps_done_sendmsg(instr) || instr->opcode == aco_opcode::p_pops_gfx9_ordered_section_done) return cls & ~storage_shared; + + if (instr->opcode == aco_opcode::s_sethalt) + return cls & ~storage_shared; } return (instr->isBarrier() && instr->barrier().exec_scope > scope_invocation) ? cls : 0; } diff --git a/src/amd/compiler/aco_scheduler.cpp b/src/amd/compiler/aco_scheduler.cpp index 1feb9b1cc90..8ea5c84887d 100644 --- a/src/amd/compiler/aco_scheduler.cpp +++ b/src/amd/compiler/aco_scheduler.cpp @@ -545,7 +545,7 @@ is_reorderable(const Instruction* instr) instr->opcode != aco_opcode::s_sleep && instr->opcode != aco_opcode::s_trap && instr->opcode != aco_opcode::p_call && instr->opcode != aco_opcode::p_logical_start && instr->opcode != aco_opcode::p_logical_end && - instr->opcode != aco_opcode::p_reload_preserved; + instr->opcode != aco_opcode::p_reload_preserved && instr->opcode != aco_opcode::s_sethalt; } struct memory_event_set { diff --git a/src/amd/compiler/instruction_selection/aco_instruction_selection.h b/src/amd/compiler/instruction_selection/aco_instruction_selection.h index a2390cd845a..de37f888103 100644 --- a/src/amd/compiler/instruction_selection/aco_instruction_selection.h +++ b/src/amd/compiler/instruction_selection/aco_instruction_selection.h @@ -251,6 +251,7 @@ isel_context setup_isel_context(Program* program, unsigned shader_count, /* aco_isel_cfg.cpp */ void emit_loop_break(isel_context* ctx); +void emit_halt(isel_context* ctx); void begin_loop(isel_context* ctx); void end_loop(isel_context* ctx); void begin_uniform_if_then(isel_context* ctx, Temp cond); diff --git a/src/amd/compiler/instruction_selection/aco_isel_cfg.cpp b/src/amd/compiler/instruction_selection/aco_isel_cfg.cpp index e4092cb746e..acdf5b9854b 100644 --- a/src/amd/compiler/instruction_selection/aco_isel_cfg.cpp +++ b/src/amd/compiler/instruction_selection/aco_isel_cfg.cpp @@ -158,6 +158,17 @@ end_loop(isel_context* ctx) ctx->loop_stack.pop_back(); } +void +emit_halt(isel_context* ctx) +{ + Builder bld(ctx->program, ctx->block); + + bld.barrier(aco_opcode::p_barrier, + memory_sync_info(storage_buffer, semantic_release, scope_device)); + + bld.sopp(aco_opcode::s_sethalt, 0x1); /* set HALT */ +} + void begin_uniform_if_then(isel_context* ctx, Temp cond) { diff --git a/src/amd/compiler/instruction_selection/aco_select_nir.cpp b/src/amd/compiler/instruction_selection/aco_select_nir.cpp index b6ac174b17d..9c7864bab5c 100644 --- a/src/amd/compiler/instruction_selection/aco_select_nir.cpp +++ b/src/amd/compiler/instruction_selection/aco_select_nir.cpp @@ -735,12 +735,11 @@ visit_jump(isel_context* ctx, nir_jump_instr* instr) { end_empty_exec_skip(ctx); - if (instr->type != nir_jump_break) { - isel_err(&instr->instr, "Unknown NIR jump instr"); - abort(); + switch (instr->type) { + case nir_jump_break: emit_loop_break(ctx); break; + case nir_jump_halt: emit_halt(ctx); break; + default: isel_err(&instr->instr, "Unknown NIR jump instr"); abort(); } - - emit_loop_break(ctx); } void