Updated spirv-tools.

This commit is contained in:
Бранимир Караџић
2019-09-14 07:09:33 -07:00
parent 2422047044
commit afff54d782
96 changed files with 2623 additions and 1250 deletions

View File

@@ -131,7 +131,6 @@ SPVTOOLS_OPT_SRC_FILES := \
source/opt/local_redundancy_elimination.cpp \
source/opt/local_single_block_elim_pass.cpp \
source/opt/local_single_store_elim_pass.cpp \
source/opt/local_ssa_elim_pass.cpp \
source/opt/loop_dependence.cpp \
source/opt/loop_dependence_helpers.cpp \
source/opt/loop_descriptor.cpp \

View File

@@ -565,8 +565,6 @@ static_library("spvtools_opt") {
"source/opt/local_single_block_elim_pass.h",
"source/opt/local_single_store_elim_pass.cpp",
"source/opt/local_single_store_elim_pass.h",
"source/opt/local_ssa_elim_pass.cpp",
"source/opt/local_ssa_elim_pass.h",
"source/opt/log.h",
"source/opt/loop_dependence.cpp",
"source/opt/loop_dependence.h",

View File

@@ -1 +1 @@
"v2019.5-dev", "SPIRV-Tools v2019.5-dev v2019.4-37-g76261e2a"
"v2019.5-dev", "SPIRV-Tools v2019.5-dev v2019.4-51-g1e146e8a"

View File

@@ -1,7 +1,7 @@
static const SpvCapability pygen_variable_caps_Addresses[] = {SpvCapabilityAddresses};
static const SpvCapability pygen_variable_caps_AddressesPhysicalStorageBufferAddressesEXT[] = {SpvCapabilityAddresses, SpvCapabilityPhysicalStorageBufferAddressesEXT};
static const SpvCapability pygen_variable_caps_AddressesPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBuffer[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer};
static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddressesEXT[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer, SpvCapabilityPhysicalStorageBufferAddressesEXT};
static const SpvCapability pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses[] = {SpvCapabilityAddresses, SpvCapabilityVariablePointers, SpvCapabilityVariablePointersStorageBuffer, SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_CooperativeMatrixNV[] = {SpvCapabilityCooperativeMatrixNV};
static const SpvCapability pygen_variable_caps_DemoteToHelperInvocationEXT[] = {SpvCapabilityDemoteToHelperInvocationEXT};
static const SpvCapability pygen_variable_caps_DerivativeControl[] = {SpvCapabilityDerivativeControl};
@@ -97,7 +97,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"TypeReserveId", SpvOpTypeReserveId, 1, pygen_variable_caps_Pipes, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeQueue", SpvOpTypeQueue, 1, pygen_variable_caps_DeviceEnqueue, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypePipe", SpvOpTypePipe, 1, pygen_variable_caps_Pipes, 2, {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ACCESS_QUALIFIER}, 1, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeForwardPointer", SpvOpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddressesEXT, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TypeForwardPointer", SpvOpTypeForwardPointer, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantTrue", SpvOpConstantTrue, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConstantFalse", SpvOpConstantFalse, 0, nullptr, 2, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Constant", SpvOpConstant, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
@@ -121,7 +121,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"CopyMemorySized", SpvOpCopyMemorySized, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AccessChain", SpvOpAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"InBoundsAccessChain", SpvOpInBoundsAccessChain, 0, nullptr, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PtrAccessChain", SpvOpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddressesEXT, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PtrAccessChain", SpvOpPtrAccessChain, 4, pygen_variable_caps_AddressesVariablePointersVariablePointersStorageBufferPhysicalStorageBufferAddresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ArrayLength", SpvOpArrayLength, 1, pygen_variable_caps_Shader, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericPtrMemSemantics", SpvOpGenericPtrMemSemantics, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"InBoundsPtrAccessChain", SpvOpInBoundsPtrAccessChain, 1, pygen_variable_caps_Addresses, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
@@ -168,10 +168,10 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"SConvert", SpvOpSConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"FConvert", SpvOpFConvert, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"QuantizeToF16", SpvOpQuantizeToF16, 0, nullptr, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertPtrToU", SpvOpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddressesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertPtrToU", SpvOpConvertPtrToU, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SatConvertSToU", SpvOpSatConvertSToU, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"SatConvertUToS", SpvOpSatConvertUToS, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertUToPtr", SpvOpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddressesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ConvertUToPtr", SpvOpConvertUToPtr, 2, pygen_variable_caps_AddressesPhysicalStorageBufferAddresses, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PtrCastToGeneric", SpvOpPtrCastToGeneric, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericCastToPtr", SpvOpGenericCastToPtr, 1, pygen_variable_caps_Kernel, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GenericCastToPtrExplicit", SpvOpGenericCastToPtrExplicit, 1, pygen_variable_caps_Kernel, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_STORAGE_CLASS}, 1, 1, 0, nullptr, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},

View File

@@ -268,6 +268,10 @@ const char* CapabilityToString(SpvCapability capability) {
return "GroupNonUniformClustered";
case SpvCapabilityGroupNonUniformQuad:
return "GroupNonUniformQuad";
case SpvCapabilityShaderLayer:
return "ShaderLayer";
case SpvCapabilityShaderViewportIndex:
return "ShaderViewportIndex";
case SpvCapabilitySubgroupBallotKHR:
return "SubgroupBallotKHR";
case SpvCapabilityDrawParameters:
@@ -348,38 +352,38 @@ const char* CapabilityToString(SpvCapability capability) {
return "FragmentDensityEXT";
case SpvCapabilityGroupNonUniformPartitionedNV:
return "GroupNonUniformPartitionedNV";
case SpvCapabilityShaderNonUniformEXT:
return "ShaderNonUniformEXT";
case SpvCapabilityRuntimeDescriptorArrayEXT:
return "RuntimeDescriptorArrayEXT";
case SpvCapabilityInputAttachmentArrayDynamicIndexingEXT:
return "InputAttachmentArrayDynamicIndexingEXT";
case SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT:
return "UniformTexelBufferArrayDynamicIndexingEXT";
case SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT:
return "StorageTexelBufferArrayDynamicIndexingEXT";
case SpvCapabilityUniformBufferArrayNonUniformIndexingEXT:
return "UniformBufferArrayNonUniformIndexingEXT";
case SpvCapabilitySampledImageArrayNonUniformIndexingEXT:
return "SampledImageArrayNonUniformIndexingEXT";
case SpvCapabilityStorageBufferArrayNonUniformIndexingEXT:
return "StorageBufferArrayNonUniformIndexingEXT";
case SpvCapabilityStorageImageArrayNonUniformIndexingEXT:
return "StorageImageArrayNonUniformIndexingEXT";
case SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT:
return "InputAttachmentArrayNonUniformIndexingEXT";
case SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT:
return "UniformTexelBufferArrayNonUniformIndexingEXT";
case SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT:
return "StorageTexelBufferArrayNonUniformIndexingEXT";
case SpvCapabilityShaderNonUniform:
return "ShaderNonUniform";
case SpvCapabilityRuntimeDescriptorArray:
return "RuntimeDescriptorArray";
case SpvCapabilityInputAttachmentArrayDynamicIndexing:
return "InputAttachmentArrayDynamicIndexing";
case SpvCapabilityUniformTexelBufferArrayDynamicIndexing:
return "UniformTexelBufferArrayDynamicIndexing";
case SpvCapabilityStorageTexelBufferArrayDynamicIndexing:
return "StorageTexelBufferArrayDynamicIndexing";
case SpvCapabilityUniformBufferArrayNonUniformIndexing:
return "UniformBufferArrayNonUniformIndexing";
case SpvCapabilitySampledImageArrayNonUniformIndexing:
return "SampledImageArrayNonUniformIndexing";
case SpvCapabilityStorageBufferArrayNonUniformIndexing:
return "StorageBufferArrayNonUniformIndexing";
case SpvCapabilityStorageImageArrayNonUniformIndexing:
return "StorageImageArrayNonUniformIndexing";
case SpvCapabilityInputAttachmentArrayNonUniformIndexing:
return "InputAttachmentArrayNonUniformIndexing";
case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing:
return "UniformTexelBufferArrayNonUniformIndexing";
case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing:
return "StorageTexelBufferArrayNonUniformIndexing";
case SpvCapabilityRayTracingNV:
return "RayTracingNV";
case SpvCapabilityVulkanMemoryModelKHR:
return "VulkanMemoryModelKHR";
case SpvCapabilityVulkanMemoryModelDeviceScopeKHR:
return "VulkanMemoryModelDeviceScopeKHR";
case SpvCapabilityPhysicalStorageBufferAddressesEXT:
return "PhysicalStorageBufferAddressesEXT";
case SpvCapabilityVulkanMemoryModel:
return "VulkanMemoryModel";
case SpvCapabilityVulkanMemoryModelDeviceScope:
return "VulkanMemoryModelDeviceScope";
case SpvCapabilityPhysicalStorageBufferAddresses:
return "PhysicalStorageBufferAddresses";
case SpvCapabilityComputeDerivativeGroupLinearNV:
return "ComputeDerivativeGroupLinearNV";
case SpvCapabilityCooperativeMatrixNV:

View File

@@ -19,6 +19,7 @@ static const SpvCapability pygen_variable_caps_FragmentShaderShadingRateInterloc
static const SpvCapability pygen_variable_caps_GenericPointer[] = {SpvCapabilityGenericPointer};
static const SpvCapability pygen_variable_caps_Geometry[] = {SpvCapabilityGeometry};
static const SpvCapability pygen_variable_caps_GeometryMeshShadingNV[] = {SpvCapabilityGeometry, SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXT[] = {SpvCapabilityGeometry, SpvCapabilityShaderLayer, SpvCapabilityShaderViewportIndexLayerEXT};
static const SpvCapability pygen_variable_caps_GeometryTessellation[] = {SpvCapabilityGeometry, SpvCapabilityTessellation};
static const SpvCapability pygen_variable_caps_GeometryTessellationMeshShadingNV[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_GeometryTessellationRayTracingNV[] = {SpvCapabilityGeometry, SpvCapabilityTessellation, SpvCapabilityRayTracingNV};
@@ -29,10 +30,10 @@ static const SpvCapability pygen_variable_caps_GroupNonUniformClustered[] = {Spv
static const SpvCapability pygen_variable_caps_GroupNonUniformPartitionedNV[] = {SpvCapabilityGroupNonUniformPartitionedNV};
static const SpvCapability pygen_variable_caps_ImageBasic[] = {SpvCapabilityImageBasic};
static const SpvCapability pygen_variable_caps_ImageBuffer[] = {SpvCapabilityImageBuffer};
static const SpvCapability pygen_variable_caps_ImageBufferShaderNonUniformEXT[] = {SpvCapabilityImageBuffer, SpvCapabilityShaderNonUniformEXT};
static const SpvCapability pygen_variable_caps_ImageBufferShaderNonUniform[] = {SpvCapabilityImageBuffer, SpvCapabilityShaderNonUniform};
static const SpvCapability pygen_variable_caps_ImageGatherExtended[] = {SpvCapabilityImageGatherExtended};
static const SpvCapability pygen_variable_caps_InputAttachment[] = {SpvCapabilityInputAttachment};
static const SpvCapability pygen_variable_caps_InputAttachmentShaderNonUniformEXT[] = {SpvCapabilityInputAttachment, SpvCapabilityShaderNonUniformEXT};
static const SpvCapability pygen_variable_caps_InputAttachmentShaderNonUniform[] = {SpvCapabilityInputAttachment, SpvCapabilityShaderNonUniform};
static const SpvCapability pygen_variable_caps_Int64[] = {SpvCapabilityInt64};
static const SpvCapability pygen_variable_caps_Kernel[] = {SpvCapabilityKernel};
static const SpvCapability pygen_variable_caps_KernelGroupNonUniform[] = {SpvCapabilityKernel, SpvCapabilityGroupNonUniform};
@@ -44,8 +45,9 @@ static const SpvCapability pygen_variable_caps_MeshShadingNV[] = {SpvCapabilityM
static const SpvCapability pygen_variable_caps_MinLod[] = {SpvCapabilityMinLod};
static const SpvCapability pygen_variable_caps_MultiView[] = {SpvCapabilityMultiView};
static const SpvCapability pygen_variable_caps_MultiViewport[] = {SpvCapabilityMultiViewport};
static const SpvCapability pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXT[] = {SpvCapabilityMultiViewport, SpvCapabilityShaderViewportIndex, SpvCapabilityShaderViewportIndexLayerEXT};
static const SpvCapability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {SpvCapabilityPerViewAttributesNV, SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_PhysicalStorageBufferAddressesEXT[] = {SpvCapabilityPhysicalStorageBufferAddressesEXT};
static const SpvCapability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
static const SpvCapability pygen_variable_caps_RoundingModeRTE[] = {SpvCapabilityRoundingModeRTE};
@@ -57,7 +59,7 @@ static const SpvCapability pygen_variable_caps_Sampled1D[] = {SpvCapabilitySampl
static const SpvCapability pygen_variable_caps_Sampled1DImage1D[] = {SpvCapabilitySampled1D, SpvCapabilityImage1D};
static const SpvCapability pygen_variable_caps_SampledBuffer[] = {SpvCapabilitySampledBuffer};
static const SpvCapability pygen_variable_caps_SampledBufferImageBuffer[] = {SpvCapabilitySampledBuffer, SpvCapabilityImageBuffer};
static const SpvCapability pygen_variable_caps_SampledBufferShaderNonUniformEXT[] = {SpvCapabilitySampledBuffer, SpvCapabilityShaderNonUniformEXT};
static const SpvCapability pygen_variable_caps_SampledBufferShaderNonUniform[] = {SpvCapabilitySampledBuffer, SpvCapabilityShaderNonUniform};
static const SpvCapability pygen_variable_caps_SampledCubeArray[] = {SpvCapabilitySampledCubeArray};
static const SpvCapability pygen_variable_caps_SampledRect[] = {SpvCapabilitySampledRect};
static const SpvCapability pygen_variable_caps_SampledRectImageRect[] = {SpvCapabilitySampledRect, SpvCapabilityImageRect};
@@ -65,7 +67,7 @@ static const SpvCapability pygen_variable_caps_Shader[] = {SpvCapabilityShader};
static const SpvCapability pygen_variable_caps_ShaderImageCubeArray[] = {SpvCapabilityShader, SpvCapabilityImageCubeArray};
static const SpvCapability pygen_variable_caps_ShaderKernel[] = {SpvCapabilityShader, SpvCapabilityKernel};
static const SpvCapability pygen_variable_caps_ShaderKernelImageMSArray[] = {SpvCapabilityShader, SpvCapabilityKernel, SpvCapabilityImageMSArray};
static const SpvCapability pygen_variable_caps_ShaderNonUniformEXT[] = {SpvCapabilityShaderNonUniformEXT};
static const SpvCapability pygen_variable_caps_ShaderNonUniform[] = {SpvCapabilityShaderNonUniform};
static const SpvCapability pygen_variable_caps_ShaderSMBuiltinsNV[] = {SpvCapabilityShaderSMBuiltinsNV};
static const SpvCapability pygen_variable_caps_ShaderStereoViewNV[] = {SpvCapabilityShaderStereoViewNV};
static const SpvCapability pygen_variable_caps_ShaderViewportIndexLayerNV[] = {SpvCapabilityShaderViewportIndexLayerNV};
@@ -82,7 +84,7 @@ static const SpvCapability pygen_variable_caps_SubgroupDispatch[] = {SpvCapabili
static const SpvCapability pygen_variable_caps_Tessellation[] = {SpvCapabilityTessellation};
static const SpvCapability pygen_variable_caps_TransformFeedback[] = {SpvCapabilityTransformFeedback};
static const SpvCapability pygen_variable_caps_VariablePointersStorageBuffer[] = {SpvCapabilityVariablePointersStorageBuffer};
static const SpvCapability pygen_variable_caps_VulkanMemoryModelKHR[] = {SpvCapabilityVulkanMemoryModelKHR};
static const SpvCapability pygen_variable_caps_VulkanMemoryModel[] = {SpvCapabilityVulkanMemoryModel};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_gpu_shader_half_float_fetch[] = {spvtools::Extension::kSPV_AMD_gpu_shader_half_float_fetch};
static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_ballot[] = {spvtools::Extension::kSPV_AMD_shader_ballot};
@@ -97,7 +99,6 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_invocation
static const spvtools::Extension pygen_variable_exts_SPV_EXT_fragment_shader_interlock[] = {spvtools::Extension::kSPV_EXT_fragment_shader_interlock};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_stencil_export[] = {spvtools::Extension::kSPV_EXT_shader_stencil_export};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layer[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer};
static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_viewport_index_layerSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_EXT_shader_viewport_index_layer, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1[] = {spvtools::Extension::kSPV_GOOGLE_hlsl_functionality1};
static const spvtools::Extension pygen_variable_exts_SPV_GOOGLE_user_type[] = {spvtools::Extension::kSPV_GOOGLE_user_type};
@@ -128,15 +129,14 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_cooperative_matrix[]
static const spvtools::Extension pygen_variable_exts_SPV_NV_fragment_shader_barycentric[] = {spvtools::Extension::kSPV_NV_fragment_shader_barycentric};
static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_passthrough[] = {spvtools::Extension::kSPV_NV_geometry_shader_passthrough};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_mesh_shader, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_NV_sample_mask_override_coverage[] = {spvtools::Extension::kSPV_NV_sample_mask_override_coverage};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_sm_builtins[] = {spvtools::Extension::kSPV_NV_shader_sm_builtins};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shading_rateSPV_EXT_fragment_invocation_density[] = {spvtools::Extension::kSPV_NV_shading_rate, spvtools::Extension::kSPV_EXT_fragment_invocation_density};
static const spvtools::Extension pygen_variable_exts_SPV_NV_stereo_view_rendering[] = {spvtools::Extension::kSPV_NV_stereo_view_rendering};
static const spvtools::Extension pygen_variable_exts_SPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_NV_viewport_array2SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_viewport_array2, spvtools::Extension::kSPV_NV_mesh_shader};
static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = {
{"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
@@ -148,10 +148,14 @@ static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = {
{"ConstOffsets", 0x0020, 1, pygen_variable_caps_ImageGatherExtended, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Sample", 0x0040, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MinLod", 0x0080, 1, pygen_variable_caps_MinLod, 0, nullptr, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
{"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
{"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MakeTexelAvailable", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeTexelAvailableKHR", 0x0100, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeTexelVisible", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeTexelVisibleKHR", 0x0200, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"NonPrivateTexel", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"NonPrivateTexelKHR", 0x0400, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VolatileTexel", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VolatileTexelKHR", 0x0800, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"SignExtend", 0x1000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"ZeroExtend", 0x2000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu}
};
@@ -205,10 +209,13 @@ static const spv_operand_desc_t pygen_variable_MemorySemanticsEntries[] = {
{"CrossWorkgroupMemory", 0x0200, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AtomicCounterMemory", 0x0400, 1, pygen_variable_caps_AtomicStorage, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ImageMemory", 0x0800, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"Volatile", 0x8000, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
{"OutputMemory", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"OutputMemoryKHR", 0x1000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeAvailable", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeAvailableKHR", 0x2000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeVisible", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakeVisibleKHR", 0x4000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"Volatile", 0x8000, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = {
@@ -216,9 +223,12 @@ static const spv_operand_desc_t pygen_variable_MemoryAccessEntries[] = {
{"Volatile", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Aligned", 0x0002, 0, nullptr, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Nontemporal", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
{"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {SPV_OPERAND_TYPE_SCOPE_ID}, 0xffffffffu, 0xffffffffu},
{"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
{"MakePointerAvailable", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakePointerAvailableKHR", 0x0008, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakePointerVisible", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"MakePointerVisibleKHR", 0x0010, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {SPV_OPERAND_TYPE_SCOPE_ID}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"NonPrivatePointer", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"NonPrivatePointerKHR", 0x0020, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_KernelProfilingInfoEntries[] = {
@@ -257,14 +267,16 @@ static const spv_operand_desc_t pygen_variable_AddressingModelEntries[] = {
{"Logical", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Physical32", 1, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Physical64", 2, 1, pygen_variable_caps_Addresses, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu}
{"PhysicalStorageBuffer64", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"PhysicalStorageBuffer64EXT", 5348, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_MemoryModelEntries[] = {
{"Simple", 0, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"GLSL450", 1, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"OpenCL", 2, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
{"Vulkan", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanKHR", 3, 1, pygen_variable_caps_VulkanMemoryModel, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = {
@@ -346,7 +358,8 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = {
{"HitAttributeNV", 5339, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayPayloadNV", 5342, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"ShaderRecordBufferNV", 5343, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu}
{"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_DimEntries[] = {
@@ -546,9 +559,12 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = {
{"PerViewNV", 5272, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
{"PerTaskNV", 5273, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
{"PerVertexNV", 5285, 1, pygen_variable_caps_FragmentBarycentricNV, 1, pygen_variable_exts_SPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu},
{"NonUniformEXT", 5300, 1, pygen_variable_caps_ShaderNonUniformEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu},
{"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddressesEXT, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu},
{"NonUniform", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"NonUniformEXT", 5300, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RestrictPointer", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RestrictPointerEXT", 5355, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"AliasedPointer", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"AliasedPointerEXT", 5356, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"CounterBuffer", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"HlslCounterBufferGOOGLE", 5634, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu},
{"UserSemantic", 5635, 0, nullptr, 1, pygen_variable_exts_SPV_GOOGLE_hlsl_functionality1, {SPV_OPERAND_TYPE_LITERAL_STRING}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
@@ -565,8 +581,8 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
{"InstanceId", 6, 1, pygen_variable_caps_Shader, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"PrimitiveId", 7, 3, pygen_variable_caps_GeometryTessellationRayTracingNV, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"InvocationId", 8, 2, pygen_variable_caps_GeometryTessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Layer", 9, 1, pygen_variable_caps_Geometry, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ViewportIndex", 10, 1, pygen_variable_caps_MultiViewport, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Layer", 9, 3, pygen_variable_caps_GeometryShaderLayerShaderViewportIndexLayerEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"ViewportIndex", 10, 3, pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXT, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TessLevelOuter", 11, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TessLevelInner", 12, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"TessCoord", 13, 1, pygen_variable_caps_Tessellation, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
@@ -621,7 +637,7 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
{"BaryCoordSmoothSampleAMD", 4997, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu},
{"BaryCoordPullModelAMD", 4998, 0, nullptr, 1, pygen_variable_exts_SPV_AMD_shader_explicit_vertex_parameter, {}, 0xffffffffu, 0xffffffffu},
{"FragStencilRefEXT", 5014, 1, pygen_variable_caps_StencilExportEXT, 1, pygen_variable_exts_SPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu},
{"ViewportMaskNV", 5253, 2, pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV, 2, pygen_variable_exts_SPV_NV_viewport_array2SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
{"ViewportMaskNV", 5253, 2, pygen_variable_caps_ShaderViewportMaskNVMeshShadingNV, 2, pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2, {}, 0xffffffffu, 0xffffffffu},
{"SecondaryPositionNV", 5257, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu},
{"SecondaryViewportMaskNV", 5258, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {}, 0xffffffffu, 0xffffffffu},
{"PositionPerViewNV", 5261, 2, pygen_variable_caps_PerViewAttributesNVMeshShadingNV, 2, pygen_variable_exts_SPV_NVX_multiview_per_view_attributesSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu},
@@ -667,7 +683,8 @@ static const spv_operand_desc_t pygen_variable_ScopeEntries[] = {
{"Workgroup", 2, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Subgroup", 3, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Invocation", 4, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModelKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
{"QueueFamily", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"QueueFamilyKHR", 5, 1, pygen_variable_caps_VulkanMemoryModel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_GroupOperationEntries[] = {
@@ -754,6 +771,8 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"GroupNonUniformShuffleRelative", 66, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformClustered", 67, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"GroupNonUniformQuad", 68, 1, pygen_variable_caps_GroupNonUniform, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"ShaderLayer", 69, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"ShaderViewportIndex", 70, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu},
{"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"SubgroupVoteKHR", 4431, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, {}, 0xffffffffu, 0xffffffffu},
@@ -769,9 +788,9 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"VariablePointers", 4442, 1, pygen_variable_caps_VariablePointersStorageBuffer, 1, pygen_variable_exts_SPV_KHR_variable_pointers, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu},
{"AtomicStorageOps", 4445, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_atomic_counter_ops, {}, 0xffffffffu, 0xffffffffu},
{"SampleMaskPostDepthCoverage", 4447, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_post_depth_coverage, {}, 0xffffffffu, 0xffffffffu},
{"StorageBuffer8BitAccess", 4448, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, 0xffffffffu, 0xffffffffu},
{"UniformAndStorageBuffer8BitAccess", 4449, 1, pygen_variable_caps_StorageBuffer8BitAccess, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, 0xffffffffu, 0xffffffffu},
{"StoragePushConstant8", 4450, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, 0xffffffffu, 0xffffffffu},
{"StorageBuffer8BitAccess", 4448, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformAndStorageBuffer8BitAccess", 4449, 1, pygen_variable_caps_StorageBuffer8BitAccess, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StoragePushConstant8", 4450, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_8bit_storage, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"DenormPreserve", 4464, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"DenormFlushToZero", 4465, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
{"SignedZeroInfNanPreserve", 4466, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls, {}, SPV_SPIRV_VERSION_WORD(1,4), 0xffffffffu},
@@ -798,22 +817,37 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"FragmentDensityEXT", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu},
{"ShadingRateNV", 5291, 1, pygen_variable_caps_Shader, 2, pygen_variable_exts_SPV_EXT_fragment_invocation_densitySPV_NV_shading_rate, {}, 0xffffffffu, 0xffffffffu},
{"GroupNonUniformPartitionedNV", 5297, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_subgroup_partitioned, {}, 0xffffffffu, 0xffffffffu},
{"ShaderNonUniformEXT", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"RuntimeDescriptorArrayEXT", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"InputAttachmentArrayDynamicIndexingEXT", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"UniformTexelBufferArrayDynamicIndexingEXT", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"StorageTexelBufferArrayDynamicIndexingEXT", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"UniformBufferArrayNonUniformIndexingEXT", 5306, 1, pygen_variable_caps_ShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"SampledImageArrayNonUniformIndexingEXT", 5307, 1, pygen_variable_caps_ShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"StorageBufferArrayNonUniformIndexingEXT", 5308, 1, pygen_variable_caps_ShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"StorageImageArrayNonUniformIndexingEXT", 5309, 1, pygen_variable_caps_ShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"InputAttachmentArrayNonUniformIndexingEXT", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"UniformTexelBufferArrayNonUniformIndexingEXT", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniformEXT, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, 0xffffffffu, 0xffffffffu},
{"ShaderNonUniform", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"ShaderNonUniformEXT", 5301, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RuntimeDescriptorArray", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RuntimeDescriptorArrayEXT", 5302, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"InputAttachmentArrayDynamicIndexing", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"InputAttachmentArrayDynamicIndexingEXT", 5303, 1, pygen_variable_caps_InputAttachment, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformTexelBufferArrayDynamicIndexing", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformTexelBufferArrayDynamicIndexingEXT", 5304, 1, pygen_variable_caps_SampledBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayDynamicIndexing", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayDynamicIndexingEXT", 5305, 1, pygen_variable_caps_ImageBuffer, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformBufferArrayNonUniformIndexing", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformBufferArrayNonUniformIndexingEXT", 5306, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"SampledImageArrayNonUniformIndexing", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"SampledImageArrayNonUniformIndexingEXT", 5307, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageBufferArrayNonUniformIndexing", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageBufferArrayNonUniformIndexingEXT", 5308, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageImageArrayNonUniformIndexing", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageImageArrayNonUniformIndexingEXT", 5309, 1, pygen_variable_caps_ShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"InputAttachmentArrayNonUniformIndexing", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"InputAttachmentArrayNonUniformIndexingEXT", 5310, 2, pygen_variable_caps_InputAttachmentShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformTexelBufferArrayNonUniformIndexing", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"UniformTexelBufferArrayNonUniformIndexingEXT", 5311, 2, pygen_variable_caps_SampledBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexing", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RayTracingNV", 5340, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, 0xffffffffu, 0xffffffffu},
{"VulkanMemoryModelDeviceScopeKHR", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, 0xffffffffu, 0xffffffffu},
{"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, 0xffffffffu, 0xffffffffu},
{"VulkanMemoryModel", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanMemoryModelDeviceScope", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanMemoryModelDeviceScopeKHR", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"PhysicalStorageBufferAddresses", 5347, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"PhysicalStorageBufferAddressesEXT", 5347, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"ComputeDerivativeGroupLinearNV", 5350, 0, nullptr, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu},
{"CooperativeMatrixNV", 5357, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu},
{"FragmentShaderSampleInterlockEXT", 5363, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu},

View File

@@ -433,6 +433,7 @@ typedef enum {
SPV_ENV_WEBGPU_0, // Work in progress WebGPU 1.0.
SPV_ENV_UNIVERSAL_1_4, // SPIR-V 1.4 latest revision, no other restrictions.
SPV_ENV_VULKAN_1_1_SPIRV_1_4, // Vulkan 1.1 with SPIR-V 1.4 binary.
SPV_ENV_UNIVERSAL_1_5, // SPIR-V 1.5 latest revision, no other restrictions.
} spv_target_env;
// SPIR-V Validator can be parameterized with the following Universal Limits.

View File

@@ -84,6 +84,7 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable,
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_UNIVERSAL_1_5:
*pExtInstTable = &kTable_1_0;
return SPV_SUCCESS;
default:

View File

@@ -34,6 +34,7 @@ if(SPIRV_BUILD_FUZZER)
fuzzer_pass_add_dead_breaks.h
fuzzer_pass_add_dead_continues.h
fuzzer_pass_add_useful_constructs.h
fuzzer_pass_copy_objects.h
fuzzer_pass_obfuscate_constants.h
fuzzer_pass_permute_blocks.h
fuzzer_pass_split_blocks.h
@@ -69,6 +70,7 @@ if(SPIRV_BUILD_FUZZER)
fuzzer_pass_add_dead_breaks.cpp
fuzzer_pass_add_dead_continues.cpp
fuzzer_pass_add_useful_constructs.cpp
fuzzer_pass_copy_objects.cpp
fuzzer_pass_obfuscate_constants.cpp
fuzzer_pass_permute_blocks.cpp
fuzzer_pass_split_blocks.cpp

View File

@@ -22,6 +22,7 @@
#include "source/fuzz/fuzzer_pass_add_dead_breaks.h"
#include "source/fuzz/fuzzer_pass_add_dead_continues.h"
#include "source/fuzz/fuzzer_pass_add_useful_constructs.h"
#include "source/fuzz/fuzzer_pass_copy_objects.h"
#include "source/fuzz/fuzzer_pass_obfuscate_constants.h"
#include "source/fuzz/fuzzer_pass_permute_blocks.h"
#include "source/fuzz/fuzzer_pass_split_blocks.h"
@@ -107,6 +108,9 @@ Fuzzer::FuzzerResultStatus Fuzzer::Run(
.Apply();
// Apply some semantics-preserving passes.
FuzzerPassCopyObjects(ir_context.get(), &fact_manager, &fuzzer_context,
transformation_sequence_out)
.Apply();
FuzzerPassSplitBlocks(ir_context.get(), &fact_manager, &fuzzer_context,
transformation_sequence_out)
.Apply();

View File

@@ -26,6 +26,7 @@ namespace {
const uint32_t kDefaultChanceOfAddingDeadBreak = 20;
const uint32_t kDefaultChanceOfAddingDeadContinue = 20;
const uint32_t kDefaultChanceOfCopyingObject = 20;
const uint32_t kDefaultChanceOfMovingBlockDown = 25;
const uint32_t kDefaultChanceOfObfuscatingConstant = 20;
const uint32_t kDefaultChanceOfSplittingBlock = 20;
@@ -48,6 +49,7 @@ FuzzerContext::FuzzerContext(RandomGenerator* random_generator,
next_fresh_id_(min_fresh_id),
chance_of_adding_dead_break_(kDefaultChanceOfAddingDeadBreak),
chance_of_adding_dead_continue_(kDefaultChanceOfAddingDeadContinue),
chance_of_copying_object_(kDefaultChanceOfCopyingObject),
chance_of_moving_block_down_(kDefaultChanceOfMovingBlockDown),
chance_of_obfuscating_constant_(kDefaultChanceOfObfuscatingConstant),
chance_of_splitting_block_(kDefaultChanceOfSplittingBlock),
@@ -58,8 +60,11 @@ FuzzerContext::~FuzzerContext() = default;
uint32_t FuzzerContext::GetFreshId() { return next_fresh_id_++; }
RandomGenerator* FuzzerContext::GetRandomGenerator() {
return random_generator_;
bool FuzzerContext::ChooseEven() { return random_generator_->RandomBool(); }
bool FuzzerContext::ChoosePercentage(uint32_t percentage_chance) {
assert(percentage_chance <= 100);
return random_generator_->RandomPercentage() < percentage_chance;
}
} // namespace fuzz

View File

@@ -34,8 +34,22 @@ class FuzzerContext {
~FuzzerContext();
// Provides the random generator used to control fuzzing.
RandomGenerator* GetRandomGenerator();
// Returns a random boolean.
bool ChooseEven();
// Returns true if and only if a randomly-chosen integer in the range [0, 100]
// is less than |percentage_chance|.
bool ChoosePercentage(uint32_t percentage_chance);
// Returns a random index into |sequence|, which is expected to have a 'size'
// method, and which must be non-empty. Typically 'HasSizeMethod' will be an
// std::vector.
template <typename HasSizeMethod>
uint32_t RandomIndex(HasSizeMethod sequence) {
assert(sequence.size() > 0);
return random_generator_->RandomUint32(
static_cast<uint32_t>(sequence.size()));
}
// Yields an id that is guaranteed not to be used in the module being fuzzed,
// or to have been issued before.
@@ -47,17 +61,17 @@ class FuzzerContext {
uint32_t GetChanceOfAddingDeadContinue() {
return chance_of_adding_dead_continue_;
}
uint32_t GetChanceOfCopyingObject() { return chance_of_copying_object_; }
uint32_t GetChanceOfMovingBlockDown() { return chance_of_moving_block_down_; }
uint32_t GetChanceOfObfuscatingConstant() {
return chance_of_obfuscating_constant_;
}
uint32_t GetChanceOfSplittingBlock() { return chance_of_splitting_block_; }
// Probability distributions to control how deeply to recurse.
// Functions to control how deeply to recurse.
// Keep them in alphabetical order.
const std::function<bool(uint32_t, RandomGenerator*)>&
GoDeeperInConstantObfuscation() {
return go_deeper_in_constant_obfuscation_;
bool GoDeeperInConstantObfuscation(uint32_t depth) {
return go_deeper_in_constant_obfuscation_(depth, random_generator_);
}
private:
@@ -70,6 +84,7 @@ class FuzzerContext {
// Keep them in alphabetical order.
uint32_t chance_of_adding_dead_break_;
uint32_t chance_of_adding_dead_continue_;
uint32_t chance_of_copying_object_;
uint32_t chance_of_moving_block_down_;
uint32_t chance_of_obfuscating_constant_;
uint32_t chance_of_splitting_block_;

View File

@@ -51,8 +51,7 @@ void FuzzerPassAddDeadBreaks::Apply() {
// merge blocks. This will lead to interesting opportunities being
// missed.
auto candidate_transformation = TransformationAddDeadBreak(
block.id(), merge_block_id,
GetFuzzerContext()->GetRandomGenerator()->RandomBool(), {});
block.id(), merge_block_id, GetFuzzerContext()->ChooseEven(), {});
if (candidate_transformation.IsApplicable(GetIRContext(),
*GetFactManager())) {
// Only consider a transformation as a candidate if it is applicable.
@@ -77,16 +76,15 @@ void FuzzerPassAddDeadBreaks::Apply() {
while (!candidate_transformations.empty()) {
// Choose a random index into the sequence of remaining candidate
// transformations.
auto index = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(candidate_transformations.size()));
auto index = GetFuzzerContext()->RandomIndex(candidate_transformations);
// Remove the transformation at the chosen index from the sequence.
auto transformation = std::move(candidate_transformations[index]);
candidate_transformations.erase(candidate_transformations.begin() + index);
// Probabilistically decide whether to try to apply it vs. ignore it, in the
// case that it is applicable.
if (transformation.IsApplicable(GetIRContext(), *GetFactManager()) &&
GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfAddingDeadBreak()) {
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingDeadBreak())) {
transformation.Apply(GetIRContext(), GetFactManager());
*GetTransformations()->add_transformation() = transformation.ToMessage();
}

View File

@@ -40,14 +40,13 @@ void FuzzerPassAddDeadContinues::Apply() {
// merge blocks. This will lead to interesting opportunities being
// missed.
auto candidate_transformation = TransformationAddDeadContinue(
block.id(), GetFuzzerContext()->GetRandomGenerator()->RandomBool(),
{});
block.id(), GetFuzzerContext()->ChooseEven(), {});
// Probabilistically decide whether to apply the transformation in the
// case that it is applicable.
if (candidate_transformation.IsApplicable(GetIRContext(),
*GetFactManager()) &&
GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfAddingDeadContinue()) {
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingDeadContinue())) {
candidate_transformation.Apply(GetIRContext(), GetFactManager());
*GetTransformations()->add_transformation() =
candidate_transformation.ToMessage();

View File

@@ -0,0 +1,148 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/fuzz/fuzzer_pass_copy_objects.h"
#include "source/fuzz/transformation_copy_object.h"
namespace spvtools {
namespace fuzz {
FuzzerPassCopyObjects::FuzzerPassCopyObjects(
opt::IRContext* ir_context, FactManager* fact_manager,
FuzzerContext* fuzzer_context,
protobufs::TransformationSequence* transformations)
: FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {}
FuzzerPassCopyObjects::~FuzzerPassCopyObjects() = default;
void FuzzerPassCopyObjects::Apply() {
// Consider every block in every function.
for (auto& function : *GetIRContext()->module()) {
for (auto& block : function) {
// We now consider every instruction in the block, randomly deciding
// whether to add an object copy before the instruction.
// In order to insert an object copy instruction, we need to be able to
// identify the instruction a copy should be inserted before. We do this
// by tracking a base instruction, which must generate a result id, and an
// offset (to allow us to identify instructions that do not generate
// result ids).
// The initial base instruction is the block label.
uint32_t base = block.id();
uint32_t offset = 0;
// Consider every instruction in the block.
for (auto inst_it = block.begin(); inst_it != block.end(); ++inst_it) {
if (inst_it->HasResultId()) {
// In the case that the instruction has a result id, we use the
// instruction as its own base, with zero offset.
base = inst_it->result_id();
offset = 0;
} else {
// The instruction does not have a result id, so we need to identify
// it via the latest instruction that did have a result id (base), and
// an incremented offset.
offset++;
}
// Check whether it is legitimate to insert a copy before this
// instruction.
if (!TransformationCopyObject::CanInsertCopyBefore(inst_it)) {
continue;
}
// Randomly decide whether to try inserting an object copy here.
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfCopyingObject())) {
continue;
}
// Populate list of potential instructions that can be copied.
// TODO(afd) The following is (relatively) simple, but may end up being
// prohibitively inefficient, as it walks the whole dominator tree for
// every copy that is added.
std::vector<opt::Instruction*> copyable_instructions;
// Consider all global declarations
for (auto& global : GetIRContext()->module()->types_values()) {
if (TransformationCopyObject::IsCopyable(GetIRContext(), &global)) {
copyable_instructions.push_back(&global);
}
}
// Consider all previous instructions in this block
for (auto prev_inst_it = block.begin(); prev_inst_it != inst_it;
++prev_inst_it) {
if (TransformationCopyObject::IsCopyable(GetIRContext(),
&*prev_inst_it)) {
copyable_instructions.push_back(&*prev_inst_it);
}
}
// Walk the dominator tree to consider all instructions from dominating
// blocks
auto dominator_analysis =
GetIRContext()->GetDominatorAnalysis(&function);
for (auto next_dominator =
dominator_analysis->ImmediateDominator(&block);
next_dominator != nullptr;
next_dominator =
dominator_analysis->ImmediateDominator(next_dominator)) {
for (auto& dominating_inst : *next_dominator) {
if (TransformationCopyObject::IsCopyable(GetIRContext(),
&dominating_inst)) {
copyable_instructions.push_back(&dominating_inst);
}
}
}
// At this point, |copyable_instructions| contains all the instructions
// we might think of copying.
if (!copyable_instructions.empty()) {
// Choose a copyable instruction at random, and create and apply an
// object copying transformation based on it.
uint32_t index =
GetFuzzerContext()->RandomIndex(copyable_instructions);
TransformationCopyObject transformation(
copyable_instructions[index]->result_id(), base, offset,
GetFuzzerContext()->GetFreshId());
assert(
transformation.IsApplicable(GetIRContext(), *GetFactManager()) &&
"This transformation should be applicable by construction.");
transformation.Apply(GetIRContext(), GetFactManager());
*GetTransformations()->add_transformation() =
transformation.ToMessage();
if (!inst_it->HasResultId()) {
// We have inserted a new instruction before the current
// instruction, and we are tracking the current id-less instruction
// via an offset (offset) from a previous instruction (base) that
// has an id. We increment |offset| to reflect the newly-inserted
// instruction.
//
// This is slightly preferable to the alternative of setting |base|
// to be the result id of the new instruction, since on replay we
// might end up eliminating this copy but keeping a subsequent copy.
offset++;
}
}
}
}
}
}
} // namespace fuzz
} // namespace spvtools

View File

@@ -0,0 +1,38 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SOURCE_FUZZ_FUZZER_PASS_COPY_OBJECTS_H_
#define SOURCE_FUZZ_FUZZER_PASS_COPY_OBJECTS_H_
#include "source/fuzz/fuzzer_pass.h"
namespace spvtools {
namespace fuzz {
// A fuzzer pass for adding adding copies of objects to the module.
class FuzzerPassCopyObjects : public FuzzerPass {
public:
FuzzerPassCopyObjects(opt::IRContext* ir_context, FactManager* fact_manager,
FuzzerContext* fuzzer_context,
protobufs::TransformationSequence* transformations);
~FuzzerPassCopyObjects();
void Apply() override;
};
} // namespace fuzz
} // namespace spvtools
#endif // SOURCE_FUZZ_FUZZER_PASS_COPY_OBJECTS_H_

View File

@@ -48,14 +48,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
// a 'greater than' or 'less than' kind of opcode, and then select a
// random opcode from the resulting subset.
SpvOp comparison_opcode;
if (GetFuzzerContext()->GetRandomGenerator()->RandomBool()) {
comparison_opcode = greater_than_opcodes
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(greater_than_opcodes.size()))];
if (GetFuzzerContext()->ChooseEven()) {
comparison_opcode = greater_than_opcodes[GetFuzzerContext()->RandomIndex(
greater_than_opcodes)];
} else {
comparison_opcode = less_than_opcodes
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(less_than_opcodes.size()))];
comparison_opcode =
less_than_opcodes[GetFuzzerContext()->RandomIndex(less_than_opcodes)];
}
// We now need to decide how to order constant_id_1 and constant_id_2 such
@@ -103,8 +101,7 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
for (uint32_t index : {0u, 1u}) {
// We randomly decide, based on the current depth of obfuscation, whether
// to further obfuscate this operand.
if (GetFuzzerContext()->GoDeeperInConstantObfuscation()(
depth, GetFuzzerContext()->GetRandomGenerator())) {
if (GetFuzzerContext()->GoDeeperInConstantObfuscation(depth)) {
auto in_operand_use = transformation::MakeIdUseDescriptor(
binary_operator_instruction->GetSingleWordInOperand(index),
binary_operator_instruction->opcode(), index,
@@ -252,9 +249,9 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant(
// elements with known values.
return;
}
auto chosen_type_id = available_types_with_uniforms
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_types_with_uniforms.size()))];
auto chosen_type_id =
available_types_with_uniforms[GetFuzzerContext()->RandomIndex(
available_types_with_uniforms)];
auto available_constants =
GetFactManager()->GetConstantsAvailableFromUniformsForType(
GetIRContext(), chosen_type_id);
@@ -269,15 +266,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstant(
// We know we have at least two known-to-be-constant uniforms of the chosen
// type. Pick one of them at random.
auto constant_index_1 =
GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_constants.size()));
auto constant_index_1 = GetFuzzerContext()->RandomIndex(available_constants);
uint32_t constant_index_2;
// Now choose another one distinct from the first one.
do {
constant_index_2 = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(available_constants.size()));
constant_index_2 = GetFuzzerContext()->RandomIndex(available_constants);
} while (constant_index_1 == constant_index_2);
auto constant_id_1 = available_constants[constant_index_1];
@@ -321,9 +315,7 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant(
// Choose a random available uniform known to be equal to the constant.
protobufs::UniformBufferElementDescriptor uniform_descriptor =
uniform_descriptors
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(uniform_descriptors.size()))];
uniform_descriptors[GetFuzzerContext()->RandomIndex(uniform_descriptors)];
// Create, apply and record a transformation to replace the constant use with
// the result of a load from the chosen uniform.
auto transformation = TransformationReplaceConstantWithUniform(
@@ -445,13 +437,12 @@ void FuzzerPassObfuscateConstants::Apply() {
// Go through the constant uses in a random order by repeatedly pulling out a
// constant use at a random index.
while (!constant_uses.empty()) {
auto index = GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(constant_uses.size()));
auto index = GetFuzzerContext()->RandomIndex(constant_uses);
auto constant_use = std::move(constant_uses[index]);
constant_uses.erase(constant_uses.begin() + index);
// Decide probabilistically whether to skip or obfuscate this constant use.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfObfuscatingConstant()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfObfuscatingConstant())) {
continue;
}
ObfuscateConstant(0, constant_use);

View File

@@ -57,8 +57,8 @@ void FuzzerPassPermuteBlocks::Apply() {
// would provide more freedom for A to move.
for (auto id = block_ids.rbegin(); id != block_ids.rend(); ++id) {
// Randomly decide whether to ignore the block id.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfMovingBlockDown()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfMovingBlockDown())) {
continue;
}
// Keep pushing the block down, until pushing down fails.

View File

@@ -44,8 +44,9 @@ void FuzzerPassSplitBlocks::Apply() {
// Now go through all the block pointers that were gathered.
for (auto& block : blocks) {
// Probabilistically decide whether to try to split this block.
if (GetFuzzerContext()->GetRandomGenerator()->RandomPercentage() >
GetFuzzerContext()->GetChanceOfSplittingBlock()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfSplittingBlock())) {
// We are not going to try to split this block.
continue;
}
// We are going to try to split this block. We now need to choose where
@@ -77,9 +78,8 @@ void FuzzerPassSplitBlocks::Apply() {
}
// Having identified all the places we might be able to split the block,
// we choose one of them.
auto base_offset = base_offset_pairs
[GetFuzzerContext()->GetRandomGenerator()->RandomUint32(
static_cast<uint32_t>(base_offset_pairs.size()))];
auto base_offset =
base_offset_pairs[GetFuzzerContext()->RandomIndex(base_offset_pairs)];
auto transformation =
TransformationSplitBlock(base_offset.first, base_offset.second,
GetFuzzerContext()->GetFreshId());

View File

@@ -205,6 +205,167 @@ opt::BasicBlock::iterator GetIteratorForBaseInstructionAndOffset(
return nullptr;
}
std::vector<uint32_t> GetSuccessors(opt::BasicBlock* block) {
std::vector<uint32_t> result;
switch (block->terminator()->opcode()) {
case SpvOpBranch:
result.push_back(block->terminator()->GetSingleWordInOperand(0));
break;
case SpvOpBranchConditional:
result.push_back(block->terminator()->GetSingleWordInOperand(1));
result.push_back(block->terminator()->GetSingleWordInOperand(2));
break;
case SpvOpSwitch:
for (uint32_t i = 1; i < block->terminator()->NumInOperands(); i += 2) {
result.push_back(block->terminator()->GetSingleWordInOperand(i));
}
break;
default:
break;
}
return result;
}
void FindBypassedBlocks(opt::IRContext* context, opt::BasicBlock* bb_from,
opt::BasicBlock* bb_to,
std::set<opt::BasicBlock*>* bypassed_blocks) {
// This algorithm finds all blocks different from |bb_from| that:
// - are in the innermost structured control flow construct containing
// |bb_from|
// - can be reached from |bb_from| without traversing a back-edge or going
// through |bb_to|
//
// This is achieved by doing a depth-first search of the function's CFG,
// exploring merge blocks before successors, and grabbing all blocks that are
// visited in the sub-search rooted at |bb_from|. (As an optimization, the
// search terminates as soon as exploration of |bb_from| has completed.)
// This represents a basic block in a partial state of exploration. As we
// wish to visit merge blocks in advance of regular successors, we track them
// separately.
struct StackNode {
opt::BasicBlock* block;
bool handled_merge;
std::vector<uint32_t> successors;
uint32_t next_successor;
};
auto enclosing_function = bb_from->GetParent();
// The set of block ids already visited during search. We put |bb_to| in
// there initially so that search automatically backtracks when this block is
// reached.
std::set<uint32_t> visited;
visited.insert(bb_to->id());
// Tracks when we are in the region of blocks that are to be grabbed; we flip
// this to 'true' once we reach |bb_from| and have finished searching its
// merge block (in the case that it happens to be a header.
bool interested = false;
std::vector<StackNode> dfs_stack;
opt::BasicBlock* entry_block = enclosing_function->entry().get();
dfs_stack.push_back({entry_block, false, GetSuccessors(entry_block), 0});
while (!dfs_stack.empty()) {
StackNode* node = &dfs_stack.back();
// First make sure we search the merge block associated ith this block, if
// there is one.
if (!node->handled_merge) {
node->handled_merge = true;
if (node->block->MergeBlockIdIfAny()) {
opt::BasicBlock* merge_block =
context->cfg()->block(node->block->MergeBlockIdIfAny());
// A block can only be the merge block for one header, so this block
// should only be in |visited| if it is |bb_to|, which we put into
// |visited| in advance.
assert(visited.count(merge_block->id()) == 0 || merge_block == bb_to);
if (visited.count(merge_block->id()) == 0) {
visited.insert(merge_block->id());
dfs_stack.push_back(
{merge_block, false, GetSuccessors(merge_block), 0});
}
}
continue;
}
// If we find |bb_from|, we are interested in grabbing previously unseen
// successor blocks (by this point we will have already searched the merge
// block associated with |bb_from|, if there is one.
if (node->block == bb_from) {
interested = true;
}
// Consider the next unexplored successor.
if (node->next_successor < node->successors.size()) {
uint32_t successor_id = node->successors[node->next_successor];
if (visited.count(successor_id) == 0) {
visited.insert(successor_id);
opt::BasicBlock* successor_block = context->cfg()->block(successor_id);
if (interested) {
// If we're in the region of interest, grab this block.
bypassed_blocks->insert(successor_block);
}
dfs_stack.push_back(
{successor_block, false, GetSuccessors(successor_block), 0});
}
node->next_successor++;
} else {
// We have finished exploring |node|. If it is |bb_from|, we can
// terminate search -- we have grabbed all the relevant blocks.
if (node->block == bb_from) {
break;
}
dfs_stack.pop_back();
}
}
}
bool NewEdgeLeavingConstructBodyRespectsUseDefDominance(
opt::IRContext* context, opt::BasicBlock* bb_from, opt::BasicBlock* bb_to) {
// Find those blocks that the edge from |bb_from| to |bb_to| might bypass.
std::set<opt::BasicBlock*> bypassed_blocks;
FindBypassedBlocks(context, bb_from, bb_to, &bypassed_blocks);
// For each bypassed block, check whether it contains a definition that is
// used by some non-bypassed block - that would be problematic.
for (auto defining_block : bypassed_blocks) {
for (auto& inst : *defining_block) {
if (!context->get_def_use_mgr()->WhileEachUse(
&inst,
[context, &bypassed_blocks](opt::Instruction* user,
uint32_t operand_index) -> bool {
// If this use is in an OpPhi, we need to check that dominance
// of the relevant *parent* block is not spoiled. Otherwise we
// need to check that dominance of the block containing the use
// is not spoiled.
opt::BasicBlock* use_block_or_phi_parent =
user->opcode() == SpvOpPhi
? context->cfg()->block(
user->GetSingleWordOperand(operand_index + 1))
: context->get_instr_block(user);
// There might not be any relevant block, e.g. if the use is in
// a decoration; in this case the new edge is unproblematic.
if (use_block_or_phi_parent == nullptr) {
return true;
}
// If the use-block is not in |bypassed_blocks| then we have
// found a block in the construct that is reachable from
// |from_block|, and which defines an id that is used outside of
// the construct. Adding an edge from |from_block| to
// |to_block| would prevent this use being dominated.
return bypassed_blocks.find(use_block_or_phi_parent) !=
bypassed_blocks.end();
})) {
return false;
}
}
}
return true;
}
} // namespace fuzzerutil
} // namespace fuzz

View File

@@ -74,6 +74,19 @@ bool BlockIsInLoopContinueConstruct(opt::IRContext* context, uint32_t block_id,
opt::BasicBlock::iterator GetIteratorForBaseInstructionAndOffset(
opt::BasicBlock* block, const opt::Instruction* base_inst, uint32_t offset);
// Block |bb_from| is assumed to be in a structured control flow construct, and
// block |bb_to| is assumed to be either the merge bock for that construct (in
// the case of a loop, conditional or switch) or the continue target for that
// construct (in the case of a loop only).
//
// The function determines whether adding an edge from |bb_from| to |bb_to| -
// i.e. a break or continue for the construct
// - is legitimate with respect to the SPIR-V rule that a definition must
// dominate all of its uses. This is because adding such an edge can change
// dominance in the control flow graph, potentially making the module invalid.
bool NewEdgeLeavingConstructBodyRespectsUseDefDominance(
opt::IRContext* context, opt::BasicBlock* bb_from, opt::BasicBlock* bb_to);
} // namespace fuzzerutil
} // namespace fuzz

View File

@@ -25,6 +25,7 @@
#include "transformation_add_type_float.h"
#include "transformation_add_type_int.h"
#include "transformation_add_type_pointer.h"
#include "transformation_copy_object.h"
#include "transformation_move_block_down.h"
#include "transformation_replace_boolean_constant_with_constant_binary.h"
#include "transformation_replace_constant_with_uniform.h"
@@ -59,6 +60,8 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
case protobufs::Transformation::TransformationCase::kAddTypePointer:
return MakeUnique<TransformationAddTypePointer>(
message.add_type_pointer());
case protobufs::Transformation::TransformationCase::kCopyObject:
return MakeUnique<TransformationCopyObject>(message.copy_object());
case protobufs::Transformation::TransformationCase::kMoveBlockDown:
return MakeUnique<TransformationMoveBlockDown>(message.move_block_down());
case protobufs::Transformation::TransformationCase::
@@ -71,13 +74,12 @@ std::unique_ptr<Transformation> Transformation::FromMessage(
message.replace_constant_with_uniform());
case protobufs::Transformation::TransformationCase::kSplitBlock:
return MakeUnique<TransformationSplitBlock>(message.split_block());
default:
assert(message.transformation_case() ==
protobufs::Transformation::TRANSFORMATION_NOT_SET &&
"Unhandled transformation type.");
case protobufs::Transformation::TRANSFORMATION_NOT_SET:
assert(false && "An unset transformation was encountered.");
return nullptr;
}
assert(false && "Should be unreachable as all cases must be handled above.");
return nullptr;
}
} // namespace fuzz

View File

@@ -162,9 +162,16 @@ bool TransformationAddDeadBreak::IsApplicable(
return false;
}
// Finally, check that adding the break would respect the rules of structured
// Check that adding the break would respect the rules of structured
// control flow.
return AddingBreakRespectsStructuredControlFlow(context, bb_from);
if (!AddingBreakRespectsStructuredControlFlow(context, bb_from)) {
return false;
}
// Check that adding the break would not violate the property that a
// definition must dominate all of its uses.
return fuzzerutil::NewEdgeLeavingConstructBodyRespectsUseDefDominance(
context, bb_from, bb_to);
}
void TransformationAddDeadBreak::Apply(opt::IRContext* context,

View File

@@ -48,6 +48,8 @@ class TransformationAddDeadBreak : public Transformation {
// the condition, and the ids in |message_.phi_ids| used to extend
// any OpPhi instructions at b as a result of the edge from a, must
// maintain validity of the module.
// In particular, the new branch must not lead to violations of the rule
// that a use must be dominated by its definition.
bool IsApplicable(opt::IRContext* context,
const FactManager& fact_manager) const override;

View File

@@ -98,6 +98,13 @@ bool TransformationAddDeadContinue::IsApplicable(
return false;
}
// Check that adding the continue would not violate the property that a
// definition must dominate all of its uses.
if (!fuzzerutil::NewEdgeLeavingConstructBodyRespectsUseDefDominance(
context, bb_from, context->cfg()->block(continue_block))) {
return false;
}
// The transformation is good if and only if the given phi ids are sufficient
// to extend relevant OpPhi instructions in the continue block.
return fuzzerutil::PhiIdsOkForNewEdge(context, bb_from,

View File

@@ -47,6 +47,9 @@ class TransformationAddDeadContinue : public Transformation {
// as the condition, and the ids in |message_.phi_ids| used to extend any
// OpPhi instructions at b as a result of the edge from a, must maintain
// validity of the module.
// In particular, adding an edge from somewhere in the loop to the continue
// target must not prevent uses of ids in the continue target from being
// dominated by the definitions of those ids.
bool IsApplicable(opt::IRContext* context,
const FactManager& fact_manager) const override;

View File

@@ -46,18 +46,7 @@ bool TransformationCopyObject::IsApplicable(
if (!object_inst) {
return false;
}
if (!object_inst->type_id()) {
// We can only apply OpCopyObject to instructions that have types.
return false;
}
if (!context->get_decoration_mgr()
->GetDecorationsFor(message_.object(), true)
.empty()) {
// We do not copy objects that have decorations: if the copy is not
// decorated analogously, using the original object vs. its copy may not be
// equivalent.
// TODO(afd): it would be possible to make the copy but not add an id
// synonym.
if (!IsCopyable(context, object_inst)) {
return false;
}
@@ -81,22 +70,11 @@ bool TransformationCopyObject::IsApplicable(
// The offset was inappropriate.
return false;
}
if (insert_before->PreviousNode() &&
(insert_before->PreviousNode()->opcode() == SpvOpLoopMerge ||
insert_before->PreviousNode()->opcode() == SpvOpSelectionMerge)) {
// We cannot insert a copy directly after a merge instruction.
return false;
}
if (insert_before->opcode() == SpvOpVariable) {
// We cannot insert a copy directly before a variable; variables in a
// function must be contiguous in the entry block.
return false;
}
// We cannot insert a copy directly before OpPhi, because OpPhi instructions
// need to be contiguous at the start of a block.
if (insert_before->opcode() == SpvOpPhi) {
if (!CanInsertCopyBefore(insert_before)) {
return false;
}
// |message_object| must be available at the point where we want to add the
// copy. It is available if it is at global scope (in which case it has no
// block), or if it dominates the point of insertion but is different from the
@@ -154,5 +132,43 @@ protobufs::Transformation TransformationCopyObject::ToMessage() const {
return result;
}
bool TransformationCopyObject::IsCopyable(opt::IRContext* ir_context,
opt::Instruction* inst) {
if (!inst->HasResultId()) {
// We can only apply OpCopyObject to instructions that generate ids.
return false;
}
if (!inst->type_id()) {
// We can only apply OpCopyObject to instructions that have types.
return false;
}
// We do not copy objects that have decorations: if the copy is not
// decorated analogously, using the original object vs. its copy may not be
// equivalent.
// TODO(afd): it would be possible to make the copy but not add an id
// synonym.
return ir_context->get_decoration_mgr()
->GetDecorationsFor(inst->result_id(), true)
.empty();
}
bool TransformationCopyObject::CanInsertCopyBefore(
const opt::BasicBlock::iterator& instruction_in_block) {
if (instruction_in_block->PreviousNode() &&
(instruction_in_block->PreviousNode()->opcode() == SpvOpLoopMerge ||
instruction_in_block->PreviousNode()->opcode() == SpvOpSelectionMerge)) {
// We cannot insert a copy directly after a merge instruction.
return false;
}
if (instruction_in_block->opcode() == SpvOpVariable) {
// We cannot insert a copy directly before a variable; variables in a
// function must be contiguous in the entry block.
return false;
}
// We cannot insert a copy directly before OpPhi, because OpPhi instructions
// need to be contiguous at the start of a block.
return instruction_in_block->opcode() != SpvOpPhi;
}
} // namespace fuzz
} // namespace spvtools

View File

@@ -28,8 +28,8 @@ class TransformationCopyObject : public Transformation {
explicit TransformationCopyObject(
const protobufs::TransformationCopyObject& message);
TransformationCopyObject(uint32_t fresh_id, uint32_t object,
uint32_t insert_after_id, uint32_t offset);
TransformationCopyObject(uint32_t object, uint32_t base_instruction_id,
uint32_t offset, uint32_t fresh_id);
// - |message_.fresh_id| must not be used by the module.
// - |message_.object| must be a result id that is a legitimate operand for
@@ -58,6 +58,14 @@ class TransformationCopyObject : public Transformation {
protobufs::Transformation ToMessage() const override;
// Determines whether it is OK to make a copy of |inst|.
static bool IsCopyable(opt::IRContext* ir_context, opt::Instruction* inst);
// Determines whether it is OK to insert a copy instruction before the given
// instruction.
static bool CanInsertCopyBefore(
const opt::BasicBlock::iterator& instruction_in_block);
private:
protobufs::TransformationCopyObject message_;
};

View File

@@ -69,7 +69,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
local_redundancy_elimination.h
local_single_block_elim_pass.h
local_single_store_elim_pass.h
local_ssa_elim_pass.h
log.h
loop_dependence.h
loop_descriptor.h
@@ -176,7 +175,6 @@ set(SPIRV_TOOLS_OPT_SOURCES
local_redundancy_elimination.cpp
local_single_block_elim_pass.cpp
local_single_store_elim_pass.cpp
local_ssa_elim_pass.cpp
loop_dependence.cpp
loop_dependence_helpers.cpp
loop_descriptor.cpp

View File

@@ -110,15 +110,26 @@ void CFG::ForEachBlockInPostOrder(BasicBlock* bb,
void CFG::ForEachBlockInReversePostOrder(
BasicBlock* bb, const std::function<void(BasicBlock*)>& f) {
WhileEachBlockInReversePostOrder(bb, [f](BasicBlock* b) {
f(b);
return true;
});
}
bool CFG::WhileEachBlockInReversePostOrder(
BasicBlock* bb, const std::function<bool(BasicBlock*)>& f) {
std::vector<BasicBlock*> po;
std::unordered_set<BasicBlock*> seen;
ComputePostOrderTraversal(bb, &po, &seen);
for (auto current_bb = po.rbegin(); current_bb != po.rend(); ++current_bb) {
if (!IsPseudoExitBlock(*current_bb) && !IsPseudoEntryBlock(*current_bb)) {
f(*current_bb);
if (!f(*current_bb)) {
return false;
}
}
}
return true;
}
void CFG::ComputeStructuredSuccessors(Function* func) {

View File

@@ -65,18 +65,21 @@ class CFG {
void ComputeStructuredOrder(Function* func, BasicBlock* root,
std::list<BasicBlock*>* order);
// Applies |f| to the basic block in post order starting with |bb|.
// Note that basic blocks that cannot be reached from |bb| node will not be
// processed.
// Applies |f| to all blocks that can be reach from |bb| in post order.
void ForEachBlockInPostOrder(BasicBlock* bb,
const std::function<void(BasicBlock*)>& f);
// Applies |f| to the basic block in reverse post order starting with |bb|.
// Note that basic blocks that cannot be reached from |bb| node will not be
// processed.
// Applies |f| to all blocks that can be reach from |bb| in reverse post
// order.
void ForEachBlockInReversePostOrder(
BasicBlock* bb, const std::function<void(BasicBlock*)>& f);
// Applies |f| to all blocks that can be reach from |bb| in reverse post
// order. Return false if |f| return false on any basic block, and stops
// processing.
bool WhileEachBlockInReversePostOrder(
BasicBlock* bb, const std::function<bool(BasicBlock*)>& f);
// Registers |blk| as a basic block in the cfg, this also updates the
// predecessor lists of each successor of |blk|. |blk| must have a terminator
// instruction at the end of the block.

View File

@@ -646,6 +646,9 @@ Instruction* InstructionFolder::FoldInstructionToConstant(
if (folded_const != nullptr) {
Instruction* const_inst =
const_mgr->GetDefiningInstruction(folded_const, inst->type_id());
if (const_inst == nullptr) {
return nullptr;
}
assert(const_inst->type_id() == inst->type_id());
// May be a new instruction that needs to be analysed.
context_->UpdateDefUse(const_inst);

View File

@@ -59,6 +59,8 @@ Pass::Status GenerateWebGPUInitializersPass::Process() {
changed = true;
auto* constant_inst = GetNullConstantForVariable(inst);
if (!constant_inst) return Status::Failure;
if (seen_null_constants_.find(constant_inst) ==
seen_null_constants_.end()) {
constant_inst->InsertBefore(inst);
@@ -78,6 +80,8 @@ Pass::Status GenerateWebGPUInitializersPass::Process() {
changed = true;
auto* constant_inst = GetNullConstantForVariable(inst);
if (!constant_inst) return Status::Failure;
AddNullInitializerToVariable(constant_inst, inst);
}
}

View File

@@ -720,6 +720,15 @@ bool InlinePass::IsInlinableFunction(Function* func) {
return false;
}
// Do not inline functions with an OpKill because they may be inlined into a
// continue construct.
bool has_opkill = !func->WhileEachInst(
[](Instruction* inst) { return inst->opcode() != SpvOpKill; });
if (has_opkill) {
return false;
}
return true;
}

View File

@@ -1,113 +0,0 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/opt/local_ssa_elim_pass.h"
#include "source/cfa.h"
#include "source/opt/iterator.h"
#include "source/opt/ssa_rewrite_pass.h"
namespace spvtools {
namespace opt {
bool LocalMultiStoreElimPass::AllExtensionsSupported() const {
// If any extension not in whitelist, return false
for (auto& ei : get_module()->extensions()) {
const char* extName =
reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]);
if (extensions_whitelist_.find(extName) == extensions_whitelist_.end())
return false;
}
return true;
}
Pass::Status LocalMultiStoreElimPass::ProcessImpl() {
// Assumes relaxed logical addressing only (see instruction.h)
// TODO(greg-lunarg): Add support for physical addressing
if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
return Status::SuccessWithoutChange;
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
// TODO(greg-lunarg): Add support for OpGroupDecorate
for (auto& ai : get_module()->annotations())
if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange;
// Do not process if any disallowed extensions are enabled
if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
// Process functions
ProcessFunction pfn = [this](Function* fp) {
return SSARewriter(this).RewriteFunctionIntoSSA(fp);
};
bool modified = context()->ProcessEntryPointCallTree(pfn);
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
LocalMultiStoreElimPass::LocalMultiStoreElimPass() = default;
Pass::Status LocalMultiStoreElimPass::Process() {
// Initialize extension whitelist
InitExtensions();
return ProcessImpl();
}
void LocalMultiStoreElimPass::InitExtensions() {
extensions_whitelist_.clear();
extensions_whitelist_.insert({
"SPV_AMD_shader_explicit_vertex_parameter",
"SPV_AMD_shader_trinary_minmax",
"SPV_AMD_gcn_shader",
"SPV_KHR_shader_ballot",
"SPV_AMD_shader_ballot",
"SPV_AMD_gpu_shader_half_float",
"SPV_KHR_shader_draw_parameters",
"SPV_KHR_subgroup_vote",
"SPV_KHR_16bit_storage",
"SPV_KHR_device_group",
"SPV_KHR_multiview",
"SPV_NVX_multiview_per_view_attributes",
"SPV_NV_viewport_array2",
"SPV_NV_stereo_view_rendering",
"SPV_NV_sample_mask_override_coverage",
"SPV_NV_geometry_shader_passthrough",
"SPV_AMD_texture_gather_bias_lod",
"SPV_KHR_storage_buffer_storage_class",
"SPV_KHR_variable_pointers",
"SPV_AMD_gpu_shader_int16",
"SPV_KHR_post_depth_coverage",
"SPV_KHR_shader_atomic_counter_ops",
"SPV_EXT_shader_stencil_export",
"SPV_EXT_shader_viewport_index_layer",
"SPV_AMD_shader_image_load_store_lod",
"SPV_AMD_shader_fragment_mask",
"SPV_EXT_fragment_fully_covered",
"SPV_AMD_gpu_shader_half_float_fetch",
"SPV_GOOGLE_decorate_string",
"SPV_GOOGLE_hlsl_functionality1",
"SPV_GOOGLE_user_type",
"SPV_NV_shader_subgroup_partitioned",
"SPV_EXT_descriptor_indexing",
"SPV_NV_fragment_shader_barycentric",
"SPV_NV_compute_shader_derivatives",
"SPV_NV_shader_image_footprint",
"SPV_NV_shading_rate",
"SPV_NV_mesh_shader",
"SPV_NV_ray_tracing",
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_physical_storage_buffer",
});
}
} // namespace opt
} // namespace spvtools

View File

@@ -1,72 +0,0 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SOURCE_OPT_LOCAL_SSA_ELIM_PASS_H_
#define SOURCE_OPT_LOCAL_SSA_ELIM_PASS_H_
#include <algorithm>
#include <map>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "source/opt/basic_block.h"
#include "source/opt/def_use_manager.h"
#include "source/opt/mem_pass.h"
#include "source/opt/module.h"
namespace spvtools {
namespace opt {
// See optimizer.hpp for documentation.
class LocalMultiStoreElimPass : public MemPass {
using cbb_ptr = const BasicBlock*;
public:
using GetBlocksFunction =
std::function<std::vector<BasicBlock*>*(const BasicBlock*)>;
LocalMultiStoreElimPass();
const char* name() const override { return "eliminate-local-multi-store"; }
Status Process() override;
IRContext::Analysis GetPreservedAnalyses() override {
return IRContext::kAnalysisDefUse |
IRContext::kAnalysisInstrToBlockMapping |
IRContext::kAnalysisConstants | IRContext::kAnalysisTypes;
}
private:
// Initialize extensions whitelist
void InitExtensions();
// Return true if all extensions in this module are allowed by this pass.
bool AllExtensionsSupported() const;
Pass::Status ProcessImpl();
// Extensions supported by this pass.
std::unordered_set<std::string> extensions_whitelist_;
};
} // namespace opt
} // namespace spvtools
#endif // SOURCE_OPT_LOCAL_SSA_ELIM_PASS_H_

View File

@@ -233,6 +233,10 @@ uint32_t MemPass::Type2Undef(uint32_t type_id) {
const auto uitr = type2undefs_.find(type_id);
if (uitr != type2undefs_.end()) return uitr->second;
const uint32_t undefId = TakeNextId();
if (undefId == 0) {
return 0;
}
std::unique_ptr<Instruction> undef_inst(
new Instruction(context(), SpvOpUndef, type_id, undefId, {}));
get_def_use_mgr()->AnalyzeInstDefUse(&*undef_inst);

View File

@@ -121,9 +121,10 @@ class MemPass : public Pass {
return (op == SpvOpDecorate || op == SpvOpDecorateId);
}
// Return undef in function for type. Create and insert an undef after the
// first non-variable in the function if it doesn't already exist. Add
// undef to function undef map.
// Return the id of an undef value with type |type_id|. Create and insert an
// undef after the first non-variable in the function if it doesn't already
// exist. Add undef to function undef map. Returns 0 of the value does not
// exist, and cannot be created.
uint32_t Type2Undef(uint32_t type_id);
// Cache of verified target vars

View File

@@ -715,7 +715,7 @@ Optimizer::PassToken CreateDeadBranchElimPass() {
Optimizer::PassToken CreateLocalMultiStoreElimPass() {
return MakeUnique<Optimizer::PassToken::Impl>(
MakeUnique<opt::LocalMultiStoreElimPass>());
MakeUnique<opt::SSARewritePass>());
}
Optimizer::PassToken CreateAggressiveDCEPass() {

View File

@@ -52,7 +52,6 @@
#include "source/opt/local_redundancy_elimination.h"
#include "source/opt/local_single_block_elim_pass.h"
#include "source/opt/local_single_store_elim_pass.h"
#include "source/opt/local_ssa_elim_pass.h"
#include "source/opt/loop_fission.h"
#include "source/opt/loop_fusion_pass.h"
#include "source/opt/loop_peeling.h"

View File

@@ -274,6 +274,9 @@ uint32_t SSARewriter::GetReachingDef(uint32_t var_id, BasicBlock* bb) {
// of the CFG, the variable is not defined, so we use undef.
if (val_id == 0) {
val_id = pass_->GetUndefVal(var_id);
if (val_id == 0) {
return 0;
}
}
WriteVariable(var_id, bb, val_id);
@@ -313,12 +316,15 @@ void SSARewriter::ProcessStore(Instruction* inst, BasicBlock* bb) {
}
}
void SSARewriter::ProcessLoad(Instruction* inst, BasicBlock* bb) {
bool SSARewriter::ProcessLoad(Instruction* inst, BasicBlock* bb) {
uint32_t var_id = 0;
(void)pass_->GetPtr(inst, &var_id);
if (pass_->IsTargetVar(var_id)) {
// Get the immediate reaching definition for |var_id|.
uint32_t val_id = GetReachingDef(var_id, bb);
if (val_id == 0) {
return false;
}
// Schedule a replacement for the result of this load instruction with
// |val_id|. After all the rewriting decisions are made, every use of
@@ -337,6 +343,7 @@ void SSARewriter::ProcessLoad(Instruction* inst, BasicBlock* bb) {
<< " (replacement for %" << load_id << " is %" << val_id << ")\n";
#endif
}
return true;
}
void SSARewriter::PrintPhiCandidates() const {
@@ -356,7 +363,7 @@ void SSARewriter::PrintReplacementTable() const {
std::cerr << "\n";
}
void SSARewriter::GenerateSSAReplacements(BasicBlock* bb) {
bool SSARewriter::GenerateSSAReplacements(BasicBlock* bb) {
#if SSA_REWRITE_DEBUGGING_LEVEL > 1
std::cerr << "Generating SSA replacements for block: " << bb->id() << "\n";
std::cerr << bb->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES)
@@ -368,7 +375,9 @@ void SSARewriter::GenerateSSAReplacements(BasicBlock* bb) {
if (opcode == SpvOpStore || opcode == SpvOpVariable) {
ProcessStore(&inst, bb);
} else if (inst.opcode() == SpvOpLoad) {
ProcessLoad(&inst, bb);
if (!ProcessLoad(&inst, bb)) {
return false;
}
}
}
@@ -381,6 +390,7 @@ void SSARewriter::GenerateSSAReplacements(BasicBlock* bb) {
PrintReplacementTable();
std::cerr << "\n\n";
#endif
return true;
}
uint32_t SSARewriter::GetReplacement(std::pair<uint32_t, uint32_t> repl) {
@@ -560,7 +570,7 @@ void SSARewriter::FinalizePhiCandidates() {
}
}
bool SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
Pass::Status SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
#if SSA_REWRITE_DEBUGGING_LEVEL > 0
std::cerr << "Function before SSA rewrite:\n"
<< fp->PrettyPrint(0) << "\n\n\n";
@@ -571,9 +581,17 @@ bool SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
// Generate all the SSA replacements and Phi candidates. This will
// generate incomplete and trivial Phis.
pass_->cfg()->ForEachBlockInReversePostOrder(
fp->entry().get(),
[this](BasicBlock* bb) { GenerateSSAReplacements(bb); });
bool succeeded = pass_->cfg()->WhileEachBlockInReversePostOrder(
fp->entry().get(), [this](BasicBlock* bb) {
if (!GenerateSSAReplacements(bb)) {
return false;
}
return true;
});
if (!succeeded) {
return Pass::Status::Failure;
}
// Remove trivial Phis and add arguments to incomplete Phis.
FinalizePhiCandidates();
@@ -586,17 +604,21 @@ bool SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
<< fp->PrettyPrint(0) << "\n";
#endif
return modified;
}
Pass::Status SSARewritePass::Process() {
bool modified = false;
for (auto& fn : *get_module()) {
modified |= SSARewriter(this).RewriteFunctionIntoSSA(&fn);
}
return modified ? Pass::Status::SuccessWithChange
: Pass::Status::SuccessWithoutChange;
}
Pass::Status SSARewritePass::Process() {
Status status = Status::SuccessWithoutChange;
for (auto& fn : *get_module()) {
status =
CombineStatus(status, SSARewriter(this).RewriteFunctionIntoSSA(&fn));
if (status == Status::Failure) {
break;
}
}
return status;
}
} // namespace opt
} // namespace spvtools

View File

@@ -46,9 +46,9 @@ class SSARewriter {
// entry point for the SSA rewrite algorithm. SSA-target variables are
// locally defined variables that meet the criteria set by IsSSATargetVar.
//
// It returns true if function |fp| was modified. Otherwise, it returns
// false.
bool RewriteFunctionIntoSSA(Function* fp);
// Returns whether the function was modified or not, and whether or not the
// rewrite was successful.
Pass::Status RewriteFunctionIntoSSA(Function* fp);
private:
class PhiCandidate {
@@ -128,8 +128,8 @@ class SSARewriter {
// Generates all the SSA rewriting decisions for basic block |bb|. This
// populates the Phi candidate table (|phi_candidate_|) and the load
// replacement table (|load_replacement_).
void GenerateSSAReplacements(BasicBlock* bb);
// replacement table (|load_replacement_). Returns true if successful.
bool GenerateSSAReplacements(BasicBlock* bb);
// Seals block |bb|. Sealing a basic block means |bb| and all its
// predecessors of |bb| have been scanned for loads/stores.
@@ -202,8 +202,8 @@ class SSARewriter {
// Processes the load operation |inst| in basic block |bb|. This extracts
// the variable ID being stored into, determines whether the variable is an
// SSA-target variable, and, if it is, it reads its reaching definition by
// calling |GetReachingDef|.
void ProcessLoad(Instruction* inst, BasicBlock* bb);
// calling |GetReachingDef|. Returns true if successful.
bool ProcessLoad(Instruction* inst, BasicBlock* bb);
// Reads the current definition for variable |var_id| in basic block |bb|.
// If |var_id| is not defined in block |bb| it walks up the predecessors of

View File

@@ -95,9 +95,14 @@ uint32_t WrapOpKill::GetOpKillFuncId() {
return 0;
}
uint32_t void_type_id = GetVoidTypeId();
if (void_type_id == 0) {
return 0;
}
// Generate the function start instruction
std::unique_ptr<Instruction> func_start(new Instruction(
context(), SpvOpFunction, GetVoidTypeId(), opkill_func_id, {}));
context(), SpvOpFunction, void_type_id, opkill_func_id, {}));
func_start->AddOperand({SPV_OPERAND_TYPE_FUNCTION_CONTROL, {0}});
func_start->AddOperand({SPV_OPERAND_TYPE_ID, {GetVoidFunctionTypeId()}});
opkill_function_.reset(new Function(std::move(func_start)));

View File

@@ -66,6 +66,8 @@ const char* spvTargetEnvDescription(spv_target_env env) {
return "SPIR-V 1.4";
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
case SPV_ENV_UNIVERSAL_1_5:
return "SPIR-V 1.5";
}
return "";
}
@@ -99,6 +101,8 @@ uint32_t spvVersionForTargetEnv(spv_target_env env) {
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return SPV_SPIRV_VERSION_WORD(1, 4);
case SPV_ENV_UNIVERSAL_1_5:
return SPV_SPIRV_VERSION_WORD(1, 5);
}
return SPV_SPIRV_VERSION_WORD(0, 0);
}
@@ -112,6 +116,7 @@ static const std::pair<const char*, spv_target_env> spvTargetEnvNameMap[] = {
{"spv1.2", SPV_ENV_UNIVERSAL_1_2},
{"spv1.3", SPV_ENV_UNIVERSAL_1_3},
{"spv1.4", SPV_ENV_UNIVERSAL_1_4},
{"spv1.5", SPV_ENV_UNIVERSAL_1_5},
{"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2},
{"opencl1.2", SPV_ENV_OPENCL_1_2},
{"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0},
@@ -165,6 +170,7 @@ bool spvIsVulkanEnv(spv_target_env env) {
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_UNIVERSAL_1_5:
return false;
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_VULKAN_1_1:
@@ -190,6 +196,7 @@ bool spvIsOpenCLEnv(spv_target_env env) {
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
case SPV_ENV_UNIVERSAL_1_5:
return false;
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
@@ -227,6 +234,7 @@ bool spvIsWebGPUEnv(spv_target_env env) {
case SPV_ENV_OPENCL_2_2:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
case SPV_ENV_UNIVERSAL_1_5:
return false;
case SPV_ENV_WEBGPU_0:
return true;
@@ -253,6 +261,7 @@ bool spvIsOpenGLEnv(spv_target_env env) {
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
case SPV_ENV_UNIVERSAL_1_5:
return false;
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
@@ -299,7 +308,8 @@ std::string spvLogStringForEnv(spv_target_env env) {
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_UNIVERSAL_1_4: {
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_UNIVERSAL_1_5: {
return "Universal";
}
}

View File

@@ -40,6 +40,7 @@ spv_context spvContextCreate(spv_target_env env) {
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_UNIVERSAL_1_5:
break;
default:
return nullptr;

View File

@@ -546,6 +546,11 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar,
<< "Expected <result-id> at the beginning of an instruction, found '"
<< firstWord << "'.";
}
if (!opcodeEntry->hasResult && !result_id.empty()) {
return context->diagnostic()
<< "Cannot set ID " << result_id << " because " << opcodeName
<< " does not produce a result ID.";
}
pInst->opcode = opcodeEntry->opcode;
context->setPosition(nextPosition);
// Reserve the first word for the instruction.

View File

@@ -2901,6 +2901,26 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
const Decoration& decoration, const Instruction& inst) {
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
// Builtins can only be applied to variables, structures or constants.
auto target_opcode = inst.opcode();
if (target_opcode != SpvOpTypeStruct && target_opcode != SpvOpVariable &&
!spvOpcodeIsConstant(target_opcode)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
<< "BuiltIns can only target variables, structs or constants";
}
if (!spvIsVulkanOrWebGPUEnv(_.context()->target_env)) {
// Early return. All currently implemented rules are based on Vulkan or
// WebGPU spec.
//
// TODO: If you are adding validation rules for environments other than
// Vulkan or WebGPU (or general rules which are not environment
// independent), then you need to modify or remove this condition. Consider
// also adding early returns into BuiltIn-specific rules, so that the system
// doesn't spawn new rules which don't do anything.
return SPV_SUCCESS;
}
if (spvIsWebGPUEnv(_.context()->target_env) &&
!IsBuiltInValidForWebGPU(label)) {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
@@ -3156,18 +3176,6 @@ spv_result_t BuiltInsValidator::Run() {
// Validates correctness of built-in variables.
spv_result_t ValidateBuiltIns(ValidationState_t& _) {
if (!spvIsVulkanOrWebGPUEnv(_.context()->target_env)) {
// Early return. All currently implemented rules are based on Vulkan or
// WebGPU spec.
//
// TODO: If you are adding validation rules for environments other than
// Vulkan or WebGPU (or general rules which are not environment
// independent), then you need to modify or remove this condition. Consider
// also adding early returns into BuiltIn-specific rules, so that the system
// doesn't spawn new rules which don't do anything.
return SPV_SUCCESS;
}
BuiltInsValidator validator(_);
return validator.Run();
}

View File

@@ -205,17 +205,24 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state,
operand_desc->capabilities, operand_desc->numCapabilities);
}
if (!state.HasAnyOfCapabilities(enabling_capabilities)) {
return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
<< "Operand " << which_operand << " of "
<< spvOpcodeString(inst->opcode())
<< " requires one of these capabilities: "
<< ToString(enabling_capabilities, state.grammar());
// When encountering an OpCapability instruction, the instruction pass
// registers a capability with the module *before* checking capabilities.
// So in the case of an OpCapability instruction, don't bother checking
// enablement by another capability.
if (inst->opcode() != SpvOpCapability) {
const bool enabled_by_cap =
state.HasAnyOfCapabilities(enabling_capabilities);
if (!enabling_capabilities.IsEmpty() && !enabled_by_cap) {
return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
<< "Operand " << which_operand << " of "
<< spvOpcodeString(inst->opcode())
<< " requires one of these capabilities: "
<< ToString(enabling_capabilities, state.grammar());
}
}
return OperandVersionExtensionCheck(state, inst, which_operand,
*operand_desc, word);
}
return SPV_SUCCESS;
}

View File

@@ -330,6 +330,12 @@ class ValidationState_t {
return module_capabilities_.Contains(cap);
}
/// Returns a reference to the set of capabilities in the module.
/// This is provided for debuggability.
const CapabilitySet& module_capabilities() const {
return module_capabilities_;
}
/// Returns true if the extension is enabled in the module.
bool HasExtension(Extension ext) const {
return module_extensions_.Contains(ext);
@@ -380,7 +386,11 @@ class ValidationState_t {
/// Registers the decoration for the given <id>
void RegisterDecorationForId(uint32_t id, const Decoration& dec) {
id_decorations_[id].push_back(dec);
auto& dec_list = id_decorations_[id];
auto lb = std::find(dec_list.begin(), dec_list.end(), dec);
if (lb == dec_list.end()) {
dec_list.push_back(dec);
}
}
/// Registers the list of decorations for the given <id>

View File

@@ -20,7 +20,7 @@ namespace {
using spvtest::ScopedContext;
using spvtest::TextToBinaryTest;
TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {
TEST_F(TextToBinaryTest, InstOpcodeProducesResultIDButNoIDDefinedFails) {
SetText("OpTypeMatrix %1 %2 1000");
EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
spvTextToBinary(ScopedContext().context, text.str, text.length,
@@ -33,5 +33,18 @@ TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {
EXPECT_EQ(0u, diagnostic->position.line);
}
TEST_F(TextToBinaryTest,
InstDefinesResultIDButOpcodeDoesNotProduceAResultFails) {
SetText("\n\n%foo = OpName %1 \"bar\"");
EXPECT_EQ(SPV_ERROR_INVALID_TEXT,
spvTextToBinary(ScopedContext().context, text.str, text.length,
&binary, &diagnostic));
ASSERT_NE(nullptr, diagnostic);
EXPECT_STREQ(
"Cannot set ID %foo because OpName does not produce a result ID.",
diagnostic->error);
EXPECT_EQ(2u, diagnostic->position.line);
}
} // namespace
} // namespace svptools

View File

@@ -107,7 +107,7 @@ TEST(CInterface, DefaultConsumerNullDiagnosticForInvalidValidating) {
}
TEST(CInterface, SpecifyConsumerNullDiagnosticForAssembling) {
const char input_text[] = "%1 = OpName\n";
const char input_text[] = " OpName\n";
auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;
@@ -213,7 +213,7 @@ TEST(CInterface, SpecifyConsumerNullDiagnosticForValidating) {
// When having both a consumer and an diagnostic object, the diagnostic object
// should take priority.
TEST(CInterface, SpecifyConsumerSpecifyDiagnosticForAssembling) {
const char input_text[] = "%1 = OpName";
const char input_text[] = " OpName";
auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1);
int invocation = 0;

View File

@@ -2080,6 +2080,485 @@ TEST(TransformationAddDeadBreakTest, PhiInstructions) {
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules1) {
// Right after the loop, an OpCopyObject defined by the loop is used. Adding
// a dead break would prevent that use from being dominated by its definition,
// so is not allowed.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
%201 = OpCopyObject %10 %200
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules2) {
// This example captures the following idiom:
//
// if {
// L1:
// }
// definition;
// L2:
// use;
//
// Adding a dead jump from L1 to L2 would lead to 'definition' no longer
// dominating 'use', and so is not allowed.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpSelectionMerge %101 None
OpBranchConditional %11 %102 %103
%102 = OpLabel
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%101 = OpLabel
%201 = OpCopyObject %10 %200
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules3) {
// Right after the loop, an OpCopyObject defined by the loop is used in an
// OpPhi. Adding a dead break is OK in this case, due to the use being in an
// OpPhi.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
%201 = OpPhi %10 %200 %102
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto good_transformation = TransformationAddDeadBreak(100, 101, false, {11});
ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager));
good_transformation.Apply(context.get(), &fact_manager);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranchConditional %11 %101 %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
%201 = OpPhi %10 %200 %102 %11 %100
OpReturn
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules4) {
// This example captures the following idiom:
//
// if {
// L1:
// }
// definition;
// L2:
// use in OpPhi;
//
// Adding a dead jump from L1 to L2 is OK, due to 'use' being in an OpPhi.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpSelectionMerge %101 None
OpBranchConditional %11 %102 %103
%102 = OpLabel
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%101 = OpLabel
%201 = OpPhi %10 %200 %103
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto good_transformation = TransformationAddDeadBreak(102, 101, false, {11});
ASSERT_TRUE(good_transformation.IsApplicable(context.get(), fact_manager));
good_transformation.Apply(context.get(), &fact_manager);
ASSERT_TRUE(IsValid(env, context.get()));
std::string after_transformation = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpSelectionMerge %101 None
OpBranchConditional %11 %102 %103
%102 = OpLabel
OpBranchConditional %11 %101 %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%101 = OpLabel
%201 = OpPhi %10 %200 %103 %11 %102
OpReturn
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules5) {
// After, but not right after, the loop, an OpCopyObject defined by the loop
// is used in an OpPhi. Adding a dead break is not OK in this case.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
OpBranch %105
%105 = OpLabel
%201 = OpPhi %10 %200 %101
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(100, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules6) {
// This example captures the following idiom:
//
// if {
// L1:
// }
// definition;
// L2:
// goto L3;
// L3:
// use in OpPhi;
//
// Adding a dead jump from L1 to L2 not OK, due to the use in an OpPhi being
// in L3.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpSelectionMerge %101 None
OpBranchConditional %11 %102 %103
%102 = OpLabel
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%101 = OpLabel
OpBranch %150
%150 = OpLabel
%201 = OpPhi %10 %200 %101
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules7) {
// This example - a variation on an earlier test - captures the following
// idiom:
//
// loop {
// L1:
// }
// definition;
// L2:
// use;
//
// Adding a dead jump from L1 to L2 would lead to 'definition' no longer
// dominating 'use', and so is not allowed.
//
// This version of the test captures the case where L1 appears after the
// loop merge (which SPIR-V dominance rules allow).
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %104 None
OpBranchConditional %11 %102 %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%101 = OpLabel
%201 = OpCopyObject %10 %200
OpReturn
%102 = OpLabel
OpBranch %103
%104 = OpLabel
OpBranch %100
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadBreakTest, RespectDominanceRules8) {
// A variation of RespectDominanceRules8 where the defining block appears
// in the loop, but after the definition of interest.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %104 None
OpBranchConditional %11 %102 %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %101
%102 = OpLabel
OpBranch %103
%101 = OpLabel
%201 = OpCopyObject %10 %200
OpReturn
%104 = OpLabel
OpBranch %100
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
auto bad_transformation = TransformationAddDeadBreak(102, 101, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
} // namespace
} // namespace fuzz
} // namespace spvtools

View File

@@ -1029,6 +1029,226 @@ TEST(TransformationAddDeadContinueTest, PhiInstructions) {
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
TEST(TransformationAddDeadContinueTest, RespectDominanceRules1) {
// Checks that a dead continue cannot be added if it would prevent a block
// later in the loop from dominating the loop's continue construct, in the
// case where said block defines and id that is used in the loop's continue
// construct.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %6
%6 = OpLabel
OpLoopMerge %8 %9 None
OpBranch %7
%7 = OpLabel
%21 = OpCopyObject %10 %11
OpBranch %9
%9 = OpLabel
%20 = OpPhi %10 %21 %7
OpBranchConditional %11 %6 %8
%8 = OpLabel
OpBranch %12
%12 = OpLabel
OpLoopMerge %14 %15 None
OpBranch %13
%13 = OpLabel
OpBranch %22
%22 = OpLabel
%23 = OpCopyObject %10 %11
OpBranch %25
%25 = OpLabel
OpBranch %15
%15 = OpLabel
%26 = OpCopyObject %10 %23
OpBranchConditional %11 %12 %14
%14 = OpLabel
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
// This transformation is not applicable because the dead continue from the
// loop body prevents the definition of %23 later in the loop body from
// dominating its use in the loop's continue target.
auto bad_transformation = TransformationAddDeadContinue(13, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
auto good_transformation_1 = TransformationAddDeadContinue(7, false, {});
ASSERT_TRUE(good_transformation_1.IsApplicable(context.get(), fact_manager));
good_transformation_1.Apply(context.get(), &fact_manager);
auto good_transformation_2 = TransformationAddDeadContinue(22, false, {});
ASSERT_TRUE(good_transformation_2.IsApplicable(context.get(), fact_manager));
good_transformation_2.Apply(context.get(), &fact_manager);
// This transformation is OK, because the definition of %21 in the loop body
// is only used in an OpPhi in the loop's continue target.
auto good_transformation_3 = TransformationAddDeadContinue(6, false, {11});
ASSERT_TRUE(good_transformation_3.IsApplicable(context.get(), fact_manager));
good_transformation_3.Apply(context.get(), &fact_manager);
std::string after_transformations = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %6
%6 = OpLabel
OpLoopMerge %8 %9 None
OpBranchConditional %11 %9 %7
%7 = OpLabel
%21 = OpCopyObject %10 %11
OpBranchConditional %11 %9 %9
%9 = OpLabel
%20 = OpPhi %10 %21 %7 %11 %6
OpBranchConditional %11 %6 %8
%8 = OpLabel
OpBranch %12
%12 = OpLabel
OpLoopMerge %14 %15 None
OpBranch %13
%13 = OpLabel
OpBranch %22
%22 = OpLabel
%23 = OpCopyObject %10 %11
OpBranchConditional %11 %15 %25
%25 = OpLabel
OpBranch %15
%15 = OpLabel
%26 = OpCopyObject %10 %23
OpBranchConditional %11 %12 %14
%14 = OpLabel
OpReturn
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformations, context.get()));
}
TEST(TransformationAddDeadContinueTest, RespectDominanceRules2) {
// Checks that a dead continue cannot be added if it would lead to a use after
// the loop failing to be dominated by its definition.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
%201 = OpCopyObject %10 %200
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
// This transformation would shortcut the part of the loop body that defines
// an id used after the loop.
auto bad_transformation = TransformationAddDeadContinue(100, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
TEST(TransformationAddDeadContinueTest, RespectDominanceRules3) {
// Checks that a dead continue cannot be added if it would lead to a dominance
// problem with an id used in an OpPhi after the loop.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%10 = OpTypeBool
%11 = OpConstantFalse %10
%4 = OpFunction %2 None %3
%5 = OpLabel
OpBranch %100
%100 = OpLabel
OpLoopMerge %101 %102 None
OpBranch %103
%103 = OpLabel
%200 = OpCopyObject %10 %11
OpBranch %104
%104 = OpLabel
OpBranch %102
%102 = OpLabel
OpBranchConditional %11 %100 %101
%101 = OpLabel
%201 = OpPhi %10 %200 %102
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, context.get()));
FactManager fact_manager;
// This transformation would shortcut the part of the loop body that defines
// an id used after the loop.
auto bad_transformation = TransformationAddDeadContinue(100, false, {});
ASSERT_FALSE(bad_transformation.IsApplicable(context.get(), fact_manager));
}
} // namespace
} // namespace fuzz
} // namespace spvtools

View File

@@ -494,8 +494,8 @@ INSTANTIATE_TEST_SUITE_P(
CASE3(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation,
RayTracingNV),
CASE2(BUILT_IN, BuiltInInvocationId, Geometry, Tessellation),
CASE1(BUILT_IN, BuiltInLayer, Geometry),
CASE1(BUILT_IN, BuiltInViewportIndex, MultiViewport), // Bug 15234
CASE2(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT),
CASE2(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT), // Bug 15234
CASE1(BUILT_IN, BuiltInTessLevelOuter, Tessellation),
CASE1(BUILT_IN, BuiltInTessLevelInner, Tessellation),
CASE1(BUILT_IN, BuiltInTessCoord, Tessellation),
@@ -532,6 +532,18 @@ INSTANTIATE_TEST_SUITE_P(
// clang-format on
})));
INSTANTIATE_TEST_SUITE_P(
BuiltInV1_5, EnumCapabilityTest,
Combine(
Values(SPV_ENV_UNIVERSAL_1_5),
ValuesIn(std::vector<EnumCapabilityCase>{
// SPIR-V 1.5 adds new capabilities to enable these two builtins.
CASE3(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer,
ShaderViewportIndexLayerEXT),
CASE3(BUILT_IN, BuiltInViewportIndex, MultiViewport,
ShaderViewportIndex, ShaderViewportIndexLayerEXT),
})));
// See SPIR-V Section 3.22 Selection Control
INSTANTIATE_TEST_SUITE_P(
SelectionControl, EnumCapabilityTest,

View File

@@ -6645,11 +6645,11 @@ TEST_F(AggressiveDCETest, NoEliminateForwardPointer) {
const std::string predefs1 =
R"(OpCapability Shader
OpCapability PhysicalStorageBufferAddressesEXT
OpCapability PhysicalStorageBufferAddresses
OpExtension "SPV_EXT_physical_storage_buffer"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
@@ -6668,7 +6668,7 @@ OpName %r "r"
OpMemberDecorate %blockType 0 Offset 0
OpMemberDecorate %blockType 1 Offset 8
OpDecorate %blockType Block
OpDecorate %b AliasedPointerEXT
OpDecorate %b AliasedPointer
OpMemberDecorate %rootBlock 0 Offset 0
OpDecorate %rootBlock Block
OpDecorate %r DescriptorSet 0
@@ -6695,50 +6695,50 @@ OpDecorate %r Binding 0
const std::string predefs2_before =
R"(%void = OpTypeVoid
%3 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_blockType PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%int = OpTypeInt 32 1
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %blockType
%_ptr_Function__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer Function %_ptr_PhysicalStorageBufferEXT_blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_blockType
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
%_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
%_ptr_Function__ptr_PhysicalStorageBuffer_blockType = OpTypePointer Function %_ptr_PhysicalStorageBuffer_blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
%_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
%r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_1 = OpConstant %int 1
%_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_531 = OpConstant %int 531
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
)";
const std::string predefs2_after =
R"(%void = OpTypeVoid
%8 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_blockType PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%int = OpTypeInt 32 1
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_blockType
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
%_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
%_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
%r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_1 = OpConstant %int 1
%_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_531 = OpConstant %int 531
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
)";
const std::string func_before =
R"(%main = OpFunction %void None %3
%5 = OpLabel
%b = OpVariable %_ptr_Function__ptr_PhysicalStorageBufferEXT_blockType Function
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType %17 %int_1
%22 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %21 Aligned 8
%b = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_blockType Function
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1
%22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
OpStore %b %22
%26 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %22 %int_0
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
OpStore %26 %int_531 Aligned 16
OpReturn
OpFunctionEnd
@@ -6747,11 +6747,11 @@ OpFunctionEnd
const std::string func_after =
R"(%main = OpFunction %void None %8
%19 = OpLabel
%20 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType %r %int_0
%21 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %20
%22 = OpAccessChain %_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType %21 %int_1
%23 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %22 Aligned 8
%24 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %23 %int_0
%20 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
%21 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %20
%22 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %21 %int_1
%23 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %22 Aligned 8
%24 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %23 %int_0
OpStore %24 %int_531 Aligned 16
OpReturn
OpFunctionEnd

View File

@@ -570,10 +570,10 @@ TEST_F(CCPTest, SkipSpecConstantInstrucitons) {
%10 = OpSpecConstantFalse %bool
%main = OpFunction %void None %4
%11 = OpLabel
%12 = OpBranchConditional %10 %l1 %l2
%l1 = OpLabel
OpBranchConditional %10 %L1 %L2
%L1 = OpLabel
OpReturn
%l2 = OpLabel
%L2 = OpLabel
OpReturn
OpFunctionEnd
)";

View File

@@ -82,6 +82,28 @@ TEST_F(ConstantManagerTest, GetDefiningInstruction2) {
EXPECT_EQ(const_inst_2->result_id(), 4);
}
TEST_F(ConstantManagerTest, GetDefiningInstructionIdOverflow) {
const std::string text = R"(
%1 = OpTypeInt 32 0
%3 = OpConstant %1 1
%4 = OpConstant %1 2
)";
std::unique_ptr<IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
ASSERT_NE(context, nullptr);
// Set the id bound to the max, so the new constant cannot be generated.
context->module()->SetIdBound(context->max_id_bound());
Type* int_type = context->get_type_mgr()->GetType(1);
IntConstant int_constant(int_type->AsInteger(), {3});
Instruction* inst =
context->get_constant_mgr()->GetDefiningInstruction(&int_constant, 1);
EXPECT_EQ(inst, nullptr);
}
} // namespace
} // namespace analysis
} // namespace opt

View File

@@ -1157,7 +1157,7 @@ OpDecorate %MyCBuffer Binding 0
OpStore %23 %35
%36 = OpAccessChain %_ptr_Function_v4float %23 %24
%37 = OpLoad %v4float %36
%39 = OpStore %36 %v4const
OpStore %36 %v4const
OpStore %out_var_SV_Target %37
OpReturn
OpFunctionEnd

View File

@@ -24,9 +24,9 @@ namespace {
using DecomposeInitializedVariablesTest = PassTest<::testing::Test>;
std::string single_entry_header = R"(OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpCapability VulkanMemoryModel
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpMemoryModel Logical Vulkan
OpEntryPoint Vertex %1 "shader"
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
@@ -126,9 +126,9 @@ TEST_F(DecomposeInitializedVariablesTest, OutputUnchanged) {
}
std::string multiple_entry_header = R"(OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpCapability VulkanMemoryModel
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpMemoryModel Logical Vulkan
OpEntryPoint Vertex %1 "vertex"
OpEntryPoint Fragment %2 "fragment"
%uint = OpTypeInt 32 0

View File

@@ -46,9 +46,9 @@ std::string GetGlobalVariableTestString(std::string ptr_str,
std::vector<const char*> result = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
ptr_str.c_str()};
@@ -132,9 +132,9 @@ std::string GetLocalVariableTestString(std::string ptr_str, std::string var_str,
std::vector<const char*> result = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
ptr_str.c_str(),
@@ -206,9 +206,9 @@ TEST_F(GenerateWebGPUInitializersTest, AlreadyInitializedUnchanged) {
std::vector<const char*> spirv = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%_ptr_Private_uint = OpTypePointer Private %uint",
@@ -232,9 +232,9 @@ TEST_F(GenerateWebGPUInitializersTest, AmbigiousArrays) {
std::vector<const char*> input_spirv = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%uint_2 = OpConstant %uint 2",
@@ -258,9 +258,9 @@ TEST_F(GenerateWebGPUInitializersTest, AmbigiousArrays) {
std::vector<const char*> expected_spirv = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%uint_2 = OpConstant %uint 2",
@@ -290,9 +290,9 @@ TEST_F(GenerateWebGPUInitializersTest, AmbigiousStructs) {
std::vector<const char*> input_spirv = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%_struct_3 = OpTypeStruct %uint",
@@ -315,9 +315,9 @@ TEST_F(GenerateWebGPUInitializersTest, AmbigiousStructs) {
std::vector<const char*> expected_spirv = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%_struct_3 = OpTypeStruct %uint",

View File

@@ -90,7 +90,7 @@ OpMemoryModel Physical64 OpenCL
TEST_F(GraphicsRobustAccessTest,
FailCantProcessPhysicalStorageBuffer64EXTAddressingModel) {
const std::string text = R"(
; CHECK: Addressing model must be Logical. Found OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
; CHECK: Addressing model must be Logical. Found OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpCapability Shader
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
)";

View File

@@ -2792,182 +2792,6 @@ TEST_F(InlineTest, SetParent) {
}
}
TEST_F(InlineTest, OpKill) {
const std::string text = R"(
; CHECK: OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpKill
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpFunctionEnd
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%voidfuncty = OpTypeFunction %void
%main = OpFunction %void None %voidfuncty
%1 = OpLabel
%2 = OpFunctionCall %void %func
OpReturn
OpFunctionEnd
%func = OpFunction %void None %voidfuncty
%3 = OpLabel
OpKill
OpFunctionEnd
)";
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
TEST_F(InlineTest, OpKillWithTrailingInstructions) {
const std::string text = R"(
; CHECK: OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: [[var:%\w+]] = OpVariable
; CHECK-NEXT: OpKill
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpStore [[var]]
; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpFunctionEnd
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%bool = OpTypeBool
%true = OpConstantTrue %bool
%bool_func_ptr = OpTypePointer Function %bool
%voidfuncty = OpTypeFunction %void
%main = OpFunction %void None %voidfuncty
%1 = OpLabel
%2 = OpVariable %bool_func_ptr Function
%3 = OpFunctionCall %void %func
OpStore %2 %true
OpReturn
OpFunctionEnd
%func = OpFunction %void None %voidfuncty
%4 = OpLabel
OpKill
OpFunctionEnd
)";
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
TEST_F(InlineTest, OpKillInIf) {
const std::string text = R"(
; CHECK: OpFunction
; CHECK: OpLabel
; CHECK: [[var:%\w+]] = OpVariable
; CHECK-NEXT: [[ld:%\w+]] = OpLoad {{%\w+}} [[var]]
; CHECK-NEXT: OpBranch [[label:%\w+]]
; CHECK-NEXT: [[label]] = OpLabel
; CHECK-NEXT: OpLoopMerge [[loop_merge:%\w+]] [[continue:%\w+]] None
; CHECK-NEXT: OpBranch [[label:%\w+]]
; CHECK-NEXT: [[label]] = OpLabel
; CHECK-NEXT: OpSelectionMerge [[sel_merge:%\w+]] None
; CHECK-NEXT: OpBranchConditional {{%\w+}} [[kill_label:%\w+]] [[label:%\w+]]
; CHECK-NEXT: [[kill_label]] = OpLabel
; CHECK-NEXT: OpKill
; CHECK-NEXT: [[label]] = OpLabel
; CHECK-NEXT: OpBranch [[loop_merge]]
; CHECK-NEXT: [[sel_merge]] = OpLabel
; CHECK-NEXT: OpBranch [[loop_merge]]
; CHECK-NEXT: [[continue]] = OpLabel
; CHECK-NEXT: OpBranchConditional
; CHECK-NEXT: [[loop_merge]] = OpLabel
; CHECK-NEXT: OpStore [[var]] [[ld]]
; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpFunctionEnd
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%bool = OpTypeBool
%true = OpConstantTrue %bool
%bool_func_ptr = OpTypePointer Function %bool
%voidfuncty = OpTypeFunction %void
%main = OpFunction %void None %voidfuncty
%1 = OpLabel
%2 = OpVariable %bool_func_ptr Function
%3 = OpLoad %bool %2
%4 = OpFunctionCall %void %func
OpStore %2 %3
OpReturn
OpFunctionEnd
%func = OpFunction %void None %voidfuncty
%5 = OpLabel
OpSelectionMerge %6 None
OpBranchConditional %true %7 %8
%7 = OpLabel
OpKill
%8 = OpLabel
OpReturn
%6 = OpLabel
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
TEST_F(InlineTest, OpKillInLoop) {
const std::string text = R"(
; CHECK: OpFunction
; CHECK: OpLabel
; CHECK: [[var:%\w+]] = OpVariable
; CHECK-NEXT: [[ld:%\w+]] = OpLoad {{%\w+}} [[var]]
; CHECK-NEXT: OpBranch [[loop:%\w+]]
; CHECK-NEXT: [[loop]] = OpLabel
; CHECK-NEXT: OpLoopMerge [[loop_merge:%\w+]] [[continue:%\w+]] None
; CHECK-NEXT: OpBranch [[label:%\w+]]
; CHECK-NEXT: [[label]] = OpLabel
; CHECK-NEXT: OpKill
; CHECK-NEXT: [[loop_merge]] = OpLabel
; CHECK-NEXT: OpBranch [[label:%\w+]]
; CHECK-NEXT: [[continue]] = OpLabel
; CHECK-NEXT: OpBranch [[loop]]
; CHECK-NEXT: [[label]] = OpLabel
; CHECK-NEXT: OpStore [[var]] [[ld]]
; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpFunctionEnd
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
%void = OpTypeVoid
%bool = OpTypeBool
%true = OpConstantTrue %bool
%voidfuncty = OpTypeFunction %void
%bool_func_ptr = OpTypePointer Function %bool
%main = OpFunction %void None %voidfuncty
%1 = OpLabel
%2 = OpVariable %bool_func_ptr Function
%3 = OpLoad %bool %2
%4 = OpFunctionCall %void %func
OpStore %2 %3
OpReturn
OpFunctionEnd
%func = OpFunction %void None %voidfuncty
%5 = OpLabel
OpBranch %10
%10 = OpLabel
OpLoopMerge %6 %7 None
OpBranch %8
%8 = OpLabel
OpKill
%6 = OpLabel
OpReturn
%7 = OpLabel
OpBranch %10
OpFunctionEnd
)";
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
TEST_F(InlineTest, OpVariableWithInit) {
// Check that there is a store that corresponds to the initializer. This
// test makes sure that is a store to the variable in the loop and before any
@@ -3112,6 +2936,46 @@ OpFunctionEnd
SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
}
TEST_F(InlineTest, DontInlineFuncWithOpKill) {
const std::string test =
R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 330
OpName %main "main"
OpName %kill_ "kill("
%void = OpTypeVoid
%3 = OpTypeFunction %void
%bool = OpTypeBool
%true = OpConstantTrue %bool
%main = OpFunction %void None %3
%5 = OpLabel
OpBranch %9
%9 = OpLabel
OpLoopMerge %11 %12 None
OpBranch %13
%13 = OpLabel
OpBranchConditional %true %10 %11
%10 = OpLabel
OpBranch %12
%12 = OpLabel
%16 = OpFunctionCall %void %kill_
OpBranch %9
%11 = OpLabel
OpReturn
OpFunctionEnd
%kill_ = OpFunction %void None %3
%7 = OpLabel
OpKill
OpFunctionEnd
)";
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// Empty modules

View File

@@ -1915,7 +1915,7 @@ TEST_F(InstBindlessTest, RuntimeArray) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -1968,7 +1968,7 @@ OpDecorate %_entryPointOutput_vColor Location 0
const std::string defs_after =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -2647,9 +2647,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -2670,9 +2670,9 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2691,9 +2691,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -2715,22 +2715,22 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2928,9 +2928,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -2951,9 +2951,9 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2972,9 +2972,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -2996,22 +2996,22 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -3198,9 +3198,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -3221,9 +3221,9 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -3242,9 +3242,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -3266,22 +3266,22 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -3704,9 +3704,9 @@ TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -3726,8 +3726,8 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 4
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %14 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %14 NonUniform
OpDecorate %b Location 1
%void = OpTypeVoid
%3 = OpTypeFunction %void
@@ -3747,9 +3747,9 @@ OpDecorate %b Location 1
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -3770,8 +3770,8 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 4
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %b Location 1
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
@@ -3978,8 +3978,8 @@ TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -4000,9 +4000,9 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %18 NonUniformEXT
OpDecorate %22 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %18 NonUniform
OpDecorate %22 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -4023,8 +4023,8 @@ OpDecorate %22 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -4046,10 +4046,10 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %89 NonUniformEXT
OpDecorate %120 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %89 NonUniform
OpDecorate %120 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_39 Block
OpMemberDecorate %_struct_39 0 Offset 0
@@ -4061,7 +4061,7 @@ OpDecorate %_struct_98 Block
OpMemberDecorate %_struct_98 0 Offset 0
OpDecorate %100 DescriptorSet 7
OpDecorate %100 Binding 1
OpDecorate %117 NonUniformEXT
OpDecorate %117 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -6313,7 +6313,7 @@ TEST_F(InstBindlessTest, RuntimeArrayV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -6366,7 +6366,7 @@ OpDecorate %_entryPointOutput_vColor Location 0
const std::string defs_after =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -6970,9 +6970,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArrayV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -6993,9 +6993,9 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -7014,9 +7014,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -7038,22 +7038,22 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -7251,9 +7251,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecatedV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -7274,9 +7274,9 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -7295,9 +7295,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -7319,22 +7319,22 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -7521,9 +7521,9 @@ TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -7544,9 +7544,9 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %16 NonUniformEXT
OpDecorate %20 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -7565,9 +7565,9 @@ OpDecorate %20 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -7589,22 +7589,22 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %102 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %102 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
OpMemberDecorate %_struct_31 0 Offset 0
OpDecorate %33 DescriptorSet 7
OpDecorate %33 Binding 1
OpDecorate %130 NonUniformEXT
OpDecorate %130 NonUniform
OpDecorate %_struct_55 Block
OpMemberDecorate %_struct_55 0 Offset 0
OpMemberDecorate %_struct_55 1 Offset 4
OpDecorate %57 DescriptorSet 7
OpDecorate %57 Binding 0
OpDecorate %gl_FragCoord BuiltIn FragCoord
OpDecorate %127 NonUniformEXT
OpDecorate %127 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -8027,9 +8027,9 @@ TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArrayV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -8049,8 +8049,8 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 4
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %14 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %14 NonUniform
OpDecorate %b Location 1
%void = OpTypeVoid
%3 = OpTypeFunction %void
@@ -8070,9 +8070,9 @@ OpDecorate %b Location 1
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability RuntimeDescriptorArrayEXT
OpCapability StorageBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -8093,8 +8093,8 @@ OpDecorate %storageBuffer DescriptorSet 0
OpDecorate %storageBuffer Binding 4
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %b Location 1
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_31 Block
@@ -8301,8 +8301,8 @@ TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArrayV2) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -8323,9 +8323,9 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %18 NonUniformEXT
OpDecorate %22 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %18 NonUniform
OpDecorate %22 NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -8346,8 +8346,8 @@ OpDecorate %22 NonUniformEXT
const std::string defs_after =
R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability UniformBufferArrayNonUniformIndexingEXT
OpCapability ShaderNonUniform
OpCapability UniformBufferArrayNonUniformIndexing
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -8369,10 +8369,10 @@ OpDecorate %uniformBuffer DescriptorSet 0
OpDecorate %uniformBuffer Binding 3
OpDecorate %nu_ii Flat
OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniformEXT
OpDecorate %7 NonUniformEXT
OpDecorate %89 NonUniformEXT
OpDecorate %120 NonUniformEXT
OpDecorate %nu_ii NonUniform
OpDecorate %7 NonUniform
OpDecorate %89 NonUniform
OpDecorate %120 NonUniform
OpDecorate %_runtimearr_uint ArrayStride 4
OpDecorate %_struct_39 Block
OpMemberDecorate %_struct_39 0 Offset 0
@@ -8384,7 +8384,7 @@ OpDecorate %_struct_98 Block
OpMemberDecorate %_struct_98 0 Offset 0
OpDecorate %100 DescriptorSet 7
OpDecorate %100 Binding 1
OpDecorate %117 NonUniformEXT
OpDecorate %117 NonUniform
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -8575,7 +8575,7 @@ TEST_F(InstBindlessTest,
const std::string defs_before =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -8622,7 +8622,7 @@ OpDecorate %images NonWritable
const std::string defs_after =
R"(OpCapability Shader
OpCapability RuntimeDescriptorArrayEXT
OpCapability RuntimeDescriptorArray
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -8895,7 +8895,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -8923,7 +8923,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9219,7 +9219,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9247,7 +9247,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9543,7 +9543,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9571,7 +9571,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9867,7 +9867,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -9895,7 +9895,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -10191,7 +10191,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -10219,7 +10219,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -10515,7 +10515,7 @@ TEST_F(InstBindlessTest,
// }
const std::string defs_before =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
@@ -10543,7 +10543,7 @@ OpDecorate %images NonWritable
)";
const std::string defs_after =
R"(OpCapability RuntimeDescriptorArrayEXT
R"(OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"

View File

@@ -51,10 +51,10 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferStore) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability PhysicalStorageBufferAddressesEXT
OpCapability PhysicalStorageBufferAddresses
OpExtension "SPV_EXT_physical_storage_buffer"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
@@ -78,31 +78,31 @@ OpDecorate %u_info DescriptorSet 0
OpDecorate %u_info Binding 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_bufStruct PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%uint = OpTypeInt 32 0
%ufoo = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_bufStruct %uint
%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
%int = OpTypeInt 32 1
%uint_2 = OpConstant %uint 2
%_arr_int_uint_2 = OpTypeArray %int %uint_2
%bufStruct = OpTypeStruct %_arr_int_uint_2 %int
%_ptr_PhysicalStorageBufferEXT_bufStruct = OpTypePointer PhysicalStorageBufferEXT %bufStruct
%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
%u_info = OpVariable %_ptr_Uniform_ufoo Uniform
%int_0 = OpConstant %int 0
%_ptr_Uniform__ptr_PhysicalStorageBufferEXT_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBufferEXT_bufStruct
%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
%int_1 = OpConstant %int 1
%int_3239 = OpConstant %int 3239
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
)";
const std::string defs_after =
R"(OpCapability Shader
OpCapability PhysicalStorageBufferAddressesEXT
OpCapability PhysicalStorageBufferAddresses
OpCapability Int64
OpExtension "SPV_EXT_physical_storage_buffer"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
@@ -138,21 +138,21 @@ OpDecorate %79 Binding 0
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
%void = OpTypeVoid
%8 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_bufStruct PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%uint = OpTypeInt 32 0
%ufoo = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_bufStruct %uint
%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
%int = OpTypeInt 32 1
%uint_2 = OpConstant %uint 2
%_arr_int_uint_2 = OpTypeArray %int %uint_2
%bufStruct = OpTypeStruct %_arr_int_uint_2 %int
%_ptr_PhysicalStorageBufferEXT_bufStruct = OpTypePointer PhysicalStorageBufferEXT %bufStruct
%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
%u_info = OpVariable %_ptr_Uniform_ufoo Uniform
%int_0 = OpConstant %int 0
%_ptr_Uniform__ptr_PhysicalStorageBufferEXT_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBufferEXT_bufStruct
%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
%int_1 = OpConstant %int 1
%int_3239 = OpConstant %int 3239
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
%ulong = OpTypeInt 64 0
%uint_4 = OpConstant %uint 4
%bool = OpTypeBool
@@ -188,9 +188,9 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_bufStruct PhysicalStorageBuf
const std::string func_before =
R"(%main = OpFunction %void None %3
%5 = OpLabel
%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBufferEXT_bufStruct %u_info %int_0
%18 = OpLoad %_ptr_PhysicalStorageBufferEXT_bufStruct %17
%22 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %18 %int_1
%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
OpStore %22 %int_3239 Aligned 16
OpReturn
OpFunctionEnd
@@ -199,9 +199,9 @@ OpFunctionEnd
const std::string func_after =
R"(%main = OpFunction %void None %8
%19 = OpLabel
%20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBufferEXT_bufStruct %u_info %int_0
%21 = OpLoad %_ptr_PhysicalStorageBufferEXT_bufStruct %20
%22 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %21 %int_1
%20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
%21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20
%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1
%24 = OpConvertPtrToU %ulong %22
%61 = OpFunctionCall %bool %26 %24 %uint_4
OpSelectionMerge %62 None
@@ -339,11 +339,11 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) {
const std::string defs_before =
R"(OpCapability Shader
OpCapability PhysicalStorageBufferAddressesEXT
OpCapability PhysicalStorageBufferAddresses
OpExtension "SPV_EXT_physical_storage_buffer"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
@@ -364,29 +364,29 @@ OpDecorate %r DescriptorSet 0
OpDecorate %r Binding 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_blockType PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%int = OpTypeInt 32 1
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_blockType
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
%_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
%_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
%r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_1 = OpConstant %int 1
%_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_531 = OpConstant %int 531
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
)";
const std::string defs_after =
R"(OpCapability Shader
OpCapability PhysicalStorageBufferAddressesEXT
OpCapability PhysicalStorageBufferAddresses
OpCapability Int64
OpExtension "SPV_EXT_physical_storage_buffer"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64EXT GLSL450
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
@@ -419,19 +419,19 @@ OpDecorate %86 Binding 0
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
%void = OpTypeVoid
%3 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_blockType PhysicalStorageBufferEXT
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%int = OpTypeInt 32 1
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBufferEXT_blockType
%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType
%_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType
%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType
%_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock
%r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_1 = OpConstant %int 1
%_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType = OpTypePointer PhysicalStorageBufferEXT %_ptr_PhysicalStorageBufferEXT_blockType
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_531 = OpConstant %int 531
%_ptr_PhysicalStorageBufferEXT_int = OpTypePointer PhysicalStorageBufferEXT %int
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%ulong = OpTypeInt 64 0
@@ -464,18 +464,18 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBufferEXT_blockType PhysicalStorageBuf
%uint_7 = OpConstant %uint 7
%uint_9 = OpConstant %uint 9
%uint_44 = OpConstant %uint 44
%132 = OpConstantNull %_ptr_PhysicalStorageBufferEXT_blockType
%132 = OpConstantNull %_ptr_PhysicalStorageBuffer_blockType
%uint_46 = OpConstant %uint 46
)";
const std::string func_before =
R"(%main = OpFunction %void None %3
%5 = OpLabel
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType %17 %int_1
%22 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %21 Aligned 8
%26 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %22 %int_0
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1
%22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
OpStore %26 %int_531 Aligned 16
OpReturn
OpFunctionEnd
@@ -484,15 +484,15 @@ OpFunctionEnd
const std::string func_after =
R"(%main = OpFunction %void None %3
%5 = OpLabel
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBufferEXT_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBufferEXT__ptr_PhysicalStorageBufferEXT_blockType %17 %int_1
%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0
%17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16
%21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1
%30 = OpConvertPtrToU %ulong %21
%67 = OpFunctionCall %bool %32 %30 %uint_8
OpSelectionMerge %68 None
OpBranchConditional %67 %69 %70
%69 = OpLabel
%71 = OpLoad %_ptr_PhysicalStorageBufferEXT_blockType %21 Aligned 8
%71 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
OpBranch %68
%70 = OpLabel
%72 = OpUConvert %uint %30
@@ -501,8 +501,8 @@ OpBranch %68
%131 = OpFunctionCall %void %76 %uint_44 %uint_2 %72 %75
OpBranch %68
%68 = OpLabel
%133 = OpPhi %_ptr_PhysicalStorageBufferEXT_blockType %71 %69 %132 %70
%26 = OpAccessChain %_ptr_PhysicalStorageBufferEXT_int %133 %int_0
%133 = OpPhi %_ptr_PhysicalStorageBuffer_blockType %71 %69 %132 %70
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %133 %int_0
%134 = OpConvertPtrToU %ulong %26
%135 = OpFunctionCall %bool %32 %134 %uint_4
OpSelectionMerge %136 None

View File

@@ -34,9 +34,9 @@ void operator+=(std::vector<const char*>& lhs,
std::vector<const char*> header = {
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%v3uint = OpTypeVector %uint 3"};

View File

@@ -138,8 +138,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, NestedForLoop) {
@@ -280,8 +280,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, ForLoopWithContinue) {
@@ -426,9 +426,9 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(
predefs + names + predefs2 + before, predefs + names + predefs2 + after,
true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + names + predefs2 + before,
predefs + names + predefs2 + after,
true, true);
}
TEST_F(LocalSSAElimTest, ForLoopWithBreak) {
@@ -567,8 +567,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, SwapProblem) {
@@ -704,8 +704,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, LostCopyProblem) {
@@ -848,8 +848,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, IfThenElse) {
@@ -948,8 +948,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, IfThen) {
@@ -1037,8 +1037,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, Switch) {
@@ -1168,8 +1168,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, SwitchWithFallThrough) {
@@ -1300,8 +1300,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(predefs + before,
predefs + after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
true);
}
TEST_F(LocalSSAElimTest, DontPatchPhiInLoopHeaderThatIsNotAVar) {
@@ -1331,7 +1331,7 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(before, before, true, true);
SinglePassRunAndCheck<SSARewritePass>(before, before, true, true);
}
TEST_F(LocalSSAElimTest, OptInitializedVariableLikeStore) {
@@ -1428,8 +1428,8 @@ OpReturn
OpFunctionEnd
)";
SinglePassRunAndCheck<LocalMultiStoreElimPass>(
predefs + func_before, predefs + func_after, true, true);
SinglePassRunAndCheck<SSARewritePass>(predefs + func_before,
predefs + func_after, true, true);
}
TEST_F(LocalSSAElimTest, PointerVariable) {
@@ -1531,7 +1531,7 @@ OpFunctionEnd
// Relax logical pointers to allow pointer allocations.
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
ValidatorOptions()->relax_logical_pointer = true;
SinglePassRunAndCheck<LocalMultiStoreElimPass>(before, after, true, true);
SinglePassRunAndCheck<SSARewritePass>(before, after, true, true);
}
TEST_F(LocalSSAElimTest, VerifyInstToBlockMap) {
@@ -1620,7 +1620,7 @@ OpFunctionEnd
// Force the instruction to block mapping to get built.
context->get_instr_block(27u);
auto pass = MakeUnique<LocalMultiStoreElimPass>();
auto pass = MakeUnique<SSARewritePass>();
pass->SetMessageConsumer(nullptr);
const auto status = pass->Run(context.get());
EXPECT_TRUE(status == Pass::Status::SuccessWithChange);
@@ -1927,7 +1927,7 @@ TEST_F(LocalSSAElimTest, VariablePointerTest2) {
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<LocalMultiStoreElimPass>(text, false);
SinglePassRunAndMatch<SSARewritePass>(text, false);
}
TEST_F(LocalSSAElimTest, ChainedTrivialPhis) {
@@ -1987,6 +1987,41 @@ TEST_F(LocalSSAElimTest, ChainedTrivialPhis) {
SinglePassRunAndMatch<SSARewritePass>(text, false);
}
TEST_F(LocalSSAElimTest, Overflowtest1) {
// Check that the copy object get the undef value implicitly assigned in the
// entry block.
const std::string text = R"(
OpCapability Geometry
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "P2Mai" %12 %17
OpExecutionMode %4 OriginUpperLeft
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%11 = OpTypePointer Input %7
%16 = OpTypePointer Output %7
%23 = OpTypePointer Function %7
%12 = OpVariable %11 Input
%17 = OpVariable %16 Output
%4 = OpFunction %2 None %3
%2177 = OpLabel
%4194302 = OpVariable %23 Function
%4194301 = OpLoad %7 %4194302
OpStore %17 %4194301
OpReturn
OpFunctionEnd
)";
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
std::vector<Message> messages = {
{SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
SetMessageConsumer(GetTestMessageConsumer(messages));
auto result = SinglePassRunToBinary<SSARewritePass>(text, true);
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// No optimization in the presence of

View File

@@ -273,7 +273,8 @@ TEST_P(VulkanToWebGPUPassTest, Ran) {
std::vector<uint32_t> optimized;
class ValidatorOptions validator_options;
ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized,
validator_options, true));
validator_options, true))
<< GetParam().input << "\n";
std::string disassembly;
{
SpirvTools tools(SPV_ENV_WEBGPU_0);
@@ -290,9 +291,9 @@ INSTANTIATE_TEST_SUITE_P(
// FlattenDecorations
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Fragment %main \"main\" %hue %saturation %value\n"
"OpExecutionMode %main OriginUpperLeft\n"
"OpDecorate %group Flat\n"
@@ -311,9 +312,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Fragment %1 \"main\" %2 %3 %4\n"
"OpExecutionMode %1 OriginUpperLeft\n"
"%void = OpTypeVoid\n"
@@ -332,9 +333,9 @@ INSTANTIATE_TEST_SUITE_P(
// Strip Debug
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %func \"shader\"\n"
"OpName %main \"main\"\n"
"OpName %void_fn \"void_fn\"\n"
@@ -346,9 +347,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%void = OpTypeVoid\n"
"%3 = OpTypeFunction %void\n"
@@ -361,9 +362,9 @@ INSTANTIATE_TEST_SUITE_P(
// Eliminate Dead Constants
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %func \"shader\"\n"
"%u32 = OpTypeInt 32 0\n"
"%u32_ptr = OpTypePointer Workgroup %u32\n"
@@ -380,9 +381,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint\n"
@@ -397,9 +398,9 @@ INSTANTIATE_TEST_SUITE_P(
// Strip Atomic Counter Memory
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %func \"shader\"\n"
"%u32 = OpTypeInt 32 0\n"
"%u32_ptr = OpTypePointer Workgroup %u32\n"
@@ -412,7 +413,7 @@ INSTANTIATE_TEST_SUITE_P(
"%void_f = OpTypeFunction %void\n"
"%func = OpFunction %void None %void_f\n"
"%label = OpLabel\n"
"%val0 = OpAtomicStore %u32_var %cross_device "
" OpAtomicStore %u32_var %cross_device "
"%acquire_release_atomic_counter_workgroup %u32_1\n"
"%val1 = OpAtomicIIncrement %u32 %u32_var %cross_device "
"%acquire_release_atomic_counter_workgroup\n"
@@ -423,9 +424,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint\n"
@@ -449,9 +450,9 @@ INSTANTIATE_TEST_SUITE_P(
// Generate WebGPU Initializers
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %func \"shader\"\n"
"%u32 = OpTypeInt 32 0\n"
"%u32_ptr = OpTypePointer Private %u32\n"
@@ -466,9 +467,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%_ptr_Private_uint = OpTypePointer Private %uint\n"
@@ -487,9 +488,9 @@ INSTANTIATE_TEST_SUITE_P(
// Legalize Vector Shuffle
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%v3uint = OpTypeVector %uint 3\n"
@@ -506,9 +507,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%v3uint = OpTypeVector %uint 3\n"
@@ -529,9 +530,9 @@ INSTANTIATE_TEST_SUITE_P(
// Split Invalid Unreachable
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%uint_1 = OpConstant %uint 1\n"
@@ -560,9 +561,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%uint_1 = OpConstant %uint 1\n"
@@ -596,9 +597,9 @@ INSTANTIATE_TEST_SUITE_P(
// Compact IDs
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1000 \"shader\"\n"
"%10 = OpTypeVoid\n"
"%100 = OpTypeFunction %10\n"
@@ -608,9 +609,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%void = OpTypeVoid\n"
"%3 = OpTypeFunction %void\n"
@@ -682,9 +683,9 @@ INSTANTIATE_TEST_SUITE_P(
// Decompose Initialized Variables
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%_ptr_Function_uint = OpTypePointer Function %uint\n"
@@ -698,9 +699,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%uint = OpTypeInt 32 0\n"
"%_ptr_Function_uint = OpTypePointer Function %uint\n"
@@ -718,9 +719,9 @@ INSTANTIATE_TEST_SUITE_P(
// Compact IDs
{// input
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1000 \"shader\"\n"
"%10 = OpTypeVoid\n"
"%100 = OpTypeFunction %10\n"
@@ -730,9 +731,9 @@ INSTANTIATE_TEST_SUITE_P(
"OpFunctionEnd\n",
// expected
"OpCapability Shader\n"
"OpCapability VulkanMemoryModelKHR\n"
"OpCapability VulkanMemoryModel\n"
"OpExtension \"SPV_KHR_vulkan_memory_model\"\n"
"OpMemoryModel Logical VulkanKHR\n"
"OpMemoryModel Logical Vulkan\n"
"OpEntryPoint Vertex %1 \"shader\"\n"
"%void = OpTypeVoid\n"
"%3 = OpTypeFunction %void\n"

View File

@@ -206,7 +206,7 @@ TEST_F(SimplificationTest, CopyObjectWithDecorations1) {
// Don't simplify OpCopyObject if the result id has a decoration that the
// operand does not.
const std::string text = R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability ShaderNonUniform
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -214,7 +214,7 @@ OpExecutionMode %2 OriginUpperLeft
OpSource GLSL 430
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpDecorate %3 NonUniformEXT
OpDecorate %3 NonUniform
%void = OpTypeVoid
%5 = OpTypeFunction %void
%int = OpTypeInt 32 1
@@ -234,7 +234,7 @@ TEST_F(SimplificationTest, CopyObjectWithDecorations2) {
// Simplify OpCopyObject if the result id is a subset of the decorations of
// the operand.
const std::string before = R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability ShaderNonUniform
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -242,7 +242,7 @@ OpExecutionMode %2 OriginUpperLeft
OpSource GLSL 430
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpDecorate %3 NonUniformEXT
OpDecorate %3 NonUniform
%void = OpTypeVoid
%5 = OpTypeFunction %void
%int = OpTypeInt 32 1
@@ -256,7 +256,7 @@ OpFunctionEnd
)";
const std::string after = R"(OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability ShaderNonUniform
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -264,7 +264,7 @@ OpExecutionMode %2 OriginUpperLeft
OpSource GLSL 430
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpDecorate %3 NonUniformEXT
OpDecorate %3 NonUniform
%void = OpTypeVoid
%5 = OpTypeFunction %void
%int = OpTypeInt 32 1

View File

@@ -24,9 +24,9 @@ namespace {
using SplitInvalidUnreachableTest = PassTest<::testing::Test>;
std::string spirv_header = R"(OpCapability Shader
OpCapability VulkanMemoryModelKHR
OpCapability VulkanMemoryModel
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpMemoryModel Logical Vulkan
OpEntryPoint Vertex %1 "shader"
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1

View File

@@ -45,9 +45,9 @@ std::string GetUnchangedString(std::string(generate_inst)(std::string),
std::vector<const char*> result = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint",
@@ -76,9 +76,9 @@ std::string GetChangedString(std::string(generate_inst)(std::string),
std::vector<const char*> result = {
// clang-format off
"OpCapability Shader",
"OpCapability VulkanMemoryModelKHR",
"OpCapability VulkanMemoryModel",
"OpExtension \"SPV_KHR_vulkan_memory_model\"",
"OpMemoryModel Logical VulkanKHR",
"OpMemoryModel Logical Vulkan",
"OpEntryPoint Vertex %1 \"shader\"",
"%uint = OpTypeInt 32 0",
"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint",

View File

@@ -34,14 +34,14 @@ OpMemoryModel Logical OpenCL
SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
}
TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelVulkanKHR) {
TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelVulkan) {
const std::string text = R"(
; CHECK: OpMemoryModel Logical VulkanKHR
; CHECK: OpMemoryModel Logical Vulkan
OpCapability Shader
OpCapability Linkage
OpCapability VulkanMemoryModelKHR
OpCapability VulkanMemoryModel
OpExtension "SPV_KHR_vulkan_memory_model"
OpMemoryModel Logical VulkanKHR
OpMemoryModel Logical Vulkan
)";
SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
@@ -49,9 +49,9 @@ OpMemoryModel Logical VulkanKHR
TEST_F(UpgradeMemoryModelTest, JustMemoryModel) {
const std::string text = R"(
; CHECK: OpCapability VulkanMemoryModelKHR
; CHECK: OpCapability VulkanMemoryModel
; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
; CHECK: OpMemoryModel Logical VulkanKHR
; CHECK: OpMemoryModel Logical Vulkan
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -79,8 +79,8 @@ OpDecorate %var Coherent
TEST_F(UpgradeMemoryModelTest, WorkgroupVariable) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -92,7 +92,7 @@ OpMemoryModel Logical GLSL450
%func = OpFunction %void None %func_ty
%1 = OpLabel
%ld = OpLoad %int %var
%st = OpStore %var %ld
OpStore %var %ld
OpReturn
OpFunctionEnd
)";
@@ -103,8 +103,8 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, WorkgroupFunctionParameter) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -116,7 +116,7 @@ OpMemoryModel Logical GLSL450
%param = OpFunctionParameter %ptr_int_Workgroup
%1 = OpLabel
%ld = OpLoad %int %param
%st = OpStore %param %ld
OpStore %param %ld
OpReturn
OpFunctionEnd
)";
@@ -128,8 +128,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformVariable) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -155,8 +155,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameter) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -208,8 +208,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableCopied) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -236,8 +236,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterCopied) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -265,8 +265,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableAccessChain) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -297,8 +297,8 @@ TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterAccessChain) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
@@ -330,8 +330,8 @@ TEST_F(UpgradeMemoryModelTest, VariablePointerSelect) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability VariablePointers
@@ -363,8 +363,8 @@ TEST_F(UpgradeMemoryModelTest, VariablePointerSelectConservative) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability VariablePointers
@@ -396,8 +396,8 @@ TEST_F(UpgradeMemoryModelTest, VariablePointerIncrement) {
const std::string text = R"(
; CHECK-NOT: OpDecorate {{%\w+}} Coherent
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability VariablePointers
@@ -439,8 +439,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentStructElement) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -470,8 +470,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentElementFullStructAccess) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -497,9 +497,9 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, CoherentElementNotAccessed) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK-NOT: MakePointerAvailableKHR
; CHECK-NOT: NonPrivatePointerKHR
; CHECK-NOT: MakePointerVisibleKHR
; CHECK-NOT: MakePointerAvailable
; CHECK-NOT: NonPrivatePointer
; CHECK-NOT: MakePointerVisible
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -529,8 +529,8 @@ TEST_F(UpgradeMemoryModelTest, MultiIndexAccessCoherent) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -563,9 +563,9 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, MultiIndexAccessNonCoherent) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK-NOT: MakePointerAvailableKHR
; CHECK-NOT: NonPrivatePointerKHR
; CHECK-NOT: MakePointerVisibleKHR
; CHECK-NOT: MakePointerAvailable
; CHECK-NOT: NonPrivatePointer
; CHECK-NOT: MakePointerVisible
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -599,8 +599,8 @@ TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainCoherent) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -639,9 +639,9 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainNonCoherent) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK-NOT: MakePointerAvailableKHR
; CHECK-NOT: NonPrivatePointerKHR
; CHECK-NOT: MakePointerVisibleKHR
; CHECK-NOT: MakePointerAvailable
; CHECK-NOT: NonPrivatePointer
; CHECK-NOT: MakePointerVisible
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -681,8 +681,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentStructElementAccess) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -722,8 +722,8 @@ TEST_F(UpgradeMemoryModelTest, NonCoherentLoadCoherentStore) {
const std::string text = R"(
; CHECK-NOT: OpMemberDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK-NOT: MakePointerVisibleKHR
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
; CHECK-NOT: MakePointerVisible
; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -763,7 +763,7 @@ TEST_F(UpgradeMemoryModelTest, CopyMemory) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[queuefamily]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[queuefamily]]
; CHECK-NOT: [[queuefamily]]
OpCapability Shader
OpCapability Linkage
@@ -791,7 +791,7 @@ TEST_F(UpgradeMemoryModelTest, CopyMemorySized) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemorySized {{%\w+}} {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[queuefamily]]
; CHECK: OpCopyMemorySized {{%\w+}} {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[queuefamily]]
; CHECK-NOT: [[queuefamily]]
OpCapability Shader
OpCapability Linkage
@@ -822,7 +822,7 @@ TEST_F(UpgradeMemoryModelTest, CopyMemoryTwoScopes) {
; CHECK-NOT: OpDecorate
; CHECK-DAG: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
; CHECK-DAG: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailableKHR|MakePointerVisibleKHR|NonPrivatePointerKHR [[workgroup]] [[queuefamily]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|MakePointerVisible|NonPrivatePointer [[workgroup]] [[queuefamily]]
OpCapability Shader
OpCapability Linkage
OpExtension "SPV_KHR_storage_buffer_storage_class"
@@ -850,7 +850,7 @@ TEST_F(UpgradeMemoryModelTest, VolatileImageRead) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -882,8 +882,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentImageRead) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -916,9 +916,9 @@ TEST_F(UpgradeMemoryModelTest, CoherentImageReadExtractedFromSampledImage) {
; CHECK-NOT: OpDecorate
; CHECK: [[image:%\w+]] = OpTypeImage
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK-NOT: NonPrivatePointerKHR
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK-NOT: NonPrivatePointer
; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -957,7 +957,7 @@ TEST_F(UpgradeMemoryModelTest, VolatileImageWrite) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageWriteWithoutFormat
@@ -989,8 +989,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentImageWrite) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageWriteWithoutFormat
@@ -1022,9 +1022,9 @@ TEST_F(UpgradeMemoryModelTest, CoherentImageWriteExtractFromSampledImage) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR
; CHECK-NOT: NonPrivatePointerKHR
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
; CHECK-NOT: NonPrivatePointer
; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageWriteWithoutFormat
@@ -1063,7 +1063,7 @@ TEST_F(UpgradeMemoryModelTest, VolatileImageSparseRead) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -1097,8 +1097,8 @@ TEST_F(UpgradeMemoryModelTest, CoherentImageSparseRead) {
const std::string text = R"(
; CHECK-NOT: OpDecorate
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -1134,9 +1134,9 @@ TEST_F(UpgradeMemoryModelTest,
; CHECK-NOT: OpDecorate
; CHECK: [[image:%\w+]] = OpTypeImage
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK-NOT: NonPrivatePointerKHR
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
; CHECK-NOT: NonPrivatePointer
; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
OpCapability Shader
OpCapability Linkage
OpCapability StorageImageReadWithoutFormat
@@ -1440,7 +1440,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeModfNoFlags) {
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]]
; CHECK-NOT: NonPrivatePointerKHR
; CHECK-NOT: NonPrivatePointer
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1474,7 +1474,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeModfWorkgroupCoherent) {
; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailableKHR|NonPrivatePointerKHR [[wg_scope]]
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1509,7 +1509,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeModfSSBOCoherent) {
; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailableKHR|NonPrivatePointerKHR [[qf_scope]]
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1579,7 +1579,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeFrexpNoFlags) {
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]]
; CHECK-NOT: NonPrivatePointerKHR
; CHECK-NOT: NonPrivatePointer
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1615,7 +1615,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeFrexpWorkgroupCoherent) {
; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailableKHR|NonPrivatePointerKHR [[wg_scope]]
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1652,7 +1652,7 @@ TEST_F(UpgradeMemoryModelTest, UpgradeFrexpSSBOCoherent) {
; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailableKHR|NonPrivatePointerKHR [[qf_scope]]
; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1785,7 +1785,7 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherent) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]] None
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1810,7 +1810,7 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentPreviousArgs) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 [[scope]] Aligned 4
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 4
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1835,7 +1835,7 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherent) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None MakePointerVisible|NonPrivatePointer [[scope]]
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1860,7 +1860,7 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherentPreviousArgs) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 [[scope]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned|MakePointerVisible|NonPrivatePointer 4 [[scope]]
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1886,7 +1886,7 @@ TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherent) {
const std::string text = R"(
; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[wg]] MakePointerVisibleKHR|NonPrivatePointerKHR [[queue]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[wg]] MakePointerVisible|NonPrivatePointer [[queue]]
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1913,7 +1913,7 @@ TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherentPreviousArgs) {
const std::string text = R"(
; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 [[queue]] Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 [[wg]]
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[queue]] Aligned|MakePointerVisible|NonPrivatePointer 4 [[wg]]
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -1989,7 +1989,7 @@ OpFunctionEnd
TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentTwoOperands) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]] None
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst
@@ -2015,7 +2015,7 @@ TEST_F(UpgradeMemoryModelTest,
SPV14CopyMemoryDstCoherentPreviousArgsTwoOperands) {
const std::string text = R"(
; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 [[scope]] Aligned 8
; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 8
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %func "func" %src %dst

View File

@@ -262,6 +262,30 @@ OpFunctionEnd
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
}
TEST_F(WrapOpKillTest, IdBoundOverflow4) {
const std::string text = R"(
OpCapability DerivativeControl
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpDecorate %2 Location 539091968
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%4 = OpFunction %2 Inline|Pure|Const %3
%4194302 = OpLabel
OpKill
OpFunctionEnd
)";
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
std::vector<Message> messages = {
{SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
SetMessageConsumer(GetTestMessageConsumer(messages));
auto result = SinglePassRunToBinary<WrapOpKill>(text, true);
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
}
} // namespace
} // namespace opt
} // namespace spvtools

View File

@@ -328,7 +328,6 @@ INSTANTIATE_TEST_SUITE_P(
using OpConstantInvalidTypeTest =
spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>;
TEST_P(OpConstantInvalidTypeTest, InvalidTypes) {
const std::string input = "%1 = " + GetParam() +
"\n"
@@ -360,8 +359,11 @@ INSTANTIATE_TEST_SUITE_P(
"OpTypeReserveId",
"OpTypeQueue",
"OpTypePipe ReadOnly",
"OpTypeForwardPointer %a UniformConstant",
// At least one thing that isn't a type at all
// Skip OpTypeForwardPointer doesn't even produce a result ID.
// The assembler errors out if we try to check it in this scenario.
// Try at least one thing that isn't a type at all
"OpNot %a %b"
},
}));
@@ -470,8 +472,10 @@ INSTANTIATE_TEST_SUITE_P(
"OpTypeReserveId",
"OpTypeQueue",
"OpTypePipe ReadOnly",
"OpTypeForwardPointer %a UniformConstant",
// At least one thing that isn't a type at all
// Skip testing OpTypeForwardPointer because it doesn't even produce a result ID.
// Try at least one thing that isn't a type at all
"OpNot %a %b"
},
}));

View File

@@ -342,7 +342,7 @@ TEST_P(OpSwitchInvalidTypeTestCase, InvalidTypes) {
"%1 = " + GetParam() +
"\n"
"%3 = OpCopyObject %1 %2\n" // We only care the type of the expression
"%4 = OpSwitch %3 %default 32 %c\n";
" OpSwitch %3 %default 32 %c\n";
EXPECT_THAT(CompileFailure(input),
Eq("The selector operand for OpSwitch must be the result of an "
"instruction that generates an integer scalar"));
@@ -371,8 +371,11 @@ INSTANTIATE_TEST_SUITE_P(
"OpTypeReserveId",
"OpTypeQueue",
"OpTypePipe ReadOnly",
"OpTypeForwardPointer %a UniformConstant",
// At least one thing that isn't a type at all
// Skip OpTypeForwardPointer becasuse it doesn't even produce a result
// ID.
// At least one thing that isn't a type at all
"OpNot %a %b"
},
}));

View File

@@ -527,54 +527,54 @@ INSTANTIATE_TEST_SUITE_P(
Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1),
ValuesIn(std::vector<AssemblyCase>{
{"OpCapability VulkanMemoryModelKHR\n",
{"OpCapability VulkanMemoryModel\n",
MakeInstruction(SpvOpCapability,
{SpvCapabilityVulkanMemoryModelKHR})},
{"OpCapability VulkanMemoryModelDeviceScopeKHR\n",
{"OpCapability VulkanMemoryModelDeviceScope\n",
MakeInstruction(SpvOpCapability,
{SpvCapabilityVulkanMemoryModelDeviceScopeKHR})},
{"OpMemoryModel Logical VulkanKHR\n",
{"OpMemoryModel Logical Vulkan\n",
MakeInstruction(SpvOpMemoryModel, {SpvAddressingModelLogical,
SpvMemoryModelVulkanKHR})},
{"OpStore %1 %2 MakePointerAvailableKHR %3\n",
{"OpStore %1 %2 MakePointerAvailable %3\n",
MakeInstruction(SpvOpStore,
{1, 2, SpvMemoryAccessMakePointerAvailableKHRMask,
3})},
{"OpStore %1 %2 Volatile|MakePointerAvailableKHR %3\n",
{"OpStore %1 %2 Volatile|MakePointerAvailable %3\n",
MakeInstruction(SpvOpStore,
{1, 2,
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
int(SpvMemoryAccessVolatileMask),
3})},
{"OpStore %1 %2 Aligned|MakePointerAvailableKHR 4 %3\n",
{"OpStore %1 %2 Aligned|MakePointerAvailable 4 %3\n",
MakeInstruction(SpvOpStore,
{1, 2,
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
int(SpvMemoryAccessAlignedMask),
4, 3})},
{"OpStore %1 %2 MakePointerAvailableKHR|NonPrivatePointerKHR %3\n",
{"OpStore %1 %2 MakePointerAvailable|NonPrivatePointer %3\n",
MakeInstruction(SpvOpStore,
{1, 2,
int(SpvMemoryAccessMakePointerAvailableKHRMask) |
int(SpvMemoryAccessNonPrivatePointerKHRMask),
3})},
{"%2 = OpLoad %1 %3 MakePointerVisibleKHR %4\n",
{"%2 = OpLoad %1 %3 MakePointerVisible %4\n",
MakeInstruction(SpvOpLoad,
{1, 2, 3, SpvMemoryAccessMakePointerVisibleKHRMask,
4})},
{"%2 = OpLoad %1 %3 Volatile|MakePointerVisibleKHR %4\n",
{"%2 = OpLoad %1 %3 Volatile|MakePointerVisible %4\n",
MakeInstruction(SpvOpLoad,
{1, 2, 3,
int(SpvMemoryAccessMakePointerVisibleKHRMask) |
int(SpvMemoryAccessVolatileMask),
4})},
{"%2 = OpLoad %1 %3 Aligned|MakePointerVisibleKHR 8 %4\n",
{"%2 = OpLoad %1 %3 Aligned|MakePointerVisible 8 %4\n",
MakeInstruction(SpvOpLoad,
{1, 2, 3,
int(SpvMemoryAccessMakePointerVisibleKHRMask) |
int(SpvMemoryAccessAlignedMask),
8, 4})},
{"%2 = OpLoad %1 %3 MakePointerVisibleKHR|NonPrivatePointerKHR "
{"%2 = OpLoad %1 %3 MakePointerVisible|NonPrivatePointer "
"%4\n",
MakeInstruction(SpvOpLoad,
{1, 2, 3,
@@ -582,9 +582,9 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvMemoryAccessNonPrivatePointerKHRMask),
4})},
{"OpCopyMemory %1 %2 "
"MakePointerAvailableKHR|"
"MakePointerVisibleKHR|"
"NonPrivatePointerKHR "
"MakePointerAvailable|"
"MakePointerVisible|"
"NonPrivatePointer "
"%3 %4\n",
MakeInstruction(SpvOpCopyMemory,
{1, 2,
@@ -593,9 +593,9 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvMemoryAccessNonPrivatePointerKHRMask)),
3, 4})},
{"OpCopyMemorySized %1 %2 %3 "
"MakePointerAvailableKHR|"
"MakePointerVisibleKHR|"
"NonPrivatePointerKHR "
"MakePointerAvailable|"
"MakePointerVisible|"
"NonPrivatePointer "
"%4 %5\n",
MakeInstruction(SpvOpCopyMemorySized,
{1, 2, 3,
@@ -604,12 +604,12 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvMemoryAccessNonPrivatePointerKHRMask)),
4, 5})},
// Image operands
{"OpImageWrite %1 %2 %3 MakeTexelAvailableKHR "
{"OpImageWrite %1 %2 %3 MakeTexelAvailable "
"%4\n",
MakeInstruction(
SpvOpImageWrite,
{1, 2, 3, int(SpvImageOperandsMakeTexelAvailableKHRMask), 4})},
{"OpImageWrite %1 %2 %3 MakeTexelAvailableKHR|NonPrivateTexelKHR "
{"OpImageWrite %1 %2 %3 MakeTexelAvailable|NonPrivateTexel "
"%4\n",
MakeInstruction(SpvOpImageWrite,
{1, 2, 3,
@@ -617,7 +617,7 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvImageOperandsNonPrivateTexelKHRMask),
4})},
{"OpImageWrite %1 %2 %3 "
"MakeTexelAvailableKHR|NonPrivateTexelKHR|VolatileTexelKHR "
"MakeTexelAvailable|NonPrivateTexel|VolatileTexel "
"%4\n",
MakeInstruction(SpvOpImageWrite,
{1, 2, 3,
@@ -625,14 +625,14 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvImageOperandsNonPrivateTexelKHRMask) |
int(SpvImageOperandsVolatileTexelKHRMask),
4})},
{"%2 = OpImageRead %1 %3 %4 MakeTexelVisibleKHR "
{"%2 = OpImageRead %1 %3 %4 MakeTexelVisible "
"%5\n",
MakeInstruction(SpvOpImageRead,
{1, 2, 3, 4,
int(SpvImageOperandsMakeTexelVisibleKHRMask),
5})},
{"%2 = OpImageRead %1 %3 %4 "
"MakeTexelVisibleKHR|NonPrivateTexelKHR "
"MakeTexelVisible|NonPrivateTexel "
"%5\n",
MakeInstruction(SpvOpImageRead,
{1, 2, 3, 4,
@@ -640,7 +640,7 @@ INSTANTIATE_TEST_SUITE_P(
int(SpvImageOperandsNonPrivateTexelKHRMask),
5})},
{"%2 = OpImageRead %1 %3 %4 "
"MakeTexelVisibleKHR|NonPrivateTexelKHR|VolatileTexelKHR "
"MakeTexelVisible|NonPrivateTexel|VolatileTexel "
"%5\n",
MakeInstruction(SpvOpImageRead,
{1, 2, 3, 4,
@@ -826,82 +826,82 @@ INSTANTIATE_TEST_SUITE_P(
MakeInstruction(SpvOpExtension,
MakeVector("SPV_EXT_descriptor_indexing"))},
// Check capabilities, by name
{"OpCapability ShaderNonUniformEXT\n",
{"OpCapability ShaderNonUniform\n",
MakeInstruction(SpvOpCapability,
{SpvCapabilityShaderNonUniformEXT})},
{"OpCapability RuntimeDescriptorArrayEXT\n",
{"OpCapability RuntimeDescriptorArray\n",
MakeInstruction(SpvOpCapability,
{SpvCapabilityRuntimeDescriptorArrayEXT})},
{"OpCapability InputAttachmentArrayDynamicIndexingEXT\n",
{"OpCapability InputAttachmentArrayDynamicIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityInputAttachmentArrayDynamicIndexingEXT})},
{"OpCapability UniformTexelBufferArrayDynamicIndexingEXT\n",
{"OpCapability UniformTexelBufferArrayDynamicIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT})},
{"OpCapability StorageTexelBufferArrayDynamicIndexingEXT\n",
{"OpCapability StorageTexelBufferArrayDynamicIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT})},
{"OpCapability UniformBufferArrayNonUniformIndexingEXT\n",
{"OpCapability UniformBufferArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityUniformBufferArrayNonUniformIndexingEXT})},
{"OpCapability SampledImageArrayNonUniformIndexingEXT\n",
{"OpCapability SampledImageArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilitySampledImageArrayNonUniformIndexingEXT})},
{"OpCapability StorageBufferArrayNonUniformIndexingEXT\n",
{"OpCapability StorageBufferArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityStorageBufferArrayNonUniformIndexingEXT})},
{"OpCapability StorageImageArrayNonUniformIndexingEXT\n",
{"OpCapability StorageImageArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityStorageImageArrayNonUniformIndexingEXT})},
{"OpCapability InputAttachmentArrayNonUniformIndexingEXT\n",
{"OpCapability InputAttachmentArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT})},
{"OpCapability UniformTexelBufferArrayNonUniformIndexingEXT\n",
{"OpCapability UniformTexelBufferArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT})},
{"OpCapability StorageTexelBufferArrayNonUniformIndexingEXT\n",
{"OpCapability StorageTexelBufferArrayNonUniformIndexing\n",
MakeInstruction(
SpvOpCapability,
{SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT})},
// Check capabilities, by number
{"OpCapability ShaderNonUniformEXT\n",
{"OpCapability ShaderNonUniform\n",
MakeInstruction(SpvOpCapability, {5301})},
{"OpCapability RuntimeDescriptorArrayEXT\n",
{"OpCapability RuntimeDescriptorArray\n",
MakeInstruction(SpvOpCapability, {5302})},
{"OpCapability InputAttachmentArrayDynamicIndexingEXT\n",
{"OpCapability InputAttachmentArrayDynamicIndexing\n",
MakeInstruction(SpvOpCapability, {5303})},
{"OpCapability UniformTexelBufferArrayDynamicIndexingEXT\n",
{"OpCapability UniformTexelBufferArrayDynamicIndexing\n",
MakeInstruction(SpvOpCapability, {5304})},
{"OpCapability StorageTexelBufferArrayDynamicIndexingEXT\n",
{"OpCapability StorageTexelBufferArrayDynamicIndexing\n",
MakeInstruction(SpvOpCapability, {5305})},
{"OpCapability UniformBufferArrayNonUniformIndexingEXT\n",
{"OpCapability UniformBufferArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5306})},
{"OpCapability SampledImageArrayNonUniformIndexingEXT\n",
{"OpCapability SampledImageArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5307})},
{"OpCapability StorageBufferArrayNonUniformIndexingEXT\n",
{"OpCapability StorageBufferArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5308})},
{"OpCapability StorageImageArrayNonUniformIndexingEXT\n",
{"OpCapability StorageImageArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5309})},
{"OpCapability InputAttachmentArrayNonUniformIndexingEXT\n",
{"OpCapability InputAttachmentArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5310})},
{"OpCapability UniformTexelBufferArrayNonUniformIndexingEXT\n",
{"OpCapability UniformTexelBufferArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5311})},
{"OpCapability StorageTexelBufferArrayNonUniformIndexingEXT\n",
{"OpCapability StorageTexelBufferArrayNonUniformIndexing\n",
MakeInstruction(SpvOpCapability, {5312})},
// Check the decoration token
{"OpDecorate %1 NonUniformEXT\n",
{"OpDecorate %1 NonUniform\n",
MakeInstruction(SpvOpDecorate, {1, SpvDecorationNonUniformEXT})},
{"OpDecorate %1 NonUniformEXT\n",
{"OpDecorate %1 NonUniform\n",
MakeInstruction(SpvOpDecorate, {1, 5300})},
})));

View File

@@ -212,7 +212,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) {
std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailableKHR %3\n";
std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailable %3\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 8, 3})));
std::string disassembly =
@@ -221,7 +221,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) {
std::string spirv = "OpCopyMemory %1 %2 MakePointerVisibleKHR %3\n";
std::string spirv = "OpCopyMemory %1 %2 MakePointerVisible %3\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 16, 3})));
std::string disassembly =
@@ -230,7 +230,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) {
std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointerKHR\n";
std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointer\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 32})));
std::string disassembly =
@@ -241,8 +241,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) {
TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessMixedGood) {
std::string spirv =
"OpCopyMemory %1 %2 "
"Volatile|Aligned|Nontemporal|MakePointerAvailableKHR|"
"MakePointerVisibleKHR|NonPrivatePointerKHR 16 %3 %4\n";
"Volatile|Aligned|Nontemporal|MakePointerAvailable|"
"MakePointerVisible|NonPrivatePointer 16 %3 %4\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 63, 16, 3, 4})));
std::string disassembly =
@@ -272,8 +272,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV14Good) {
TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) {
std::string spirv =
"OpCopyMemory %1 %2 Volatile|Nontemporal|"
"MakePointerVisibleKHR %3 "
"Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 16 %4\n";
"MakePointerVisible %3 "
"Aligned|MakePointerAvailable|NonPrivatePointer 16 %4\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 21, 3, 42, 16, 4})));
std::string disassembly =
@@ -341,7 +341,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) {
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailableKHR %4\n";
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailable %4\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 8, 4})));
std::string disassembly =
@@ -350,7 +350,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) {
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisibleKHR %4\n";
std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisible %4\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 16, 4})));
std::string disassembly =
@@ -359,7 +359,7 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) {
}
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) {
std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointerKHR\n";
std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointer\n";
EXPECT_THAT(CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 32})));
std::string disassembly =
@@ -370,8 +370,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) {
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessMixedGood) {
std::string spirv =
"OpCopyMemorySized %1 %2 %3 "
"Volatile|Aligned|Nontemporal|MakePointerAvailableKHR|"
"MakePointerVisibleKHR|NonPrivatePointerKHR 16 %4 %5\n";
"Volatile|Aligned|Nontemporal|MakePointerAvailable|"
"MakePointerVisible|NonPrivatePointer 16 %4 %5\n";
EXPECT_THAT(
CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5})));
@@ -402,8 +402,8 @@ TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV14Good) {
TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessMixedV14Good) {
std::string spirv =
"OpCopyMemorySized %1 %2 %3 Volatile|Nontemporal|"
"MakePointerVisibleKHR %4 "
"Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 16 %5\n";
"MakePointerVisible %4 "
"Aligned|MakePointerAvailable|NonPrivatePointer 16 %5\n";
EXPECT_THAT(
CompiledInstructions(spirv),
Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 21, 4, 42, 16, 5})));

View File

@@ -270,8 +270,8 @@ class ValidObjectFile1_3(ReturnCodeIsZero, CorrectObjectFilePreamble):
return True, ''
class ValidObjectFile1_4(ReturnCodeIsZero, CorrectObjectFilePreamble):
"""Mixin class for checking that every input file generates a valid SPIR-V 1.4
class ValidObjectFile1_5(ReturnCodeIsZero, CorrectObjectFilePreamble):
"""Mixin class for checking that every input file generates a valid SPIR-V 1.5
object file following the object file naming rule, and there is no output on
stdout/stderr."""
@@ -279,7 +279,7 @@ class ValidObjectFile1_4(ReturnCodeIsZero, CorrectObjectFilePreamble):
for input_filename in status.input_filenames:
object_filename = get_object_filename(input_filename)
success, message = self.verify_object_file_preamble(
os.path.join(status.directory, object_filename), 0x10400)
os.path.join(status.directory, object_filename), 0x10500)
if not success:
return False, message
return True, ''

View File

@@ -34,7 +34,7 @@ def empty_main_assembly():
@inside_spirv_testsuite('SpirvOptBase')
class TestAssemblyFileAsOnlyParameter(expect.ValidObjectFile1_4):
class TestAssemblyFileAsOnlyParameter(expect.ValidObjectFile1_5):
"""Tests that spirv-opt accepts a SPIR-V object file."""
shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
@@ -52,7 +52,7 @@ class TestHelpFlag(expect.ReturnCodeIsZero, expect.StdoutMatch):
@inside_spirv_testsuite('SpirvOptFlags')
class TestValidPassFlags(expect.ValidObjectFile1_4,
class TestValidPassFlags(expect.ValidObjectFile1_5,
expect.ExecutedListOfPasses):
"""Tests that spirv-opt accepts all valid optimization flags."""
@@ -91,7 +91,7 @@ class TestValidPassFlags(expect.ValidObjectFile1_4,
'eliminate-dead-variables',
# --eliminate-insert-extract runs the simplify-instructions pass.
'simplify-instructions',
'eliminate-local-multi-store',
'ssa-rewrite',
'eliminate-local-single-block',
'eliminate-local-single-store',
'flatten-decorations',
@@ -129,7 +129,7 @@ class TestValidPassFlags(expect.ValidObjectFile1_4,
@inside_spirv_testsuite('SpirvOptFlags')
class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_4,
class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_5,
expect.ExecutedListOfPasses):
"""Tests that spirv-opt schedules all the passes triggered by -O."""
@@ -149,7 +149,7 @@ class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_4,
'eliminate-local-single-block',
'eliminate-local-single-store',
'eliminate-dead-code-aggressive',
'eliminate-local-multi-store',
'ssa-rewrite',
'eliminate-dead-code-aggressive',
'ccp',
'eliminate-dead-code-aggressive',
@@ -177,7 +177,7 @@ class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_4,
@inside_spirv_testsuite('SpirvOptFlags')
class TestSizeOptimizationPasses(expect.ValidObjectFile1_4,
class TestSizeOptimizationPasses(expect.ValidObjectFile1_5,
expect.ExecutedListOfPasses):
"""Tests that spirv-opt schedules all the passes triggered by -Os."""
@@ -196,7 +196,7 @@ class TestSizeOptimizationPasses(expect.ValidObjectFile1_4,
'eliminate-dead-code-aggressive',
'simplify-instructions',
'eliminate-dead-inserts',
'eliminate-local-multi-store',
'ssa-rewrite',
'eliminate-dead-code-aggressive',
'ccp',
'eliminate-dead-code-aggressive',
@@ -217,7 +217,7 @@ class TestSizeOptimizationPasses(expect.ValidObjectFile1_4,
@inside_spirv_testsuite('SpirvOptFlags')
class TestLegalizationPasses(expect.ValidObjectFile1_4,
class TestLegalizationPasses(expect.ValidObjectFile1_5,
expect.ExecutedListOfPasses):
"""Tests that spirv-opt schedules all the passes triggered by --legalize-hlsl.
"""
@@ -238,7 +238,7 @@ class TestLegalizationPasses(expect.ValidObjectFile1_4,
'eliminate-local-single-block',
'eliminate-local-single-store',
'eliminate-dead-code-aggressive',
'eliminate-local-multi-store',
'ssa-rewrite',
'eliminate-dead-code-aggressive',
'ccp',
'loop-unroll',

View File

@@ -28,7 +28,6 @@ add_spvtools_unittest(TARGET val_abcde
val_barriers_test.cpp
val_bitwise_test.cpp
val_builtins_test.cpp
val_capability_test.cpp
val_cfg_test.cpp
val_composites_test.cpp
val_constants_test.cpp
@@ -44,6 +43,13 @@ add_spvtools_unittest(TARGET val_abcde
PCH_FILE pch_test_val
)
add_spvtools_unittest(TARGET val_capability
SRCS
val_capability_test.cpp
LIBS ${SPIRV_TOOLS}
PCH_FILE pch_test_val
)
add_spvtools_unittest(TARGET val_limits
SRCS val_limits_test.cpp
${VAL_TEST_COMMON_SRCS}

View File

@@ -144,7 +144,7 @@ OpBranch %end_label
%false_label = OpLabel
OpBranch %end_label
%end_label = OpLabel
%line = OpLine %string 0 0
OpLine %string 0 0
%result = OpPhi %bool %true %true_label %false %false_label
)";
@@ -178,7 +178,7 @@ OpBranch %end_label
%false_label = OpLabel
OpBranch %end_label
%end_label = OpLabel
%line = OpLine %string 0 0
OpLine %string 0 0
%result = OpPhi %bool %true %true_label %false %false_label
)";

View File

@@ -708,7 +708,7 @@ OpAtomicStore %f32_var %device %relaxed %u32_1
TEST_F(ValidateAtomics, AtomicExchangeShaderSuccess) {
const std::string body = R"(
%val1 = OpAtomicStore %u32_var %device %relaxed %u32_1
OpAtomicStore %u32_var %device %relaxed %u32_1
%val2 = OpAtomicExchange %u32 %u32_var %device %relaxed %u32_0
)";
@@ -720,7 +720,7 @@ TEST_F(ValidateAtomics, AtomicExchangeKernelSuccess) {
const std::string body = R"(
OpAtomicStore %f32_var %device %relaxed %f32_1
%val2 = OpAtomicExchange %f32 %f32_var %device %relaxed %f32_0
%val3 = OpAtomicStore %u32_var %device %relaxed %u32_1
OpAtomicStore %u32_var %device %relaxed %u32_1
%val4 = OpAtomicExchange %u32 %u32_var %device %relaxed %u32_0
)";
@@ -743,7 +743,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
TEST_F(ValidateAtomics, AtomicExchangeWrongResultType) {
const std::string body = R"(
%val1 = OpStore %f32vec4_var %f32vec4_0000
OpStore %f32vec4_var %f32vec4_0000
%val2 = OpAtomicExchange %f32vec4 %f32vec4_var %device %relaxed %f32vec4_0000
)";
@@ -768,7 +768,7 @@ TEST_F(ValidateAtomics, AtomicExchangeWrongPointerType) {
TEST_F(ValidateAtomics, AtomicExchangeWrongPointerDataType) {
const std::string body = R"(
%val1 = OpStore %f32vec4_var %f32vec4_0000
OpStore %f32vec4_var %f32vec4_0000
%val2 = OpAtomicExchange %f32 %f32vec4_var %device %relaxed %f32vec4_0000
)";
@@ -822,7 +822,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
TEST_F(ValidateAtomics, AtomicCompareExchangeShaderSuccess) {
const std::string body = R"(
%val1 = OpAtomicStore %u32_var %device %relaxed %u32_1
OpAtomicStore %u32_var %device %relaxed %u32_1
%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0
)";
@@ -834,7 +834,7 @@ TEST_F(ValidateAtomics, AtomicCompareExchangeKernelSuccess) {
const std::string body = R"(
OpAtomicStore %f32_var %device %relaxed %f32_1
%val2 = OpAtomicCompareExchange %f32 %f32_var %device %relaxed %relaxed %f32_0 %f32_1
%val3 = OpAtomicStore %u32_var %device %relaxed %u32_1
OpAtomicStore %u32_var %device %relaxed %u32_1
%val4 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0
)";
@@ -857,7 +857,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
TEST_F(ValidateAtomics, AtomicCompareExchangeWrongResultType) {
const std::string body = R"(
%val1 = OpStore %f32vec4_var %f32vec4_0000
OpStore %f32vec4_var %f32vec4_0000
%val2 = OpAtomicCompareExchange %f32vec4 %f32vec4_var %device %relaxed %relaxed %f32vec4_0000 %f32vec4_0000
)";
@@ -882,7 +882,7 @@ TEST_F(ValidateAtomics, AtomicCompareExchangeWrongPointerType) {
TEST_F(ValidateAtomics, AtomicCompareExchangeWrongPointerDataType) {
const std::string body = R"(
%val1 = OpStore %f32vec4_var %f32vec4_0000
OpStore %f32vec4_var %f32vec4_0000
%val2 = OpAtomicCompareExchange %f32 %f32vec4_var %device %relaxed %relaxed %f32_0 %f32_1
)";
@@ -975,7 +975,7 @@ OpAtomicStore %f32_var %device %relaxed %f32_1
TEST_F(ValidateAtomics, AtomicCompareExchangeWeakSuccess) {
const std::string body = R"(
%val3 = OpAtomicStore %u32_var %device %relaxed %u32_1
OpAtomicStore %u32_var %device %relaxed %u32_1
%val4 = OpAtomicCompareExchangeWeak %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0
)";

View File

@@ -2330,9 +2330,9 @@ OpDecorate %copy BuiltIn WorkgroupSize
CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Vulkan spec requires BuiltIn WorkgroupSize to be a "
"constant. ID <2> (OpCopyObject) is not a constant"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("BuiltIns can only target variables, structs or constants"));
}
CodeGenerator GetWorkgroupSizeNotVectorGenerator(spv_target_env env) {
@@ -3302,6 +3302,78 @@ OpFunctionEnd
HasSubstr("BuiltIn SubgroupId cannot be used as a member decoration"));
}
TEST_F(ValidateBuiltIns, TargetIsType) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %void BuiltIn Position
%void = OpTypeVoid
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("BuiltIns can only target variables, structs or constants"));
}
TEST_F(ValidateBuiltIns, TargetIsVariable) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %wg_var BuiltIn Position
%int = OpTypeInt 32 0
%int_wg_ptr = OpTypePointer Workgroup %int
%wg_var = OpVariable %int_wg_ptr Workgroup
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
TEST_F(ValidateBuiltIns, TargetIsStruct) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %struct BuiltIn Position
%struct = OpTypeStruct
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
TEST_F(ValidateBuiltIns, TargetIsConstant) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %int0 BuiltIn Position
%int = OpTypeInt 32 0
%int0 = OpConstant %int 0
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
TEST_F(ValidateBuiltIns, TargetIsSpecConstant) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpDecorate %int0 BuiltIn Position
%int = OpTypeInt 32 0
%int0 = OpSpecConstant %int 0
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
} // namespace
} // namespace val
} // namespace spvtools

View File

@@ -23,6 +23,7 @@
#include "gmock/gmock.h"
#include "source/assembly_grammar.h"
#include "source/spirv_target_env.h"
#include "spirv-tools/libspirv.h"
#include "test/test_fixture.h"
#include "test/unit_spirv.h"
#include "test/val/val_fixtures.h"
@@ -33,6 +34,7 @@ namespace {
using spvtest::ScopedContext;
using testing::Combine;
using testing::Eq;
using testing::HasSubstr;
using testing::Values;
using testing::ValuesIn;
@@ -1286,221 +1288,264 @@ INSTANTIATE_TEST_SUITE_P(BuiltIn, ValidateCapability,
Values(
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn Position\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn Position\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
// Just mentioning PointSize, ClipDistance, or CullDistance as a BuiltIn does
// not trigger the requirement for the associated capability.
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn ClipDistance\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn ClipDistance\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn VertexId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn VertexId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn InstanceId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn InstanceId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn PrimitiveId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PrimitiveId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
GeometryTessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn InvocationId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn InvocationId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
GeometryTessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn Layer\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn Layer\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
GeometryDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn ViewportIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn ViewportIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
std::vector<std::string>{"MultiViewport"}),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn TessLevelOuter\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn TessLevelOuter\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
TessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn TessLevelInner\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn TessLevelInner\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
TessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn TessCoord\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn TessCoord\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
TessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn PatchVertices\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PatchVertices\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
TessellationDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn FragCoord\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn FragCoord\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn PointCoord\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PointCoord\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn FrontFacing\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn FrontFacing\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn SampleId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SampleId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
std::vector<std::string>{"SampleRateShading"}),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn SamplePosition\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SamplePosition\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
std::vector<std::string>{"SampleRateShading"}),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn SampleMask\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SampleMask\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn FragDepth\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn FragDepth\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn HelperInvocation\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn HelperInvocation\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn VertexIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn VertexIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn InstanceIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn InstanceIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn NumWorkgroups\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn NumWorkgroups\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn WorkgroupSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn WorkgroupSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn WorkgroupId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn WorkgroupId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn LocalInvocationId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn LocalInvocationId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn GlobalInvocationId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn GlobalInvocationId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn LocalInvocationIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn LocalInvocationIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllCapabilities()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn WorkDim\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn WorkDim\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn GlobalSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn GlobalSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn EnqueuedWorkgroupSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn EnqueuedWorkgroupSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn GlobalOffset\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn GlobalOffset\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn GlobalLinearId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn GlobalLinearId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn SubgroupSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SubgroupSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelAndGroupNonUniformDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn SubgroupMaxSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SubgroupMaxSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn NumSubgroups\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn NumSubgroups\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelAndGroupNonUniformDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn NumEnqueuedSubgroups\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn NumEnqueuedSubgroups\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn SubgroupId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SubgroupId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelAndGroupNonUniformDependencies()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn SubgroupLocalInvocationId\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn SubgroupLocalInvocationId\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
KernelAndGroupNonUniformDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn VertexIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn VertexIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies()),
std::make_pair(std::string(kOpenCLMemoryModel) +
"OpEntryPoint Kernel %func \"compute\" \n" +
"OpDecorate %intt BuiltIn InstanceIndex\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn InstanceIndex\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
ShaderDependencies())
)));
@@ -1548,18 +1593,21 @@ INSTANTIATE_TEST_SUITE_P(BuiltIn, ValidateCapabilityOpenGL40,
Values(
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllSpirV10Capabilities()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn ClipDistance\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn ClipDistance\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllSpirV10Capabilities()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllSpirV10Capabilities())
)));
@@ -1580,13 +1628,15 @@ INSTANTIATE_TEST_SUITE_P(Capabilities, ValidateCapabilityVulkan11,
Values(
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn PointSize\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllVulkan11Capabilities()),
std::make_pair(std::string(kGLSL450MemoryModel) +
"OpEntryPoint Vertex %func \"shader\" \n" +
"OpDecorate %intt BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
"OpDecorate %int0 BuiltIn CullDistance\n"
"%intt = OpTypeInt 32 0\n"
"%int0 = OpConstant %intt 0\n" + std::string(kVoidFVoid),
AllVulkan11Capabilities())
)));
@@ -2436,6 +2486,178 @@ OpFunctionEnd
<< getDiagnosticString();
}
// Test that extensions incorporated into SPIR-V 1.5 no longer require
// the associated OpExtension instruction. Test one capability per extension.
struct CapabilityExtensionVersionCase {
std::string capability;
std::string capability_new_name;
std::string extension;
spv_target_env last_version_requiring_extension;
spv_target_env first_version_in_core;
};
using ValidateCapabilityExtensionVersionTest =
spvtest::ValidateBase<CapabilityExtensionVersionCase>;
// Returns a minimal shader module with the given capability instruction.
std::string MinimalShaderModuleWithCapability(std::string cap) {
std::string mem_model =
(cap.find("VulkanMemory") == 0) ? "VulkanKHR" : "GLSL450";
std::string extra_cap = (cap.find("VulkanMemoryModelDeviceScope") == 0)
? "\nOpCapability VulkanMemoryModelKHR\n"
: "";
return std::string("OpCapability ") + cap + extra_cap + R"(
OpCapability Shader
OpMemoryModel Logical )" + mem_model + R"(
OpEntryPoint Vertex %main "main"
%void = OpTypeVoid
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
OpReturn
OpFunctionEnd
)";
}
TEST_P(ValidateCapabilityExtensionVersionTest, FailsInOlderSpirvVersion) {
const auto spirv = MinimalShaderModuleWithCapability(GetParam().capability);
CompileSuccessfully(spirv, GetParam().last_version_requiring_extension);
EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION,
ValidateInstructions(GetParam().last_version_requiring_extension));
EXPECT_THAT(getDiagnosticString(),
HasSubstr(std::string("1st operand of Capability: operand ") +
GetParam().capability_new_name))
<< spirv << "\n";
EXPECT_THAT(getDiagnosticString(),
HasSubstr(std::string("requires one of these extensions: ") +
GetParam().extension));
}
TEST_P(ValidateCapabilityExtensionVersionTest,
SucceedsInNewerSpirvVersionWithOldName) {
const auto spirv = MinimalShaderModuleWithCapability(GetParam().capability);
CompileSuccessfully(spirv, GetParam().first_version_in_core);
EXPECT_EQ(SPV_SUCCESS,
ValidateInstructions(GetParam().first_version_in_core));
EXPECT_THAT(getDiagnosticString(), Eq("")) << spirv << "\n";
}
TEST_P(ValidateCapabilityExtensionVersionTest,
SucceedsInNewerSpirvVersionWithNewName) {
const auto spirv =
MinimalShaderModuleWithCapability(GetParam().capability_new_name);
CompileSuccessfully(spirv, GetParam().first_version_in_core);
EXPECT_EQ(SPV_SUCCESS,
ValidateInstructions(GetParam().first_version_in_core));
EXPECT_THAT(getDiagnosticString(), Eq("")) << spirv << "\n";
}
std::vector<CapabilityExtensionVersionCase> CapVersionCases1_5() {
#define IN15NOSUFFIX(C, E) \
{ C, C, E, SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_5 }
#define IN15(C, C_WITHOUT_SUFFIX, E) \
{ C, C_WITHOUT_SUFFIX, E, SPV_ENV_UNIVERSAL_1_4, SPV_ENV_UNIVERSAL_1_5 }
return std::vector<CapabilityExtensionVersionCase>{
// SPV_KHR_8bit_storage
IN15NOSUFFIX("StorageBuffer8BitAccess", "SPV_KHR_8bit_storage"),
IN15NOSUFFIX("UniformAndStorageBuffer8BitAccess", "SPV_KHR_8bit_storage"),
IN15NOSUFFIX("StoragePushConstant8", "SPV_KHR_8bit_storage"),
// SPV_EXT_descriptor_indexing
IN15("ShaderNonUniformEXT", "ShaderNonUniform",
"SPV_EXT_descriptor_indexing"),
IN15("RuntimeDescriptorArrayEXT", "RuntimeDescriptorArray",
"SPV_EXT_descriptor_indexing"),
IN15("InputAttachmentArrayDynamicIndexingEXT",
"InputAttachmentArrayDynamicIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("UniformTexelBufferArrayDynamicIndexingEXT",
"UniformTexelBufferArrayDynamicIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("StorageTexelBufferArrayDynamicIndexingEXT",
"StorageTexelBufferArrayDynamicIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("UniformBufferArrayNonUniformIndexingEXT",
"UniformBufferArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("SampledImageArrayNonUniformIndexingEXT",
"SampledImageArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("StorageBufferArrayNonUniformIndexingEXT",
"StorageBufferArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("StorageImageArrayNonUniformIndexingEXT",
"StorageImageArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("InputAttachmentArrayNonUniformIndexingEXT",
"InputAttachmentArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("UniformTexelBufferArrayNonUniformIndexingEXT",
"UniformTexelBufferArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
IN15("StorageTexelBufferArrayNonUniformIndexingEXT",
"StorageTexelBufferArrayNonUniformIndexing",
"SPV_EXT_descriptor_indexing"),
// SPV_EXT_physical_storage_buffer
IN15("PhysicalStorageBufferAddressesEXT",
"PhysicalStorageBufferAddresses", "SPV_EXT_physical_storage_buffer"),
// SPV_KHR_vulkan_memory_model
IN15("VulkanMemoryModelKHR", "VulkanMemoryModel",
"SPV_KHR_vulkan_memory_model"),
IN15("VulkanMemoryModelDeviceScopeKHR", "VulkanMemoryModelDeviceScope",
"SPV_KHR_vulkan_memory_model"),
};
#undef IN15
}
INSTANTIATE_TEST_SUITE_P(NewInSpirv1_5, ValidateCapabilityExtensionVersionTest,
ValuesIn(CapVersionCases1_5()));
TEST_P(ValidateCapability,
CapShaderViewportIndexLayerFailsInOlderSpirvVersion) {
const auto spirv =
MinimalShaderModuleWithCapability("ShaderViewportIndexLayerEXT");
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"1st operand of Capability: operand ShaderViewportIndexLayerEXT"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("requires one of these extensions: "
"SPV_EXT_shader_viewport_index_layer"));
}
TEST_P(ValidateCapability, CapShaderViewportIndexLayerFailsInNewSpirvVersion) {
const auto spirv =
MinimalShaderModuleWithCapability("ShaderViewportIndexLayerEXT");
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"1st operand of Capability: operand ShaderViewportIndexLayerEXT"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("requires one of these extensions: "
"SPV_EXT_shader_viewport_index_layer"));
}
TEST_F(ValidateCapability, CapShaderViewportIndexSucceedsInNewSpirvVersion) {
const auto spirv = MinimalShaderModuleWithCapability("ShaderViewportIndex");
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(getDiagnosticString(), Eq(""));
}
TEST_F(ValidateCapability, CapShaderLayerSucceedsInNewSpirvVersion) {
const auto spirv = MinimalShaderModuleWithCapability("ShaderLayer");
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(getDiagnosticString(), Eq(""));
}
} // namespace
} // namespace val
} // namespace spvtools

View File

@@ -4785,7 +4785,8 @@ TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13Bad) {
ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("requires SPIR-V version 1.4 or later\n"
" OpDecorateId %int0 UniformId %subgroupscope"));
" OpDecorateId %int0 UniformId %subgroupscope"))
<< spirv;
}
TEST_F(ValidateDecorations, UniformIdDecorationWithScopeIdV13BadTargetV14) {

View File

@@ -2317,8 +2317,8 @@ TEST_F(ValidateIdWithMessage, OpLoadGood) {
%6 = OpFunction %1 None %4
%7 = OpLabel
%8 = OpLoad %2 %5
%9 = OpReturn
%10 = OpFunctionEnd
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv.c_str());
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());

View File

@@ -2938,7 +2938,7 @@ TEST_F(ValidateImage, ReadCoordinateSizeTooSmall) {
TEST_F(ValidateImage, WriteSuccess1) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123
OpImageWrite %img %u32vec2_01 %u32vec4_0123
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -2949,7 +2949,7 @@ TEST_F(ValidateImage, WriteSuccess1) {
TEST_F(ValidateImage, WriteSuccess2) {
const std::string body = R"(
%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
%res1 = OpImageWrite %img %u32_1 %f32vec4_0000
OpImageWrite %img %u32_1 %f32vec4_0000
)";
const std::string extra = "\nOpCapability Image1D\n";
@@ -2960,7 +2960,7 @@ TEST_F(ValidateImage, WriteSuccess2) {
TEST_F(ValidateImage, WriteSuccess3) {
const std::string body = R"(
%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
%res1 = OpImageWrite %img %u32vec3_012 %f32vec4_0000
OpImageWrite %img %u32vec3_012 %f32vec4_0000
)";
const std::string extra = "\nOpCapability ImageCubeArray\n";
@@ -2972,8 +2972,8 @@ TEST_F(ValidateImage, WriteSuccess4) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
;TODO(atgoo@github.com) Is it legal to write to MS image without sample index?
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000
%res2 = OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
OpImageWrite %img %u32vec2_01 %f32vec4_0000
OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -2984,7 +2984,7 @@ TEST_F(ValidateImage, WriteSuccess4) {
TEST_F(ValidateImage, WriteSubpassData) {
const std::string body = R"(
%img = OpLoad %type_image_f32_spd_0002 %uniform_image_f32_spd_0002
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000
OpImageWrite %img %u32vec2_01 %f32vec4_0000
)";
CompileSuccessfully(GenerateShaderCode(body).c_str());
@@ -2996,7 +2996,7 @@ TEST_F(ValidateImage, WriteSubpassData) {
TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123
OpImageWrite %img %u32vec2_01 %u32vec4_0123
)";
CompileSuccessfully(GenerateShaderCode(body).c_str());
@@ -3006,7 +3006,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormat) {
TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123
OpImageWrite %img %u32vec2_01 %u32vec4_0123
)";
spv_target_env env = SPV_ENV_VULKAN_1_0;
@@ -3023,7 +3023,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityStorageImageWriteWithoutFormatVulkan) {
TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
const std::string body = R"(
%img = OpLoad %type_image_f32_1d_0002_rgba32f %uniform_image_f32_1d_0002_rgba32f
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000
OpImageWrite %img %u32vec2_01 %f32vec4_0000
)";
CompileSuccessfully(GenerateShaderCode(body).c_str());
@@ -3036,7 +3036,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityImage1D) {
TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
const std::string body = R"(
%img = OpLoad %type_image_f32_cube_0102_rgba32f %uniform_image_f32_cube_0102_rgba32f
%res1 = OpImageWrite %img %u32vec3_012 %f32vec4_0000
OpImageWrite %img %u32vec3_012 %f32vec4_0000
)";
CompileSuccessfully(GenerateShaderCode(body).c_str());
@@ -3050,7 +3050,7 @@ TEST_F(ValidateImage, WriteNeedCapabilityImageCubeArray) {
TEST_F(ValidateImage, WriteNotImage) {
const std::string body = R"(
%sampler = OpLoad %type_sampler %uniform_sampler
%res1 = OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
OpImageWrite %sampler %u32vec2_01 %f32vec4_0000
)";
CompileSuccessfully(GenerateShaderCode(body).c_str());
@@ -3062,7 +3062,7 @@ TEST_F(ValidateImage, WriteNotImage) {
TEST_F(ValidateImage, WriteImageSampled) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000
OpImageWrite %img %u32vec2_01 %f32vec4_0000
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3075,7 +3075,7 @@ TEST_F(ValidateImage, WriteImageSampled) {
TEST_F(ValidateImage, WriteWrongCoordinateType) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %f32vec2_00 %u32vec4_0123
OpImageWrite %img %f32vec2_00 %u32vec4_0123
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3088,7 +3088,7 @@ TEST_F(ValidateImage, WriteWrongCoordinateType) {
TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32_1 %u32vec4_0123
OpImageWrite %img %u32_1 %u32vec4_0123
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3102,7 +3102,7 @@ TEST_F(ValidateImage, WriteCoordinateSizeTooSmall) {
TEST_F(ValidateImage, WriteTexelWrongType) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %img
OpImageWrite %img %u32vec2_01 %img
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3115,7 +3115,7 @@ TEST_F(ValidateImage, WriteTexelWrongType) {
TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec3_012
OpImageWrite %img %u32vec2_01 %u32vec3_012
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3128,7 +3128,7 @@ TEST_F(ValidateImage, DISABLED_WriteTexelNotVector4) {
TEST_F(ValidateImage, WriteTexelWrongComponentType) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000
OpImageWrite %img %u32vec2_01 %f32vec4_0000
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3143,7 +3143,7 @@ TEST_F(ValidateImage, WriteTexelWrongComponentType) {
TEST_F(ValidateImage, WriteSampleNotInteger) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0010 %uniform_image_f32_2d_0010
%res1 = OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %f32_1
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -3156,7 +3156,7 @@ TEST_F(ValidateImage, WriteSampleNotInteger) {
TEST_F(ValidateImage, SampleNotMultisampled) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
%res2 = OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
OpImageWrite %img %u32vec2_01 %f32vec4_0000 Sample %u32_1
)";
const std::string extra = "\nOpCapability StorageImageWriteWithoutFormat\n";
@@ -4527,7 +4527,7 @@ OpExtension "SPV_KHR_vulkan_memory_model"
TEST_F(ValidateImage, MakeTexelAvailableKHRSuccessImageWrite) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_2
)";
const std::string extra = R"(
@@ -4567,7 +4567,7 @@ OpExtension "SPV_KHR_vulkan_memory_model"
TEST_F(ValidateImage, MakeTexelAvailableKHRFailureMissingNonPrivate) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR %u32_1
)";
const std::string extra = R"(
@@ -4588,7 +4588,7 @@ OpExtension "SPV_KHR_vulkan_memory_model"
TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteBad) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
)";
const std::string extra = R"(
@@ -4610,7 +4610,7 @@ OpExtension "SPV_KHR_vulkan_memory_model"
TEST_F(ValidateImage, VulkanMemoryModelDeviceScopeImageWriteGood) {
const std::string body = R"(
%img = OpLoad %type_image_u32_2d_0000 %uniform_image_u32_2d_0000
%res1 = OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
OpImageWrite %img %u32vec2_01 %u32vec4_0123 MakeTexelAvailableKHR|NonPrivateTexelKHR %u32_1
)";
const std::string extra = R"(

View File

@@ -212,7 +212,7 @@ TEST_F(ValidateLimits, SwitchNumBranchesGood) {
%5 = OpFunction %1 None %2
%7 = OpLabel
%8 = OpIAdd %3 %4 %4
%9 = OpSwitch %4 %10)";
OpSwitch %4 %10)";
// Now add the (literal, label) pairs
for (int i = 0; i < 16383; ++i) {
@@ -240,7 +240,7 @@ TEST_F(ValidateLimits, SwitchNumBranchesBad) {
%5 = OpFunction %1 None %2
%7 = OpLabel
%8 = OpIAdd %3 %4 %4
%9 = OpSwitch %4 %10)";
OpSwitch %4 %10)";
// Now add the (literal, label) pairs
for (int i = 0; i < 16384; ++i) {
@@ -271,7 +271,7 @@ TEST_F(ValidateLimits, CustomizedSwitchNumBranchesGood) {
%5 = OpFunction %1 None %2
%7 = OpLabel
%8 = OpIAdd %3 %4 %4
%9 = OpSwitch %4 %10)";
OpSwitch %4 %10)";
// Now add the (literal, label) pairs
for (int i = 0; i < 10; ++i) {
@@ -301,7 +301,7 @@ TEST_F(ValidateLimits, CustomizedSwitchNumBranchesBad) {
%5 = OpFunction %1 None %2
%7 = OpLabel
%8 = OpIAdd %3 %4 %4
%9 = OpSwitch %4 %10)";
OpSwitch %4 %10)";
// Now add the (literal, label) pairs
for (int i = 0; i < 11; ++i) {

View File

@@ -1492,8 +1492,8 @@ OpFunctionEnd
getDiagnosticString(),
HasSubstr(
"Source memory access must not include MakePointerAvailableKHR\n"
" OpCopyMemory %5 %6 MakePointerAvailableKHR|NonPrivatePointerKHR"
" %uint_1 MakePointerAvailableKHR|NonPrivatePointerKHR %uint_1"));
" OpCopyMemory %5 %6 MakePointerAvailable|NonPrivatePointer"
" %uint_1 MakePointerAvailable|NonPrivatePointer %uint_1"));
}
TEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessSecondWithVisBad) {
@@ -1525,10 +1525,9 @@ OpFunctionEnd
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Target memory access must not include MakePointerVisibleKHR\n"
" OpCopyMemory %5 %6 MakePointerVisibleKHR|NonPrivatePointerKHR"
" %uint_1 MakePointerVisibleKHR|NonPrivatePointerKHR %uint_1"));
HasSubstr("Target memory access must not include MakePointerVisibleKHR\n"
" OpCopyMemory %5 %6 MakePointerVisible|NonPrivatePointer"
" %uint_1 MakePointerVisible|NonPrivatePointer %uint_1"));
}
TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {

View File

@@ -201,7 +201,7 @@ TEST_F(ValidateWebGPU, NonLogicalAddressingModelBad) {
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Addressing model must be Logical for WebGPU "
"environment.\n OpMemoryModel Physical32 "
"VulkanKHR\n"));
"Vulkan\n"));
}
TEST_F(ValidateWebGPU, NonVulkanKHRMemoryModelBad) {

View File

@@ -48,7 +48,7 @@ Options:
argv0, argv0, target_env_list.c_str());
}
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_4;
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
int main(int argc, char** argv) {
const char* inFile = nullptr;

View File

@@ -44,7 +44,7 @@ Options:
argv0, argv0);
}
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_4;
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
int main(int argc, char** argv) {
const char* inFile = nullptr;

View File

@@ -60,7 +60,7 @@ Options:
argv0, argv0);
}
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_4;
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
int main(int argc, char** argv) {
const char* inFile = nullptr;

View File

@@ -59,7 +59,7 @@ std::string GetListOfPassesAsString(const spvtools::Optimizer& optimizer) {
return ss.str();
}
const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_4;
const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
std::string GetLegalizationPasses() {
spvtools::Optimizer optimizer(kDefaultEnvironment);

View File

@@ -217,7 +217,7 @@ void DumpShader(spvtools::opt::IRContext* context, const char* filename) {
DumpShader(binary, filename);
}
const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_4;
const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;
int main(int argc, const char** argv) {
const char* in_file = nullptr;

View File

@@ -74,7 +74,7 @@ Options:
int main(int argc, char** argv) {
const char* inFile = nullptr;
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_4;
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_5;
spvtools::ValidatorOptions options;
bool continue_processing = true;
int return_code = 0;
@@ -108,12 +108,13 @@ int main(int argc, char** argv) {
printf("%s\n", spvSoftwareVersionDetailsString());
printf(
"Targets:\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n "
"%s\n",
"%s\n %s\n",
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_0),
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_1),
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_2),
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_3),
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_4),
spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_5),
spvTargetEnvDescription(SPV_ENV_OPENCL_2_2),
spvTargetEnvDescription(SPV_ENV_VULKAN_1_0),
spvTargetEnvDescription(SPV_ENV_VULKAN_1_1),

View File

@@ -653,6 +653,30 @@ def generate_all_string_enum_mappings(extensions, operand_kinds):
def precondition_operand_kinds(operand_kinds):
"""For operand kinds that have the same number, make sure they all have the
same extension list."""
# Map operand kind and value to list of the union of extensions
# for same-valued enumerants.
exts = {}
for kind_entry in operand_kinds:
kind = kind_entry.get('kind')
for enum_entry in kind_entry.get('enumerants', []):
value = enum_entry.get('value')
key = kind + '.' + str(value)
if key in exts:
exts[key].extend(enum_entry.get('extensions', []))
else:
exts[key] = enum_entry.get('extensions', [])
exts[key] = sorted(set(exts[key]))
# Now make each entry the same list.
for kind_entry in operand_kinds:
kind = kind_entry.get('kind')
for enum_entry in kind_entry.get('enumerants', []):
value = enum_entry.get('value')
key = kind + '.' + str(value)
if len(exts[key]) > 0:
enum_entry['extensions'] = exts[key]
return operand_kinds