From a782809f81dc32079691b3a280580dbf7b800dba Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 18 Mar 2024 18:12:41 -0500 Subject: [PATCH] nir/builder: Correctly handle decl_reg or undef as the first instruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are both handled by inserting them directly at the top of the nir_function_impl. However, if the cursor is already at the top, it never gets updated so we end up inserting other stuff after the newly inserted undef or decl_reg. It's an odd edge case to be sure but I hit it with my new NIR CF pass for NAK. Fixes: 1be4c61c957d ("nir/builder: Add a helper for creating undefs") Reviewed-by: Alyssa Rosenzweig Reviewed-by: Daniel Schürmann Part-of: --- src/compiler/nir/nir_builder.c | 16 ++++++++++++++++ src/compiler/nir/nir_builder.h | 7 +++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/compiler/nir/nir_builder.c b/src/compiler/nir/nir_builder.c index 8a93394730f..3e2a64ec976 100644 --- a/src/compiler/nir/nir_builder.c +++ b/src/compiler/nir/nir_builder.c @@ -379,6 +379,22 @@ nir_builder_instr_insert(nir_builder *build, nir_instr *instr) build->cursor = nir_after_instr(instr); } +void +nir_builder_instr_insert_at_top(nir_builder *build, nir_instr *instr) +{ + nir_cursor top = nir_before_impl(build->impl); + const bool at_top = build->cursor.block != NULL && + nir_cursors_equal(build->cursor, top); + + nir_instr_insert(top, instr); + + if (build->update_divergence) + nir_update_instr_divergence(build->shader, instr); + + if (at_top) + build->cursor = nir_after_instr(instr); +} + void nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) { diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h index 661c70d8f16..0fbad8e0fdb 100644 --- a/src/compiler/nir/nir_builder.h +++ b/src/compiler/nir/nir_builder.h @@ -182,6 +182,7 @@ nir_shader_intrinsics_pass(nir_shader *shader, } void nir_builder_instr_insert(nir_builder *build, nir_instr *instr); +void nir_builder_instr_insert_at_top(nir_builder *build, nir_instr *instr); static inline nir_instr * nir_builder_last_instr(nir_builder *build) @@ -250,9 +251,7 @@ nir_undef(nir_builder *build, unsigned num_components, unsigned bit_size) if (!undef) return NULL; - nir_instr_insert(nir_before_impl(build->impl), &undef->instr); - if (build->update_divergence) - nir_update_instr_divergence(build->shader, &undef->instr); + nir_builder_instr_insert_at_top(build, &undef->instr); return &undef->def; } @@ -1832,7 +1831,7 @@ nir_decl_reg(nir_builder *b, unsigned num_components, unsigned bit_size, nir_intrinsic_set_divergent(decl, true); nir_def_init(&decl->instr, &decl->def, 1, 32); - nir_instr_insert(nir_before_impl(b->impl), &decl->instr); + nir_builder_instr_insert_at_top(b, &decl->instr); return &decl->def; }