@@ -4316,7 +4316,7 @@ TEST_F(ValidateCFG, StructuredSelections_RegisterBothTrueAndFalse) {
43164316 OpMemoryModel Logical Simple
43174317 OpEntryPoint Fragment %main "main"
43184318 OpExecutionMode %main OriginUpperLeft
4319-
4319+
43204320 %void = OpTypeVoid
43214321 %void_fn = OpTypeFunction %void
43224322
@@ -5241,6 +5241,156 @@ OpFunctionEnd
52415241 EXPECT_EQ (SPV_SUCCESS, ValidateInstructions ());
52425242}
52435243
5244+ TEST_F (ValidateCFG, LifetimeGood) {
5245+ const std::string text = R"(
5246+ OpCapability Kernel
5247+ OpCapability Addresses
5248+ OpCapability Int64
5249+ OpCapability Int8
5250+ OpMemoryModel Physical64 OpenCL
5251+ OpEntryPoint Kernel %func "main"
5252+ OpExecutionMode %func ContractionOff
5253+ OpDecorate %24 Alignment 4
5254+ %uint = OpTypeInt 32 0
5255+ %void = OpTypeVoid
5256+ %5 = OpTypeFunction %void
5257+ %ulong = OpTypeInt 64 0
5258+ %uint_4 = OpConstant %uint 4
5259+ %_arr_uint_4 = OpTypeArray %uint %uint_4
5260+ %_ptr_arr_uint_4 = OpTypePointer Function %_arr_uint_4
5261+ %uchar = OpTypeInt 8 0
5262+ %_ptr_uchar = OpTypePointer Function %uchar
5263+ %14 = OpTypeFunction %void %_ptr_uchar
5264+ %_ptr_uint = OpTypePointer Function %uint
5265+ %bool = OpTypeBool
5266+ %uint_n = OpConstantNull %uint
5267+ %uint_1 = OpConstant %uint 1
5268+ %func = OpFunction %void None %5
5269+ %52 = OpLabel
5270+ %24 = OpVariable %_ptr_arr_uint_4 Function
5271+ %28 = OpSGreaterThan %bool %uint_1 %uint_n
5272+ OpBranchConditional %28 %53 %54
5273+ %53 = OpLabel
5274+ %29 = OpBitcast %_ptr_uchar %24
5275+
5276+ OpLifetimeStart %29 16
5277+ %30 = OpBitcast %_ptr_uint %24
5278+ OpStore %30 %uint_1 Aligned 4
5279+ %36 = OpBitcast %_ptr_uchar %24
5280+ OpLifetimeStop %36 16
5281+
5282+ OpBranch %54
5283+ %54 = OpLabel
5284+ OpReturn
5285+ OpFunctionEnd
5286+ )" ;
5287+
5288+ CompileSuccessfully (text);
5289+ EXPECT_EQ (SPV_SUCCESS, ValidateInstructions ());
5290+ }
5291+
5292+ TEST_F (ValidateCFG, LifetimeStorageClass) {
5293+ const std::string text = R"(
5294+ OpCapability Kernel
5295+ OpCapability Addresses
5296+ OpCapability Int64
5297+ OpCapability Int8
5298+ OpMemoryModel Physical64 OpenCL
5299+ OpEntryPoint Kernel %func "main"
5300+ OpExecutionMode %func ContractionOff
5301+ OpDecorate %24 Alignment 4
5302+ %uint = OpTypeInt 32 0
5303+ %void = OpTypeVoid
5304+ %5 = OpTypeFunction %void
5305+ %ulong = OpTypeInt 64 0
5306+ %uint_4 = OpConstant %uint 4
5307+ %_arr_uint_4 = OpTypeArray %uint %uint_4
5308+ %_ptr_arr_uint_4 = OpTypePointer Function %_arr_uint_4
5309+ %uchar = OpTypeInt 8 0
5310+ %_ptr_uchar = OpTypePointer CrossWorkgroup %uchar
5311+ %14 = OpTypeFunction %void %_ptr_uchar
5312+ %_ptr_uint = OpTypePointer Function %uint
5313+ %bool = OpTypeBool
5314+ %uint_n = OpConstantNull %uint
5315+ %uint_1 = OpConstant %uint 1
5316+ %func = OpFunction %void None %5
5317+ %52 = OpLabel
5318+ %24 = OpVariable %_ptr_arr_uint_4 Function
5319+ %28 = OpSGreaterThan %bool %uint_1 %uint_n
5320+ OpBranchConditional %28 %53 %54
5321+ %53 = OpLabel
5322+ %29 = OpBitcast %_ptr_uchar %24
5323+
5324+ OpLifetimeStart %29 16
5325+ %30 = OpBitcast %_ptr_uint %24
5326+ OpStore %30 %uint_1 Aligned 4
5327+ %36 = OpBitcast %_ptr_uchar %24
5328+ OpLifetimeStop %36 16
5329+
5330+ OpBranch %54
5331+ %54 = OpLabel
5332+ OpReturn
5333+ OpFunctionEnd
5334+ )" ;
5335+
5336+ CompileSuccessfully (text);
5337+ EXPECT_EQ (SPV_ERROR_INVALID_DATA, ValidateInstructions ());
5338+ EXPECT_THAT (getDiagnosticString (),
5339+ HasSubstr (" OpLifetimeStart pointer operand must be in the "
5340+ " Function storage class" ));
5341+ }
5342+
5343+ TEST_F (ValidateCFG, LifetimeNonPointer) {
5344+ const std::string text = R"(
5345+ OpCapability Kernel
5346+ OpCapability Addresses
5347+ OpCapability Int64
5348+ OpCapability Int8
5349+ OpMemoryModel Physical64 OpenCL
5350+ OpEntryPoint Kernel %func "main"
5351+ OpExecutionMode %func ContractionOff
5352+ OpDecorate %24 Alignment 4
5353+ %uint = OpTypeInt 32 0
5354+ %void = OpTypeVoid
5355+ %5 = OpTypeFunction %void
5356+ %ulong = OpTypeInt 64 0
5357+ %uint_4 = OpConstant %uint 4
5358+ %_arr_uint_4 = OpTypeArray %uint %uint_4
5359+ %_ptr_arr_uint_4 = OpTypePointer Function %_arr_uint_4
5360+ %uchar = OpTypeInt 8 0
5361+ %_ptr_uchar = OpTypePointer Function %uchar
5362+ %14 = OpTypeFunction %void %_ptr_uchar
5363+ %_ptr_uint = OpTypePointer Function %uint
5364+ %bool = OpTypeBool
5365+ %uint_n = OpConstantNull %uint
5366+ %uint_1 = OpConstant %uint 1
5367+ %func = OpFunction %void None %5
5368+ %52 = OpLabel
5369+ %24 = OpVariable %_ptr_arr_uint_4 Function
5370+ %28 = OpSGreaterThan %bool %uint_1 %uint_n
5371+ OpBranchConditional %28 %53 %54
5372+ %53 = OpLabel
5373+
5374+ OpLifetimeStart %28 16
5375+ %30 = OpBitcast %_ptr_uint %24
5376+ OpStore %30 %uint_1 Aligned 4
5377+ %36 = OpBitcast %_ptr_uchar %24
5378+ OpLifetimeStop %36 16
5379+
5380+ OpBranch %54
5381+ %54 = OpLabel
5382+ OpReturn
5383+ OpFunctionEnd
5384+ )" ;
5385+
5386+ CompileSuccessfully (text);
5387+ EXPECT_EQ (SPV_ERROR_INVALID_DATA, ValidateInstructions ());
5388+ EXPECT_THAT (
5389+ getDiagnosticString (),
5390+ HasSubstr (
5391+ " OpLifetimeStart pointer operand type must be a OpTypePointer" ));
5392+ }
5393+
52445394} // namespace
52455395} // namespace val
52465396} // namespace spvtools
0 commit comments