aco: skip continue_or_break LCSSA phis when not needed
Fixes:
//exec is empty here
loop {
%1:s[16-17] = ...
if () {
break
}
%2:s[16-17] = ...
continue_or_break
}
%3 = phi %1, undef
//because of the undef, %2 can use s[16-17] and overwrite the address
load(%3:s[16-17])
No fossil-db changes.
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Fixes: bbe4652430
("aco: create lcssa phis for continue_or_break loops when necessary")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11333
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29838>
This commit is contained in:
@@ -10186,6 +10186,17 @@ lcssa_workaround(isel_context* ctx, nir_loop* loop)
|
||||
|
||||
std::map<unsigned, unsigned> renames;
|
||||
nir_foreach_block_in_cf_node (block, &loop->cf_node) {
|
||||
/* These values are reachable from the loop exit even when continue_or_break is used. We
|
||||
* shouldn't create phis with undef operands in case the contents are important even if exec
|
||||
* is zero (for example, memory access addresses). */
|
||||
if (nir_block_dominates(block, nir_loop_last_block(loop)))
|
||||
continue;
|
||||
|
||||
/* Definitions in this block are not reachable from the loop exit, and so all uses are inside
|
||||
* the loop. */
|
||||
if (!nir_block_dominates(block, block_after_loop))
|
||||
continue;
|
||||
|
||||
nir_foreach_instr (instr, block) {
|
||||
nir_def* def = nir_instr_def(instr);
|
||||
if (!def)
|
||||
|
@@ -289,7 +289,7 @@ init_context(isel_context* ctx, nir_shader* shader)
|
||||
nir_metadata_preserve(impl, nir_metadata_none);
|
||||
|
||||
/* we'll need these for isel */
|
||||
nir_metadata_require(impl, nir_metadata_block_index);
|
||||
nir_metadata_require(impl, nir_metadata_block_index | nir_metadata_dominance);
|
||||
|
||||
if (ctx->options->dump_preoptir) {
|
||||
fprintf(stderr, "NIR shader before instruction selection:\n");
|
||||
|
Reference in New Issue
Block a user