Mesa (staging/21.2): nir: prevent peephole from generating invalid NIR

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 27 17:23:31 UTC 2021


Module: Mesa
Branch: staging/21.2
Commit: 71a2d809806e5d584aeba8105aaabd17a5687052
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=71a2d809806e5d584aeba8105aaabd17a5687052

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Mon Aug 23 16:45:20 2021 +0300

nir: prevent peephole from generating invalid NIR

We can't append instructions following a return/halt instruction
because the control flow helpers will modify the successor of the
block containing the return/halt. And the NIR validator enforces that
the return/halt must have the end of the function as successor.

This tends to happen following lower_shader_calls lowering which
inserts halts. This probably doesn't prevent the optimization, it'll
just happen in one of the return shaders after the halt has been
removed.

v2: Move prev block ending check earlier in the function (Daniel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Daniel Schürmann <daniel at schuermann.dev>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12506>
(cherry picked from commit a13e79843e054cc9b35f8f5b8b31fdf28b6ae95d)

---

 .pick_status.json                          |  2 +-
 src/compiler/nir/nir.h                     | 15 +++++++++++++++
 src/compiler/nir/nir_opt_peephole_select.c | 13 +++++++++++--
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index 58ad650db7c..434cbb74585 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1444,7 +1444,7 @@
         "description": "nir: prevent peephole from generating invalid NIR",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": null
     },
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index efeaff2d258..dd6cb11094e 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2749,6 +2749,21 @@ nir_block_ends_in_jump(nir_block *block)
           nir_block_last_instr(block)->type == nir_instr_type_jump;
 }
 
+static inline bool
+nir_block_ends_in_return_or_halt(nir_block *block)
+{
+   if (exec_list_is_empty(&block->instr_list))
+      return false;
+
+   nir_instr *instr = nir_block_last_instr(block);
+   if (instr->type != nir_instr_type_jump)
+      return false;
+
+   nir_jump_instr *jump_instr = nir_instr_as_jump(instr);
+   return jump_instr->type == nir_jump_return ||
+          jump_instr->type == nir_jump_halt;
+}
+
 static inline bool
 nir_block_ends_in_break(nir_block *block)
 {
diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c
index 5eeb5f66b94..72b6249cf43 100644
--- a/src/compiler/nir/nir_opt_peephole_select.c
+++ b/src/compiler/nir/nir_opt_peephole_select.c
@@ -381,6 +381,17 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader,
    if (prev_node->type != nir_cf_node_if)
       return false;
 
+   nir_block *prev_block = nir_cf_node_as_block(nir_cf_node_prev(prev_node));
+
+   /* If the last instruction before this if/else block is a jump, we can't
+    * append stuff after it because it would break a bunch of assumption about
+    * control flow (nir_validate expects the successor of a return/halt jump
+    * to be the end of the function, which might not match the successor of
+    * the if/else blocks).
+    */
+   if (nir_block_ends_in_return_or_halt(prev_block))
+      return false;
+
    nir_if *if_stmt = nir_cf_node_as_if(prev_node);
 
    /* first, try to collapse the if */
@@ -422,8 +433,6 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader,
     * selects.
     */
 
-   nir_block *prev_block = nir_cf_node_as_block(nir_cf_node_prev(prev_node));
-
    /* First, we move the remaining instructions from the blocks to the
     * block before.  We have already guaranteed that this is safe by
     * calling block_check_for_allowed_instrs()



More information about the mesa-commit mailing list