summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir_deref.c8
-rw-r--r--src/compiler/nir/nir_from_ssa.c2
-rw-r--r--src/compiler/nir/nir_validate.c9
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