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
Extension allows multiple same OpTypePointer types #783
Conversation
SPV_KHR_variable_pointers allows OpTypePointer to declare multiple identical types if they have different declarations. KhronosGroup#781
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.
Thanks for the quick turnaround.
I think it's not quite right in its internals, and I think some of the tests are incorrect.
test/val/val_type_unique_test.cpp
Outdated
@@ -238,4 +238,57 @@ OpMemoryModel Physical32 OpenCL | |||
Not(HasSubstr(GetErrorString(SpvOpTypeVoid)))); | |||
} | |||
|
|||
TEST_F(ValidateTypeUnique, PointerTypesSameArrayStrideNoExtension) { |
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.
The test name is misleading to me: The array strides here are different, but the test name is ....SameArrayStride...
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.
CopyPaste
source/val/validation_state.cpp
Outdated
const auto result = decoration_params.emplace(decoration.dec_type(), | ||
&decoration.params()); | ||
(void)result; | ||
assert(result.second); |
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.
I don't think you should assert here? There's nothing wrong with redundant decorations, except that it wastes space.
I don't think the storage behind id_decorations has unique'd it.
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.
It's worth saying you're assuming that a single decoration enum can only be set once per target ID.
It think that's true currently, and is likely to be true always. But I don't recall a SPIR-V validation rule about that. (Perhaps an oversight.)
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.
I will assume that decorations are not unique, but only use the last one.
source/val/validation_state.cpp
Outdated
@@ -425,6 +426,22 @@ bool ValidationState_t::RegisterUniqueTypeDeclaration( | |||
key.insert(key.end(), inst.words + words_begin, inst.words + words_end); | |||
} | |||
|
|||
if (inst.opcode == SpvOpTypePointer && |
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.
Better to have a comment describing the rule you're enforcing.
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.
Done.
test/val/val_type_unique_test.cpp
Outdated
CompileSuccessfully(str.c_str()); | ||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); | ||
EXPECT_THAT(getDiagnosticString(), | ||
HasSubstr(GetErrorString(SpvOpTypePointer))); |
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.
I'm confused. The validation succeeds, but generates an error string?
Does this test even pass?
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.
It logs a warning but returns SPV_SUCCESS.
source/validate_type_unique.cpp
Outdated
@@ -49,7 +49,7 @@ spv_result_t TypeUniquePass(ValidationState_t& _, | |||
// return _.diag(SPV_ERROR_INVALID_DATA) | |||
return _.diag(SPV_SUCCESS) | |||
<< "Duplicate non-aggregate type declarations are not allowed." | |||
<< " Opcode: " << inst->opcode; | |||
<< " Opcode: " << spvOpcodeString(SpvOp(inst->opcode)); |
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.
This is an improvement. But in actual practice I've found having the ID generated by this instruction is easier to work with. It pinpoints the exact instruction at fault.
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.
Done
test/val/val_type_unique_test.cpp
Outdated
OpCapability Shader | ||
OpCapability Linkage | ||
OpMemoryModel Logical GLSL450 | ||
OpDecorate %ptr1 ArrayStride 4 |
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.
Or maybe you just have a typo here?
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.
Ready for review.
source/val/validation_state.cpp
Outdated
const auto result = decoration_params.emplace(decoration.dec_type(), | ||
&decoration.params()); | ||
(void)result; | ||
assert(result.second); |
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.
I will assume that decorations are not unique, but only use the last one.
source/val/validation_state.cpp
Outdated
@@ -425,6 +426,22 @@ bool ValidationState_t::RegisterUniqueTypeDeclaration( | |||
key.insert(key.end(), inst.words + words_begin, inst.words + words_end); | |||
} | |||
|
|||
if (inst.opcode == SpvOpTypePointer && |
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.
Done.
source/validate_type_unique.cpp
Outdated
@@ -49,7 +49,7 @@ spv_result_t TypeUniquePass(ValidationState_t& _, | |||
// return _.diag(SPV_ERROR_INVALID_DATA) | |||
return _.diag(SPV_SUCCESS) | |||
<< "Duplicate non-aggregate type declarations are not allowed." | |||
<< " Opcode: " << inst->opcode; | |||
<< " Opcode: " << spvOpcodeString(SpvOp(inst->opcode)); |
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.
Done
test/val/val_type_unique_test.cpp
Outdated
@@ -238,4 +238,57 @@ OpMemoryModel Physical32 OpenCL | |||
Not(HasSubstr(GetErrorString(SpvOpTypeVoid)))); | |||
} | |||
|
|||
TEST_F(ValidateTypeUnique, PointerTypesSameArrayStrideNoExtension) { |
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.
CopyPaste
test/val/val_type_unique_test.cpp
Outdated
CompileSuccessfully(str.c_str()); | ||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); | ||
EXPECT_THAT(getDiagnosticString(), | ||
HasSubstr(GetErrorString(SpvOpTypePointer))); |
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.
It logs a warning but returns SPV_SUCCESS.
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.
The rule should be more relaxed than what you implemented.
source/val/validation_state.cpp
Outdated
for (const auto& kv : decoration_params) { | ||
// Append decoration data to the key, sorted by decoration type. | ||
// Use magic number to separate unrelated chunks of data. | ||
const uint32_t kMagicSeparator = 0xffff9296; |
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.
Low level comment: This magic number mechanism is fragile. Better to push a kv.second.size() then its contents.
(But really we should not care about duplication of decorations.)
source/val/validation_state.cpp
Outdated
@@ -425,6 +426,25 @@ bool ValidationState_t::RegisterUniqueTypeDeclaration( | |||
key.insert(key.end(), inst.words + words_begin, inst.words + words_end); | |||
} | |||
|
|||
// If module has extension SPV_KHR_variable_pointers, then OpTypePointer | |||
// is allowed to create identical types so long as their decorations differ. |
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.
Looking again, this is not the rule.
The SPV_KHR_variable_pointers extension says
Pointer types are also allowed to have multiple id's for the same opcode and operands, to allow for differing ArrayStride Array Stride decoration values.
Also, in that paragraph, "non-aggregate types" will then generally be "non-aggregate non-pointer types."
From 2.8 in the SPIR-V spec:
It is valid to declare multiple aggregate type s having the same opcode and operands. This is to allow multiple instances of aggregate types with the same structure to be decorated differently. (Different decorations are not required; two different aggregate type ids are allowed to have identical declarations and decorations, and will still be two different types.)
That means the validator should allow distinct OpTypePointer with the same operands, and with the same decorations.
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.
So I think all this new code boils down to:
if (inst.opcode == SpvOpTypePointer && HasExtension....) return true;
Even better: put the check up in the callee, along with the aggregate types. That is, modify TypeUniquePass to do the pointer-and-has-extension check.
Ready for review. |
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.
Aside from being correct, this is even cleaner.
LGTM, and thanks.
Hmm. Except that the commit message was inaccurate. I'll fix it on the rebase. |
Rebased, squashed, and pushed into master as 725284c |
SPV_KHR_variable_pointers allows OpTypePointer to declare multiple
identical types
#781