From cba4b07aa0febbf9033d5156952d9a4e211d1773 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 16 Nov 2022 17:34:08 +0200 Subject: nir/lower_shader_calls: wrap only jumps rather than entire code blocks Moving entire chunks of code into a dummy if block is causing issues in some situations. To work around the issue that we tried to fix in 35d82ecf1e ("nir/lower_shader_calls: put inserted instructions into a dummy block") which is that we cannot cut and past a block of instruction that ends with a jump if there are more instruction behind where we're going to past. We can instead just wraps the jumps into dummy if blocks. Signed-off-by: Lionel Landwerlin Cc: mesa-stable Reviewed-by: Konstantin Seurer Part-of: (cherry picked from commit 3686d5a31291354eb836ce6ea757bf6fbf41ad5b) --- .pick_status.json | 2 +- src/compiler/nir/nir_lower_shader_calls.c | 33 ++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index cf8bea1c6a3..81cf82505e0 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -760,7 +760,7 @@ "description": "nir/lower_shader_calls: wrap only jumps rather than entire code blocks", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/compiler/nir/nir_lower_shader_calls.c b/src/compiler/nir/nir_lower_shader_calls.c index 30882d3358a..8a4192d9511 100644 --- a/src/compiler/nir/nir_lower_shader_calls.c +++ b/src/compiler/nir/nir_lower_shader_calls.c @@ -1036,11 +1036,42 @@ found_resume: return true; } +static bool +wrap_jump_instr(nir_builder *b, nir_instr *instr, void *data) +{ + if (instr->type != nir_instr_type_jump) + return false; + + b->cursor = nir_before_instr(instr); + + nir_if *_if = nir_push_if(b, nir_imm_true(b)); + nir_pop_if(b, NULL); + + nir_cf_list cf_list; + nir_cf_extract(&cf_list, nir_before_instr(instr), nir_after_instr(instr)); + nir_cf_reinsert(&cf_list, nir_before_block(nir_if_first_then_block(_if))); + + return true; +} + +/* This pass wraps jump instructions in a dummy if block so that when + * flatten_resume_if_ladder() does its job, it doesn't move a jump instruction + * directly in front of another instruction which the NIR control flow helpers + * do not allow. + */ +static bool +wrap_jumps(nir_shader *shader) +{ + return nir_shader_instructions_pass(shader, wrap_jump_instr, + nir_metadata_none, NULL); +} + static nir_instr * lower_resume(nir_shader *shader, int call_idx) { - nir_function_impl *impl = nir_shader_get_entrypoint(shader); + wrap_jumps(shader); + nir_function_impl *impl = nir_shader_get_entrypoint(shader); nir_instr *resume_instr = find_resume_instr(impl, call_idx); if (duplicate_loop_bodies(impl, resume_instr)) { -- cgit v1.2.1