Home | History | Annotate | Download | only in opt
      1 // Copyright (c) 2017 Google Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <cstdarg>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "gmock/gmock.h"
     20 #include "pass_utils.h"
     21 #include "test/opt/assembly_builder.h"
     22 #include "test/opt/pass_fixture.h"
     23 
     24 namespace spvtools {
     25 namespace opt {
     26 namespace {
     27 
     28 using ReplaceInvalidOpcodeTest = PassTest<::testing::Test>;
     29 
     30 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstruction) {
     31   const std::string text = R"(
     32 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
     33 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
     34 ; CHECK-NOT: OpImageSampleImplicitLod
     35 ; CHECK: OpStore [[:%\w+]] [[constant]]
     36                 OpCapability Shader
     37           %1 = OpExtInstImport "GLSL.std.450"
     38                OpMemoryModel Logical GLSL450
     39                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
     40                OpSource GLSL 400
     41                OpSourceExtension "GL_ARB_separate_shader_objects"
     42                OpSourceExtension "GL_ARB_shading_language_420pack"
     43                OpName %main "main"
     44                OpDecorate %3 Location 0
     45                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
     46                OpMemberDecorate %_struct_6 0 BuiltIn Position
     47                OpDecorate %_struct_6 Block
     48        %void = OpTypeVoid
     49           %8 = OpTypeFunction %void
     50       %float = OpTypeFloat 32
     51          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
     52 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
     53          %12 = OpTypeSampler
     54 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
     55          %14 = OpTypeSampledImage %10
     56     %v4float = OpTypeVector %float 4
     57     %v2float = OpTypeVector %float 2
     58 %_ptr_Output_v4float = OpTypePointer Output %v4float
     59           %3 = OpVariable %_ptr_Output_v4float Output
     60         %int = OpTypeInt 32 1
     61 %_ptr_Input_int = OpTypePointer Input %int
     62 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
     63   %_struct_6 = OpTypeStruct %v4float
     64 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
     65           %5 = OpVariable %_ptr_Output__struct_6 Output
     66       %int_0 = OpConstant %int 0
     67     %float_0 = OpConstant %float 0
     68          %23 = OpConstantComposite %v2float %float_0 %float_0
     69          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
     70          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
     71        %main = OpFunction %void None %8
     72          %26 = OpLabel
     73          %27 = OpLoad %12 %25
     74          %28 = OpLoad %10 %24
     75          %29 = OpSampledImage %14 %28 %27
     76          %30 = OpImageSampleImplicitLod %v4float %29 %23
     77          %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
     78                OpStore %31 %30
     79                OpReturn
     80                OpFunctionEnd)";
     81 
     82   SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
     83 }
     84 
     85 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionInNonEntryPoint) {
     86   const std::string text = R"(
     87 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
     88 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
     89 ; CHECK-NOT: OpImageSampleImplicitLod
     90 ; CHECK: OpStore [[:%\w+]] [[constant]]
     91                OpCapability Shader
     92           %1 = OpExtInstImport "GLSL.std.450"
     93                OpMemoryModel Logical GLSL450
     94                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
     95                OpSource GLSL 400
     96                OpSourceExtension "GL_ARB_separate_shader_objects"
     97                OpSourceExtension "GL_ARB_shading_language_420pack"
     98                OpName %main "main"
     99                OpDecorate %3 Location 0
    100                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    101                OpMemberDecorate %_struct_6 0 BuiltIn Position
    102                OpDecorate %_struct_6 Block
    103        %void = OpTypeVoid
    104           %8 = OpTypeFunction %void
    105       %float = OpTypeFloat 32
    106          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
    107 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
    108          %12 = OpTypeSampler
    109 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
    110          %14 = OpTypeSampledImage %10
    111     %v4float = OpTypeVector %float 4
    112     %v2float = OpTypeVector %float 2
    113 %_ptr_Output_v4float = OpTypePointer Output %v4float
    114           %3 = OpVariable %_ptr_Output_v4float Output
    115         %int = OpTypeInt 32 1
    116 %_ptr_Input_int = OpTypePointer Input %int
    117 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    118   %_struct_6 = OpTypeStruct %v4float
    119 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
    120           %5 = OpVariable %_ptr_Output__struct_6 Output
    121       %int_0 = OpConstant %int 0
    122     %float_0 = OpConstant %float 0
    123          %23 = OpConstantComposite %v2float %float_0 %float_0
    124          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
    125          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
    126        %main = OpFunction %void None %8
    127          %26 = OpLabel
    128          %27 = OpFunctionCall %void %28
    129                OpReturn
    130                OpFunctionEnd
    131          %28 = OpFunction %void None %8
    132          %29 = OpLabel
    133          %30 = OpLoad %12 %25
    134          %31 = OpLoad %10 %24
    135          %32 = OpSampledImage %14 %31 %30
    136          %33 = OpImageSampleImplicitLod %v4float %32 %23
    137          %34 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    138                OpStore %34 %33
    139                OpReturn
    140                OpFunctionEnd)";
    141 
    142   SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
    143 }
    144 
    145 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionMultipleEntryPoints) {
    146   const std::string text = R"(
    147 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
    148 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
    149 ; CHECK-NOT: OpImageSampleImplicitLod
    150 ; CHECK: OpStore [[:%\w+]] [[constant]]
    151 ; CHECK-NOT: OpImageSampleImplicitLod
    152 ; CHECK: OpStore [[:%\w+]] [[constant]]
    153                 OpCapability Shader
    154           %1 = OpExtInstImport "GLSL.std.450"
    155                OpMemoryModel Logical GLSL450
    156                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
    157                OpEntryPoint Vertex %main2 "main2" %3 %gl_VertexIndex %5
    158                OpSource GLSL 400
    159                OpSourceExtension "GL_ARB_separate_shader_objects"
    160                OpSourceExtension "GL_ARB_shading_language_420pack"
    161                OpName %main "main"
    162                OpName %main2 "main2"
    163                OpDecorate %3 Location 0
    164                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    165                OpMemberDecorate %_struct_6 0 BuiltIn Position
    166                OpDecorate %_struct_6 Block
    167        %void = OpTypeVoid
    168           %8 = OpTypeFunction %void
    169       %float = OpTypeFloat 32
    170          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
    171 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
    172          %12 = OpTypeSampler
    173 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
    174          %14 = OpTypeSampledImage %10
    175     %v4float = OpTypeVector %float 4
    176     %v2float = OpTypeVector %float 2
    177 %_ptr_Output_v4float = OpTypePointer Output %v4float
    178           %3 = OpVariable %_ptr_Output_v4float Output
    179         %int = OpTypeInt 32 1
    180 %_ptr_Input_int = OpTypePointer Input %int
    181 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    182   %_struct_6 = OpTypeStruct %v4float
    183 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
    184           %5 = OpVariable %_ptr_Output__struct_6 Output
    185       %int_0 = OpConstant %int 0
    186     %float_0 = OpConstant %float 0
    187          %23 = OpConstantComposite %v2float %float_0 %float_0
    188          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
    189          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
    190        %main = OpFunction %void None %8
    191          %26 = OpLabel
    192          %27 = OpLoad %12 %25
    193          %28 = OpLoad %10 %24
    194          %29 = OpSampledImage %14 %28 %27
    195          %30 = OpImageSampleImplicitLod %v4float %29 %23
    196          %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    197                OpStore %31 %30
    198                OpReturn
    199                OpFunctionEnd
    200       %main2 = OpFunction %void None %8
    201          %46 = OpLabel
    202          %47 = OpLoad %12 %25
    203          %48 = OpLoad %10 %24
    204          %49 = OpSampledImage %14 %48 %47
    205          %50 = OpImageSampleImplicitLod %v4float %49 %23
    206          %51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    207                OpStore %51 %50
    208                OpReturn
    209                OpFunctionEnd)";
    210 
    211   SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
    212 }
    213 TEST_F(ReplaceInvalidOpcodeTest, DontReplaceInstruction) {
    214   const std::string text = R"(
    215                 OpCapability Shader
    216           %1 = OpExtInstImport "GLSL.std.450"
    217                OpMemoryModel Logical GLSL450
    218                OpEntryPoint Fragment %main "main" %3 %gl_VertexIndex %5
    219                OpSource GLSL 400
    220                OpSourceExtension "GL_ARB_separate_shader_objects"
    221                OpSourceExtension "GL_ARB_shading_language_420pack"
    222                OpName %main "main"
    223                OpDecorate %3 Location 0
    224                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    225                OpMemberDecorate %_struct_6 0 BuiltIn Position
    226                OpDecorate %_struct_6 Block
    227        %void = OpTypeVoid
    228           %8 = OpTypeFunction %void
    229       %float = OpTypeFloat 32
    230          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
    231 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
    232          %12 = OpTypeSampler
    233 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
    234          %14 = OpTypeSampledImage %10
    235     %v4float = OpTypeVector %float 4
    236     %v2float = OpTypeVector %float 2
    237 %_ptr_Output_v4float = OpTypePointer Output %v4float
    238           %3 = OpVariable %_ptr_Output_v4float Output
    239         %int = OpTypeInt 32 1
    240 %_ptr_Input_int = OpTypePointer Input %int
    241 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    242   %_struct_6 = OpTypeStruct %v4float
    243 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
    244           %5 = OpVariable %_ptr_Output__struct_6 Output
    245       %int_0 = OpConstant %int 0
    246     %float_0 = OpConstant %float 0
    247          %23 = OpConstantComposite %v2float %float_0 %float_0
    248          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
    249          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
    250        %main = OpFunction %void None %8
    251          %26 = OpLabel
    252          %27 = OpLoad %12 %25
    253          %28 = OpLoad %10 %24
    254          %29 = OpSampledImage %14 %28 %27
    255          %30 = OpImageSampleImplicitLod %v4float %29 %23
    256          %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    257                OpStore %31 %30
    258                OpReturn
    259                OpFunctionEnd)";
    260 
    261   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    262       text, /* skip_nop = */ true, /* do_validation = */ false);
    263   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
    264 }
    265 
    266 TEST_F(ReplaceInvalidOpcodeTest, MultipleEntryPointsDifferentStage) {
    267   const std::string text = R"(
    268                 OpCapability Shader
    269           %1 = OpExtInstImport "GLSL.std.450"
    270                OpMemoryModel Logical GLSL450
    271                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
    272                OpEntryPoint Fragment %main2 "main2" %3 %gl_VertexIndex %5
    273                OpSource GLSL 400
    274                OpSourceExtension "GL_ARB_separate_shader_objects"
    275                OpSourceExtension "GL_ARB_shading_language_420pack"
    276                OpName %main "main"
    277                OpName %main2 "main2"
    278                OpDecorate %3 Location 0
    279                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    280                OpMemberDecorate %_struct_6 0 BuiltIn Position
    281                OpDecorate %_struct_6 Block
    282        %void = OpTypeVoid
    283           %8 = OpTypeFunction %void
    284       %float = OpTypeFloat 32
    285          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
    286 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
    287          %12 = OpTypeSampler
    288 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
    289          %14 = OpTypeSampledImage %10
    290     %v4float = OpTypeVector %float 4
    291     %v2float = OpTypeVector %float 2
    292 %_ptr_Output_v4float = OpTypePointer Output %v4float
    293           %3 = OpVariable %_ptr_Output_v4float Output
    294         %int = OpTypeInt 32 1
    295 %_ptr_Input_int = OpTypePointer Input %int
    296 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    297   %_struct_6 = OpTypeStruct %v4float
    298 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
    299           %5 = OpVariable %_ptr_Output__struct_6 Output
    300       %int_0 = OpConstant %int 0
    301     %float_0 = OpConstant %float 0
    302          %23 = OpConstantComposite %v2float %float_0 %float_0
    303          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
    304          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
    305        %main = OpFunction %void None %8
    306          %26 = OpLabel
    307          %27 = OpLoad %12 %25
    308          %28 = OpLoad %10 %24
    309          %29 = OpSampledImage %14 %28 %27
    310          %30 = OpImageSampleImplicitLod %v4float %29 %23
    311          %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    312                OpStore %31 %30
    313                OpReturn
    314                OpFunctionEnd
    315       %main2 = OpFunction %void None %8
    316          %46 = OpLabel
    317          %47 = OpLoad %12 %25
    318          %48 = OpLoad %10 %24
    319          %49 = OpSampledImage %14 %48 %47
    320          %50 = OpImageSampleImplicitLod %v4float %49 %23
    321          %51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    322                OpStore %51 %50
    323                OpReturn
    324                OpFunctionEnd)";
    325 
    326   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    327       text, /* skip_nop = */ true, /* do_validation = */ false);
    328   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
    329 }
    330 
    331 TEST_F(ReplaceInvalidOpcodeTest, DontReplaceLinkage) {
    332   const std::string text = R"(
    333                 OpCapability Shader
    334                 OpCapability Linkage
    335           %1 = OpExtInstImport "GLSL.std.450"
    336                OpMemoryModel Logical GLSL450
    337                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
    338                OpSource GLSL 400
    339                OpSourceExtension "GL_ARB_separate_shader_objects"
    340                OpSourceExtension "GL_ARB_shading_language_420pack"
    341                OpName %main "main"
    342                OpDecorate %3 Location 0
    343                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    344                OpMemberDecorate %_struct_6 0 BuiltIn Position
    345                OpDecorate %_struct_6 Block
    346        %void = OpTypeVoid
    347           %8 = OpTypeFunction %void
    348       %float = OpTypeFloat 32
    349          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
    350 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
    351          %12 = OpTypeSampler
    352 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
    353          %14 = OpTypeSampledImage %10
    354     %v4float = OpTypeVector %float 4
    355     %v2float = OpTypeVector %float 2
    356 %_ptr_Output_v4float = OpTypePointer Output %v4float
    357           %3 = OpVariable %_ptr_Output_v4float Output
    358         %int = OpTypeInt 32 1
    359 %_ptr_Input_int = OpTypePointer Input %int
    360 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    361   %_struct_6 = OpTypeStruct %v4float
    362 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
    363           %5 = OpVariable %_ptr_Output__struct_6 Output
    364       %int_0 = OpConstant %int 0
    365     %float_0 = OpConstant %float 0
    366          %23 = OpConstantComposite %v2float %float_0 %float_0
    367          %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
    368          %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
    369        %main = OpFunction %void None %8
    370          %26 = OpLabel
    371          %27 = OpLoad %12 %25
    372          %28 = OpLoad %10 %24
    373          %29 = OpSampledImage %14 %28 %27
    374          %30 = OpImageSampleImplicitLod %v4float %29 %23
    375          %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    376                OpStore %31 %30
    377                OpReturn
    378                OpFunctionEnd)";
    379 
    380   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    381       text, /* skip_nop = */ true, /* do_validation = */ false);
    382   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
    383 }
    384 
    385 TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplace) {
    386   const std::string text = R"(
    387             OpCapability Shader
    388        %1 = OpExtInstImport "GLSL.std.450"
    389             OpMemoryModel Logical GLSL450
    390             OpEntryPoint GLCompute %main "main"
    391             OpExecutionMode %main LocalSize 1 1 1
    392             OpSource GLSL 450
    393             OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
    394             OpSourceExtension "GL_GOOGLE_include_directive"
    395             OpName %main "main"
    396     %void = OpTypeVoid
    397        %3 = OpTypeFunction %void
    398     %uint = OpTypeInt 32 0
    399   %uint_2 = OpConstant %uint 2
    400 %uint_264 = OpConstant %uint 264
    401     %main = OpFunction %void None %3
    402        %5 = OpLabel
    403             OpControlBarrier %uint_2 %uint_2 %uint_264
    404             OpReturn
    405             OpFunctionEnd)";
    406 
    407   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    408       text, /* skip_nop = */ true, /* do_validation = */ false);
    409   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
    410 }
    411 
    412 TEST_F(ReplaceInvalidOpcodeTest, BarrierReplace) {
    413   const std::string text = R"(
    414 ; CHECK-NOT: OpControlBarrier
    415             OpCapability Shader
    416        %1 = OpExtInstImport "GLSL.std.450"
    417             OpMemoryModel Logical GLSL450
    418             OpEntryPoint Vertex %main "main"
    419             OpExecutionMode %main LocalSize 1 1 1
    420             OpSource GLSL 450
    421             OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
    422             OpSourceExtension "GL_GOOGLE_include_directive"
    423             OpName %main "main"
    424     %void = OpTypeVoid
    425        %3 = OpTypeFunction %void
    426     %uint = OpTypeInt 32 0
    427   %uint_2 = OpConstant %uint 2
    428 %uint_264 = OpConstant %uint 264
    429     %main = OpFunction %void None %3
    430        %5 = OpLabel
    431             OpControlBarrier %uint_2 %uint_2 %uint_264
    432             OpReturn
    433             OpFunctionEnd)";
    434 
    435   SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
    436 }
    437 
    438 TEST_F(ReplaceInvalidOpcodeTest, MessageTest) {
    439   const std::string text = R"(
    440                OpCapability Shader
    441           %1 = OpExtInstImport "GLSL.std.450"
    442                OpMemoryModel Logical GLSL450
    443                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
    444                OpSource GLSL 400
    445           %6 = OpString "test.hlsl"
    446                OpSourceExtension "GL_ARB_separate_shader_objects"
    447                OpSourceExtension "GL_ARB_shading_language_420pack"
    448                OpName %main "main"
    449                OpDecorate %3 Location 0
    450                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    451                OpMemberDecorate %_struct_7 0 BuiltIn Position
    452                OpDecorate %_struct_7 Block
    453        %void = OpTypeVoid
    454           %9 = OpTypeFunction %void
    455       %float = OpTypeFloat 32
    456          %11 = OpTypeImage %float 2D 0 0 0 1 Unknown
    457 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
    458          %13 = OpTypeSampler
    459 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
    460          %15 = OpTypeSampledImage %11
    461     %v4float = OpTypeVector %float 4
    462     %v2float = OpTypeVector %float 2
    463 %_ptr_Output_v4float = OpTypePointer Output %v4float
    464           %3 = OpVariable %_ptr_Output_v4float Output
    465         %int = OpTypeInt 32 1
    466 %_ptr_Input_int = OpTypePointer Input %int
    467 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    468   %_struct_7 = OpTypeStruct %v4float
    469 %_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
    470           %5 = OpVariable %_ptr_Output__struct_7 Output
    471       %int_0 = OpConstant %int 0
    472     %float_0 = OpConstant %float 0
    473          %24 = OpConstantComposite %v2float %float_0 %float_0
    474          %25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
    475          %26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
    476        %main = OpFunction %void None %9
    477          %27 = OpLabel
    478                OpLine %6 2 4
    479          %28 = OpLoad %13 %26
    480          %29 = OpLoad %11 %25
    481          %30 = OpSampledImage %15 %29 %28
    482          %31 = OpImageSampleImplicitLod %v4float %30 %24
    483          %32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    484                OpStore %32 %31
    485                OpReturn
    486                OpFunctionEnd)";
    487 
    488   std::vector<Message> messages = {
    489       {SPV_MSG_WARNING, "test.hlsl", 2, 4,
    490        "Removing ImageSampleImplicitLod instruction because of incompatible "
    491        "execution model."}};
    492   SetMessageConsumer(GetTestMessageConsumer(messages));
    493   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    494       text, /* skip_nop = */ true, /* do_validation = */ false);
    495   EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
    496 }
    497 
    498 TEST_F(ReplaceInvalidOpcodeTest, MultipleMessageTest) {
    499   const std::string text = R"(
    500                OpCapability Shader
    501           %1 = OpExtInstImport "GLSL.std.450"
    502                OpMemoryModel Logical GLSL450
    503                OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
    504                OpSource GLSL 400
    505           %6 = OpString "test.hlsl"
    506                OpSourceExtension "GL_ARB_separate_shader_objects"
    507                OpSourceExtension "GL_ARB_shading_language_420pack"
    508                OpName %main "main"
    509                OpDecorate %3 Location 0
    510                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    511                OpMemberDecorate %_struct_7 0 BuiltIn Position
    512                OpDecorate %_struct_7 Block
    513        %void = OpTypeVoid
    514           %9 = OpTypeFunction %void
    515       %float = OpTypeFloat 32
    516          %11 = OpTypeImage %float 2D 0 0 0 1 Unknown
    517 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
    518          %13 = OpTypeSampler
    519 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
    520          %15 = OpTypeSampledImage %11
    521     %v4float = OpTypeVector %float 4
    522     %v2float = OpTypeVector %float 2
    523 %_ptr_Output_v4float = OpTypePointer Output %v4float
    524           %3 = OpVariable %_ptr_Output_v4float Output
    525         %int = OpTypeInt 32 1
    526 %_ptr_Input_int = OpTypePointer Input %int
    527 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    528   %_struct_7 = OpTypeStruct %v4float
    529 %_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
    530           %5 = OpVariable %_ptr_Output__struct_7 Output
    531       %int_0 = OpConstant %int 0
    532     %float_0 = OpConstant %float 0
    533          %24 = OpConstantComposite %v2float %float_0 %float_0
    534          %25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
    535          %26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
    536        %main = OpFunction %void None %9
    537          %27 = OpLabel
    538                OpLine %6 2 4
    539          %28 = OpLoad %13 %26
    540          %29 = OpLoad %11 %25
    541          %30 = OpSampledImage %15 %29 %28
    542          %31 = OpImageSampleImplicitLod %v4float %30 %24
    543                OpLine %6 12 4
    544          %41 = OpImageSampleProjImplicitLod %v4float %30 %24
    545          %32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
    546                OpStore %32 %31
    547                OpReturn
    548                OpFunctionEnd)";
    549 
    550   std::vector<Message> messages = {
    551       {SPV_MSG_WARNING, "test.hlsl", 2, 4,
    552        "Removing ImageSampleImplicitLod instruction because of incompatible "
    553        "execution model."},
    554       {SPV_MSG_WARNING, "test.hlsl", 12, 4,
    555        "Removing ImageSampleProjImplicitLod instruction because of "
    556        "incompatible "
    557        "execution model."}};
    558   SetMessageConsumer(GetTestMessageConsumer(messages));
    559   auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
    560       text, /* skip_nop = */ true, /* do_validation = */ false);
    561   EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
    562 }
    563 
    564 }  // namespace
    565 }  // namespace opt
    566 }  // namespace spvtools
    567