summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/nir/nir_opt_copy_prop_vars.c32
1 files changed, 22 insertions, 10 deletions
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: