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:
Jason Ekstrand
2016-09-16 21:55:08 -07:00
parent fc03ecfeaf
commit 4d02faede5

View File

@@ -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;
}