Home | History | Annotate | Download | only in opt
      1 // Copyright (c) 2017 Valve Corporation
      2 // Copyright (c) 2017 LunarG Inc.
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //     http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "test/opt/assembly_builder.h"
     20 #include "test/opt/pass_fixture.h"
     21 #include "test/opt/pass_utils.h"
     22 
     23 namespace spvtools {
     24 namespace opt {
     25 namespace {
     26 
     27 using InstBindlessTest = PassTest<::testing::Test>;
     28 
     29 TEST_F(InstBindlessTest, Simple) {
     30   // Texture2D g_tColor[128];
     31   //
     32   // layout(push_constant) cbuffer PerViewConstantBuffer_t
     33   // {
     34   //   uint g_nDataIdx;
     35   // };
     36   //
     37   // SamplerState g_sAniso;
     38   //
     39   // struct PS_INPUT
     40   // {
     41   //   float2 vTextureCoords : TEXCOORD2;
     42   // };
     43   //
     44   // struct PS_OUTPUT
     45   // {
     46   //   float4 vColor : SV_Target0;
     47   // };
     48   //
     49   // PS_OUTPUT MainPs(PS_INPUT i)
     50   // {
     51   //   PS_OUTPUT ps_output;
     52   //   ps_output.vColor =
     53   //       g_tColor[ g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy);
     54   //   return ps_output;
     55   // }
     56 
     57   const std::string entry_before =
     58       R"(OpCapability Shader
     59 %1 = OpExtInstImport "GLSL.std.450"
     60 OpMemoryModel Logical GLSL450
     61 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
     62 OpExecutionMode %MainPs OriginUpperLeft
     63 OpSource HLSL 500
     64 )";
     65 
     66   const std::string entry_after =
     67       R"(OpCapability Shader
     68 OpExtension "SPV_KHR_storage_buffer_storage_class"
     69 %1 = OpExtInstImport "GLSL.std.450"
     70 OpMemoryModel Logical GLSL450
     71 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
     72 OpExecutionMode %MainPs OriginUpperLeft
     73 OpSource HLSL 500
     74 )";
     75 
     76   const std::string names_annots =
     77       R"(OpName %MainPs "MainPs"
     78 OpName %g_tColor "g_tColor"
     79 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
     80 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
     81 OpName %_ ""
     82 OpName %g_sAniso "g_sAniso"
     83 OpName %i_vTextureCoords "i.vTextureCoords"
     84 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
     85 OpDecorate %g_tColor DescriptorSet 3
     86 OpDecorate %g_tColor Binding 0
     87 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
     88 OpDecorate %PerViewConstantBuffer_t Block
     89 OpDecorate %g_sAniso DescriptorSet 0
     90 OpDecorate %i_vTextureCoords Location 0
     91 OpDecorate %_entryPointOutput_vColor Location 0
     92 )";
     93 
     94   const std::string new_annots =
     95       R"(OpDecorate %_runtimearr_uint ArrayStride 4
     96 OpDecorate %_struct_55 Block
     97 OpMemberDecorate %_struct_55 0 Offset 0
     98 OpMemberDecorate %_struct_55 1 Offset 4
     99 OpDecorate %57 DescriptorSet 7
    100 OpDecorate %57 Binding 0
    101 OpDecorate %gl_FragCoord BuiltIn FragCoord
    102 )";
    103 
    104   const std::string consts_types_vars =
    105       R"(%void = OpTypeVoid
    106 %10 = OpTypeFunction %void
    107 %float = OpTypeFloat 32
    108 %v2float = OpTypeVector %float 2
    109 %v4float = OpTypeVector %float 4
    110 %int = OpTypeInt 32 1
    111 %int_0 = OpConstant %int 0
    112 %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
    113 %uint = OpTypeInt 32 0
    114 %uint_128 = OpConstant %uint 128
    115 %_arr_16_uint_128 = OpTypeArray %16 %uint_128
    116 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
    117 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
    118 %PerViewConstantBuffer_t = OpTypeStruct %uint
    119 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    120 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    121 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    122 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
    123 %24 = OpTypeSampler
    124 %_ptr_UniformConstant_24 = OpTypePointer UniformConstant %24
    125 %g_sAniso = OpVariable %_ptr_UniformConstant_24 UniformConstant
    126 %26 = OpTypeSampledImage %16
    127 %_ptr_Input_v2float = OpTypePointer Input %v2float
    128 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    129 %_ptr_Output_v4float = OpTypePointer Output %v4float
    130 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    131 )";
    132 
    133   const std::string new_consts_types_vars =
    134       R"(%uint_0 = OpConstant %uint 0
    135 %bool = OpTypeBool
    136 %48 = OpTypeFunction %void %uint %uint %uint %uint
    137 %_runtimearr_uint = OpTypeRuntimeArray %uint
    138 %_struct_55 = OpTypeStruct %uint %_runtimearr_uint
    139 %_ptr_StorageBuffer__struct_55 = OpTypePointer StorageBuffer %_struct_55
    140 %57 = OpVariable %_ptr_StorageBuffer__struct_55 StorageBuffer
    141 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
    142 %uint_9 = OpConstant %uint 9
    143 %uint_4 = OpConstant %uint 4
    144 %uint_1 = OpConstant %uint 1
    145 %uint_23 = OpConstant %uint 23
    146 %uint_2 = OpConstant %uint 2
    147 %uint_3 = OpConstant %uint 3
    148 %_ptr_Input_v4float = OpTypePointer Input %v4float
    149 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
    150 %v4uint = OpTypeVector %uint 4
    151 %uint_5 = OpConstant %uint 5
    152 %uint_6 = OpConstant %uint 6
    153 %uint_7 = OpConstant %uint 7
    154 %uint_8 = OpConstant %uint 8
    155 %uint_56 = OpConstant %uint 56
    156 %103 = OpConstantNull %v4float
    157 )";
    158 
    159   const std::string func_pt1 =
    160       R"(%MainPs = OpFunction %void None %10
    161 %29 = OpLabel
    162 %30 = OpLoad %v2float %i_vTextureCoords
    163 %31 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    164 %32 = OpLoad %uint %31
    165 %33 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %32
    166 %34 = OpLoad %16 %33
    167 %35 = OpLoad %24 %g_sAniso
    168 %36 = OpSampledImage %26 %34 %35
    169 )";
    170 
    171   const std::string func_pt2_before =
    172       R"(%37 = OpImageSampleImplicitLod %v4float %36 %30
    173 OpStore %_entryPointOutput_vColor %37
    174 OpReturn
    175 OpFunctionEnd
    176 )";
    177 
    178   const std::string func_pt2_after =
    179       R"(%40 = OpULessThan %bool %32 %uint_128
    180 OpSelectionMerge %41 None
    181 OpBranchConditional %40 %42 %43
    182 %42 = OpLabel
    183 %44 = OpLoad %16 %33
    184 %45 = OpSampledImage %26 %44 %35
    185 %46 = OpImageSampleImplicitLod %v4float %45 %30
    186 OpBranch %41
    187 %43 = OpLabel
    188 %102 = OpFunctionCall %void %47 %uint_56 %uint_0 %32 %uint_128
    189 OpBranch %41
    190 %41 = OpLabel
    191 %104 = OpPhi %v4float %46 %42 %103 %43
    192 OpStore %_entryPointOutput_vColor %104
    193 OpReturn
    194 OpFunctionEnd
    195 )";
    196 
    197   const std::string output_func =
    198       R"(%47 = OpFunction %void None %48
    199 %49 = OpFunctionParameter %uint
    200 %50 = OpFunctionParameter %uint
    201 %51 = OpFunctionParameter %uint
    202 %52 = OpFunctionParameter %uint
    203 %53 = OpLabel
    204 %59 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_0
    205 %62 = OpAtomicIAdd %uint %59 %uint_4 %uint_0 %uint_9
    206 %63 = OpIAdd %uint %62 %uint_9
    207 %64 = OpArrayLength %uint %57 1
    208 %65 = OpULessThanEqual %bool %63 %64
    209 OpSelectionMerge %66 None
    210 OpBranchConditional %65 %67 %66
    211 %67 = OpLabel
    212 %68 = OpIAdd %uint %62 %uint_0
    213 %70 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %68
    214 OpStore %70 %uint_9
    215 %72 = OpIAdd %uint %62 %uint_1
    216 %73 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %72
    217 OpStore %73 %uint_23
    218 %75 = OpIAdd %uint %62 %uint_2
    219 %76 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %75
    220 OpStore %76 %49
    221 %78 = OpIAdd %uint %62 %uint_3
    222 %79 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %78
    223 OpStore %79 %uint_4
    224 %82 = OpLoad %v4float %gl_FragCoord
    225 %84 = OpBitcast %v4uint %82
    226 %85 = OpCompositeExtract %uint %84 0
    227 %86 = OpIAdd %uint %62 %uint_4
    228 %87 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %86
    229 OpStore %87 %85
    230 %88 = OpCompositeExtract %uint %84 1
    231 %90 = OpIAdd %uint %62 %uint_5
    232 %91 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %90
    233 OpStore %91 %88
    234 %93 = OpIAdd %uint %62 %uint_6
    235 %94 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %93
    236 OpStore %94 %50
    237 %96 = OpIAdd %uint %62 %uint_7
    238 %97 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %96
    239 OpStore %97 %51
    240 %99 = OpIAdd %uint %62 %uint_8
    241 %100 = OpAccessChain %_ptr_StorageBuffer_uint %57 %uint_1 %99
    242 OpStore %100 %52
    243 OpBranch %66
    244 %66 = OpLabel
    245 OpReturn
    246 OpFunctionEnd
    247 )";
    248 
    249   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    250   SinglePassRunAndCheck<InstBindlessCheckPass>(
    251       entry_before + names_annots + consts_types_vars + func_pt1 +
    252           func_pt2_before,
    253       entry_after + names_annots + new_annots + consts_types_vars +
    254           new_consts_types_vars + func_pt1 + func_pt2_after + output_func,
    255       true, true);
    256 }
    257 
    258 TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) {
    259   // Texture2D g_tColor[128];
    260   //
    261   // SamplerState g_sAniso;
    262   //
    263   // struct PS_INPUT
    264   // {
    265   //   float2 vTextureCoords : TEXCOORD2;
    266   // };
    267   //
    268   // struct PS_OUTPUT
    269   // {
    270   //   float4 vColor : SV_Target0;
    271   // };
    272   //
    273   // PS_OUTPUT MainPs(PS_INPUT i)
    274   // {
    275   //   PS_OUTPUT ps_output;
    276   //
    277   //   ps_output.vColor = g_tColor[ 37 ].Sample(g_sAniso, i.vTextureCoords.xy);
    278   //   return ps_output;
    279   // }
    280 
    281   const std::string before =
    282       R"(OpCapability Shader
    283 %1 = OpExtInstImport "GLSL.std.450"
    284 OpMemoryModel Logical GLSL450
    285 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
    286 OpExecutionMode %MainPs OriginUpperLeft
    287 OpSource HLSL 500
    288 OpName %MainPs "MainPs"
    289 OpName %g_tColor "g_tColor"
    290 OpName %g_sAniso "g_sAniso"
    291 OpName %i_vTextureCoords "i.vTextureCoords"
    292 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    293 OpDecorate %g_tColor DescriptorSet 3
    294 OpDecorate %g_tColor Binding 0
    295 OpDecorate %g_sAniso DescriptorSet 0
    296 OpDecorate %i_vTextureCoords Location 0
    297 OpDecorate %_entryPointOutput_vColor Location 0
    298 %void = OpTypeVoid
    299 %8 = OpTypeFunction %void
    300 %float = OpTypeFloat 32
    301 %v2float = OpTypeVector %float 2
    302 %v4float = OpTypeVector %float 4
    303 %int = OpTypeInt 32 1
    304 %int_0 = OpConstant %int 0
    305 %int_37 = OpConstant %int 37
    306 %15 = OpTypeImage %float 2D 0 0 0 1 Unknown
    307 %uint = OpTypeInt 32 0
    308 %uint_128 = OpConstant %uint 128
    309 %_arr_15_uint_128 = OpTypeArray %15 %uint_128
    310 %_ptr_UniformConstant__arr_15_uint_128 = OpTypePointer UniformConstant %_arr_15_uint_128
    311 %g_tColor = OpVariable %_ptr_UniformConstant__arr_15_uint_128 UniformConstant
    312 %_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
    313 %21 = OpTypeSampler
    314 %_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
    315 %g_sAniso = OpVariable %_ptr_UniformConstant_21 UniformConstant
    316 %23 = OpTypeSampledImage %15
    317 %_ptr_Input_v2float = OpTypePointer Input %v2float
    318 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    319 %_ptr_Output_v4float = OpTypePointer Output %v4float
    320 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    321 %MainPs = OpFunction %void None %8
    322 %26 = OpLabel
    323 %27 = OpLoad %v2float %i_vTextureCoords
    324 %28 = OpAccessChain %_ptr_UniformConstant_15 %g_tColor %int_37
    325 %29 = OpLoad %15 %28
    326 %30 = OpLoad %21 %g_sAniso
    327 %31 = OpSampledImage %23 %29 %30
    328 %32 = OpImageSampleImplicitLod %v4float %31 %27
    329 OpStore %_entryPointOutput_vColor %32
    330 OpReturn
    331 OpFunctionEnd
    332 )";
    333 
    334   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    335   SinglePassRunAndCheck<InstBindlessCheckPass>(before, before, true, true);
    336 }
    337 
    338 TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
    339   // Texture2D g_tColor[128];
    340   //
    341   // layout(push_constant) cbuffer PerViewConstantBuffer_t
    342   // {
    343   //   uint g_nDataIdx;
    344   //   uint g_nDataIdx2;
    345   // };
    346   //
    347   // SamplerState g_sAniso;
    348   //
    349   // struct PS_INPUT
    350   // {
    351   //   float2 vTextureCoords : TEXCOORD2;
    352   // };
    353   //
    354   // struct PS_OUTPUT
    355   // {
    356   //   float4 vColor : SV_Target0;
    357   // };
    358   //
    359   // PS_OUTPUT MainPs(PS_INPUT i)
    360   // {
    361   //   PS_OUTPUT ps_output;
    362   //
    363   //   float t  = g_tColor[g_nDataIdx ].Sample(g_sAniso, i.vTextureCoords.xy);
    364   //   float t2 = g_tColor[g_nDataIdx2].Sample(g_sAniso, i.vTextureCoords.xy);
    365   //   ps_output.vColor = t + t2;
    366   //   return ps_output;
    367   // }
    368 
    369   const std::string defs_before =
    370       R"(OpCapability Shader
    371 %1 = OpExtInstImport "GLSL.std.450"
    372 OpMemoryModel Logical GLSL450
    373 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
    374 OpExecutionMode %MainPs OriginUpperLeft
    375 OpSource HLSL 500
    376 OpName %MainPs "MainPs"
    377 OpName %g_tColor "g_tColor"
    378 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    379 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    380 OpName %_ ""
    381 OpName %g_sAniso "g_sAniso"
    382 OpName %i_vTextureCoords "i.vTextureCoords"
    383 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    384 OpDecorate %g_tColor DescriptorSet 3
    385 OpDecorate %g_tColor Binding 0
    386 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    387 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
    388 OpDecorate %PerViewConstantBuffer_t Block
    389 OpDecorate %g_sAniso DescriptorSet 0
    390 OpDecorate %i_vTextureCoords Location 0
    391 OpDecorate %_entryPointOutput_vColor Location 0
    392 %void = OpTypeVoid
    393 %10 = OpTypeFunction %void
    394 %float = OpTypeFloat 32
    395 %v2float = OpTypeVector %float 2
    396 %v4float = OpTypeVector %float 4
    397 %int = OpTypeInt 32 1
    398 %int_0 = OpConstant %int 0
    399 %int_1 = OpConstant %int 1
    400 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
    401 %uint = OpTypeInt 32 0
    402 %uint_128 = OpConstant %uint 128
    403 %_arr_17_uint_128 = OpTypeArray %17 %uint_128
    404 %_ptr_UniformConstant__arr_17_uint_128 = OpTypePointer UniformConstant %_arr_17_uint_128
    405 %g_tColor = OpVariable %_ptr_UniformConstant__arr_17_uint_128 UniformConstant
    406 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint
    407 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    408 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    409 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    410 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
    411 %25 = OpTypeSampler
    412 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
    413 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
    414 %27 = OpTypeSampledImage %17
    415 %_ptr_Input_v2float = OpTypePointer Input %v2float
    416 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    417 %_ptr_Output_v4float = OpTypePointer Output %v4float
    418 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    419 )";
    420 
    421   const std::string defs_after =
    422       R"(OpCapability Shader
    423 OpExtension "SPV_KHR_storage_buffer_storage_class"
    424 %1 = OpExtInstImport "GLSL.std.450"
    425 OpMemoryModel Logical GLSL450
    426 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
    427 OpExecutionMode %MainPs OriginUpperLeft
    428 OpSource HLSL 500
    429 OpName %MainPs "MainPs"
    430 OpName %g_tColor "g_tColor"
    431 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    432 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    433 OpName %_ ""
    434 OpName %g_sAniso "g_sAniso"
    435 OpName %i_vTextureCoords "i.vTextureCoords"
    436 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    437 OpDecorate %g_tColor DescriptorSet 3
    438 OpDecorate %g_tColor Binding 0
    439 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    440 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
    441 OpDecorate %PerViewConstantBuffer_t Block
    442 OpDecorate %g_sAniso DescriptorSet 0
    443 OpDecorate %i_vTextureCoords Location 0
    444 OpDecorate %_entryPointOutput_vColor Location 0
    445 OpDecorate %_runtimearr_uint ArrayStride 4
    446 OpDecorate %_struct_63 Block
    447 OpMemberDecorate %_struct_63 0 Offset 0
    448 OpMemberDecorate %_struct_63 1 Offset 4
    449 OpDecorate %65 DescriptorSet 7
    450 OpDecorate %65 Binding 0
    451 OpDecorate %gl_FragCoord BuiltIn FragCoord
    452 %void = OpTypeVoid
    453 %10 = OpTypeFunction %void
    454 %float = OpTypeFloat 32
    455 %v2float = OpTypeVector %float 2
    456 %v4float = OpTypeVector %float 4
    457 %int = OpTypeInt 32 1
    458 %int_0 = OpConstant %int 0
    459 %int_1 = OpConstant %int 1
    460 %17 = OpTypeImage %float 2D 0 0 0 1 Unknown
    461 %uint = OpTypeInt 32 0
    462 %uint_128 = OpConstant %uint 128
    463 %_arr_17_uint_128 = OpTypeArray %17 %uint_128
    464 %_ptr_UniformConstant__arr_17_uint_128 = OpTypePointer UniformConstant %_arr_17_uint_128
    465 %g_tColor = OpVariable %_ptr_UniformConstant__arr_17_uint_128 UniformConstant
    466 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint
    467 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    468 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    469 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    470 %_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
    471 %25 = OpTypeSampler
    472 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
    473 %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
    474 %27 = OpTypeSampledImage %17
    475 %_ptr_Input_v2float = OpTypePointer Input %v2float
    476 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    477 %_ptr_Output_v4float = OpTypePointer Output %v4float
    478 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    479 %uint_0 = OpConstant %uint 0
    480 %bool = OpTypeBool
    481 %56 = OpTypeFunction %void %uint %uint %uint %uint
    482 %_runtimearr_uint = OpTypeRuntimeArray %uint
    483 %_struct_63 = OpTypeStruct %uint %_runtimearr_uint
    484 %_ptr_StorageBuffer__struct_63 = OpTypePointer StorageBuffer %_struct_63
    485 %65 = OpVariable %_ptr_StorageBuffer__struct_63 StorageBuffer
    486 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
    487 %uint_9 = OpConstant %uint 9
    488 %uint_4 = OpConstant %uint 4
    489 %uint_1 = OpConstant %uint 1
    490 %uint_23 = OpConstant %uint 23
    491 %uint_2 = OpConstant %uint 2
    492 %uint_3 = OpConstant %uint 3
    493 %_ptr_Input_v4float = OpTypePointer Input %v4float
    494 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
    495 %v4uint = OpTypeVector %uint 4
    496 %uint_5 = OpConstant %uint 5
    497 %uint_6 = OpConstant %uint 6
    498 %uint_7 = OpConstant %uint 7
    499 %uint_8 = OpConstant %uint 8
    500 %uint_58 = OpConstant %uint 58
    501 %111 = OpConstantNull %v4float
    502 %uint_64 = OpConstant %uint 64
    503 )";
    504 
    505   const std::string func_before =
    506       R"(%MainPs = OpFunction %void None %10
    507 %30 = OpLabel
    508 %31 = OpLoad %v2float %i_vTextureCoords
    509 %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    510 %33 = OpLoad %uint %32
    511 %34 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %33
    512 %35 = OpLoad %17 %34
    513 %36 = OpLoad %25 %g_sAniso
    514 %37 = OpSampledImage %27 %35 %36
    515 %38 = OpImageSampleImplicitLod %v4float %37 %31
    516 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    517 %40 = OpLoad %uint %39
    518 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40
    519 %42 = OpLoad %17 %41
    520 %43 = OpSampledImage %27 %42 %36
    521 %44 = OpImageSampleImplicitLod %v4float %43 %31
    522 %45 = OpFAdd %v4float %38 %44
    523 OpStore %_entryPointOutput_vColor %45
    524 OpReturn
    525 OpFunctionEnd
    526 )";
    527 
    528   const std::string func_after =
    529       R"(%MainPs = OpFunction %void None %10
    530 %30 = OpLabel
    531 %31 = OpLoad %v2float %i_vTextureCoords
    532 %32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    533 %33 = OpLoad %uint %32
    534 %34 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %33
    535 %35 = OpLoad %17 %34
    536 %36 = OpLoad %25 %g_sAniso
    537 %37 = OpSampledImage %27 %35 %36
    538 %48 = OpULessThan %bool %33 %uint_128
    539 OpSelectionMerge %49 None
    540 OpBranchConditional %48 %50 %51
    541 %50 = OpLabel
    542 %52 = OpLoad %17 %34
    543 %53 = OpSampledImage %27 %52 %36
    544 %54 = OpImageSampleImplicitLod %v4float %53 %31
    545 OpBranch %49
    546 %51 = OpLabel
    547 %110 = OpFunctionCall %void %55 %uint_58 %uint_0 %33 %uint_128
    548 OpBranch %49
    549 %49 = OpLabel
    550 %112 = OpPhi %v4float %54 %50 %111 %51
    551 %39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    552 %40 = OpLoad %uint %39
    553 %41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40
    554 %42 = OpLoad %17 %41
    555 %43 = OpSampledImage %27 %42 %36
    556 %113 = OpULessThan %bool %40 %uint_128
    557 OpSelectionMerge %114 None
    558 OpBranchConditional %113 %115 %116
    559 %115 = OpLabel
    560 %117 = OpLoad %17 %41
    561 %118 = OpSampledImage %27 %117 %36
    562 %119 = OpImageSampleImplicitLod %v4float %118 %31
    563 OpBranch %114
    564 %116 = OpLabel
    565 %121 = OpFunctionCall %void %55 %uint_64 %uint_0 %40 %uint_128
    566 OpBranch %114
    567 %114 = OpLabel
    568 %122 = OpPhi %v4float %119 %115 %111 %116
    569 %45 = OpFAdd %v4float %112 %122
    570 OpStore %_entryPointOutput_vColor %45
    571 OpReturn
    572 OpFunctionEnd
    573 )";
    574 
    575   const std::string output_func =
    576       R"(%55 = OpFunction %void None %56
    577 %57 = OpFunctionParameter %uint
    578 %58 = OpFunctionParameter %uint
    579 %59 = OpFunctionParameter %uint
    580 %60 = OpFunctionParameter %uint
    581 %61 = OpLabel
    582 %67 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_0
    583 %70 = OpAtomicIAdd %uint %67 %uint_4 %uint_0 %uint_9
    584 %71 = OpIAdd %uint %70 %uint_9
    585 %72 = OpArrayLength %uint %65 1
    586 %73 = OpULessThanEqual %bool %71 %72
    587 OpSelectionMerge %74 None
    588 OpBranchConditional %73 %75 %74
    589 %75 = OpLabel
    590 %76 = OpIAdd %uint %70 %uint_0
    591 %78 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %76
    592 OpStore %78 %uint_9
    593 %80 = OpIAdd %uint %70 %uint_1
    594 %81 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %80
    595 OpStore %81 %uint_23
    596 %83 = OpIAdd %uint %70 %uint_2
    597 %84 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %83
    598 OpStore %84 %57
    599 %86 = OpIAdd %uint %70 %uint_3
    600 %87 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %86
    601 OpStore %87 %uint_4
    602 %90 = OpLoad %v4float %gl_FragCoord
    603 %92 = OpBitcast %v4uint %90
    604 %93 = OpCompositeExtract %uint %92 0
    605 %94 = OpIAdd %uint %70 %uint_4
    606 %95 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %94
    607 OpStore %95 %93
    608 %96 = OpCompositeExtract %uint %92 1
    609 %98 = OpIAdd %uint %70 %uint_5
    610 %99 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %98
    611 OpStore %99 %96
    612 %101 = OpIAdd %uint %70 %uint_6
    613 %102 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %101
    614 OpStore %102 %58
    615 %104 = OpIAdd %uint %70 %uint_7
    616 %105 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %104
    617 OpStore %105 %59
    618 %107 = OpIAdd %uint %70 %uint_8
    619 %108 = OpAccessChain %_ptr_StorageBuffer_uint %65 %uint_1 %107
    620 OpStore %108 %60
    621 OpBranch %74
    622 %74 = OpLabel
    623 OpReturn
    624 OpFunctionEnd
    625 )";
    626 
    627   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    628   SinglePassRunAndCheck<InstBindlessCheckPass>(
    629       defs_before + func_before, defs_after + func_after + output_func, true,
    630       true);
    631 }
    632 
    633 TEST_F(InstBindlessTest, ReuseConstsTypesBuiltins) {
    634   // This test verifies that the pass resuses existing constants, types
    635   // and builtin variables.  This test was created by editing the SPIR-V
    636   // from the Simple test.
    637 
    638   const std::string defs_before =
    639       R"(OpCapability Shader
    640 OpExtension "SPV_KHR_storage_buffer_storage_class"
    641 %1 = OpExtInstImport "GLSL.std.450"
    642 OpMemoryModel Logical GLSL450
    643 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
    644 OpExecutionMode %MainPs OriginUpperLeft
    645 OpSource HLSL 500
    646 OpName %MainPs "MainPs"
    647 OpName %g_tColor "g_tColor"
    648 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    649 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    650 OpName %_ ""
    651 OpName %g_sAniso "g_sAniso"
    652 OpName %i_vTextureCoords "i.vTextureCoords"
    653 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    654 OpDecorate %g_tColor DescriptorSet 3
    655 OpDecorate %g_tColor Binding 0
    656 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    657 OpDecorate %PerViewConstantBuffer_t Block
    658 OpDecorate %g_sAniso DescriptorSet 0
    659 OpDecorate %i_vTextureCoords Location 0
    660 OpDecorate %_entryPointOutput_vColor Location 0
    661 OpDecorate %85 DescriptorSet 7
    662 OpDecorate %85 Binding 0
    663 OpDecorate %gl_FragCoord BuiltIn FragCoord
    664 %void = OpTypeVoid
    665 %3 = OpTypeFunction %void
    666 %float = OpTypeFloat 32
    667 %v2float = OpTypeVector %float 2
    668 %v4float = OpTypeVector %float 4
    669 %int = OpTypeInt 32 1
    670 %int_0 = OpConstant %int 0
    671 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown
    672 %uint = OpTypeInt 32 0
    673 %uint_128 = OpConstant %uint 128
    674 %_arr_20_uint_128 = OpTypeArray %20 %uint_128
    675 %_ptr_UniformConstant__arr_20_uint_128 = OpTypePointer UniformConstant %_arr_20_uint_128
    676 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20_uint_128 UniformConstant
    677 %PerViewConstantBuffer_t = OpTypeStruct %uint
    678 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    679 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    680 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    681 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
    682 %35 = OpTypeSampler
    683 %_ptr_UniformConstant_35 = OpTypePointer UniformConstant %35
    684 %g_sAniso = OpVariable %_ptr_UniformConstant_35 UniformConstant
    685 %39 = OpTypeSampledImage %20
    686 %_ptr_Input_v2float = OpTypePointer Input %v2float
    687 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    688 %_ptr_Output_v4float = OpTypePointer Output %v4float
    689 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    690 %uint_0 = OpConstant %uint 0
    691 %bool = OpTypeBool
    692 %_runtimearr_uint = OpTypeRuntimeArray %uint
    693 %_struct_83 = OpTypeStruct %uint %_runtimearr_uint
    694 %_ptr_StorageBuffer__struct_83 = OpTypePointer StorageBuffer %_struct_83
    695 %85 = OpVariable %_ptr_StorageBuffer__struct_83 StorageBuffer
    696 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
    697 %uint_10 = OpConstant %uint 10
    698 %uint_4 = OpConstant %uint 4
    699 %uint_1 = OpConstant %uint 1
    700 %uint_23 = OpConstant %uint 23
    701 %uint_2 = OpConstant %uint 2
    702 %uint_9 = OpConstant %uint 9
    703 %uint_3 = OpConstant %uint 3
    704 %_ptr_Input_v4float = OpTypePointer Input %v4float
    705 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
    706 %v4uint = OpTypeVector %uint 4
    707 %uint_5 = OpConstant %uint 5
    708 %uint_6 = OpConstant %uint 6
    709 %uint_7 = OpConstant %uint 7
    710 %uint_8 = OpConstant %uint 8
    711 %131 = OpConstantNull %v4float
    712 )";
    713 
    714   const std::string defs_after =
    715       R"(OpCapability Shader
    716 OpExtension "SPV_KHR_storage_buffer_storage_class"
    717 %1 = OpExtInstImport "GLSL.std.450"
    718 OpMemoryModel Logical GLSL450
    719 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
    720 OpExecutionMode %MainPs OriginUpperLeft
    721 OpSource HLSL 500
    722 OpName %MainPs "MainPs"
    723 OpName %g_tColor "g_tColor"
    724 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    725 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    726 OpName %_ ""
    727 OpName %g_sAniso "g_sAniso"
    728 OpName %i_vTextureCoords "i.vTextureCoords"
    729 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    730 OpDecorate %g_tColor DescriptorSet 3
    731 OpDecorate %g_tColor Binding 0
    732 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    733 OpDecorate %PerViewConstantBuffer_t Block
    734 OpDecorate %g_sAniso DescriptorSet 0
    735 OpDecorate %i_vTextureCoords Location 0
    736 OpDecorate %_entryPointOutput_vColor Location 0
    737 OpDecorate %10 DescriptorSet 7
    738 OpDecorate %10 Binding 0
    739 OpDecorate %gl_FragCoord BuiltIn FragCoord
    740 OpDecorate %_runtimearr_uint ArrayStride 4
    741 OpDecorate %_struct_34 Block
    742 OpMemberDecorate %_struct_34 0 Offset 0
    743 OpMemberDecorate %_struct_34 1 Offset 4
    744 OpDecorate %74 DescriptorSet 7
    745 OpDecorate %74 Binding 0
    746 %void = OpTypeVoid
    747 %12 = OpTypeFunction %void
    748 %float = OpTypeFloat 32
    749 %v2float = OpTypeVector %float 2
    750 %v4float = OpTypeVector %float 4
    751 %int = OpTypeInt 32 1
    752 %int_0 = OpConstant %int 0
    753 %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
    754 %uint = OpTypeInt 32 0
    755 %uint_128 = OpConstant %uint 128
    756 %_arr_18_uint_128 = OpTypeArray %18 %uint_128
    757 %_ptr_UniformConstant__arr_18_uint_128 = OpTypePointer UniformConstant %_arr_18_uint_128
    758 %g_tColor = OpVariable %_ptr_UniformConstant__arr_18_uint_128 UniformConstant
    759 %PerViewConstantBuffer_t = OpTypeStruct %uint
    760 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    761 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    762 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    763 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
    764 %26 = OpTypeSampler
    765 %_ptr_UniformConstant_26 = OpTypePointer UniformConstant %26
    766 %g_sAniso = OpVariable %_ptr_UniformConstant_26 UniformConstant
    767 %28 = OpTypeSampledImage %18
    768 %_ptr_Input_v2float = OpTypePointer Input %v2float
    769 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    770 %_ptr_Output_v4float = OpTypePointer Output %v4float
    771 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    772 %uint_0 = OpConstant %uint 0
    773 %bool = OpTypeBool
    774 %_runtimearr_uint = OpTypeRuntimeArray %uint
    775 %_struct_34 = OpTypeStruct %uint %_runtimearr_uint
    776 %_ptr_StorageBuffer__struct_34 = OpTypePointer StorageBuffer %_struct_34
    777 %10 = OpVariable %_ptr_StorageBuffer__struct_34 StorageBuffer
    778 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
    779 %uint_10 = OpConstant %uint 10
    780 %uint_4 = OpConstant %uint 4
    781 %uint_1 = OpConstant %uint 1
    782 %uint_23 = OpConstant %uint 23
    783 %uint_2 = OpConstant %uint 2
    784 %uint_9 = OpConstant %uint 9
    785 %uint_3 = OpConstant %uint 3
    786 %_ptr_Input_v4float = OpTypePointer Input %v4float
    787 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
    788 %v4uint = OpTypeVector %uint 4
    789 %uint_5 = OpConstant %uint 5
    790 %uint_6 = OpConstant %uint 6
    791 %uint_7 = OpConstant %uint 7
    792 %uint_8 = OpConstant %uint 8
    793 %50 = OpConstantNull %v4float
    794 %68 = OpTypeFunction %void %uint %uint %uint %uint
    795 %74 = OpVariable %_ptr_StorageBuffer__struct_34 StorageBuffer
    796 %uint_82 = OpConstant %uint 82
    797 )";
    798 
    799   const std::string func_before =
    800       R"(%MainPs = OpFunction %void None %3
    801 %5 = OpLabel
    802 %53 = OpLoad %v2float %i_vTextureCoords
    803 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    804 %64 = OpLoad %uint %63
    805 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64
    806 %67 = OpLoad %35 %g_sAniso
    807 %78 = OpLoad %20 %65
    808 %79 = OpSampledImage %39 %78 %67
    809 %71 = OpImageSampleImplicitLod %v4float %79 %53
    810 OpStore %_entryPointOutput_vColor %71
    811 OpReturn
    812 OpFunctionEnd
    813 )";
    814 
    815   const std::string func_after =
    816       R"(%MainPs = OpFunction %void None %12
    817 %51 = OpLabel
    818 %52 = OpLoad %v2float %i_vTextureCoords
    819 %53 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    820 %54 = OpLoad %uint %53
    821 %55 = OpAccessChain %_ptr_UniformConstant_18 %g_tColor %54
    822 %56 = OpLoad %26 %g_sAniso
    823 %57 = OpLoad %18 %55
    824 %58 = OpSampledImage %28 %57 %56
    825 %60 = OpULessThan %bool %54 %uint_128
    826 OpSelectionMerge %61 None
    827 OpBranchConditional %60 %62 %63
    828 %62 = OpLabel
    829 %64 = OpLoad %18 %55
    830 %65 = OpSampledImage %28 %64 %56
    831 %66 = OpImageSampleImplicitLod %v4float %65 %52
    832 OpBranch %61
    833 %63 = OpLabel
    834 %105 = OpFunctionCall %void %67 %uint_82 %uint_0 %54 %uint_128
    835 OpBranch %61
    836 %61 = OpLabel
    837 %106 = OpPhi %v4float %66 %62 %50 %63
    838 OpStore %_entryPointOutput_vColor %106
    839 OpReturn
    840 OpFunctionEnd
    841 )";
    842 
    843   const std::string output_func =
    844       R"(%67 = OpFunction %void None %68
    845 %69 = OpFunctionParameter %uint
    846 %70 = OpFunctionParameter %uint
    847 %71 = OpFunctionParameter %uint
    848 %72 = OpFunctionParameter %uint
    849 %73 = OpLabel
    850 %75 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_0
    851 %76 = OpAtomicIAdd %uint %75 %uint_4 %uint_0 %uint_9
    852 %77 = OpIAdd %uint %76 %uint_9
    853 %78 = OpArrayLength %uint %74 1
    854 %79 = OpULessThanEqual %bool %77 %78
    855 OpSelectionMerge %80 None
    856 OpBranchConditional %79 %81 %80
    857 %81 = OpLabel
    858 %82 = OpIAdd %uint %76 %uint_0
    859 %83 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %82
    860 OpStore %83 %uint_9
    861 %84 = OpIAdd %uint %76 %uint_1
    862 %85 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %84
    863 OpStore %85 %uint_23
    864 %86 = OpIAdd %uint %76 %uint_2
    865 %87 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %86
    866 OpStore %87 %69
    867 %88 = OpIAdd %uint %76 %uint_3
    868 %89 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %88
    869 OpStore %89 %uint_4
    870 %90 = OpLoad %v4float %gl_FragCoord
    871 %91 = OpBitcast %v4uint %90
    872 %92 = OpCompositeExtract %uint %91 0
    873 %93 = OpIAdd %uint %76 %uint_4
    874 %94 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %93
    875 OpStore %94 %92
    876 %95 = OpCompositeExtract %uint %91 1
    877 %96 = OpIAdd %uint %76 %uint_5
    878 %97 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %96
    879 OpStore %97 %95
    880 %98 = OpIAdd %uint %76 %uint_6
    881 %99 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %98
    882 OpStore %99 %70
    883 %100 = OpIAdd %uint %76 %uint_7
    884 %101 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %100
    885 OpStore %101 %71
    886 %102 = OpIAdd %uint %76 %uint_8
    887 %103 = OpAccessChain %_ptr_StorageBuffer_uint %74 %uint_1 %102
    888 OpStore %103 %72
    889 OpBranch %80
    890 %80 = OpLabel
    891 OpReturn
    892 OpFunctionEnd
    893 )";
    894 
    895   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
    896   SinglePassRunAndCheck<InstBindlessCheckPass>(
    897       defs_before + func_before, defs_after + func_after + output_func, true,
    898       true);
    899 }
    900 
    901 TEST_F(InstBindlessTest, InstrumentOpImage) {
    902   // This test verifies that the pass will correctly instrument shader
    903   // using OpImage. This test was created by editing the SPIR-V
    904   // from the Simple test.
    905 
    906   const std::string defs_before =
    907       R"(OpCapability Shader
    908 OpCapability StorageImageReadWithoutFormat
    909 %1 = OpExtInstImport "GLSL.std.450"
    910 OpMemoryModel Logical GLSL450
    911 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
    912 OpExecutionMode %MainPs OriginUpperLeft
    913 OpSource HLSL 500
    914 OpName %MainPs "MainPs"
    915 OpName %g_tColor "g_tColor"
    916 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    917 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    918 OpName %_ ""
    919 OpName %i_vTextureCoords "i.vTextureCoords"
    920 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    921 OpDecorate %g_tColor DescriptorSet 3
    922 OpDecorate %g_tColor Binding 0
    923 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    924 OpDecorate %PerViewConstantBuffer_t Block
    925 OpDecorate %i_vTextureCoords Location 0
    926 OpDecorate %_entryPointOutput_vColor Location 0
    927 %void = OpTypeVoid
    928 %3 = OpTypeFunction %void
    929 %float = OpTypeFloat 32
    930 %v4float = OpTypeVector %float 4
    931 %int = OpTypeInt 32 1
    932 %v2int = OpTypeVector %int 2
    933 %int_0 = OpConstant %int 0
    934 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown
    935 %uint = OpTypeInt 32 0
    936 %uint_128 = OpConstant %uint 128
    937 %39 = OpTypeSampledImage %20
    938 %_arr_39_uint_128 = OpTypeArray %39 %uint_128
    939 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128
    940 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant
    941 %PerViewConstantBuffer_t = OpTypeStruct %uint
    942 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    943 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    944 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    945 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39
    946 %_ptr_Input_v2int = OpTypePointer Input %v2int
    947 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
    948 %_ptr_Output_v4float = OpTypePointer Output %v4float
    949 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    950 )";
    951 
    952   const std::string defs_after =
    953       R"(OpCapability Shader
    954 OpCapability StorageImageReadWithoutFormat
    955 OpExtension "SPV_KHR_storage_buffer_storage_class"
    956 %1 = OpExtInstImport "GLSL.std.450"
    957 OpMemoryModel Logical GLSL450
    958 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
    959 OpExecutionMode %MainPs OriginUpperLeft
    960 OpSource HLSL 500
    961 OpName %MainPs "MainPs"
    962 OpName %g_tColor "g_tColor"
    963 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    964 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    965 OpName %_ ""
    966 OpName %i_vTextureCoords "i.vTextureCoords"
    967 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    968 OpDecorate %g_tColor DescriptorSet 3
    969 OpDecorate %g_tColor Binding 0
    970 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    971 OpDecorate %PerViewConstantBuffer_t Block
    972 OpDecorate %i_vTextureCoords Location 0
    973 OpDecorate %_entryPointOutput_vColor Location 0
    974 OpDecorate %_runtimearr_uint ArrayStride 4
    975 OpDecorate %_struct_51 Block
    976 OpMemberDecorate %_struct_51 0 Offset 0
    977 OpMemberDecorate %_struct_51 1 Offset 4
    978 OpDecorate %53 DescriptorSet 7
    979 OpDecorate %53 Binding 0
    980 OpDecorate %gl_FragCoord BuiltIn FragCoord
    981 %void = OpTypeVoid
    982 %9 = OpTypeFunction %void
    983 %float = OpTypeFloat 32
    984 %v4float = OpTypeVector %float 4
    985 %int = OpTypeInt 32 1
    986 %v2int = OpTypeVector %int 2
    987 %int_0 = OpConstant %int 0
    988 %15 = OpTypeImage %float 2D 0 0 0 0 Unknown
    989 %uint = OpTypeInt 32 0
    990 %uint_128 = OpConstant %uint 128
    991 %18 = OpTypeSampledImage %15
    992 %_arr_18_uint_128 = OpTypeArray %18 %uint_128
    993 %_ptr_UniformConstant__arr_18_uint_128 = OpTypePointer UniformConstant %_arr_18_uint_128
    994 %g_tColor = OpVariable %_ptr_UniformConstant__arr_18_uint_128 UniformConstant
    995 %PerViewConstantBuffer_t = OpTypeStruct %uint
    996 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    997 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    998 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    999 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
   1000 %_ptr_Input_v2int = OpTypePointer Input %v2int
   1001 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
   1002 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1003 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
   1004 %uint_0 = OpConstant %uint 0
   1005 %bool = OpTypeBool
   1006 %44 = OpTypeFunction %void %uint %uint %uint %uint
   1007 %_runtimearr_uint = OpTypeRuntimeArray %uint
   1008 %_struct_51 = OpTypeStruct %uint %_runtimearr_uint
   1009 %_ptr_StorageBuffer__struct_51 = OpTypePointer StorageBuffer %_struct_51
   1010 %53 = OpVariable %_ptr_StorageBuffer__struct_51 StorageBuffer
   1011 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
   1012 %uint_9 = OpConstant %uint 9
   1013 %uint_4 = OpConstant %uint 4
   1014 %uint_1 = OpConstant %uint 1
   1015 %uint_23 = OpConstant %uint 23
   1016 %uint_2 = OpConstant %uint 2
   1017 %uint_3 = OpConstant %uint 3
   1018 %_ptr_Input_v4float = OpTypePointer Input %v4float
   1019 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
   1020 %v4uint = OpTypeVector %uint 4
   1021 %uint_5 = OpConstant %uint 5
   1022 %uint_6 = OpConstant %uint 6
   1023 %uint_7 = OpConstant %uint 7
   1024 %uint_8 = OpConstant %uint 8
   1025 %uint_51 = OpConstant %uint 51
   1026 %99 = OpConstantNull %v4float
   1027 )";
   1028 
   1029   const std::string func_before =
   1030       R"(%MainPs = OpFunction %void None %3
   1031 %5 = OpLabel
   1032 %53 = OpLoad %v2int %i_vTextureCoords
   1033 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1034 %64 = OpLoad %uint %63
   1035 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64
   1036 %66 = OpLoad %39 %65
   1037 %75 = OpImage %20 %66
   1038 %71 = OpImageRead %v4float %75 %53
   1039 OpStore %_entryPointOutput_vColor %71
   1040 OpReturn
   1041 OpFunctionEnd
   1042 )";
   1043 
   1044   const std::string func_after =
   1045       R"(%MainPs = OpFunction %void None %9
   1046 %26 = OpLabel
   1047 %27 = OpLoad %v2int %i_vTextureCoords
   1048 %28 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1049 %29 = OpLoad %uint %28
   1050 %30 = OpAccessChain %_ptr_UniformConstant_18 %g_tColor %29
   1051 %31 = OpLoad %18 %30
   1052 %32 = OpImage %15 %31
   1053 %36 = OpULessThan %bool %29 %uint_128
   1054 OpSelectionMerge %37 None
   1055 OpBranchConditional %36 %38 %39
   1056 %38 = OpLabel
   1057 %40 = OpLoad %18 %30
   1058 %41 = OpImage %15 %40
   1059 %42 = OpImageRead %v4float %41 %27
   1060 OpBranch %37
   1061 %39 = OpLabel
   1062 %98 = OpFunctionCall %void %43 %uint_51 %uint_0 %29 %uint_128
   1063 OpBranch %37
   1064 %37 = OpLabel
   1065 %100 = OpPhi %v4float %42 %38 %99 %39
   1066 OpStore %_entryPointOutput_vColor %100
   1067 OpReturn
   1068 OpFunctionEnd
   1069 )";
   1070 
   1071   const std::string output_func =
   1072       R"(%43 = OpFunction %void None %44
   1073 %45 = OpFunctionParameter %uint
   1074 %46 = OpFunctionParameter %uint
   1075 %47 = OpFunctionParameter %uint
   1076 %48 = OpFunctionParameter %uint
   1077 %49 = OpLabel
   1078 %55 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_0
   1079 %58 = OpAtomicIAdd %uint %55 %uint_4 %uint_0 %uint_9
   1080 %59 = OpIAdd %uint %58 %uint_9
   1081 %60 = OpArrayLength %uint %53 1
   1082 %61 = OpULessThanEqual %bool %59 %60
   1083 OpSelectionMerge %62 None
   1084 OpBranchConditional %61 %63 %62
   1085 %63 = OpLabel
   1086 %64 = OpIAdd %uint %58 %uint_0
   1087 %66 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %64
   1088 OpStore %66 %uint_9
   1089 %68 = OpIAdd %uint %58 %uint_1
   1090 %69 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %68
   1091 OpStore %69 %uint_23
   1092 %71 = OpIAdd %uint %58 %uint_2
   1093 %72 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %71
   1094 OpStore %72 %45
   1095 %74 = OpIAdd %uint %58 %uint_3
   1096 %75 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %74
   1097 OpStore %75 %uint_4
   1098 %78 = OpLoad %v4float %gl_FragCoord
   1099 %80 = OpBitcast %v4uint %78
   1100 %81 = OpCompositeExtract %uint %80 0
   1101 %82 = OpIAdd %uint %58 %uint_4
   1102 %83 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %82
   1103 OpStore %83 %81
   1104 %84 = OpCompositeExtract %uint %80 1
   1105 %86 = OpIAdd %uint %58 %uint_5
   1106 %87 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %86
   1107 OpStore %87 %84
   1108 %89 = OpIAdd %uint %58 %uint_6
   1109 %90 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %89
   1110 OpStore %90 %46
   1111 %92 = OpIAdd %uint %58 %uint_7
   1112 %93 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %92
   1113 OpStore %93 %47
   1114 %95 = OpIAdd %uint %58 %uint_8
   1115 %96 = OpAccessChain %_ptr_StorageBuffer_uint %53 %uint_1 %95
   1116 OpStore %96 %48
   1117 OpBranch %62
   1118 %62 = OpLabel
   1119 OpReturn
   1120 OpFunctionEnd
   1121 )";
   1122 
   1123   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   1124   SinglePassRunAndCheck<InstBindlessCheckPass>(
   1125       defs_before + func_before, defs_after + func_after + output_func, true,
   1126       true);
   1127 }
   1128 
   1129 TEST_F(InstBindlessTest, InstrumentSampledImage) {
   1130   // This test verifies that the pass will correctly instrument shader
   1131   // using sampled image. This test was created by editing the SPIR-V
   1132   // from the Simple test.
   1133 
   1134   const std::string defs_before =
   1135       R"(OpCapability Shader
   1136 %1 = OpExtInstImport "GLSL.std.450"
   1137 OpMemoryModel Logical GLSL450
   1138 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
   1139 OpExecutionMode %MainPs OriginUpperLeft
   1140 OpSource HLSL 500
   1141 OpName %MainPs "MainPs"
   1142 OpName %g_tColor "g_tColor"
   1143 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
   1144 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
   1145 OpName %_ ""
   1146 OpName %i_vTextureCoords "i.vTextureCoords"
   1147 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
   1148 OpDecorate %g_tColor DescriptorSet 3
   1149 OpDecorate %g_tColor Binding 0
   1150 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
   1151 OpDecorate %PerViewConstantBuffer_t Block
   1152 OpDecorate %i_vTextureCoords Location 0
   1153 OpDecorate %_entryPointOutput_vColor Location 0
   1154 %void = OpTypeVoid
   1155 %3 = OpTypeFunction %void
   1156 %float = OpTypeFloat 32
   1157 %v2float = OpTypeVector %float 2
   1158 %v4float = OpTypeVector %float 4
   1159 %int = OpTypeInt 32 1
   1160 %int_0 = OpConstant %int 0
   1161 %20 = OpTypeImage %float 2D 0 0 0 1 Unknown
   1162 %uint = OpTypeInt 32 0
   1163 %uint_128 = OpConstant %uint 128
   1164 %39 = OpTypeSampledImage %20
   1165 %_arr_39_uint_128 = OpTypeArray %39 %uint_128
   1166 %_ptr_UniformConstant__arr_39_uint_128 = OpTypePointer UniformConstant %_arr_39_uint_128
   1167 %g_tColor = OpVariable %_ptr_UniformConstant__arr_39_uint_128 UniformConstant
   1168 %PerViewConstantBuffer_t = OpTypeStruct %uint
   1169 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
   1170 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
   1171 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
   1172 %_ptr_UniformConstant_39 = OpTypePointer UniformConstant %39
   1173 %_ptr_Input_v2float = OpTypePointer Input %v2float
   1174 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
   1175 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1176 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
   1177 )";
   1178 
   1179   const std::string defs_after =
   1180       R"(OpCapability Shader
   1181 OpExtension "SPV_KHR_storage_buffer_storage_class"
   1182 %1 = OpExtInstImport "GLSL.std.450"
   1183 OpMemoryModel Logical GLSL450
   1184 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
   1185 OpExecutionMode %MainPs OriginUpperLeft
   1186 OpSource HLSL 500
   1187 OpName %MainPs "MainPs"
   1188 OpName %g_tColor "g_tColor"
   1189 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
   1190 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
   1191 OpName %_ ""
   1192 OpName %i_vTextureCoords "i.vTextureCoords"
   1193 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
   1194 OpDecorate %g_tColor DescriptorSet 3
   1195 OpDecorate %g_tColor Binding 0
   1196 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
   1197 OpDecorate %PerViewConstantBuffer_t Block
   1198 OpDecorate %i_vTextureCoords Location 0
   1199 OpDecorate %_entryPointOutput_vColor Location 0
   1200 OpDecorate %_runtimearr_uint ArrayStride 4
   1201 OpDecorate %_struct_49 Block
   1202 OpMemberDecorate %_struct_49 0 Offset 0
   1203 OpMemberDecorate %_struct_49 1 Offset 4
   1204 OpDecorate %51 DescriptorSet 7
   1205 OpDecorate %51 Binding 0
   1206 OpDecorate %gl_FragCoord BuiltIn FragCoord
   1207 %void = OpTypeVoid
   1208 %9 = OpTypeFunction %void
   1209 %float = OpTypeFloat 32
   1210 %v2float = OpTypeVector %float 2
   1211 %v4float = OpTypeVector %float 4
   1212 %int = OpTypeInt 32 1
   1213 %int_0 = OpConstant %int 0
   1214 %15 = OpTypeImage %float 2D 0 0 0 1 Unknown
   1215 %uint = OpTypeInt 32 0
   1216 %uint_128 = OpConstant %uint 128
   1217 %18 = OpTypeSampledImage %15
   1218 %_arr_18_uint_128 = OpTypeArray %18 %uint_128
   1219 %_ptr_UniformConstant__arr_18_uint_128 = OpTypePointer UniformConstant %_arr_18_uint_128
   1220 %g_tColor = OpVariable %_ptr_UniformConstant__arr_18_uint_128 UniformConstant
   1221 %PerViewConstantBuffer_t = OpTypeStruct %uint
   1222 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
   1223 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
   1224 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
   1225 %_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
   1226 %_ptr_Input_v2float = OpTypePointer Input %v2float
   1227 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
   1228 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1229 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
   1230 %uint_0 = OpConstant %uint 0
   1231 %bool = OpTypeBool
   1232 %42 = OpTypeFunction %void %uint %uint %uint %uint
   1233 %_runtimearr_uint = OpTypeRuntimeArray %uint
   1234 %_struct_49 = OpTypeStruct %uint %_runtimearr_uint
   1235 %_ptr_StorageBuffer__struct_49 = OpTypePointer StorageBuffer %_struct_49
   1236 %51 = OpVariable %_ptr_StorageBuffer__struct_49 StorageBuffer
   1237 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
   1238 %uint_9 = OpConstant %uint 9
   1239 %uint_4 = OpConstant %uint 4
   1240 %uint_1 = OpConstant %uint 1
   1241 %uint_23 = OpConstant %uint 23
   1242 %uint_2 = OpConstant %uint 2
   1243 %uint_3 = OpConstant %uint 3
   1244 %_ptr_Input_v4float = OpTypePointer Input %v4float
   1245 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
   1246 %v4uint = OpTypeVector %uint 4
   1247 %uint_5 = OpConstant %uint 5
   1248 %uint_6 = OpConstant %uint 6
   1249 %uint_7 = OpConstant %uint 7
   1250 %uint_8 = OpConstant %uint 8
   1251 %uint_49 = OpConstant %uint 49
   1252 %97 = OpConstantNull %v4float
   1253 )";
   1254 
   1255   const std::string func_before =
   1256       R"(%MainPs = OpFunction %void None %3
   1257 %5 = OpLabel
   1258 %53 = OpLoad %v2float %i_vTextureCoords
   1259 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1260 %64 = OpLoad %uint %63
   1261 %65 = OpAccessChain %_ptr_UniformConstant_39 %g_tColor %64
   1262 %66 = OpLoad %39 %65
   1263 %71 = OpImageSampleImplicitLod %v4float %66 %53
   1264 OpStore %_entryPointOutput_vColor %71
   1265 OpReturn
   1266 OpFunctionEnd
   1267 )";
   1268 
   1269   const std::string func_after =
   1270       R"(%MainPs = OpFunction %void None %9
   1271 %26 = OpLabel
   1272 %27 = OpLoad %v2float %i_vTextureCoords
   1273 %28 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1274 %29 = OpLoad %uint %28
   1275 %30 = OpAccessChain %_ptr_UniformConstant_18 %g_tColor %29
   1276 %31 = OpLoad %18 %30
   1277 %35 = OpULessThan %bool %29 %uint_128
   1278 OpSelectionMerge %36 None
   1279 OpBranchConditional %35 %37 %38
   1280 %37 = OpLabel
   1281 %39 = OpLoad %18 %30
   1282 %40 = OpImageSampleImplicitLod %v4float %39 %27
   1283 OpBranch %36
   1284 %38 = OpLabel
   1285 %96 = OpFunctionCall %void %41 %uint_49 %uint_0 %29 %uint_128
   1286 OpBranch %36
   1287 %36 = OpLabel
   1288 %98 = OpPhi %v4float %40 %37 %97 %38
   1289 OpStore %_entryPointOutput_vColor %98
   1290 OpReturn
   1291 OpFunctionEnd
   1292 )";
   1293 
   1294   const std::string output_func =
   1295       R"(%41 = OpFunction %void None %42
   1296 %43 = OpFunctionParameter %uint
   1297 %44 = OpFunctionParameter %uint
   1298 %45 = OpFunctionParameter %uint
   1299 %46 = OpFunctionParameter %uint
   1300 %47 = OpLabel
   1301 %53 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_0
   1302 %56 = OpAtomicIAdd %uint %53 %uint_4 %uint_0 %uint_9
   1303 %57 = OpIAdd %uint %56 %uint_9
   1304 %58 = OpArrayLength %uint %51 1
   1305 %59 = OpULessThanEqual %bool %57 %58
   1306 OpSelectionMerge %60 None
   1307 OpBranchConditional %59 %61 %60
   1308 %61 = OpLabel
   1309 %62 = OpIAdd %uint %56 %uint_0
   1310 %64 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %62
   1311 OpStore %64 %uint_9
   1312 %66 = OpIAdd %uint %56 %uint_1
   1313 %67 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %66
   1314 OpStore %67 %uint_23
   1315 %69 = OpIAdd %uint %56 %uint_2
   1316 %70 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %69
   1317 OpStore %70 %43
   1318 %72 = OpIAdd %uint %56 %uint_3
   1319 %73 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %72
   1320 OpStore %73 %uint_4
   1321 %76 = OpLoad %v4float %gl_FragCoord
   1322 %78 = OpBitcast %v4uint %76
   1323 %79 = OpCompositeExtract %uint %78 0
   1324 %80 = OpIAdd %uint %56 %uint_4
   1325 %81 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %80
   1326 OpStore %81 %79
   1327 %82 = OpCompositeExtract %uint %78 1
   1328 %84 = OpIAdd %uint %56 %uint_5
   1329 %85 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %84
   1330 OpStore %85 %82
   1331 %87 = OpIAdd %uint %56 %uint_6
   1332 %88 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %87
   1333 OpStore %88 %44
   1334 %90 = OpIAdd %uint %56 %uint_7
   1335 %91 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %90
   1336 OpStore %91 %45
   1337 %93 = OpIAdd %uint %56 %uint_8
   1338 %94 = OpAccessChain %_ptr_StorageBuffer_uint %51 %uint_1 %93
   1339 OpStore %94 %46
   1340 OpBranch %60
   1341 %60 = OpLabel
   1342 OpReturn
   1343 OpFunctionEnd
   1344 )";
   1345 
   1346   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   1347   SinglePassRunAndCheck<InstBindlessCheckPass>(
   1348       defs_before + func_before, defs_after + func_after + output_func, true,
   1349       true);
   1350 }
   1351 
   1352 TEST_F(InstBindlessTest, InstrumentImageWrite) {
   1353   // This test verifies that the pass will correctly instrument shader
   1354   // doing bindless image write. This test was created by editing the SPIR-V
   1355   // from the Simple test.
   1356 
   1357   const std::string defs_before =
   1358       R"(OpCapability Shader
   1359 OpCapability StorageImageWriteWithoutFormat
   1360 %1 = OpExtInstImport "GLSL.std.450"
   1361 OpMemoryModel Logical GLSL450
   1362 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
   1363 OpExecutionMode %MainPs OriginUpperLeft
   1364 OpSource HLSL 500
   1365 OpName %MainPs "MainPs"
   1366 OpName %g_tColor "g_tColor"
   1367 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
   1368 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
   1369 OpName %_ ""
   1370 OpName %i_vTextureCoords "i.vTextureCoords"
   1371 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
   1372 OpDecorate %g_tColor DescriptorSet 3
   1373 OpDecorate %g_tColor Binding 0
   1374 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
   1375 OpDecorate %PerViewConstantBuffer_t Block
   1376 OpDecorate %i_vTextureCoords Location 0
   1377 OpDecorate %_entryPointOutput_vColor Location 0
   1378 %void = OpTypeVoid
   1379 %3 = OpTypeFunction %void
   1380 %float = OpTypeFloat 32
   1381 %v2float = OpTypeVector %float 2
   1382 %v4float = OpTypeVector %float 4
   1383 %int = OpTypeInt 32 1
   1384 %v2int = OpTypeVector %int 2
   1385 %int_0 = OpConstant %int 0
   1386 %20 = OpTypeImage %float 2D 0 0 0 0 Unknown
   1387 %uint = OpTypeInt 32 0
   1388 %uint_128 = OpConstant %uint 128
   1389 %80 = OpConstantNull %v4float
   1390 %_arr_20_uint_128 = OpTypeArray %20 %uint_128
   1391 %_ptr_UniformConstant__arr_20_uint_128 = OpTypePointer UniformConstant %_arr_20_uint_128
   1392 %g_tColor = OpVariable %_ptr_UniformConstant__arr_20_uint_128 UniformConstant
   1393 %PerViewConstantBuffer_t = OpTypeStruct %uint
   1394 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
   1395 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
   1396 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
   1397 %_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
   1398 %_ptr_Input_v2int = OpTypePointer Input %v2int
   1399 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
   1400 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1401 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
   1402 )";
   1403 
   1404   const std::string defs_after =
   1405       R"(OpCapability Shader
   1406 OpCapability StorageImageWriteWithoutFormat
   1407 OpExtension "SPV_KHR_storage_buffer_storage_class"
   1408 %1 = OpExtInstImport "GLSL.std.450"
   1409 OpMemoryModel Logical GLSL450
   1410 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
   1411 OpExecutionMode %MainPs OriginUpperLeft
   1412 OpSource HLSL 500
   1413 OpName %MainPs "MainPs"
   1414 OpName %g_tColor "g_tColor"
   1415 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
   1416 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
   1417 OpName %_ ""
   1418 OpName %i_vTextureCoords "i.vTextureCoords"
   1419 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
   1420 OpDecorate %g_tColor DescriptorSet 3
   1421 OpDecorate %g_tColor Binding 0
   1422 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
   1423 OpDecorate %PerViewConstantBuffer_t Block
   1424 OpDecorate %i_vTextureCoords Location 0
   1425 OpDecorate %_entryPointOutput_vColor Location 0
   1426 OpDecorate %_runtimearr_uint ArrayStride 4
   1427 OpDecorate %_struct_48 Block
   1428 OpMemberDecorate %_struct_48 0 Offset 0
   1429 OpMemberDecorate %_struct_48 1 Offset 4
   1430 OpDecorate %50 DescriptorSet 7
   1431 OpDecorate %50 Binding 0
   1432 OpDecorate %gl_FragCoord BuiltIn FragCoord
   1433 %void = OpTypeVoid
   1434 %9 = OpTypeFunction %void
   1435 %float = OpTypeFloat 32
   1436 %v2float = OpTypeVector %float 2
   1437 %v4float = OpTypeVector %float 4
   1438 %int = OpTypeInt 32 1
   1439 %v2int = OpTypeVector %int 2
   1440 %int_0 = OpConstant %int 0
   1441 %16 = OpTypeImage %float 2D 0 0 0 0 Unknown
   1442 %uint = OpTypeInt 32 0
   1443 %uint_128 = OpConstant %uint 128
   1444 %19 = OpConstantNull %v4float
   1445 %_arr_16_uint_128 = OpTypeArray %16 %uint_128
   1446 %_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
   1447 %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
   1448 %PerViewConstantBuffer_t = OpTypeStruct %uint
   1449 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
   1450 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
   1451 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
   1452 %_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
   1453 %_ptr_Input_v2int = OpTypePointer Input %v2int
   1454 %i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
   1455 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1456 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
   1457 %uint_0 = OpConstant %uint 0
   1458 %bool = OpTypeBool
   1459 %41 = OpTypeFunction %void %uint %uint %uint %uint
   1460 %_runtimearr_uint = OpTypeRuntimeArray %uint
   1461 %_struct_48 = OpTypeStruct %uint %_runtimearr_uint
   1462 %_ptr_StorageBuffer__struct_48 = OpTypePointer StorageBuffer %_struct_48
   1463 %50 = OpVariable %_ptr_StorageBuffer__struct_48 StorageBuffer
   1464 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
   1465 %uint_9 = OpConstant %uint 9
   1466 %uint_4 = OpConstant %uint 4
   1467 %uint_1 = OpConstant %uint 1
   1468 %uint_23 = OpConstant %uint 23
   1469 %uint_2 = OpConstant %uint 2
   1470 %uint_3 = OpConstant %uint 3
   1471 %_ptr_Input_v4float = OpTypePointer Input %v4float
   1472 %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
   1473 %v4uint = OpTypeVector %uint 4
   1474 %uint_5 = OpConstant %uint 5
   1475 %uint_6 = OpConstant %uint 6
   1476 %uint_7 = OpConstant %uint 7
   1477 %uint_8 = OpConstant %uint 8
   1478 %uint_51 = OpConstant %uint 51
   1479 )";
   1480 
   1481   const std::string func_before =
   1482       R"(%MainPs = OpFunction %void None %3
   1483 %5 = OpLabel
   1484 %53 = OpLoad %v2int %i_vTextureCoords
   1485 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1486 %64 = OpLoad %uint %63
   1487 %65 = OpAccessChain %_ptr_UniformConstant_20 %g_tColor %64
   1488 %66 = OpLoad %20 %65
   1489 OpImageWrite %66 %53 %80
   1490 OpStore %_entryPointOutput_vColor %80
   1491 OpReturn
   1492 OpFunctionEnd
   1493 )";
   1494 
   1495   const std::string func_after =
   1496       R"(%MainPs = OpFunction %void None %9
   1497 %27 = OpLabel
   1498 %28 = OpLoad %v2int %i_vTextureCoords
   1499 %29 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
   1500 %30 = OpLoad %uint %29
   1501 %31 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %30
   1502 %32 = OpLoad %16 %31
   1503 %35 = OpULessThan %bool %30 %uint_128
   1504 OpSelectionMerge %36 None
   1505 OpBranchConditional %35 %37 %38
   1506 %37 = OpLabel
   1507 %39 = OpLoad %16 %31
   1508 OpImageWrite %39 %28 %19
   1509 OpBranch %36
   1510 %38 = OpLabel
   1511 %95 = OpFunctionCall %void %40 %uint_51 %uint_0 %30 %uint_128
   1512 OpBranch %36
   1513 %36 = OpLabel
   1514 OpStore %_entryPointOutput_vColor %19
   1515 OpReturn
   1516 OpFunctionEnd
   1517 )";
   1518 
   1519   const std::string output_func =
   1520       R"(%40 = OpFunction %void None %41
   1521 %42 = OpFunctionParameter %uint
   1522 %43 = OpFunctionParameter %uint
   1523 %44 = OpFunctionParameter %uint
   1524 %45 = OpFunctionParameter %uint
   1525 %46 = OpLabel
   1526 %52 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_0
   1527 %55 = OpAtomicIAdd %uint %52 %uint_4 %uint_0 %uint_9
   1528 %56 = OpIAdd %uint %55 %uint_9
   1529 %57 = OpArrayLength %uint %50 1
   1530 %58 = OpULessThanEqual %bool %56 %57
   1531 OpSelectionMerge %59 None
   1532 OpBranchConditional %58 %60 %59
   1533 %60 = OpLabel
   1534 %61 = OpIAdd %uint %55 %uint_0
   1535 %63 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %61
   1536 OpStore %63 %uint_9
   1537 %65 = OpIAdd %uint %55 %uint_1
   1538 %66 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %65
   1539 OpStore %66 %uint_23
   1540 %68 = OpIAdd %uint %55 %uint_2
   1541 %69 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %68
   1542 OpStore %69 %42
   1543 %71 = OpIAdd %uint %55 %uint_3
   1544 %72 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %71
   1545 OpStore %72 %uint_4
   1546 %75 = OpLoad %v4float %gl_FragCoord
   1547 %77 = OpBitcast %v4uint %75
   1548 %78 = OpCompositeExtract %uint %77 0
   1549 %79 = OpIAdd %uint %55 %uint_4
   1550 %80 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %79
   1551 OpStore %80 %78
   1552 %81 = OpCompositeExtract %uint %77 1
   1553 %83 = OpIAdd %uint %55 %uint_5
   1554 %84 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %83
   1555 OpStore %84 %81
   1556 %86 = OpIAdd %uint %55 %uint_6
   1557 %87 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %86
   1558 OpStore %87 %43
   1559 %89 = OpIAdd %uint %55 %uint_7
   1560 %90 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %89
   1561 OpStore %90 %44
   1562 %92 = OpIAdd %uint %55 %uint_8
   1563 %93 = OpAccessChain %_ptr_StorageBuffer_uint %50 %uint_1 %92
   1564 OpStore %93 %45
   1565 OpBranch %59
   1566 %59 = OpLabel
   1567 OpReturn
   1568 OpFunctionEnd
   1569 )";
   1570 
   1571   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   1572   SinglePassRunAndCheck<InstBindlessCheckPass>(
   1573       defs_before + func_before, defs_after + func_after + output_func, true,
   1574       true);
   1575 }
   1576 
   1577 TEST_F(InstBindlessTest, InstrumentVertexSimple) {
   1578   // This test verifies that the pass will correctly instrument shader
   1579   // doing bindless image write. This test was created by editing the SPIR-V
   1580   // from the Simple test.
   1581 
   1582   const std::string defs_before =
   1583       R"(OpCapability Shader
   1584 OpCapability Sampled1D
   1585 %1 = OpExtInstImport "GLSL.std.450"
   1586 OpMemoryModel Logical GLSL450
   1587 OpEntryPoint Vertex %main "main" %_ %coords2D
   1588 OpSource GLSL 450
   1589 OpName %main "main"
   1590 OpName %lod "lod"
   1591 OpName %coords1D "coords1D"
   1592 OpName %gl_PerVertex "gl_PerVertex"
   1593 OpMemberName %gl_PerVertex 0 "gl_Position"
   1594 OpMemberName %gl_PerVertex 1 "gl_PointSize"
   1595 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
   1596 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
   1597 OpName %_ ""
   1598 OpName %texSampler1D "texSampler1D"
   1599 OpName %foo "foo"
   1600 OpMemberName %foo 0 "g_idx"
   1601 OpName %__0 ""
   1602 OpName %coords2D "coords2D"
   1603 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
   1604 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
   1605 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
   1606 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
   1607 OpDecorate %gl_PerVertex Block
   1608 OpDecorate %texSampler1D DescriptorSet 0
   1609 OpDecorate %texSampler1D Binding 3
   1610 OpMemberDecorate %foo 0 Offset 0
   1611 OpDecorate %foo Block
   1612 OpDecorate %__0 DescriptorSet 0
   1613 OpDecorate %__0 Binding 5
   1614 OpDecorate %coords2D Location 0
   1615 %void = OpTypeVoid
   1616 %3 = OpTypeFunction %void
   1617 %float = OpTypeFloat 32
   1618 %_ptr_Function_float = OpTypePointer Function %float
   1619 %float_3 = OpConstant %float 3
   1620 %float_1_78900003 = OpConstant %float 1.78900003
   1621 %v4float = OpTypeVector %float 4
   1622 %uint = OpTypeInt 32 0
   1623 %uint_1 = OpConstant %uint 1
   1624 %_arr_float_uint_1 = OpTypeArray %float %uint_1
   1625 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
   1626 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
   1627 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
   1628 %int = OpTypeInt 32 1
   1629 %int_0 = OpConstant %int 0
   1630 %21 = OpTypeImage %float 1D 0 0 0 1 Unknown
   1631 %22 = OpTypeSampledImage %21
   1632 %uint_128 = OpConstant %uint 128
   1633 %_arr_22_uint_128 = OpTypeArray %22 %uint_128
   1634 %_ptr_UniformConstant__arr_22_uint_128 = OpTypePointer UniformConstant %_arr_22_uint_128
   1635 %texSampler1D = OpVariable %_ptr_UniformConstant__arr_22_uint_128 UniformConstant
   1636 %foo = OpTypeStruct %int
   1637 %_ptr_Uniform_foo = OpTypePointer Uniform %foo
   1638 %__0 = OpVariable %_ptr_Uniform_foo Uniform
   1639 %_ptr_Uniform_int = OpTypePointer Uniform %int
   1640 %_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
   1641 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1642 %v2float = OpTypeVector %float 2
   1643 %_ptr_Input_v2float = OpTypePointer Input %v2float
   1644 %coords2D = OpVariable %_ptr_Input_v2float Input
   1645 )";
   1646 
   1647   const std::string defs_after =
   1648       R"(OpCapability Shader
   1649 OpCapability Sampled1D
   1650 OpExtension "SPV_KHR_storage_buffer_storage_class"
   1651 %1 = OpExtInstImport "GLSL.std.450"
   1652 OpMemoryModel Logical GLSL450
   1653 OpEntryPoint Vertex %main "main" %_ %coords2D %gl_VertexIndex %gl_InstanceIndex
   1654 OpSource GLSL 450
   1655 OpName %main "main"
   1656 OpName %lod "lod"
   1657 OpName %coords1D "coords1D"
   1658 OpName %gl_PerVertex "gl_PerVertex"
   1659 OpMemberName %gl_PerVertex 0 "gl_Position"
   1660 OpMemberName %gl_PerVertex 1 "gl_PointSize"
   1661 OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
   1662 OpMemberName %gl_PerVertex 3 "gl_CullDistance"
   1663 OpName %_ ""
   1664 OpName %texSampler1D "texSampler1D"
   1665 OpName %foo "foo"
   1666 OpMemberName %foo 0 "g_idx"
   1667 OpName %__0 ""
   1668 OpName %coords2D "coords2D"
   1669 OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
   1670 OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
   1671 OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
   1672 OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
   1673 OpDecorate %gl_PerVertex Block
   1674 OpDecorate %texSampler1D DescriptorSet 0
   1675 OpDecorate %texSampler1D Binding 3
   1676 OpMemberDecorate %foo 0 Offset 0
   1677 OpDecorate %foo Block
   1678 OpDecorate %__0 DescriptorSet 0
   1679 OpDecorate %__0 Binding 5
   1680 OpDecorate %coords2D Location 0
   1681 OpDecorate %_runtimearr_uint ArrayStride 4
   1682 OpDecorate %_struct_61 Block
   1683 OpMemberDecorate %_struct_61 0 Offset 0
   1684 OpMemberDecorate %_struct_61 1 Offset 4
   1685 OpDecorate %63 DescriptorSet 7
   1686 OpDecorate %63 Binding 0
   1687 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
   1688 OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
   1689 %void = OpTypeVoid
   1690 %12 = OpTypeFunction %void
   1691 %float = OpTypeFloat 32
   1692 %_ptr_Function_float = OpTypePointer Function %float
   1693 %float_3 = OpConstant %float 3
   1694 %float_1_78900003 = OpConstant %float 1.78900003
   1695 %v4float = OpTypeVector %float 4
   1696 %uint = OpTypeInt 32 0
   1697 %uint_1 = OpConstant %uint 1
   1698 %_arr_float_uint_1 = OpTypeArray %float %uint_1
   1699 %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
   1700 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
   1701 %_ = OpVariable %_ptr_Output_gl_PerVertex Output
   1702 %int = OpTypeInt 32 1
   1703 %int_0 = OpConstant %int 0
   1704 %24 = OpTypeImage %float 1D 0 0 0 1 Unknown
   1705 %25 = OpTypeSampledImage %24
   1706 %uint_128 = OpConstant %uint 128
   1707 %_arr_25_uint_128 = OpTypeArray %25 %uint_128
   1708 %_ptr_UniformConstant__arr_25_uint_128 = OpTypePointer UniformConstant %_arr_25_uint_128
   1709 %texSampler1D = OpVariable %_ptr_UniformConstant__arr_25_uint_128 UniformConstant
   1710 %foo = OpTypeStruct %int
   1711 %_ptr_Uniform_foo = OpTypePointer Uniform %foo
   1712 %__0 = OpVariable %_ptr_Uniform_foo Uniform
   1713 %_ptr_Uniform_int = OpTypePointer Uniform %int
   1714 %_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
   1715 %_ptr_Output_v4float = OpTypePointer Output %v4float
   1716 %v2float = OpTypeVector %float 2
   1717 %_ptr_Input_v2float = OpTypePointer Input %v2float
   1718 %coords2D = OpVariable %_ptr_Input_v2float Input
   1719 %uint_0 = OpConstant %uint 0
   1720 %bool = OpTypeBool
   1721 %54 = OpTypeFunction %void %uint %uint %uint %uint
   1722 %_runtimearr_uint = OpTypeRuntimeArray %uint
   1723 %_struct_61 = OpTypeStruct %uint %_runtimearr_uint
   1724 %_ptr_StorageBuffer__struct_61 = OpTypePointer StorageBuffer %_struct_61
   1725 %63 = OpVariable %_ptr_StorageBuffer__struct_61 StorageBuffer
   1726 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
   1727 %uint_9 = OpConstant %uint 9
   1728 %uint_4 = OpConstant %uint 4
   1729 %uint_23 = OpConstant %uint 23
   1730 %uint_2 = OpConstant %uint 2
   1731 %uint_3 = OpConstant %uint 3
   1732 %_ptr_Input_uint = OpTypePointer Input %uint
   1733 %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
   1734 %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
   1735 %uint_5 = OpConstant %uint 5
   1736 %uint_6 = OpConstant %uint 6
   1737 %uint_7 = OpConstant %uint 7
   1738 %uint_8 = OpConstant %uint 8
   1739 %uint_74 = OpConstant %uint 74
   1740 %106 = OpConstantNull %v4float
   1741 )";
   1742 
   1743   const std::string func_before =
   1744       R"(%main = OpFunction %void None %3
   1745 %5 = OpLabel
   1746 %lod = OpVariable %_ptr_Function_float Function
   1747 %coords1D = OpVariable %_ptr_Function_float Function
   1748 OpStore %lod %float_3
   1749 OpStore %coords1D %float_1_78900003
   1750 %31 = OpAccessChain %_ptr_Uniform_int %__0 %int_0
   1751 %32 = OpLoad %int %31
   1752 %34 = OpAccessChain %_ptr_UniformConstant_22 %texSampler1D %32
   1753 %35 = OpLoad %22 %34
   1754 %36 = OpLoad %float %coords1D
   1755 %37 = OpLoad %float %lod
   1756 %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37
   1757 %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0
   1758 OpStore %40 %38
   1759 OpReturn
   1760 OpFunctionEnd
   1761 )";
   1762 
   1763   const std::string func_after =
   1764       R"(%main = OpFunction %void None %12
   1765 %35 = OpLabel
   1766 %lod = OpVariable %_ptr_Function_float Function
   1767 %coords1D = OpVariable %_ptr_Function_float Function
   1768 OpStore %lod %float_3
   1769 OpStore %coords1D %float_1_78900003
   1770 %36 = OpAccessChain %_ptr_Uniform_int %__0 %int_0
   1771 %37 = OpLoad %int %36
   1772 %38 = OpAccessChain %_ptr_UniformConstant_25 %texSampler1D %37
   1773 %39 = OpLoad %25 %38
   1774 %40 = OpLoad %float %coords1D
   1775 %41 = OpLoad %float %lod
   1776 %46 = OpULessThan %bool %37 %uint_128
   1777 OpSelectionMerge %47 None
   1778 OpBranchConditional %46 %48 %49
   1779 %48 = OpLabel
   1780 %50 = OpLoad %25 %38
   1781 %51 = OpImageSampleExplicitLod %v4float %50 %40 Lod %41
   1782 OpBranch %47
   1783 %49 = OpLabel
   1784 %52 = OpBitcast %uint %37
   1785 %105 = OpFunctionCall %void %53 %uint_74 %uint_0 %52 %uint_128
   1786 OpBranch %47
   1787 %47 = OpLabel
   1788 %107 = OpPhi %v4float %51 %48 %106 %49
   1789 %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0
   1790 OpStore %43 %107
   1791 OpReturn
   1792 OpFunctionEnd
   1793 )";
   1794 
   1795   const std::string output_func =
   1796       R"(%53 = OpFunction %void None %54
   1797 %55 = OpFunctionParameter %uint
   1798 %56 = OpFunctionParameter %uint
   1799 %57 = OpFunctionParameter %uint
   1800 %58 = OpFunctionParameter %uint
   1801 %59 = OpLabel
   1802 %65 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_0
   1803 %68 = OpAtomicIAdd %uint %65 %uint_4 %uint_0 %uint_9
   1804 %69 = OpIAdd %uint %68 %uint_9
   1805 %70 = OpArrayLength %uint %63 1
   1806 %71 = OpULessThanEqual %bool %69 %70
   1807 OpSelectionMerge %72 None
   1808 OpBranchConditional %71 %73 %72
   1809 %73 = OpLabel
   1810 %74 = OpIAdd %uint %68 %uint_0
   1811 %75 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %74
   1812 OpStore %75 %uint_9
   1813 %77 = OpIAdd %uint %68 %uint_1
   1814 %78 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %77
   1815 OpStore %78 %uint_23
   1816 %80 = OpIAdd %uint %68 %uint_2
   1817 %81 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %80
   1818 OpStore %81 %55
   1819 %83 = OpIAdd %uint %68 %uint_3
   1820 %84 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %83
   1821 OpStore %84 %uint_0
   1822 %87 = OpLoad %uint %gl_VertexIndex
   1823 %88 = OpIAdd %uint %68 %uint_4
   1824 %89 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %88
   1825 OpStore %89 %87
   1826 %91 = OpLoad %uint %gl_InstanceIndex
   1827 %93 = OpIAdd %uint %68 %uint_5
   1828 %94 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %93
   1829 OpStore %94 %91
   1830 %96 = OpIAdd %uint %68 %uint_6
   1831 %97 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %96
   1832 OpStore %97 %56
   1833 %99 = OpIAdd %uint %68 %uint_7
   1834 %100 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %99
   1835 OpStore %100 %57
   1836 %102 = OpIAdd %uint %68 %uint_8
   1837 %103 = OpAccessChain %_ptr_StorageBuffer_uint %63 %uint_1 %102
   1838 OpStore %103 %58
   1839 OpBranch %72
   1840 %72 = OpLabel
   1841 OpReturn
   1842 OpFunctionEnd
   1843 )";
   1844 
   1845   // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   1846   SinglePassRunAndCheck<InstBindlessCheckPass>(
   1847       defs_before + func_before, defs_after + func_after + output_func, true,
   1848       true);
   1849 }
   1850 
   1851 // TODO(greg-lunarg): Add tests to verify handling of these cases:
   1852 //
   1853 // TODO(greg-lunarg): Come up with cases to put here :)
   1854 
   1855 }  // namespace
   1856 }  // namespace opt
   1857 }  // namespace spvtools
   1858