spirv: Add support for all bit sizes in OpSwitch
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 6 Dec 2017 18:01:22 +0000 (10:01 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 12 Dec 2017 06:28:34 +0000 (22:28 -0800)
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101560

src/compiler/spirv/vtn_cfg.c

index 28b811fc9a9900daf3127ba19f138f7441ea6d40..8ddd0f4a40d54adfd16d82b27f2490e2f9f53db4 100644 (file)
@@ -170,7 +170,7 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
 static void
 vtn_add_case(struct vtn_builder *b, struct vtn_switch *swtch,
              struct vtn_block *break_block,
-             uint32_t block_id, uint32_t val, bool is_default)
+             uint32_t block_id, uint64_t val, bool is_default)
 {
    struct vtn_block *case_block =
       vtn_value(b, block_id, vtn_value_type_block)->block;
@@ -197,7 +197,7 @@ vtn_add_case(struct vtn_builder *b, struct vtn_switch *swtch,
    if (is_default) {
       case_block->switch_case->is_default = true;
    } else {
-      util_dynarray_append(&case_block->switch_case->values, uint32_t, val);
+      util_dynarray_append(&case_block->switch_case->values, uint64_t, val);
    }
 }
 
@@ -425,11 +425,29 @@ vtn_cfg_walk_blocks(struct vtn_builder *b, struct list_head *cf_list,
          const uint32_t *branch_end =
             block->branch + (block->branch[0] >> SpvWordCountShift);
 
+         struct vtn_value *cond_val = vtn_untyped_value(b, block->branch[1]);
+         vtn_fail_if(!cond_val->type ||
+                     cond_val->type->base_type != vtn_base_type_scalar,
+                     "Selector of OpSelect must have a type of OpTypeInt");
+
+         nir_alu_type cond_type =
+            nir_get_nir_type_for_glsl_type(cond_val->type->type);
+         vtn_fail_if(nir_alu_type_get_base_type(cond_type) != nir_type_int &&
+                     nir_alu_type_get_base_type(cond_type) != nir_type_uint,
+                     "Selector of OpSelect must have a type of OpTypeInt");
+
          bool is_default = true;
          for (const uint32_t *w = block->branch + 2; w < branch_end;) {
-            uint32_t literal = 0;
-            if (!is_default)
-               literal = *(w++);
+            uint64_t literal = 0;
+            if (!is_default) {
+               if (nir_alu_type_get_type_size(cond_type) <= 32) {
+                  literal = *(w++);
+               } else {
+                  assert(nir_alu_type_get_type_size(cond_type) == 64);
+                  literal = vtn_u64_literal(w);
+                  w += 2;
+               }
+            }
 
             uint32_t block_id = *(w++);
 
@@ -727,9 +745,9 @@ vtn_emit_cf_list(struct vtn_builder *b, struct list_head *cf_list,
             }
 
             nir_ssa_def *cond = NULL;
-            util_dynarray_foreach(&cse->values, uint32_t, val) {
-               nir_ssa_def *is_val =
-                  nir_ieq(&b->nb, sel, nir_imm_int(&b->nb, *val));
+            util_dynarray_foreach(&cse->values, uint64_t, val) {
+               nir_ssa_def *imm = nir_imm_intN_t(&b->nb, *val, sel->bit_size);
+               nir_ssa_def *is_val = nir_ieq(&b->nb, sel, imm);
 
                cond = cond ? nir_ior(&b->nb, cond, is_val) : is_val;
             }