-
Notifications
You must be signed in to change notification settings - Fork 556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spirv-val: Validate outter descriptor array index #5577
spirv-val: Validate outter descriptor array index #5577
Conversation
@@ -1276,14 +1276,13 @@ spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { | |||
|
|||
spv_result_t ValidateAccessChain(ValidationState_t& _, | |||
const Instruction* inst) { | |||
std::string instr_name = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved string logic to error message time as assume most OpAccessChain
are valid and don't need to spend time building this string
const uint32_t cur_index = cur_word_instr->word(3); | ||
auto array_length_id = _.FindDef(type_pointee->word(3)); | ||
if (spv::Op::OpConstant == array_length_id->opcode()) { | ||
const uint32_t array_length = array_length_id->word(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while the OpAccessChain
indexes are required to be 32-bit int scalar but can be negative
I realize from the failing spirv-opt
tests is the OpTypeArray
length operand can be a 64-bit length
case spv::Op::OpTypeStruct: { | ||
// In case of structures, there is an additional constraint on the | ||
// index: the index must be an OpConstant. | ||
if (spv::Op::OpConstant != cur_word_instr->opcode()) { | ||
return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) | ||
<< "The <id> passed to " << instr_name | ||
<< "The <id> passed to Op" << spvOpcodeString(opcode) | ||
<< " to index into a " | ||
"structure must be an OpConstant."; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alan-baker working more into this, I found the line below makes it seem like it is legal to have a -1
access chain index?
So this means if I have a
layout(set=0, binding=0) buffer foo { int x[3]; } var;
These are valid?
%int_n1 = OpConstant %int -1
%int_5 = OpConstant %int 5
%ac = OpAccessChain %ptr %var %int_0 %int_n1
// or
%ac = OpAccessChain %sb_ptr %var %int_0 %int_5
(I realize this code should be checking 64-bit, I am adding that)
Are we sure we want this in the validator? Having an OpAccessChain that is oob is not invalid, it is undefined behaviour, if it is executed. This is important because someone might have code that is guarded by a conditional statement that will only execute it when it is allowed. This seems like a better fit for the linter. |
@s-perron I guess the issue was someone had the shader in #5468 and it seemed like something that could be caught statically so it was not be validated in the validation layers SPIR-V runtime We are currently checking if some of the |
That surprises me because I thought we had agreed it was not a validation error. |
When I look at the code we currently on check OpTypeStruct indexing. That is specifically called out as must (validity) in SPIR-V. As I mentioned in the other issue, I would be ok with Vulkan specific checks that error on guaranteed undefined behaviour. I agree with Steven that that means you might have to limit where those checks are applied (e.g. always executed). |
Ok, good to know!
Ok, let me take another stab at this, while we do plan to have GPU Validation on OOB, there is a large amount of trivial cases that could be caught, happy to guard (and comment in the code) the restriction of the checking |
After spending more time on this, decided that
closing and just gonna keep this as a runtime check |
I found out that
spirv-val
wasn't validating access chain OOB for the outer array of a descriptor array