From ff2225cf88d8773c599277362306a4bcf4ba6b01 Mon Sep 17 00:00:00 2001 From: Andrii Simiklit Date: Wed, 7 Aug 2019 13:56:38 +0300 Subject: 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 ) v3: -fixed comment -the condition merged with other one (Jason Ekstrand ) Reviewed-by: Jason Ekstrand Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111286 Signed-off-by: Andrii Simiklit --- src/compiler/nir/nir_opt_find_array_copies.c | 12 ++++++++---- 1 file 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; -- cgit v1.2.3