diff --git a/src/compiler/nir/nir_lower_io_to_vector.c b/src/compiler/nir/nir_lower_io_to_vector.c index 27913b507e9..f7e589022f1 100644 --- a/src/compiler/nir/nir_lower_io_to_vector.c +++ b/src/compiler/nir/nir_lower_io_to_vector.c @@ -24,6 +24,7 @@ #include "nir.h" #include "nir_builder.h" #include "nir_deref.h" +#include "util/u_dynarray.h" /** @file nir_lower_io_to_vector.c * @@ -210,7 +211,8 @@ get_flat_type(const nir_shader *shader, nir_variable *old_vars[MAX_SLOTS][4], static bool create_new_io_vars(nir_shader *shader, nir_variable_mode mode, nir_variable *new_vars[MAX_SLOTS][4], - bool flat_vars[MAX_SLOTS]) + bool flat_vars[MAX_SLOTS], + struct util_dynarray *demote_vars) { nir_variable *old_vars[MAX_SLOTS][4] = {{0}}; @@ -277,7 +279,10 @@ create_new_io_vars(nir_shader *shader, nir_variable_mode mode, nir_shader_add_variable(shader, var); for (unsigned i = first; i < frac; i++) { new_vars[loc][i] = var; - old_vars[loc][i] = NULL; + if (old_vars[loc][i]) { + util_dynarray_append(demote_vars, nir_variable *, old_vars[loc][i]); + old_vars[loc][i] = NULL; + } } old_vars[loc][first] = var; @@ -411,6 +416,9 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes) nir_metadata_require(impl, nir_metadata_dominance); + struct util_dynarray demote_vars; + util_dynarray_init(&demote_vars, NULL); + nir_shader *shader = impl->function->shader; nir_variable *new_inputs[MAX_SLOTS][4] = {{0}}; nir_variable *new_outputs[MAX_SLOTS][4] = {{0}}; @@ -425,7 +433,7 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes) * so we don't bother doing extra non-work. */ if (!create_new_io_vars(shader, nir_var_shader_in, - new_inputs, flat_inputs)) + new_inputs, flat_inputs, &demote_vars)) modes &= ~nir_var_shader_in; } @@ -434,7 +442,7 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes) * so we don't bother doing extra non-work. */ if (!create_new_io_vars(shader, nir_var_shader_out, - new_outputs, flat_outputs)) + new_outputs, flat_outputs, &demote_vars)) modes &= ~nir_var_shader_out; } @@ -585,6 +593,15 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes) } } + /* Demote the old var to a global, so that things like + * nir_lower_io_to_temporaries() don't trigger on it. + */ + util_dynarray_foreach(&demote_vars, nir_variable *, varp) { + (*varp)->data.mode = nir_var_shader_temp; + } + nir_fixup_deref_modes(b.shader); + util_dynarray_fini(&demote_vars); + if (progress) { nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance);