spirv: fix visiting inner loops with same break/continue block
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 15 May 2018 10:00:30 +0000 (12:00 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 15 May 2018 19:38:19 +0000 (21:38 +0200)
We should stop walking through the CFG when the inner loop's
break block ends up as the same block as the outer loop's
continue block because we are already going to visit it.

This fixes the following assertion which ends up by crashing
in RADV or ANV:

SPIR-V parsing FAILED:
In file ../src/compiler/spirv/vtn_cfg.c:381
block->node.link.next == NULL
0 bytes into the SPIR-V binary

This also fixes a crash with a camera shader from SteamVR.

v2: make use of vtn_get_branch_type() and add an assertion

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106090
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=106504
CC: 18.0 18.1 <mesa-stable@lists.freedesktop.org>
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/spirv/vtn_cfg.c

index e7d2f9ea61427ab4e577406608ad61353f4819b2..ad4374112e1c1aee9e86679ae7fb8412182284b9 100644 (file)
@@ -374,6 +374,19 @@ vtn_cfg_walk_blocks(struct vtn_builder *b, struct list_head *cf_list,
          vtn_cfg_walk_blocks(b, &loop->cont_body, new_loop_cont, NULL, NULL,
                              new_loop_break, NULL, block);
 
+         enum vtn_branch_type branch_type =
+            vtn_get_branch_type(b, new_loop_break, switch_case, switch_break,
+                                loop_break, loop_cont);
+
+         if (branch_type != vtn_branch_type_none) {
+            /* Stop walking through the CFG when this inner loop's break block
+             * ends up as the same block as the outer loop's continue block
+             * because we are already going to visit it.
+             */
+            vtn_assert(branch_type == vtn_branch_type_loop_continue);
+            return;
+         }
+
          block = new_loop_break;
          continue;
       }