diff --git a/src/compiler/nir/nir_to_lcssa.c b/src/compiler/nir/nir_to_lcssa.c index 1f314902687..e48df1a42d3 100644 --- a/src/compiler/nir/nir_to_lcssa.c +++ b/src/compiler/nir/nir_to_lcssa.c @@ -223,6 +223,11 @@ convert_loop_exit_for_ssa(nir_def *def, void *void_state) if (all_uses_inside_loop) return true; + if (def->parent_instr->type == nir_instr_type_deref) { + nir_rematerialize_deref_in_use_blocks(nir_instr_as_deref(def->parent_instr)); + return true; + } + /* Initialize a phi-instruction */ nir_phi_instr *phi = nir_phi_instr_create(state->shader); nir_def_init(&phi->instr, &phi->def, def->num_components, @@ -239,23 +244,6 @@ convert_loop_exit_for_ssa(nir_def *def, void *void_state) nir_instr_insert_before_block(state->block_after_loop, &phi->instr); nir_def *dest = &phi->def; - /* deref instructions need a cast after the phi */ - if (def->parent_instr->type == nir_instr_type_deref) { - nir_deref_instr *cast = - nir_deref_instr_create(state->shader, nir_deref_type_cast); - - nir_deref_instr *instr = nir_instr_as_deref(def->parent_instr); - cast->modes = instr->modes; - cast->type = instr->type; - cast->parent = nir_src_for_ssa(&phi->def); - cast->cast.ptr_stride = nir_deref_instr_array_stride(instr); - - nir_def_init(&cast->instr, &cast->def, - phi->def.num_components, phi->def.bit_size); - nir_instr_insert(nir_after_phis(state->block_after_loop), &cast->instr); - dest = &cast->def; - } - /* Run through all uses and rewrite those outside the loop to point to * the phi instead of pointing to the ssa-def. */ @@ -340,8 +328,8 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state) } } - nir_foreach_block_in_cf_node(block, cf_node) { - nir_foreach_instr(instr, block) { + nir_foreach_block_in_cf_node_reverse(block, cf_node) { + nir_foreach_instr_reverse_safe(instr, block) { nir_foreach_def(instr, convert_loop_exit_for_ssa, state); /* for outer loops, invariant instructions can be variant */ @@ -381,8 +369,8 @@ nir_convert_loop_to_lcssa(nir_loop *loop) state->skip_invariants = false; state->skip_bool_invariants = false; - nir_foreach_block_in_cf_node(block, &loop->cf_node) { - nir_foreach_instr(instr, block) + nir_foreach_block_in_cf_node_reverse(block, &loop->cf_node) { + nir_foreach_instr_reverse_safe(instr, block) nir_foreach_def(instr, convert_loop_exit_for_ssa, state); }