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 <memory>
     17 #include <string>
     18 #include <vector>
     19 
     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 ProcessLinesTest = PassTest<::testing::Test>;
     28 
     29 TEST_F(ProcessLinesTest, SimplePropagation) {
     30   // Texture2D g_tColor[128];
     31   //
     32   // layout(push_constant) cbuffer PerViewConstantBuffer_t
     33   // {
     34   //   uint g_nDataIdx;
     35   //   uint g_nDataIdx2;
     36   //   bool g_B;
     37   // };
     38   //
     39   // SamplerState g_sAniso;
     40   //
     41   // struct PS_INPUT
     42   // {
     43   //   float2 vTextureCoords : TEXCOORD2;
     44   // };
     45   //
     46   // struct PS_OUTPUT
     47   // {
     48   //   float4 vColor : SV_Target0;
     49   // };
     50   //
     51   // PS_OUTPUT MainPs(PS_INPUT i)
     52   // {
     53   //   PS_OUTPUT ps_output;
     54   //
     55   //   uint u;
     56   //   if (g_B)
     57   //     u = g_nDataIdx;
     58   //   else
     59   //     u = g_nDataIdx2;
     60   //   ps_output.vColor = g_tColor[u].Sample(g_sAniso, i.vTextureCoords.xy);
     61   //   return ps_output;
     62   // }
     63 
     64   const std::string predefs =
     65       R"(OpCapability Shader
     66 %1 = OpExtInstImport "GLSL.std.450"
     67 OpMemoryModel Logical GLSL450
     68 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
     69 OpExecutionMode %MainPs OriginUpperLeft
     70 %5 = OpString "foo.frag"
     71 OpSource HLSL 500
     72 OpName %MainPs "MainPs"
     73 OpName %PS_INPUT "PS_INPUT"
     74 OpMemberName %PS_INPUT 0 "vTextureCoords"
     75 OpName %PS_OUTPUT "PS_OUTPUT"
     76 OpMemberName %PS_OUTPUT 0 "vColor"
     77 OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
     78 OpName %i "i"
     79 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
     80 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
     81 OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
     82 OpMemberName %PerViewConstantBuffer_t 2 "g_B"
     83 OpName %_ ""
     84 OpName %u "u"
     85 OpName %ps_output "ps_output"
     86 OpName %g_tColor "g_tColor"
     87 OpName %g_sAniso "g_sAniso"
     88 OpName %i_0 "i"
     89 OpName %i_vTextureCoords "i.vTextureCoords"
     90 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
     91 OpName %param "param"
     92 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
     93 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
     94 OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
     95 OpDecorate %PerViewConstantBuffer_t Block
     96 OpDecorate %g_tColor DescriptorSet 0
     97 OpDecorate %g_sAniso DescriptorSet 0
     98 OpDecorate %i_vTextureCoords Location 0
     99 OpDecorate %_entryPointOutput_vColor Location 0
    100 )";
    101 
    102   const std::string before =
    103       R"(%void = OpTypeVoid
    104 %19 = OpTypeFunction %void
    105 %float = OpTypeFloat 32
    106 %v2float = OpTypeVector %float 2
    107 %PS_INPUT = OpTypeStruct %v2float
    108 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
    109 %v4float = OpTypeVector %float 4
    110 %PS_OUTPUT = OpTypeStruct %v4float
    111 %24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
    112 %uint = OpTypeInt 32 0
    113 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
    114 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    115 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    116 %int = OpTypeInt 32 1
    117 %int_2 = OpConstant %int 2
    118 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    119 %bool = OpTypeBool
    120 %uint_0 = OpConstant %uint 0
    121 %_ptr_Function_uint = OpTypePointer Function %uint
    122 %int_0 = OpConstant %int 0
    123 %int_1 = OpConstant %int 1
    124 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
    125 %36 = OpTypeImage %float 2D 0 0 0 1 Unknown
    126 %uint_128 = OpConstant %uint 128
    127 %_arr_36_uint_128 = OpTypeArray %36 %uint_128
    128 %_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
    129 %g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
    130 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
    131 %41 = OpTypeSampler
    132 %_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
    133 %g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
    134 %43 = OpTypeSampledImage %36
    135 %_ptr_Function_v2float = OpTypePointer Function %v2float
    136 %_ptr_Function_v4float = OpTypePointer Function %v4float
    137 %_ptr_Input_v2float = OpTypePointer Input %v2float
    138 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    139 %_ptr_Output_v4float = OpTypePointer Output %v4float
    140 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    141 %MainPs = OpFunction %void None %19
    142 %48 = OpLabel
    143 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
    144 %param = OpVariable %_ptr_Function_PS_INPUT Function
    145 OpLine %5 23 0
    146 %49 = OpLoad %v2float %i_vTextureCoords
    147 %50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
    148 OpStore %50 %49
    149 %51 = OpLoad %PS_INPUT %i_0
    150 OpStore %param %51
    151 %52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
    152 %53 = OpCompositeExtract %v4float %52 0
    153 OpStore %_entryPointOutput_vColor %53
    154 OpReturn
    155 OpFunctionEnd
    156 %_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
    157 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
    158 %54 = OpLabel
    159 %u = OpVariable %_ptr_Function_uint Function
    160 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
    161 OpLine %5 27 0
    162 %55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
    163 %56 = OpLoad %uint %55
    164 %57 = OpINotEqual %bool %56 %uint_0
    165 OpSelectionMerge %58 None
    166 OpBranchConditional %57 %59 %60
    167 %59 = OpLabel
    168 OpLine %5 28 0
    169 %61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    170 %62 = OpLoad %uint %61
    171 OpStore %u %62
    172 OpBranch %58
    173 %60 = OpLabel
    174 OpLine %5 30 0
    175 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    176 %64 = OpLoad %uint %63
    177 OpStore %u %64
    178 OpBranch %58
    179 %58 = OpLabel
    180 OpLine %5 31 0
    181 %65 = OpLoad %uint %u
    182 %66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
    183 %67 = OpLoad %36 %66
    184 %68 = OpLoad %41 %g_sAniso
    185 %69 = OpSampledImage %43 %67 %68
    186 %70 = OpAccessChain %_ptr_Function_v2float %i %int_0
    187 %71 = OpLoad %v2float %70
    188 %72 = OpImageSampleImplicitLod %v4float %69 %71
    189 %73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
    190 OpStore %73 %72
    191 OpLine %5 32 0
    192 %74 = OpLoad %PS_OUTPUT %ps_output
    193 OpReturnValue %74
    194 OpFunctionEnd
    195 )";
    196 
    197   const std::string after =
    198       R"(OpNoLine
    199 %void = OpTypeVoid
    200 OpNoLine
    201 %19 = OpTypeFunction %void
    202 OpNoLine
    203 %float = OpTypeFloat 32
    204 OpNoLine
    205 %v2float = OpTypeVector %float 2
    206 OpNoLine
    207 %PS_INPUT = OpTypeStruct %v2float
    208 OpNoLine
    209 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
    210 OpNoLine
    211 %v4float = OpTypeVector %float 4
    212 OpNoLine
    213 %PS_OUTPUT = OpTypeStruct %v4float
    214 OpNoLine
    215 %24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
    216 OpNoLine
    217 %uint = OpTypeInt 32 0
    218 OpNoLine
    219 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
    220 OpNoLine
    221 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    222 OpNoLine
    223 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    224 OpNoLine
    225 %int = OpTypeInt 32 1
    226 OpNoLine
    227 %int_2 = OpConstant %int 2
    228 OpNoLine
    229 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    230 OpNoLine
    231 %bool = OpTypeBool
    232 OpNoLine
    233 %uint_0 = OpConstant %uint 0
    234 OpNoLine
    235 %_ptr_Function_uint = OpTypePointer Function %uint
    236 OpNoLine
    237 %int_0 = OpConstant %int 0
    238 OpNoLine
    239 %int_1 = OpConstant %int 1
    240 OpNoLine
    241 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
    242 OpNoLine
    243 %36 = OpTypeImage %float 2D 0 0 0 1 Unknown
    244 OpNoLine
    245 %uint_128 = OpConstant %uint 128
    246 OpNoLine
    247 %_arr_36_uint_128 = OpTypeArray %36 %uint_128
    248 OpNoLine
    249 %_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
    250 OpNoLine
    251 %g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
    252 OpNoLine
    253 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
    254 OpNoLine
    255 %41 = OpTypeSampler
    256 OpNoLine
    257 %_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
    258 OpNoLine
    259 %g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
    260 OpNoLine
    261 %43 = OpTypeSampledImage %36
    262 OpNoLine
    263 %_ptr_Function_v2float = OpTypePointer Function %v2float
    264 OpNoLine
    265 %_ptr_Function_v4float = OpTypePointer Function %v4float
    266 OpNoLine
    267 %_ptr_Input_v2float = OpTypePointer Input %v2float
    268 OpNoLine
    269 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    270 OpNoLine
    271 %_ptr_Output_v4float = OpTypePointer Output %v4float
    272 OpNoLine
    273 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    274 OpNoLine
    275 %MainPs = OpFunction %void None %19
    276 OpNoLine
    277 %48 = OpLabel
    278 OpNoLine
    279 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
    280 OpNoLine
    281 %param = OpVariable %_ptr_Function_PS_INPUT Function
    282 OpLine %5 23 0
    283 %49 = OpLoad %v2float %i_vTextureCoords
    284 OpLine %5 23 0
    285 %50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
    286 OpLine %5 23 0
    287 OpStore %50 %49
    288 OpLine %5 23 0
    289 %51 = OpLoad %PS_INPUT %i_0
    290 OpLine %5 23 0
    291 OpStore %param %51
    292 OpLine %5 23 0
    293 %52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
    294 OpLine %5 23 0
    295 %53 = OpCompositeExtract %v4float %52 0
    296 OpLine %5 23 0
    297 OpStore %_entryPointOutput_vColor %53
    298 OpLine %5 23 0
    299 OpReturn
    300 OpNoLine
    301 OpFunctionEnd
    302 OpNoLine
    303 %_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
    304 OpNoLine
    305 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
    306 OpNoLine
    307 %54 = OpLabel
    308 OpNoLine
    309 %u = OpVariable %_ptr_Function_uint Function
    310 OpNoLine
    311 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
    312 OpLine %5 27 0
    313 %55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
    314 OpLine %5 27 0
    315 %56 = OpLoad %uint %55
    316 OpLine %5 27 0
    317 %57 = OpINotEqual %bool %56 %uint_0
    318 OpLine %5 27 0
    319 OpSelectionMerge %58 None
    320 OpBranchConditional %57 %59 %60
    321 OpNoLine
    322 %59 = OpLabel
    323 OpLine %5 28 0
    324 %61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    325 OpLine %5 28 0
    326 %62 = OpLoad %uint %61
    327 OpLine %5 28 0
    328 OpStore %u %62
    329 OpLine %5 28 0
    330 OpBranch %58
    331 OpNoLine
    332 %60 = OpLabel
    333 OpLine %5 30 0
    334 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    335 OpLine %5 30 0
    336 %64 = OpLoad %uint %63
    337 OpLine %5 30 0
    338 OpStore %u %64
    339 OpLine %5 30 0
    340 OpBranch %58
    341 OpNoLine
    342 %58 = OpLabel
    343 OpLine %5 31 0
    344 %65 = OpLoad %uint %u
    345 OpLine %5 31 0
    346 %66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
    347 OpLine %5 31 0
    348 %67 = OpLoad %36 %66
    349 OpLine %5 31 0
    350 %68 = OpLoad %41 %g_sAniso
    351 OpLine %5 31 0
    352 %69 = OpSampledImage %43 %67 %68
    353 OpLine %5 31 0
    354 %70 = OpAccessChain %_ptr_Function_v2float %i %int_0
    355 OpLine %5 31 0
    356 %71 = OpLoad %v2float %70
    357 OpLine %5 31 0
    358 %72 = OpImageSampleImplicitLod %v4float %69 %71
    359 OpLine %5 31 0
    360 %73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
    361 OpLine %5 31 0
    362 OpStore %73 %72
    363 OpLine %5 32 0
    364 %74 = OpLoad %PS_OUTPUT %ps_output
    365 OpLine %5 32 0
    366 OpReturnValue %74
    367 OpNoLine
    368 OpFunctionEnd
    369 )";
    370 
    371   SinglePassRunAndCheck<ProcessLinesPass>(predefs + before, predefs + after,
    372                                           false, true, kLinesPropagateLines);
    373 }
    374 
    375 TEST_F(ProcessLinesTest, SimpleElimination) {
    376   // Previous test with before and after reversed
    377 
    378   const std::string predefs =
    379       R"(OpCapability Shader
    380 %1 = OpExtInstImport "GLSL.std.450"
    381 OpMemoryModel Logical GLSL450
    382 OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
    383 OpExecutionMode %MainPs OriginUpperLeft
    384 %5 = OpString "foo.frag"
    385 OpSource HLSL 500
    386 OpName %MainPs "MainPs"
    387 OpName %PS_INPUT "PS_INPUT"
    388 OpMemberName %PS_INPUT 0 "vTextureCoords"
    389 OpName %PS_OUTPUT "PS_OUTPUT"
    390 OpMemberName %PS_OUTPUT 0 "vColor"
    391 OpName %_MainPs_struct_PS_INPUT_vf21_ "@MainPs(struct-PS_INPUT-vf21;"
    392 OpName %i "i"
    393 OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
    394 OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
    395 OpMemberName %PerViewConstantBuffer_t 1 "g_nDataIdx2"
    396 OpMemberName %PerViewConstantBuffer_t 2 "g_B"
    397 OpName %_ ""
    398 OpName %u "u"
    399 OpName %ps_output "ps_output"
    400 OpName %g_tColor "g_tColor"
    401 OpName %g_sAniso "g_sAniso"
    402 OpName %i_0 "i"
    403 OpName %i_vTextureCoords "i.vTextureCoords"
    404 OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
    405 OpName %param "param"
    406 OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
    407 OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 4
    408 OpMemberDecorate %PerViewConstantBuffer_t 2 Offset 8
    409 OpDecorate %PerViewConstantBuffer_t Block
    410 OpDecorate %g_tColor DescriptorSet 0
    411 OpDecorate %g_sAniso DescriptorSet 0
    412 OpDecorate %i_vTextureCoords Location 0
    413 OpDecorate %_entryPointOutput_vColor Location 0
    414 )";
    415 
    416   const std::string before =
    417       R"(OpNoLine
    418 %void = OpTypeVoid
    419 OpNoLine
    420 %19 = OpTypeFunction %void
    421 OpNoLine
    422 %float = OpTypeFloat 32
    423 OpNoLine
    424 %v2float = OpTypeVector %float 2
    425 OpNoLine
    426 %PS_INPUT = OpTypeStruct %v2float
    427 OpNoLine
    428 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
    429 OpNoLine
    430 %v4float = OpTypeVector %float 4
    431 OpNoLine
    432 %PS_OUTPUT = OpTypeStruct %v4float
    433 OpNoLine
    434 %24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
    435 OpNoLine
    436 %uint = OpTypeInt 32 0
    437 OpNoLine
    438 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
    439 OpNoLine
    440 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    441 OpNoLine
    442 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    443 OpNoLine
    444 %int = OpTypeInt 32 1
    445 OpNoLine
    446 %int_2 = OpConstant %int 2
    447 OpNoLine
    448 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    449 OpNoLine
    450 %bool = OpTypeBool
    451 OpNoLine
    452 %uint_0 = OpConstant %uint 0
    453 OpNoLine
    454 %_ptr_Function_uint = OpTypePointer Function %uint
    455 OpNoLine
    456 %int_0 = OpConstant %int 0
    457 OpNoLine
    458 %int_1 = OpConstant %int 1
    459 OpNoLine
    460 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
    461 OpNoLine
    462 %36 = OpTypeImage %float 2D 0 0 0 1 Unknown
    463 OpNoLine
    464 %uint_128 = OpConstant %uint 128
    465 OpNoLine
    466 %_arr_36_uint_128 = OpTypeArray %36 %uint_128
    467 OpNoLine
    468 %_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
    469 OpNoLine
    470 %g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
    471 OpNoLine
    472 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
    473 OpNoLine
    474 %41 = OpTypeSampler
    475 OpNoLine
    476 %_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
    477 OpNoLine
    478 %g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
    479 OpNoLine
    480 %43 = OpTypeSampledImage %36
    481 OpNoLine
    482 %_ptr_Function_v2float = OpTypePointer Function %v2float
    483 OpNoLine
    484 %_ptr_Function_v4float = OpTypePointer Function %v4float
    485 OpNoLine
    486 %_ptr_Input_v2float = OpTypePointer Input %v2float
    487 OpNoLine
    488 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    489 OpNoLine
    490 %_ptr_Output_v4float = OpTypePointer Output %v4float
    491 OpNoLine
    492 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    493 OpNoLine
    494 %MainPs = OpFunction %void None %19
    495 OpNoLine
    496 %48 = OpLabel
    497 OpNoLine
    498 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
    499 OpNoLine
    500 %param = OpVariable %_ptr_Function_PS_INPUT Function
    501 OpLine %5 23 0
    502 %49 = OpLoad %v2float %i_vTextureCoords
    503 OpLine %5 23 0
    504 %50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
    505 OpLine %5 23 0
    506 OpStore %50 %49
    507 OpLine %5 23 0
    508 %51 = OpLoad %PS_INPUT %i_0
    509 OpLine %5 23 0
    510 OpStore %param %51
    511 OpLine %5 23 0
    512 %52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
    513 OpLine %5 23 0
    514 %53 = OpCompositeExtract %v4float %52 0
    515 OpLine %5 23 0
    516 OpStore %_entryPointOutput_vColor %53
    517 OpLine %5 23 0
    518 OpReturn
    519 OpNoLine
    520 OpFunctionEnd
    521 OpNoLine
    522 %_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
    523 OpNoLine
    524 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
    525 OpNoLine
    526 %54 = OpLabel
    527 OpNoLine
    528 %u = OpVariable %_ptr_Function_uint Function
    529 OpNoLine
    530 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
    531 OpLine %5 27 0
    532 %55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
    533 OpLine %5 27 0
    534 %56 = OpLoad %uint %55
    535 OpLine %5 27 0
    536 %57 = OpINotEqual %bool %56 %uint_0
    537 OpLine %5 27 0
    538 OpSelectionMerge %58 None
    539 OpBranchConditional %57 %59 %60
    540 OpNoLine
    541 %59 = OpLabel
    542 OpLine %5 28 0
    543 %61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    544 OpLine %5 28 0
    545 %62 = OpLoad %uint %61
    546 OpLine %5 28 0
    547 OpStore %u %62
    548 OpLine %5 28 0
    549 OpBranch %58
    550 OpNoLine
    551 %60 = OpLabel
    552 OpLine %5 30 0
    553 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    554 OpLine %5 30 0
    555 %64 = OpLoad %uint %63
    556 OpLine %5 30 0
    557 OpStore %u %64
    558 OpLine %5 30 0
    559 OpBranch %58
    560 OpNoLine
    561 %58 = OpLabel
    562 OpLine %5 31 0
    563 %65 = OpLoad %uint %u
    564 OpLine %5 31 0
    565 %66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
    566 OpLine %5 31 0
    567 %67 = OpLoad %36 %66
    568 OpLine %5 31 0
    569 %68 = OpLoad %41 %g_sAniso
    570 OpLine %5 31 0
    571 %69 = OpSampledImage %43 %67 %68
    572 OpLine %5 31 0
    573 %70 = OpAccessChain %_ptr_Function_v2float %i %int_0
    574 OpLine %5 31 0
    575 %71 = OpLoad %v2float %70
    576 OpLine %5 31 0
    577 %72 = OpImageSampleImplicitLod %v4float %69 %71
    578 OpLine %5 31 0
    579 %73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
    580 OpLine %5 31 0
    581 OpStore %73 %72
    582 OpLine %5 32 0
    583 %74 = OpLoad %PS_OUTPUT %ps_output
    584 OpLine %5 32 0
    585 OpReturnValue %74
    586 OpNoLine
    587 OpFunctionEnd
    588 )";
    589 
    590   const std::string after =
    591       R"(%void = OpTypeVoid
    592 %19 = OpTypeFunction %void
    593 %float = OpTypeFloat 32
    594 %v2float = OpTypeVector %float 2
    595 %PS_INPUT = OpTypeStruct %v2float
    596 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
    597 %v4float = OpTypeVector %float 4
    598 %PS_OUTPUT = OpTypeStruct %v4float
    599 %24 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
    600 %uint = OpTypeInt 32 0
    601 %PerViewConstantBuffer_t = OpTypeStruct %uint %uint %uint
    602 %_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
    603 %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
    604 %int = OpTypeInt 32 1
    605 %int_2 = OpConstant %int 2
    606 %_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
    607 %bool = OpTypeBool
    608 %uint_0 = OpConstant %uint 0
    609 %_ptr_Function_uint = OpTypePointer Function %uint
    610 %int_0 = OpConstant %int 0
    611 %int_1 = OpConstant %int 1
    612 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
    613 %36 = OpTypeImage %float 2D 0 0 0 1 Unknown
    614 %uint_128 = OpConstant %uint 128
    615 %_arr_36_uint_128 = OpTypeArray %36 %uint_128
    616 %_ptr_UniformConstant__arr_36_uint_128 = OpTypePointer UniformConstant %_arr_36_uint_128
    617 %g_tColor = OpVariable %_ptr_UniformConstant__arr_36_uint_128 UniformConstant
    618 %_ptr_UniformConstant_36 = OpTypePointer UniformConstant %36
    619 %41 = OpTypeSampler
    620 %_ptr_UniformConstant_41 = OpTypePointer UniformConstant %41
    621 %g_sAniso = OpVariable %_ptr_UniformConstant_41 UniformConstant
    622 %43 = OpTypeSampledImage %36
    623 %_ptr_Function_v2float = OpTypePointer Function %v2float
    624 %_ptr_Function_v4float = OpTypePointer Function %v4float
    625 %_ptr_Input_v2float = OpTypePointer Input %v2float
    626 %i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
    627 %_ptr_Output_v4float = OpTypePointer Output %v4float
    628 %_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
    629 %MainPs = OpFunction %void None %19
    630 %48 = OpLabel
    631 %i_0 = OpVariable %_ptr_Function_PS_INPUT Function
    632 %param = OpVariable %_ptr_Function_PS_INPUT Function
    633 OpLine %5 23 0
    634 %49 = OpLoad %v2float %i_vTextureCoords
    635 %50 = OpAccessChain %_ptr_Function_v2float %i_0 %int_0
    636 OpStore %50 %49
    637 %51 = OpLoad %PS_INPUT %i_0
    638 OpStore %param %51
    639 %52 = OpFunctionCall %PS_OUTPUT %_MainPs_struct_PS_INPUT_vf21_ %param
    640 %53 = OpCompositeExtract %v4float %52 0
    641 OpStore %_entryPointOutput_vColor %53
    642 OpReturn
    643 OpFunctionEnd
    644 %_MainPs_struct_PS_INPUT_vf21_ = OpFunction %PS_OUTPUT None %24
    645 %i = OpFunctionParameter %_ptr_Function_PS_INPUT
    646 %54 = OpLabel
    647 %u = OpVariable %_ptr_Function_uint Function
    648 %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
    649 OpLine %5 27 0
    650 %55 = OpAccessChain %_ptr_PushConstant_uint %_ %int_2
    651 %56 = OpLoad %uint %55
    652 %57 = OpINotEqual %bool %56 %uint_0
    653 OpSelectionMerge %58 None
    654 OpBranchConditional %57 %59 %60
    655 %59 = OpLabel
    656 OpLine %5 28 0
    657 %61 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
    658 %62 = OpLoad %uint %61
    659 OpStore %u %62
    660 OpBranch %58
    661 %60 = OpLabel
    662 OpLine %5 30 0
    663 %63 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
    664 %64 = OpLoad %uint %63
    665 OpStore %u %64
    666 OpBranch %58
    667 %58 = OpLabel
    668 OpLine %5 31 0
    669 %65 = OpLoad %uint %u
    670 %66 = OpAccessChain %_ptr_UniformConstant_36 %g_tColor %65
    671 %67 = OpLoad %36 %66
    672 %68 = OpLoad %41 %g_sAniso
    673 %69 = OpSampledImage %43 %67 %68
    674 %70 = OpAccessChain %_ptr_Function_v2float %i %int_0
    675 %71 = OpLoad %v2float %70
    676 %72 = OpImageSampleImplicitLod %v4float %69 %71
    677 %73 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
    678 OpStore %73 %72
    679 OpLine %5 32 0
    680 %74 = OpLoad %PS_OUTPUT %ps_output
    681 OpReturnValue %74
    682 OpFunctionEnd
    683 )";
    684 
    685   SinglePassRunAndCheck<ProcessLinesPass>(
    686       predefs + before, predefs + after, false, true, kLinesEliminateDeadLines);
    687 }
    688 
    689 // TODO(greg-lunarg): Add tests to verify handling of these cases:
    690 //
    691 //    TODO(greg-lunarg): Think about other tests :)
    692 
    693 }  // namespace
    694 }  // namespace opt
    695 }  // namespace spvtools
    696