nir: fix opt_if_loop_last_continue()
Rather than skipping code that looked like this: loop { ... if (cond) { do_work_1(); continue; } else { break; } do_work_2(); } Previously we would turn this into: loop { ... if (cond) { do_work_1(); continue; } else { do_work_2(); break; } } This was clearly wrong. This change checks for this case and makes sure we now leave it for nir_opt_dead_cf() to clean up. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -855,7 +855,8 @@ opt_if_loop_last_continue(nir_loop *loop)
|
||||
/* If both branches end in a continue do nothing, this should be handled
|
||||
* by nir_opt_dead_cf().
|
||||
*/
|
||||
if (then_ends_in_continue && else_ends_in_continue)
|
||||
if ((then_ends_in_continue || nir_block_ends_in_break(then_block)) &&
|
||||
(else_ends_in_continue || nir_block_ends_in_break(else_block)))
|
||||
return false;
|
||||
|
||||
if (!then_ends_in_continue && !else_ends_in_continue)
|
||||
@@ -872,15 +873,10 @@ opt_if_loop_last_continue(nir_loop *loop)
|
||||
nir_cf_list tmp;
|
||||
nir_cf_extract(&tmp, nir_after_cf_node(if_node),
|
||||
nir_after_block(last_block));
|
||||
if (then_ends_in_continue) {
|
||||
nir_cursor last_blk_cursor = nir_after_cf_list(&nif->else_list);
|
||||
nir_cf_reinsert(&tmp,
|
||||
nir_after_block_before_jump(last_blk_cursor.block));
|
||||
} else {
|
||||
nir_cursor last_blk_cursor = nir_after_cf_list(&nif->then_list);
|
||||
nir_cf_reinsert(&tmp,
|
||||
nir_after_block_before_jump(last_blk_cursor.block));
|
||||
}
|
||||
if (then_ends_in_continue)
|
||||
nir_cf_reinsert(&tmp, nir_after_cf_list(&nif->else_list));
|
||||
else
|
||||
nir_cf_reinsert(&tmp, nir_after_cf_list(&nif->then_list));
|
||||
|
||||
/* In order to avoid running nir_lower_regs_to_ssa_impl() every time an if
|
||||
* opt makes progress we leave nir_opt_trivial_continues() to remove the
|
||||
|
Reference in New Issue
Block a user