From 4d02faede57b782264ab97d57919e9dad7dd8131 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 16 Sep 2016 21:55:08 -0700 Subject: [PATCH] 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 Cc: "12.0" --- src/compiler/spirv/vtn_cfg.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index d9096f43ef6..475454e1d03 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -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; } -- 2.30.2