summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Simiklit <andrii.simiklit@globallogic.com>2019-08-07 13:56:38 +0300
committerJason Ekstrand <jason@jlekstrand.net>2019-08-14 18:11:31 +0000
commitff2225cf88d8773c599277362306a4bcf4ba6b01 (patch)
tree2fbc4f3fcb738309ee90090cbba6ab096498cf99
parentc4a4f3db5a4c8676798855e131c360cdf0e4a6bc (diff)
nir/find_array_copies: Reject copies with mismatched lengths
copy_deref for wildcard dereferences requires the same arrays lengths otherwise it leads to a crash in optimizations like 'nir_opt_copy_prop_vars' because these optimizations expect 'copy_deref' just for arrays with the same lengths. v2: check was moved to 'try_match_deref' to fix aoa cases (Jason Ekstrand <jason@jlekstrand.net>) v3: -fixed comment -the condition merged with other one (Jason Ekstrand <jason@jlekstrand.net>) Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111286 Signed-off-by: Andrii Simiklit <andrii.simiklit@globallogic.com>
-rw-r--r--src/compiler/nir/nir_opt_find_array_copies.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/compiler/nir/nir_opt_find_array_copies.c b/src/compiler/nir/nir_opt_find_array_copies.c
index b3fafe77375..7f3988417de 100644
--- a/src/compiler/nir/nir_opt_find_array_copies.c
+++ b/src/compiler/nir/nir_opt_find_array_copies.c
@@ -260,7 +260,8 @@ clobber(struct match_node *node, struct match_state *state)
static bool
try_match_deref(nir_deref_path *base_path, int *path_array_idx,
- nir_deref_path *deref_path, int arr_idx)
+ nir_deref_path *deref_path, int arr_idx,
+ nir_deref_instr *dst)
{
for (int i = 0; ; i++) {
nir_deref_instr *b = base_path->path[i];
@@ -292,11 +293,13 @@ try_match_deref(nir_deref_path *base_path, int *path_array_idx,
/* If we don't have an index into the path yet or if this entry in
* the path is at the array index, see if this is a candidate. We're
* looking for an index which is zero in the base deref and arr_idx
- * in the search deref.
+ * in the search deref and has a matching array size.
*/
if ((*path_array_idx < 0 || *path_array_idx == i) &&
const_b_idx && b_idx == 0 &&
- const_d_idx && d_idx == arr_idx) {
+ const_d_idx && d_idx == arr_idx &&
+ glsl_get_length(nir_deref_instr_parent(b)->type) ==
+ glsl_get_length(nir_deref_instr_parent(dst)->type)) {
*path_array_idx = i;
continue;
}
@@ -398,7 +401,8 @@ handle_write(nir_deref_instr *dst, nir_deref_instr *src,
nir_deref_path_init(&src_path, src, state->dead_ctx);
bool result = try_match_deref(&dst_node->first_src_path,
&dst_node->src_wildcard_idx,
- &src_path, dst_node->next_array_idx);
+ &src_path, dst_node->next_array_idx,
+ *instr);
nir_deref_path_finish(&src_path);
if (!result)
goto reset;