aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2020-04-14 11:01:15 -0500
committerMarge Bot <[email protected]>2020-04-28 22:55:25 +0000
commitd9af5277b36a01af4cc6870c542a8059848a6e4d (patch)
tree0c0dbf53d522077fd6ea257776624cf8192745e8 /src/compiler/nir
parent118f045fb7d1c6520e808317235c175833237631 (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')
-rw-r--r--src/compiler/nir/nir_opt_copy_prop_vars.c34
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;