summaryrefslogtreecommitdiffstats
path: root/src/compiler/spirv/vtn_cfg.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-09-16 21:55:08 -0700
committerJason Ekstrand <[email protected]>2016-10-01 15:40:14 -0700
commit4d02faede57b782264ab97d57919e9dad7dd8131 (patch)
tree4ce586d0529a54869dc44c7620c34105b4f95f4a /src/compiler/spirv/vtn_cfg.c
parentfc03ecfeaf5a10a8b84d366f24f02e74ab03b145 (diff)
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 <[email protected]> Cc: "12.0" <[email protected]>
Diffstat (limited to 'src/compiler/spirv/vtn_cfg.c')
-rw-r--r--src/compiler/spirv/vtn_cfg.c13
1 files changed, 13 insertions, 0 deletions
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;
}