nir/repair_ssa: Insert deref casts when needed
authorJason Ekstrand <jason@jlekstrand.net>
Fri, 30 Aug 2019 19:16:07 +0000 (14:16 -0500)
committerJason Ekstrand <jason@jlekstrand.net>
Fri, 6 Sep 2019 23:39:01 +0000 (23:39 +0000)
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
src/compiler/nir/nir_repair_ssa.c

index b6ec10388435468ae491394414883c9f1807186f..757afff490d30f9c8cd7b9edb549f7f7ea63a39c 100644 (file)
@@ -105,8 +105,35 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
       nir_block *src_block = get_src_block(src);
       if (nir_block_is_unreachable(src_block) ||
           !nir_block_dominates(def->parent_instr->block, src_block)) {
-         nir_instr_rewrite_src(src->parent_instr, src, nir_src_for_ssa(
-            nir_phi_builder_value_get_block_def(val, src_block)));
+         nir_ssa_def *block_def =
+            nir_phi_builder_value_get_block_def(val, src_block);
+
+         /* If def was a deref and the use we're looking at is a deref that
+          * isn't a cast, we need to wrap it in a cast so we don't loose any
+          * deref information.
+          */
+         if (def->parent_instr->type == nir_instr_type_deref &&
+             src->parent_instr->type == nir_instr_type_deref &&
+             nir_instr_as_deref(src->parent_instr)->deref_type != nir_deref_type_cast) {
+            nir_deref_instr *cast =
+               nir_deref_instr_create(state->impl->function->shader,
+                                      nir_deref_type_cast);
+
+            nir_deref_instr *deref = nir_instr_as_deref(def->parent_instr);
+            cast->mode = deref->mode;
+            cast->type = deref->type;
+            cast->parent = nir_src_for_ssa(block_def);
+            cast->cast.ptr_stride = nir_deref_instr_ptr_as_array_stride(deref);
+
+            nir_ssa_dest_init(&cast->instr, &cast->dest,
+                              def->num_components, def->bit_size, NULL);
+            nir_instr_insert(nir_before_instr(src->parent_instr),
+                             &cast->instr);
+            block_def = &cast->dest.ssa;
+         }
+
+         nir_instr_rewrite_src(src->parent_instr, src,
+                               nir_src_for_ssa(block_def));
       }
    }