nir/spirv/cfg: Handle switches whose break block is a loop continue
It is possible that the break block of a switch is actually the continue of the loop containing the switch. In this case, we need to identify the break block as a continue and break out of current level of CFG handling. If we don't, the continue portion of the loop will get handled twice, once by following after the break and a second time by the loop handling code handling it explicitly. This fixes 6 of the new Vulkan CTS tests: - dEQP-VK.spirv_assembly.instruction.graphics.opphi.out_of_order* - dEQP-VK.spirv_assembly.instruction.graphics.selection_block_order.out_of_order* Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Cc: "12.0" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
@@ -443,6 +443,19 @@ vtn_cfg_walk_blocks(struct vtn_builder *b, struct list_head *cf_list,
|
||||
vtn_order_case(swtch, case_block->switch_case);
|
||||
}
|
||||
|
||||
enum vtn_branch_type branch_type =
|
||||
vtn_get_branch_type(break_block, switch_case, NULL,
|
||||
loop_break, loop_cont);
|
||||
|
||||
if (branch_type != vtn_branch_type_none) {
|
||||
/* It is possible that the break is actually the continue block
|
||||
* for the containing loop. In this case, we need to bail and let
|
||||
* the loop parsing code handle the continue properly.
|
||||
*/
|
||||
assert(branch_type == vtn_branch_type_loop_continue);
|
||||
return;
|
||||
}
|
||||
|
||||
block = break_block;
|
||||
continue;
|
||||
}
|
||||
|
Reference in New Issue
Block a user