diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/nir/nir_deref.c | 8 | ||||
-rw-r--r-- | src/compiler/nir/nir_from_ssa.c | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_validate.c | 9 |
3 files changed, 17 insertions, 2 deletions
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index f1e6eee7745..90bb9a0dc3c 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -601,6 +601,8 @@ rematerialize_deref_src(nir_src *src, void *_state) * used. After this pass has been run, every use of a deref will be of a * deref in the same block as the use. Also, all unused derefs will be * deleted as a side-effect. + * + * Derefs used as sources of phi instructions are not rematerialized. */ bool nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl) @@ -620,6 +622,12 @@ nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl) nir_deref_instr_remove_if_unused(nir_instr_as_deref(instr))) continue; + /* If a deref is used in a phi, we can't rematerialize it, as the new + * derefs would appear before the phi, which is not valid. + */ + if (instr->type == nir_instr_type_phi) + continue; + state.builder.cursor = nir_before_instr(instr); nir_foreach_src(instr, rematerialize_deref_src, &state); } diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c index b406e7401d6..2ac67b2b997 100644 --- a/src/compiler/nir/nir_from_ssa.c +++ b/src/compiler/nir/nir_from_ssa.c @@ -902,8 +902,6 @@ nir_lower_phis_to_regs_block(nir_block *block) nir_foreach_phi_src(src, phi) { assert(src->src.is_ssa); - /* We don't want derefs ending up in phi sources */ - assert(!nir_src_as_deref(src->src)); place_phi_read(shader, reg, src->src.ssa, src->pred); } diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index bf3f23f2547..682ed762f57 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -499,6 +499,15 @@ validate_deref_instr(nir_deref_instr *instr, validate_state *state) * NULL, an explicit comparison operation should be used. */ validate_assert(state, list_empty(&instr->dest.ssa.if_uses)); + + /* Only certain modes can be used as sources for phi instructions. */ + nir_foreach_use(use, &instr->dest.ssa) { + if (use->parent_instr->type == nir_instr_type_phi) { + validate_assert(state, instr->mode == nir_var_mem_ubo || + instr->mode == nir_var_mem_ssbo || + instr->mode == nir_var_mem_shared); + } + } } static void |