diff options
author | Timothy Arceri <[email protected]> | 2019-03-20 22:59:40 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2019-03-22 09:58:18 +1100 |
commit | a1bd9dd5bcd6e4aa9a5cf33d9901046f68d3d580 (patch) | |
tree | f38d2403126a3ba139a892e5d341d1e54f977b69 /src/compiler | |
parent | 620df57dbb74f1001fcdf5b401f5bc7555f8884b (diff) |
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 <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir_opt_if.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c index bc128f79f3c..4d3183ed151 100644 --- a/src/compiler/nir/nir_opt_if.c +++ b/src/compiler/nir/nir_opt_if.c @@ -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 |