From d9af5277b36a01af4cc6870c542a8059848a6e4d Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 14 Apr 2020 11:01:15 -0500 Subject: [PATCH] nir/copy_prop_vars: Handle volatile better For deref_store, we can still delete invalid stores that write to statically OOB data. For everything, we need to make sure that we kill aliases of destinations even if it's volatile. Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- src/compiler/nir/nir_opt_copy_prop_vars.c | 34 ++++++++++++----------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index 05bdec50f45..dca5320a676 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -930,9 +930,6 @@ copy_prop_vars_block(struct copy_prop_var_state *state, case nir_intrinsic_store_deref: { if (debug) dump_instr(instr); - if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) - break; - nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]); assert(glsl_type_is_vector_or_scalar(dst->type)); @@ -954,6 +951,12 @@ copy_prop_vars_block(struct copy_prop_var_state *state, } } + if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) { + unsigned wrmask = nir_intrinsic_write_mask(intrin); + kill_aliases(copies, dst, wrmask); + break; + } + struct copy_entry *entry = lookup_entry_for_deref(copies, dst, nir_derefs_equal_bit); if (entry && value_equals_store_src(&entry->src, intrin)) { @@ -977,25 +980,27 @@ copy_prop_vars_block(struct copy_prop_var_state *state, case nir_intrinsic_copy_deref: { if (debug) dump_instr(instr); - if ((nir_intrinsic_src_access(intrin) & ACCESS_VOLATILE) || - (nir_intrinsic_dst_access(intrin) & ACCESS_VOLATILE)) - break; - nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]); nir_deref_instr *src = nir_src_as_deref(intrin->src[1]); - if (nir_compare_derefs(src, dst) & nir_derefs_equal_bit) { - /* This is a no-op self-copy. Get rid of it */ - nir_instr_remove(instr); - 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 ((nir_intrinsic_src_access(intrin) & ACCESS_VOLATILE) || + (nir_intrinsic_dst_access(intrin) & ACCESS_VOLATILE)) { + kill_aliases(copies, dst, full_mask); + break; + } + + if (nir_compare_derefs(src, dst) & nir_derefs_equal_bit) { + /* This is a no-op self-copy. Get rid of it */ + nir_instr_remove(instr); + continue; + } + /* Copy of direct array derefs of vectors are not handled. Just * invalidate what's written and bail. */ @@ -1058,9 +1063,6 @@ copy_prop_vars_block(struct copy_prop_var_state *state, case nir_intrinsic_deref_atomic_comp_swap: if (debug) dump_instr(instr); - if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) - break; - 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; -- 2.30.2