spirv: deal with null pointers

%2456 = some complicated struct...
       %8307 = OpTypeInt 32 0
       %8308 = OpTypeInt 8 0
       %8467 = OpTypePointer Generic %8308
       %8500 = OpTypePointer Generic %2456
       %8586 = OpConstantNull %8500
       %8312 = OpConstant %8307 0
       %8314 = OpConstant %8307 2
       %9752 = OpInBoundsPtrAccessChain %8467 %8586 %8312 %8314

Right now the parser can't deal with this %8586. Let's create a value
off the Null constant.

v2: add helpers

v3: Correctly create the Null value

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10672>
This commit is contained in:
Lionel Landwerlin 2021-05-06 22:16:21 +03:00 committed by Marge Bot
parent 333472f0de
commit ee1f0451a8
3 changed files with 51 additions and 19 deletions

View file

@ -225,7 +225,7 @@ vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
return val;
}
static struct vtn_ssa_value *
struct vtn_ssa_value *
vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
const struct glsl_type *type)
{
@ -3622,13 +3622,13 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode,
case SpvOpAtomicFMinEXT:
case SpvOpAtomicFMaxEXT:
case SpvOpAtomicFlagTestAndSet:
ptr = vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
ptr = vtn_pointer(b, w[3]);
scope = vtn_constant_uint(b, w[4]);
semantics = vtn_constant_uint(b, w[5]);
break;
case SpvOpAtomicFlagClear:
case SpvOpAtomicStore:
ptr = vtn_value(b, w[1], vtn_value_type_pointer)->pointer;
ptr = vtn_pointer(b, w[1]);
scope = vtn_constant_uint(b, w[2]);
semantics = vtn_constant_uint(b, w[3]);
break;

View file

@ -737,6 +737,10 @@ struct vtn_pointer *
vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
struct vtn_type *ptr_type);
struct vtn_ssa_value *
vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
const struct glsl_type *type);
static inline struct vtn_value *
vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)
{
@ -787,6 +791,35 @@ vtn_value(struct vtn_builder *b, uint32_t value_id,
return val;
}
static inline struct vtn_value *
vtn_pointer_value(struct vtn_builder *b, uint32_t value_id)
{
struct vtn_value *val = vtn_untyped_value(b, value_id);
vtn_fail_if(val->value_type != vtn_value_type_pointer &&
!val->is_null_constant,
"SPIR-V id %u is the wrong kind of value", value_id);
return val;
}
static inline struct vtn_pointer *
vtn_value_to_pointer(struct vtn_builder *b, struct vtn_value *value)
{
if (value->is_null_constant) {
vtn_assert(glsl_type_is_vector_or_scalar(value->type->type));
nir_ssa_def *const_ssa =
vtn_const_ssa_value(b, value->constant, value->type->type)->def;
return vtn_pointer_from_ssa(b, const_ssa, value->type);
}
vtn_assert(value->value_type == vtn_value_type_pointer);
return value->pointer;
}
static inline struct vtn_pointer *
vtn_pointer(struct vtn_builder *b, uint32_t value_id)
{
return vtn_value_to_pointer(b, vtn_pointer_value(b, value_id));
}
bool
vtn_set_instruction_result_type(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count);

View file

@ -518,7 +518,7 @@ _vtn_local_load_store(struct vtn_builder *b, bool load, nir_deref_instr *deref,
nir_deref_instr *
vtn_nir_deref(struct vtn_builder *b, uint32_t id)
{
struct vtn_pointer *ptr = vtn_value(b, id, vtn_value_type_pointer)->pointer;
struct vtn_pointer *ptr = vtn_pointer(b, id);
return vtn_pointer_to_deref(b, ptr);
}
@ -2417,8 +2417,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
}
struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
struct vtn_pointer *base =
vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
struct vtn_pointer *base = vtn_pointer(b, w[3]);
/* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
access |= base->access & ACCESS_NON_UNIFORM;
@ -2431,10 +2431,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
}
case SpvOpCopyMemory: {
struct vtn_value *dest_val = vtn_value(b, w[1], vtn_value_type_pointer);
struct vtn_value *src_val = vtn_value(b, w[2], vtn_value_type_pointer);
struct vtn_pointer *dest = dest_val->pointer;
struct vtn_pointer *src = src_val->pointer;
struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
struct vtn_value *src_val = vtn_pointer_value(b, w[2]);
struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
vtn_assert_types_equal(b, opcode, dest_val->type->deref,
src_val->type->deref);
@ -2463,11 +2463,11 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
}
case SpvOpCopyMemorySized: {
struct vtn_value *dest_val = vtn_value(b, w[1], vtn_value_type_pointer);
struct vtn_value *src_val = vtn_value(b, w[2], vtn_value_type_pointer);
struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
struct vtn_value *src_val = vtn_pointer_value(b, w[2]);
nir_ssa_def *size = vtn_get_nir_ssa(b, w[3]);
struct vtn_pointer *dest = dest_val->pointer;
struct vtn_pointer *src = src_val->pointer;
struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
unsigned idx = 4, dest_alignment, src_alignment;
SpvMemoryAccessMask dest_access, src_access;
@ -2498,7 +2498,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
case SpvOpLoad: {
struct vtn_type *res_type = vtn_get_type(b, w[1]);
struct vtn_value *src_val = vtn_value(b, w[3], vtn_value_type_pointer);
struct vtn_pointer *src = src_val->pointer;
struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
vtn_assert_types_equal(b, opcode, res_type, src_val->type->deref);
@ -2515,8 +2515,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
}
case SpvOpStore: {
struct vtn_value *dest_val = vtn_value(b, w[1], vtn_value_type_pointer);
struct vtn_pointer *dest = dest_val->pointer;
struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
/* OpStore requires us to actually have a storage type */
@ -2558,8 +2558,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
}
case SpvOpArrayLength: {
struct vtn_pointer *ptr =
vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
struct vtn_pointer *ptr = vtn_pointer(b, w[3]);
const uint32_t field = w[4];
vtn_fail_if(ptr->type->base_type != vtn_base_type_struct,