spirv: consider bitsize when handling OpSwitch cases
authorEero Tamminen <eero.t.tamminen@intel.com>
Tue, 26 Dec 2017 15:21:21 +0000 (07:21 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 28 Dec 2017 18:38:58 +0000 (10:38 -0800)
This reverts commit 7665383a33f9ce9256aa121cbe4d3bd948dff145 and is
squashed together with https://patchwork.freedesktop.org/patch/194610/
(spirv: avoid infinite loop / freeze in vtn_cfg_walk_blocks()) which
fixes https://bugs.freedesktop.org/show_bug.cgi?id=104359 properly.

Fixes: 9702fac68e (spirv: consider bitsize when handling OpSwitch cases)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104359
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/spirv/vtn_cfg.c

index 8582c4f0e9433043e1ead8c5c1be3ef3a6a12f64..3d5de378ac9fe3f065158045943798b41976dddf 100644 (file)
@@ -513,13 +513,14 @@ vtn_cfg_walk_blocks(struct vtn_builder *b, struct list_head *cf_list,
                      "Selector of OpSelect must have a type of OpTypeInt");
 
          bool is_default = true;
+         const uint bitsize = nir_alu_type_get_type_size(cond_type);
          for (const uint32_t *w = block->branch + 2; w < branch_end;) {
             uint64_t literal = 0;
             if (!is_default) {
-               if (nir_alu_type_get_type_size(cond_type) <= 32) {
+               if (bitsize <= 32) {
                   literal = *(w++);
                } else {
-                  assert(nir_alu_type_get_type_size(cond_type) == 64);
+                  assert(bitsize == 64);
                   literal = vtn_u64_literal(w);
                   w += 2;
                }
@@ -544,10 +545,17 @@ vtn_cfg_walk_blocks(struct vtn_builder *b, struct list_head *cf_list,
          /* Finally, we walk over all of the cases one more time and put
           * them in fall-through order.
           */
-         for (const uint32_t *w = block->branch + 2; w < branch_end; w += 2) {
+         for (const uint32_t *w = block->branch + 2; w < branch_end;) {
             struct vtn_block *case_block =
                vtn_value(b, *w, vtn_value_type_block)->block;
 
+            if (bitsize <= 32) {
+               w += 2;
+            } else {
+               assert(bitsize == 64);
+               w += 3;
+            }
+
             if (case_block == break_block)
                continue;