summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2022-11-16 17:34:08 +0200
committerDylan Baker <dylan.c.baker@intel.com>2022-11-21 09:46:53 -0800
commitcba4b07aa0febbf9033d5156952d9a4e211d1773 (patch)
tree3c9645651458f5efa49336048fdabc14c35a8d88
parent1f39b0c57c05d5038881d46e859691d0dd7be429 (diff)
downloadmesa-cba4b07aa0febbf9033d5156952d9a4e211d1773.tar.gz
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 <lionel.g.landwerlin@intel.com> Cc: mesa-stable Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19820> (cherry picked from commit 3686d5a31291354eb836ce6ea757bf6fbf41ad5b)
-rw-r--r--.pick_status.json2
-rw-r--r--src/compiler/nir/nir_lower_shader_calls.c33
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)) {