diff options
author | Jason Ekstrand <[email protected]> | 2020-04-14 11:01:15 -0500 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-04-28 22:55:25 +0000 |
commit | d9af5277b36a01af4cc6870c542a8059848a6e4d (patch) | |
tree | 0c0dbf53d522077fd6ea257776624cf8192745e8 /src/compiler/nir/nir_opt_copy_prop_vars.c | |
parent | 118f045fb7d1c6520e808317235c175833237631 (diff) |
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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4767>
Diffstat (limited to 'src/compiler/nir/nir_opt_copy_prop_vars.c')
-rw-r--r-- | src/compiler/nir/nir_opt_copy_prop_vars.c | 34 |
1 files 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; |