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 <algorithm>
     16 #include <cstdarg>
     17 #include <iostream>
     18 #include <sstream>
     19 #include <string>
     20 #include <unordered_set>
     21 
     22 #include "gmock/gmock.h"
     23 #include "test/opt/assembly_builder.h"
     24 #include "test/opt/pass_fixture.h"
     25 #include "test/opt/pass_utils.h"
     26 
     27 namespace spvtools {
     28 namespace opt {
     29 namespace {
     30 
     31 using Workaround1209Test = PassTest<::testing::Test>;
     32 
     33 TEST_F(Workaround1209Test, RemoveOpUnreachableInLoop) {
     34   const std::string text = R"(
     35                OpCapability Shader
     36           %1 = OpExtInstImport "GLSL.std.450"
     37                OpMemoryModel Logical GLSL450
     38                OpEntryPoint Vertex %main "main" %texcoord %gl_VertexIndex %_
     39                OpSource GLSL 400
     40                OpSourceExtension "GL_ARB_separate_shader_objects"
     41                OpSourceExtension "GL_ARB_shading_language_420pack"
     42                OpName %main "main"
     43                OpName %texcoord "texcoord"
     44                OpName %buf "buf"
     45                OpMemberName %buf 0 "MVP"
     46                OpMemberName %buf 1 "position"
     47                OpMemberName %buf 2 "attr"
     48                OpName %ubuf "ubuf"
     49                OpName %gl_VertexIndex "gl_VertexIndex"
     50                OpName %gl_PerVertex "gl_PerVertex"
     51                OpMemberName %gl_PerVertex 0 "gl_Position"
     52                OpName %_ ""
     53                OpDecorate %texcoord Location 0
     54                OpDecorate %_arr_v4float_uint_72 ArrayStride 16
     55                OpDecorate %_arr_v4float_uint_72_0 ArrayStride 16
     56                OpMemberDecorate %buf 0 ColMajor
     57                OpMemberDecorate %buf 0 Offset 0
     58                OpMemberDecorate %buf 0 MatrixStride 16
     59                OpMemberDecorate %buf 1 Offset 64
     60                OpMemberDecorate %buf 2 Offset 1216
     61                OpDecorate %buf Block
     62                OpDecorate %ubuf DescriptorSet 0
     63                OpDecorate %ubuf Binding 0
     64                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
     65                OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
     66                OpDecorate %gl_PerVertex Block
     67        %void = OpTypeVoid
     68          %12 = OpTypeFunction %void
     69       %float = OpTypeFloat 32
     70     %v4float = OpTypeVector %float 4
     71 %_ptr_Output_v4float = OpTypePointer Output %v4float
     72    %texcoord = OpVariable %_ptr_Output_v4float Output
     73 %mat4v4float = OpTypeMatrix %v4float 4
     74        %uint = OpTypeInt 32 0
     75     %uint_72 = OpConstant %uint 72
     76 %_arr_v4float_uint_72 = OpTypeArray %v4float %uint_72
     77 %_arr_v4float_uint_72_0 = OpTypeArray %v4float %uint_72
     78         %buf = OpTypeStruct %mat4v4float %_arr_v4float_uint_72 %_arr_v4float_uint_72_0
     79 %_ptr_Uniform_buf = OpTypePointer Uniform %buf
     80        %ubuf = OpVariable %_ptr_Uniform_buf Uniform
     81         %int = OpTypeInt 32 1
     82       %int_2 = OpConstant %int 2
     83 %_ptr_Input_int = OpTypePointer Input %int
     84 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
     85 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
     86 %gl_PerVertex = OpTypeStruct %v4float
     87 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
     88           %_ = OpVariable %_ptr_Output_gl_PerVertex Output
     89       %int_0 = OpConstant %int 0
     90       %int_1 = OpConstant %int 1
     91     %float_1 = OpConstant %float 1
     92          %28 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
     93        %main = OpFunction %void None %12
     94          %29 = OpLabel
     95                OpBranch %30
     96          %30 = OpLabel
     97 ; CHECK: OpLoopMerge [[merge:%[a-zA-Z_\d]+]]
     98                OpLoopMerge %31 %32 None
     99                OpBranch %33
    100          %33 = OpLabel
    101 ; CHECK: OpSelectionMerge [[sel_merge:%[a-zA-Z_\d]+]]
    102                OpSelectionMerge %34 None
    103                OpSwitch %int_1 %35
    104          %35 = OpLabel
    105          %36 = OpLoad %int %gl_VertexIndex
    106          %37 = OpAccessChain %_ptr_Uniform_v4float %ubuf %int_2 %36
    107          %38 = OpLoad %v4float %37
    108                OpStore %texcoord %38
    109          %39 = OpAccessChain %_ptr_Output_v4float %_ %int_0
    110                OpStore %39 %28
    111                OpBranch %31
    112 ; CHECK: [[sel_merge]] = OpLabel
    113          %34 = OpLabel
    114 ; CHECK-NEXT: OpBranch [[merge]]
    115                OpUnreachable
    116          %32 = OpLabel
    117                OpBranch %30
    118          %31 = OpLabel
    119                OpReturn
    120                OpFunctionEnd)";
    121 
    122   SinglePassRunAndMatch<Workaround1209>(text, false);
    123 }
    124 
    125 TEST_F(Workaround1209Test, RemoveOpUnreachableInNestedLoop) {
    126   const std::string text = R"(
    127                OpCapability Shader
    128           %1 = OpExtInstImport "GLSL.std.450"
    129                OpMemoryModel Logical GLSL450
    130                OpEntryPoint Vertex %2 "main" %3 %4 %5
    131                OpSource GLSL 400
    132                OpSourceExtension "GL_ARB_separate_shader_objects"
    133                OpSourceExtension "GL_ARB_shading_language_420pack"
    134                OpName %2 "main"
    135                OpName %3 "texcoord"
    136                OpName %6 "buf"
    137                OpMemberName %6 0 "MVP"
    138                OpMemberName %6 1 "position"
    139                OpMemberName %6 2 "attr"
    140                OpName %7 "ubuf"
    141                OpName %4 "gl_VertexIndex"
    142                OpName %8 "gl_PerVertex"
    143                OpMemberName %8 0 "gl_Position"
    144                OpName %5 ""
    145                OpDecorate %3 Location 0
    146                OpDecorate %9 ArrayStride 16
    147                OpDecorate %10 ArrayStride 16
    148                OpMemberDecorate %6 0 ColMajor
    149                OpMemberDecorate %6 0 Offset 0
    150                OpMemberDecorate %6 0 MatrixStride 16
    151                OpMemberDecorate %6 1 Offset 64
    152                OpMemberDecorate %6 2 Offset 1216
    153                OpDecorate %6 Block
    154                OpDecorate %7 DescriptorSet 0
    155                OpDecorate %7 Binding 0
    156                OpDecorate %4 BuiltIn VertexIndex
    157                OpMemberDecorate %8 0 BuiltIn Position
    158                OpDecorate %8 Block
    159          %11 = OpTypeVoid
    160          %12 = OpTypeFunction %11
    161          %13 = OpTypeFloat 32
    162          %14 = OpTypeVector %13 4
    163          %15 = OpTypePointer Output %14
    164           %3 = OpVariable %15 Output
    165          %16 = OpTypeMatrix %14 4
    166          %17 = OpTypeInt 32 0
    167          %18 = OpConstant %17 72
    168           %9 = OpTypeArray %14 %18
    169          %10 = OpTypeArray %14 %18
    170           %6 = OpTypeStruct %16 %9 %10
    171          %19 = OpTypePointer Uniform %6
    172           %7 = OpVariable %19 Uniform
    173          %20 = OpTypeInt 32 1
    174          %21 = OpConstant %20 2
    175          %22 = OpTypePointer Input %20
    176           %4 = OpVariable %22 Input
    177          %23 = OpTypePointer Uniform %14
    178           %8 = OpTypeStruct %14
    179          %24 = OpTypePointer Output %8
    180           %5 = OpVariable %24 Output
    181          %25 = OpConstant %20 0
    182          %26 = OpConstant %20 1
    183          %27 = OpConstant %13 1
    184          %28 = OpConstantComposite %14 %27 %27 %27 %27
    185           %2 = OpFunction %11 None %12
    186          %29 = OpLabel
    187                OpBranch %31
    188          %31 = OpLabel
    189 ; CHECK: OpLoopMerge
    190                OpLoopMerge %32 %33 None
    191                OpBranch %30
    192          %30 = OpLabel
    193 ; CHECK: OpLoopMerge [[merge:%[a-zA-Z_\d]+]]
    194                OpLoopMerge %34 %35 None
    195                OpBranch %36
    196          %36 = OpLabel
    197 ; CHECK: OpSelectionMerge [[sel_merge:%[a-zA-Z_\d]+]]
    198                OpSelectionMerge %37 None
    199                OpSwitch %26 %38
    200          %38 = OpLabel
    201          %39 = OpLoad %20 %4
    202          %40 = OpAccessChain %23 %7 %21 %39
    203          %41 = OpLoad %14 %40
    204                OpStore %3 %41
    205          %42 = OpAccessChain %15 %5 %25
    206                OpStore %42 %28
    207                OpBranch %34
    208 ; CHECK: [[sel_merge]] = OpLabel
    209          %37 = OpLabel
    210 ; CHECK-NEXT: OpBranch [[merge]]
    211                OpUnreachable
    212          %35 = OpLabel
    213                OpBranch %30
    214          %34 = OpLabel
    215                OpBranch %32
    216          %33 = OpLabel
    217                OpBranch %31
    218          %32 = OpLabel
    219                OpReturn
    220                OpFunctionEnd)";
    221 
    222   SinglePassRunAndMatch<Workaround1209>(text, false);
    223 }
    224 
    225 TEST_F(Workaround1209Test, RemoveOpUnreachableInAdjacentLoops) {
    226   const std::string text = R"(
    227                OpCapability Shader
    228           %1 = OpExtInstImport "GLSL.std.450"
    229                OpMemoryModel Logical GLSL450
    230                OpEntryPoint Vertex %2 "main" %3 %4 %5
    231                OpSource GLSL 400
    232                OpSourceExtension "GL_ARB_separate_shader_objects"
    233                OpSourceExtension "GL_ARB_shading_language_420pack"
    234                OpName %2 "main"
    235                OpName %3 "texcoord"
    236                OpName %6 "buf"
    237                OpMemberName %6 0 "MVP"
    238                OpMemberName %6 1 "position"
    239                OpMemberName %6 2 "attr"
    240                OpName %7 "ubuf"
    241                OpName %4 "gl_VertexIndex"
    242                OpName %8 "gl_PerVertex"
    243                OpMemberName %8 0 "gl_Position"
    244                OpName %5 ""
    245                OpDecorate %3 Location 0
    246                OpDecorate %9 ArrayStride 16
    247                OpDecorate %10 ArrayStride 16
    248                OpMemberDecorate %6 0 ColMajor
    249                OpMemberDecorate %6 0 Offset 0
    250                OpMemberDecorate %6 0 MatrixStride 16
    251                OpMemberDecorate %6 1 Offset 64
    252                OpMemberDecorate %6 2 Offset 1216
    253                OpDecorate %6 Block
    254                OpDecorate %7 DescriptorSet 0
    255                OpDecorate %7 Binding 0
    256                OpDecorate %4 BuiltIn VertexIndex
    257                OpMemberDecorate %8 0 BuiltIn Position
    258                OpDecorate %8 Block
    259          %11 = OpTypeVoid
    260          %12 = OpTypeFunction %11
    261          %13 = OpTypeFloat 32
    262          %14 = OpTypeVector %13 4
    263          %15 = OpTypePointer Output %14
    264           %3 = OpVariable %15 Output
    265          %16 = OpTypeMatrix %14 4
    266          %17 = OpTypeInt 32 0
    267          %18 = OpConstant %17 72
    268           %9 = OpTypeArray %14 %18
    269          %10 = OpTypeArray %14 %18
    270           %6 = OpTypeStruct %16 %9 %10
    271          %19 = OpTypePointer Uniform %6
    272           %7 = OpVariable %19 Uniform
    273          %20 = OpTypeInt 32 1
    274          %21 = OpConstant %20 2
    275          %22 = OpTypePointer Input %20
    276           %4 = OpVariable %22 Input
    277          %23 = OpTypePointer Uniform %14
    278           %8 = OpTypeStruct %14
    279          %24 = OpTypePointer Output %8
    280           %5 = OpVariable %24 Output
    281          %25 = OpConstant %20 0
    282          %26 = OpConstant %20 1
    283          %27 = OpConstant %13 1
    284          %28 = OpConstantComposite %14 %27 %27 %27 %27
    285           %2 = OpFunction %11 None %12
    286          %29 = OpLabel
    287                OpBranch %30
    288          %30 = OpLabel
    289 ; CHECK: OpLoopMerge [[merge1:%[a-zA-Z_\d]+]]
    290                OpLoopMerge %31 %32 None
    291                OpBranch %33
    292          %33 = OpLabel
    293 ; CHECK: OpSelectionMerge [[sel_merge1:%[a-zA-Z_\d]+]]
    294                OpSelectionMerge %34 None
    295                OpSwitch %26 %35
    296          %35 = OpLabel
    297          %36 = OpLoad %20 %4
    298          %37 = OpAccessChain %23 %7 %21 %36
    299          %38 = OpLoad %14 %37
    300                OpStore %3 %38
    301          %39 = OpAccessChain %15 %5 %25
    302                OpStore %39 %28
    303                OpBranch %31
    304 ; CHECK: [[sel_merge1]] = OpLabel
    305          %34 = OpLabel
    306 ; CHECK-NEXT: OpBranch [[merge1]]
    307                OpUnreachable
    308          %32 = OpLabel
    309                OpBranch %30
    310          %31 = OpLabel
    311 ; CHECK: OpLoopMerge [[merge2:%[a-zA-Z_\d]+]]
    312                OpLoopMerge %40 %41 None
    313                OpBranch %42
    314          %42 = OpLabel
    315 ; CHECK: OpSelectionMerge [[sel_merge2:%[a-zA-Z_\d]+]]
    316                OpSelectionMerge %43 None
    317                OpSwitch %26 %44
    318          %44 = OpLabel
    319          %45 = OpLoad %20 %4
    320          %46 = OpAccessChain %23 %7 %21 %45
    321          %47 = OpLoad %14 %46
    322                OpStore %3 %47
    323          %48 = OpAccessChain %15 %5 %25
    324                OpStore %48 %28
    325                OpBranch %40
    326 ; CHECK: [[sel_merge2]] = OpLabel
    327          %43 = OpLabel
    328 ; CHECK-NEXT: OpBranch [[merge2]]
    329                OpUnreachable
    330          %41 = OpLabel
    331                OpBranch %31
    332          %40 = OpLabel
    333                OpReturn
    334                OpFunctionEnd)";
    335 
    336   SinglePassRunAndMatch<Workaround1209>(text, false);
    337 }
    338 
    339 TEST_F(Workaround1209Test, LeaveUnreachableNotInLoop) {
    340   const std::string text = R"(
    341                OpCapability Shader
    342           %1 = OpExtInstImport "GLSL.std.450"
    343                OpMemoryModel Logical GLSL450
    344                OpEntryPoint Vertex %main "main" %texcoord %gl_VertexIndex %_
    345                OpSource GLSL 400
    346                OpSourceExtension "GL_ARB_separate_shader_objects"
    347                OpSourceExtension "GL_ARB_shading_language_420pack"
    348                OpName %main "main"
    349                OpName %texcoord "texcoord"
    350                OpName %buf "buf"
    351                OpMemberName %buf 0 "MVP"
    352                OpMemberName %buf 1 "position"
    353                OpMemberName %buf 2 "attr"
    354                OpName %ubuf "ubuf"
    355                OpName %gl_VertexIndex "gl_VertexIndex"
    356                OpName %gl_PerVertex "gl_PerVertex"
    357                OpMemberName %gl_PerVertex 0 "gl_Position"
    358                OpName %_ ""
    359                OpDecorate %texcoord Location 0
    360                OpDecorate %_arr_v4float_uint_72 ArrayStride 16
    361                OpDecorate %_arr_v4float_uint_72_0 ArrayStride 16
    362                OpMemberDecorate %buf 0 ColMajor
    363                OpMemberDecorate %buf 0 Offset 0
    364                OpMemberDecorate %buf 0 MatrixStride 16
    365                OpMemberDecorate %buf 1 Offset 64
    366                OpMemberDecorate %buf 2 Offset 1216
    367                OpDecorate %buf Block
    368                OpDecorate %ubuf DescriptorSet 0
    369                OpDecorate %ubuf Binding 0
    370                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
    371                OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
    372                OpDecorate %gl_PerVertex Block
    373        %void = OpTypeVoid
    374          %12 = OpTypeFunction %void
    375       %float = OpTypeFloat 32
    376     %v4float = OpTypeVector %float 4
    377 %_ptr_Output_v4float = OpTypePointer Output %v4float
    378    %texcoord = OpVariable %_ptr_Output_v4float Output
    379 %mat4v4float = OpTypeMatrix %v4float 4
    380        %uint = OpTypeInt 32 0
    381     %uint_72 = OpConstant %uint 72
    382 %_arr_v4float_uint_72 = OpTypeArray %v4float %uint_72
    383 %_arr_v4float_uint_72_0 = OpTypeArray %v4float %uint_72
    384         %buf = OpTypeStruct %mat4v4float %_arr_v4float_uint_72 %_arr_v4float_uint_72_0
    385 %_ptr_Uniform_buf = OpTypePointer Uniform %buf
    386        %ubuf = OpVariable %_ptr_Uniform_buf Uniform
    387         %int = OpTypeInt 32 1
    388       %int_2 = OpConstant %int 2
    389 %_ptr_Input_int = OpTypePointer Input %int
    390 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
    391 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
    392 %gl_PerVertex = OpTypeStruct %v4float
    393 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
    394           %_ = OpVariable %_ptr_Output_gl_PerVertex Output
    395       %int_0 = OpConstant %int 0
    396       %int_1 = OpConstant %int 1
    397     %float_1 = OpConstant %float 1
    398          %28 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
    399        %main = OpFunction %void None %12
    400          %29 = OpLabel
    401                OpBranch %30
    402          %30 = OpLabel
    403                OpSelectionMerge %34 None
    404                OpSwitch %int_1 %35
    405          %35 = OpLabel
    406          %36 = OpLoad %int %gl_VertexIndex
    407          %37 = OpAccessChain %_ptr_Uniform_v4float %ubuf %int_2 %36
    408          %38 = OpLoad %v4float %37
    409                OpStore %texcoord %38
    410          %39 = OpAccessChain %_ptr_Output_v4float %_ %int_0
    411                OpStore %39 %28
    412                OpReturn
    413          %34 = OpLabel
    414 ; CHECK: OpUnreachable
    415                OpUnreachable
    416                OpFunctionEnd)";
    417 
    418   SinglePassRunAndMatch<Workaround1209>(text, false);
    419 }
    420 
    421 }  // namespace
    422 }  // namespace opt
    423 }  // namespace spvtools
    424