summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCaio Marcelo de Oliveira Filho <[email protected]>2019-04-04 12:46:42 -0700
committerCaio Marcelo de Oliveira Filho <[email protected]>2019-04-05 09:43:46 -0700
commitc037dbb0efad573aab1467befd35d2c4f4cdbbce (patch)
treed95bc34960b23d50b752e61c6d770b4eabf4a533 /src
parent26e161b1e942564b649d355df359fc2e22b46188 (diff)
nir: Take if_uses into account when repairing SSA
If a def is used as an condition before its definition, we should also consider this a case to repair. When repairing, make sure we rewrite any if conditions too. Found in while inspecting a SPIR-V conversion from a 'continue block' that contains a conditional branch. We pull the continue block up to the beggining of the loop, and the condition in the branch ends up defined afterwards. Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> Fixes: 364212f1ede4b "nir: Add a pass to repair SSA form"
Diffstat (limited to 'src')
-rw-r--r--src/compiler/nir/nir_repair_ssa.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_repair_ssa.c b/src/compiler/nir/nir_repair_ssa.c
index b4d22d91c27..f182818374d 100644
--- a/src/compiler/nir/nir_repair_ssa.c
+++ b/src/compiler/nir/nir_repair_ssa.c
@@ -77,6 +77,15 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
}
}
+ nir_foreach_if_use(src, def) {
+ nir_block *block_before_if =
+ nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
+ if (!nir_block_dominates(def->parent_instr->block, block_before_if)) {
+ is_valid = false;
+ break;
+ }
+ }
+
if (is_valid)
return true;
@@ -98,6 +107,15 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
}
}
+ nir_foreach_if_use_safe(src, def) {
+ nir_block *block_before_if =
+ nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
+ if (!nir_block_dominates(def->parent_instr->block, block_before_if)) {
+ nir_if_rewrite_condition(src->parent_if, nir_src_for_ssa(
+ nir_phi_builder_value_get_block_def(val, block_before_if)));
+ }
+ }
+
return true;
}