nir: validate that loop continue statements always link to continue constructs
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39942>
This commit is contained in:
Daniel Schürmann 2026-02-09 15:03:12 +01:00 committed by Marge Bot
parent 94f959972d
commit 4ca0eb9f54
2 changed files with 12 additions and 21 deletions

View file

@ -3830,18 +3830,6 @@ nir_loop_last_continue_block(nir_loop *loop)
return nir_cf_node_as_block(exec_node_data(nir_cf_node, tail, node));
}
/**
* Return the target block of a nir_jump_continue statement
*/
static inline nir_block *
nir_loop_continue_target(nir_loop *loop)
{
if (nir_loop_has_continue_construct(loop))
return nir_loop_first_continue_block(loop);
else
return nir_loop_first_block(loop);
}
/**
* Return true if this list of cf_nodes contains a single empty block.
*/

View file

@ -1248,8 +1248,11 @@ validate_jump_instr(nir_jump_instr *instr, validate_state *state)
validate_assert(state, state->impl->structured);
validate_assert(state, state->loop != NULL);
if (state->loop) {
nir_block *cont_block = nir_loop_continue_target(state->loop);
validate_assert(state, block->successors[0] == cont_block);
validate_assert(state, nir_loop_has_continue_construct(state->loop));
if (nir_loop_has_continue_construct(state->loop)) {
nir_block *cont_block = nir_loop_first_continue_block(state->loop);
validate_assert(state, block->successors[0] == cont_block);
}
}
validate_assert(state, block->successors[1] == NULL);
validate_assert(state, instr->target == NULL);
@ -1500,14 +1503,13 @@ validate_block(nir_block *block, validate_state *state)
if (next == NULL) {
switch (state->parent_node->type) {
case nir_cf_node_loop: {
if (block == nir_loop_last_block(state->loop)) {
nir_block *cont = nir_loop_continue_target(state->loop);
validate_assert(state, block->successors[0] == cont);
if (!nir_loop_has_continue_construct(state->loop) ||
block == nir_loop_last_continue_block(state->loop)) {
nir_block *header = nir_loop_first_block(state->loop);
validate_assert(state, block->successors[0] == header);
} else {
validate_assert(state, nir_loop_has_continue_construct(state->loop) &&
block == nir_loop_last_continue_block(state->loop));
nir_block *head = nir_loop_first_block(state->loop);
validate_assert(state, block->successors[0] == head);
nir_block *cont = nir_loop_first_continue_block(state->loop);
validate_assert(state, block->successors[0] == cont);
}
/* due to the hack for infinite loops, block->successors[1] may
* point to the block after the loop.
@ -1614,6 +1616,7 @@ validate_loop(nir_loop *loop, validate_state *state)
validate_assert(state, next_node->type == nir_cf_node_block);
validate_assert(state, !exec_list_is_empty(&loop->body));
validate_assert(state, nir_loop_first_block(loop)->predecessors.entries <= 2);
nir_cf_node *old_parent = state->parent_node;
state->parent_node = &loop->cf_node;