}
case nir_deref_type_array_wildcard:
- idx = glsl_get_length(instr->type);
+ idx = parent->num_children - 1;
break;
case nir_deref_type_array:
if (nir_src_is_const(instr->arr.index)) {
idx = nir_src_as_uint(instr->arr.index);
+ assert(idx < parent->num_children - 1);
} else {
- idx = glsl_get_length(instr->type);
+ idx = parent->num_children - 1;
}
break;
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];
/* 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;
}
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;
/* There must be no indirects in the source or destination and no known
* out-of-bounds accesses in the source, and the copy must be fully
* qualified, or else we can't build up the array copy. We handled
- * out-of-bounds accesses to the dest above.
+ * out-of-bounds accesses to the dest above. The types must match, since
+ * copy_deref currently can't bitcast mismatched deref types.
*/
if (src_deref &&
(nir_deref_instr_has_indirect(src_deref) ||
nir_deref_instr_is_known_out_of_bounds(src_deref) ||
nir_deref_instr_has_indirect(dst_deref) ||
- !glsl_type_is_vector_or_scalar(src_deref->type))) {
+ !glsl_type_is_vector_or_scalar(src_deref->type) ||
+ glsl_get_bare_type(src_deref->type) !=
+ glsl_get_bare_type(dst_deref->type))) {
src_deref = NULL;
}