KhronosGroup / SPIRV-Tools

Apache License 2.0
1.08k stars 555 forks source link

Validate variable pointer container restrictions #2107

Open alan-baker opened 5 years ago

alan-baker commented 5 years ago

A variable pointer with the Logical addressing model cannot

  • be an operand to an OpArrayLength instruction
  • point to an object that is or contains any OpTypeMatrix types
sarahM0 commented 5 years ago

By the rule "be an operand to an OpArrayLength instruction" do we mean such this test should fail? if not could you give an example that is invalid according this rule.

TEST_F(ValidateMemory, ArrayLenCorrectResultType) { std::string spirv = R"( OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %1 "main" OpExecutionMode %1 OriginUpperLeft %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 %uint = OpTypeInt 32 0 %_runtimearr_float = OpTypeRuntimeArray %float %_struct_7 = OpTypeStruct %_runtimearr_float %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 %1 = OpFunction %void None %3 %9 = OpLabel %10 = OpVariable %_ptr_Function__struct_7 Function %11 = OpArrayLength %uint %10 0 OpReturn OpFunctionEnd

)";

CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); }

alan-baker commented 5 years ago

The test you quote does pass a variable pointer to the OpArrayLength instruction so it is fine. An invalid example is:

OpCapability Shader
OpCapability VariablePointersStorageBuffer
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode LocalSize 1 1 1
OpDecorate %block Block
OpMemberDecorate %block 0 Offset 0
%void = OpTypeVoid
%int = OpTypeInt 32 0
%block = OpTypeStruct %int
%ptr_ssbo_block = OpTypePointer StorageBuffer %block
%null = OpConstantNull %ptr_ssbo_block
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%length = OpArrayLength %int %null 0
OpReturn
OpFunctionEnd

That is the simplest variable pointer you can generate.

sarahM0 commented 5 years ago

The test you quote has another issue since in the OpArrayLength spec it says: Structure must be a pointer to an OpTypeStruct whose last member is a run-time array.
As a result it is incorrect to pass a variable pointer to a OpArrayLength instruction and the rule "be an operand to an OpArrayLength instruction" is implicitly implemented. Does this make sense?

alan-baker commented 5 years ago

Sorry, my example should have had an OpTypeRuntimeArray %int as its member. In that case I don't see that we catch it.