diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index 83680b6139d..e59cd18b98d 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -64,8 +64,8 @@ struct value { bool is_ssa; union { struct { - nir_ssa_def *def[4]; - uint8_t component[4]; + nir_ssa_def *def[NIR_MAX_VEC_COMPONENTS]; + uint8_t component[NIR_MAX_VEC_COMPONENTS]; } ssa; nir_deref_instr *deref; }; @@ -394,7 +394,7 @@ value_set_from_value(struct value *value, const struct value *from, memset(&value->ssa, 0, sizeof(value->ssa)); value->is_ssa = true; /* Only overwrite the written components */ - for (unsigned i = 0; i < 4; i++) { + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { if (write_mask & (1 << i)) { value->ssa.def[i] = from->ssa.def[i]; value->ssa.component[i] = from->ssa.component[i]; @@ -408,7 +408,7 @@ value_set_from_value(struct value *value, const struct value *from, } /* Do a "load" from an SSA-based entry return it in "value" as a value with a - * single SSA def. Because an entry could reference up to 4 different SSA + * single SSA def. Because an entry could reference multiple different SSA * defs, a vecN operation may be inserted to combine them into a single SSA * def before handing it back to the caller. If the load instruction is no * longer needed, it is removed and nir_instr::block is set to NULL. (It is @@ -831,7 +831,9 @@ copy_prop_vars_block(struct copy_prop_var_state *state, /* Not handled yet. Writing into an element of 'dst' invalidates * any related entries in copies. */ - kill_aliases(copies, nir_deref_instr_parent(dst), 0xf); + nir_deref_instr *vector = nir_deref_instr_parent(dst); + unsigned vector_components = glsl_get_vector_elements(vector->type); + kill_aliases(copies, vector, (1 << vector_components) - 1); } else { struct value value = {0}; value_set_ssa_components(&value, intrin->src[1].ssa, @@ -857,12 +859,18 @@ copy_prop_vars_block(struct copy_prop_var_state *state, continue; } + /* The copy_deref intrinsic doesn't keep track of num_components, so + * get it ourselves. + */ + unsigned num_components = glsl_get_vector_elements(dst->type); + unsigned full_mask = (1 << num_components) - 1; + if (is_array_deref_of_vector(src) || is_array_deref_of_vector(dst)) { /* Cases not handled yet. Writing into an element of 'dst' * invalidates any related entries in copies. Reading from 'src' * doesn't invalidate anything, so no action needed for it. */ - kill_aliases(copies, dst, 0xf); + kill_aliases(copies, dst, full_mask); break; } @@ -872,7 +880,7 @@ copy_prop_vars_block(struct copy_prop_var_state *state, if (try_load_from_entry(state, src_entry, b, intrin, src, &value)) { /* If load works, intrin (the copy_deref) is removed. */ if (value.is_ssa) { - nir_store_deref(b, dst, value.ssa.def[0], 0xf); + nir_store_deref(b, dst, value.ssa.def[0], full_mask); } else { /* If this would be a no-op self-copy, don't bother. */ if (nir_compare_derefs(value.deref, dst) & nir_derefs_equal_bit) @@ -894,8 +902,8 @@ copy_prop_vars_block(struct copy_prop_var_state *state, } struct copy_entry *dst_entry = - get_entry_and_kill_aliases(copies, dst, 0xf); - value_set_from_value(&dst_entry->src, &value, 0xf); + get_entry_and_kill_aliases(copies, dst, full_mask); + value_set_from_value(&dst_entry->src, &value, full_mask); break; } @@ -910,7 +918,11 @@ copy_prop_vars_block(struct copy_prop_var_state *state, case nir_intrinsic_deref_atomic_exchange: case nir_intrinsic_deref_atomic_comp_swap: if (debug) dump_instr(instr); - kill_aliases(copies, nir_src_as_deref(intrin->src[0]), 0xf); + + nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]); + unsigned num_components = glsl_get_vector_elements(dst->type); + unsigned full_mask = (1 << num_components) - 1; + kill_aliases(copies, dst, full_mask); break; default: