spirv-val: Better error message when types are the same (#6427)
> OpAccessChain result type (OpTypeInt) does not match the type that
results from indexing into the base <id> (OpTypeInt).
This was confusing, Ideally we could print out the 2 `OpTypeInt`, but
for a short "better quality of life" fix, just made the message point
out what is likely going on
diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp
index 1225722..d33c3c2 100644
--- a/source/val/validate_memory.cpp
+++ b/source/val/validate_memory.cpp
@@ -1847,13 +1847,19 @@
// At this point, we have fully walked down from the base using the indeces.
// The type being pointed to should be the same as the result type.
if (type_pointee->id() != result_type_pointee->id()) {
+ bool same_type = result_type_pointee->opcode() == type_pointee->opcode();
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "Op" << spvOpcodeString(opcode) << " result type (Op"
+ << "Op" << spvOpcodeString(opcode) << " result type <id> "
+ << _.getIdName(result_type_pointee->id()) << " (Op"
<< spvOpcodeString(result_type_pointee->opcode())
<< ") does not match the type that results from indexing into the "
"base "
- "<id> (Op"
- << spvOpcodeString(type_pointee->opcode()) << ").";
+ "<id> "
+ << _.getIdName(type_pointee->id()) << " (Op"
+ << spvOpcodeString(type_pointee->opcode()) << ")."
+ << (same_type ? " (The types must be the exact same Id, so the "
+ "two types referenced are slighlty different)"
+ : "");
}
}
diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp
index 20f6560..0fc3aea 100644
--- a/test/val/val_id_test.cpp
+++ b/test/val/val_id_test.cpp
@@ -4176,10 +4176,46 @@
getValidatorOptions()->relax_logical_pointer = true;
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
- EXPECT_THAT(
- getDiagnosticString(),
- HasSubstr("result type (OpTypeMatrix) does not match the type that "
- "results from indexing into the base <id> (OpTypeFloat)."));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("result type <id> '6[%mat4v3float]' (OpTypeMatrix) "
+ "does not match the type that results from indexing "
+ "into the base <id> '4[%float]' (OpTypeFloat)"));
+}
+
+TEST_P(AccessChainInstructionTest, AccessChainDifferentIntTypes) {
+ std::string spirv = R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %_
+ OpExecutionMode %main LocalSize 1 1 1
+ OpDecorate %_arr_uint_uint_32 ArrayStride 4
+ OpDecorate %SSBO Block
+ OpMemberDecorate %SSBO 0 Offset 0
+ OpDecorate %_ Binding 0
+ OpDecorate %_ DescriptorSet 0
+ %void = OpTypeVoid
+ %4 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %uint_32 = OpConstant %uint 32
+%_arr_uint_uint_32 = OpTypeArray %uint %uint_32
+ %SSBO = OpTypeStruct %_arr_uint_uint_32
+%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO
+ %_ = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %uint_1 = OpConstant %uint 1
+%ptr_ssbo_int = OpTypePointer StorageBuffer %int
+ %main = OpFunction %void None %4
+ %6 = OpLabel
+ %18 = OpAccessChain %ptr_ssbo_int %_ %int_0 %int_0
+ OpReturn
+ OpFunctionEnd
+ )";
+ CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("The types must be the exact same Id, so the two types "
+ "referenced are slighlty different"));
}
// Valid: 255 indexes passed to the access chain instruction. Limit is 255.
@@ -4375,10 +4411,11 @@
OpReturn
OpFunctionEnd
)";
- const std::string expected_err = instr +
- " result type (OpTypeFloat) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeVector).";
+ const std::string expected_err =
+ instr +
+ " result type <id> '4[%float]' (OpTypeFloat) does not match the type "
+ "that results from indexing into the base <id> '18[%v4float]' "
+ "(OpTypeVector).";
getValidatorOptions()->relax_logical_pointer = true;
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
@@ -4532,10 +4569,11 @@
OpReturn
OpFunctionEnd
)";
- const std::string expected_err = instr +
- " result type (OpTypeMatrix) does not match "
- "the type that results from indexing into "
- "the base <id> (OpTypeFloat).";
+ const std::string expected_err =
+ instr +
+ " result type <id> '6[%mat4v3float]' (OpTypeMatrix) does not match the "
+ "type that results from indexing into the base <id> '4[%float]' "
+ "(OpTypeFloat).";
getValidatorOptions()->relax_logical_pointer = true;
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());