aco: handle loop exit and IF merge phis with break/discard

ACO considers discards jumps and creates edges in the CFG for them but NIR
does neither of these.

This can be fixed instead by keeping track of whether a side of an IF had
a break/discard, but this doesn't solve the issue with discards affecting
loop exit phis. So this reworks phi handling a bit.

Fixes these tests:
dEQP-VK.graphicsfuzz.disc-and-add-in-func-in-loop
dEQP-VK.graphicsfuzz.loop-call-discard
dEQP-VK.graphicsfuzz.complex-nested-loops-and-call

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
This commit is contained in:
Rhys Perry
2019-11-18 17:26:38 +00:00
parent 06fc83989c
commit 0e8da9f607
2 changed files with 80 additions and 54 deletions
@@ -69,6 +69,7 @@ struct isel_context {
bool is_divergent = false;
} parent_if;
bool exec_potentially_empty = false;
std::unique_ptr<unsigned[]> nir_to_aco; /* NIR block index to ACO block index */
} cf_info;
Temp arg_temps[AC_MAX_ARGS];
@@ -133,6 +134,8 @@ void init_context(isel_context *ctx, nir_shader *shader)
unsigned spi_ps_inputs = 0;
std::unique_ptr<unsigned[]> nir_to_aco{new unsigned[impl->num_blocks]()};
bool done = false;
while (!done) {
done = true;
@@ -538,6 +541,7 @@ void init_context(isel_context *ctx, nir_shader *shader)
allocated[i] = Temp(ctx->program->allocateId(), allocated[i].regClass());
ctx->allocated.reset(allocated.release());
ctx->cf_info.nir_to_aco.reset(nir_to_aco.release());
}
Pseudo_instruction *add_startpgm(struct isel_context *ctx)
@@ -899,6 +903,7 @@ setup_isel_context(Program* program,
nir_function_impl *func = nir_shader_get_entrypoint(nir);
nir_index_ssa_defs(func);
nir_metadata_require(func, nir_metadata_block_index);
if (args->options->dump_preoptir) {
fprintf(stderr, "NIR shader before instruction selection:\n");