Mesa (staging/21.2): spirv: deal with null pointers
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Oct 12 17:45:24 UTC 2021
Module: Mesa
Branch: staging/21.2
Commit: 06bbb6e6c0c8fb6523c5bc5b6f499aa8c1ffff08
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=06bbb6e6c0c8fb6523c5bc5b6f499aa8c1ffff08
Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date: Thu May 6 22:16:21 2021 +0300
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 at intel.com>
Cc: mesa-stable
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10672>
(cherry picked from commit ee1f0451a8d304bf172cbaae6a0626f3ca9b5b17)
Conflicts:
src/compiler/spirv/spirv_to_nir.c
---
.pick_status.json | 2 +-
src/compiler/spirv/spirv_to_nir.c | 6 +++---
src/compiler/spirv/vtn_private.h | 33 +++++++++++++++++++++++++++++++++
src/compiler/spirv/vtn_variables.c | 31 +++++++++++++++----------------
4 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/.pick_status.json b/.pick_status.json
index ccb55438e54..e280e8bfb92 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -850,7 +850,7 @@
"description": "spirv: deal with null pointers",
"nominated": true,
"nomination_type": 0,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": null
},
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index c4e05878062..517777a95d1 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -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)
{
@@ -3598,13 +3598,13 @@ vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode,
case SpvOpAtomicFAddEXT:
case SpvOpAtomicFMinEXT:
case SpvOpAtomicFMaxEXT:
- 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 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;
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index f2cfe144405..ea48211a9fe 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -731,6 +731,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)
{
@@ -781,6 +785,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);
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 8423434e1c7..3f15f4a2677 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -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);
}
@@ -2334,8 +2334,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;
@@ -2348,10 +2348,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);
@@ -2380,11 +2380,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;
@@ -2415,7 +2415,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);
@@ -2432,8 +2432,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 */
@@ -2475,8 +2475,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,
More information about the mesa-commit
mailing list