summaryrefslogtreecommitdiffstats
path: root/src/compiler/spirv
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2017-12-06 10:01:22 -0800
committerJason Ekstrand <[email protected]>2017-12-11 22:28:34 -0800
commitdf657ebb68a000b031d1b052748af5df4b645b59 (patch)
tree0a41105d8a4987f5ec73713eeffbc0ea2ca03467 /src/compiler/spirv
parent58cabae8cc8e848cfe39c7a63973c12c92a4ee96 (diff)
spirv: Add support for all bit sizes in OpSwitch
Reviewed-by: Ian Romanick <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101560
Diffstat (limited to 'src/compiler/spirv')
-rw-r--r--src/compiler/spirv/vtn_cfg.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index 28b811fc9a9..8ddd0f4a40d 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -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;
}