From df657ebb68a000b031d1b052748af5df4b645b59 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 6 Dec 2017 10:01:22 -0800 Subject: [PATCH] spirv: Add support for all bit sizes in OpSwitch Reviewed-by: Ian Romanick Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101560 --- src/compiler/spirv/vtn_cfg.c | 34 ++++++++++++++++++++++++++-------- 1 file 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; } -- 2.30.2