1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Valve Corporation 2fd4e5da5Sopenharmony_ci// Copyright (c) 2017 LunarG Inc. 3fd4e5da5Sopenharmony_ci// 4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 7fd4e5da5Sopenharmony_ci// 8fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 9fd4e5da5Sopenharmony_ci// 10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 14fd4e5da5Sopenharmony_ci// limitations under the License. 15fd4e5da5Sopenharmony_ci 16fd4e5da5Sopenharmony_ci#include <string> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace opt { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciusing BlockMergeTest = PassTest<::testing::Test>; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, Simple) { 28fd4e5da5Sopenharmony_ci // Note: SPIR-V hand edited to insert block boundary 29fd4e5da5Sopenharmony_ci // between two statements in main. 30fd4e5da5Sopenharmony_ci // 31fd4e5da5Sopenharmony_ci // #version 140 32fd4e5da5Sopenharmony_ci // 33fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 34fd4e5da5Sopenharmony_ci // 35fd4e5da5Sopenharmony_ci // void main() 36fd4e5da5Sopenharmony_ci // { 37fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 38fd4e5da5Sopenharmony_ci // gl_FragColor = v; 39fd4e5da5Sopenharmony_ci // } 40fd4e5da5Sopenharmony_ci 41fd4e5da5Sopenharmony_ci const std::string predefs = 42fd4e5da5Sopenharmony_ci R"(OpCapability Shader 43fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 44fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 45fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 46fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 47fd4e5da5Sopenharmony_ciOpSource GLSL 140 48fd4e5da5Sopenharmony_ciOpName %main "main" 49fd4e5da5Sopenharmony_ciOpName %v "v" 50fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 51fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 52fd4e5da5Sopenharmony_ci%void = OpTypeVoid 53fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 54fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 55fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 56fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 57fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 58fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 59fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 60fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 61fd4e5da5Sopenharmony_ci)"; 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci const std::string before = 64fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 65fd4e5da5Sopenharmony_ci%13 = OpLabel 66fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 67fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor 68fd4e5da5Sopenharmony_ciOpStore %v %14 69fd4e5da5Sopenharmony_ciOpBranch %15 70fd4e5da5Sopenharmony_ci%15 = OpLabel 71fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %v 72fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %16 73fd4e5da5Sopenharmony_ciOpReturn 74fd4e5da5Sopenharmony_ciOpFunctionEnd 75fd4e5da5Sopenharmony_ci)"; 76fd4e5da5Sopenharmony_ci 77fd4e5da5Sopenharmony_ci const std::string after = 78fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 79fd4e5da5Sopenharmony_ci%13 = OpLabel 80fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 81fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor 82fd4e5da5Sopenharmony_ciOpStore %v %14 83fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %v 84fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %16 85fd4e5da5Sopenharmony_ciOpReturn 86fd4e5da5Sopenharmony_ciOpFunctionEnd 87fd4e5da5Sopenharmony_ci)"; 88fd4e5da5Sopenharmony_ci 89fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(predefs + before, predefs + after, true, 90fd4e5da5Sopenharmony_ci true); 91fd4e5da5Sopenharmony_ci} 92fd4e5da5Sopenharmony_ci 93fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, BlockMergeForLinkage) { 94fd4e5da5Sopenharmony_ci const std::string before = 95fd4e5da5Sopenharmony_ci R"(OpCapability Shader 96fd4e5da5Sopenharmony_ciOpCapability Linkage 97fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 98fd4e5da5Sopenharmony_ciOpSource HLSL 630 99fd4e5da5Sopenharmony_ciOpName %main "main" 100fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 101fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 102fd4e5da5Sopenharmony_ciOpName %v "v" 103fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export 104fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 105fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 106fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 107fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %v4float %_ptr_Function_v4float 108fd4e5da5Sopenharmony_ci%main = OpFunction %v4float None %8 109fd4e5da5Sopenharmony_ci%BaseColor = OpFunctionParameter %_ptr_Function_v4float 110fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 111fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 112fd4e5da5Sopenharmony_ci%9 = OpLoad %v4float %BaseColor 113fd4e5da5Sopenharmony_ciOpStore %v %9 114fd4e5da5Sopenharmony_ciOpBranch %10 115fd4e5da5Sopenharmony_ci%10 = OpLabel 116fd4e5da5Sopenharmony_ci%11 = OpLoad %v4float %v 117fd4e5da5Sopenharmony_ciOpBranch %12 118fd4e5da5Sopenharmony_ci%12 = OpLabel 119fd4e5da5Sopenharmony_ciOpReturnValue %11 120fd4e5da5Sopenharmony_ciOpFunctionEnd 121fd4e5da5Sopenharmony_ci)"; 122fd4e5da5Sopenharmony_ci 123fd4e5da5Sopenharmony_ci const std::string after = 124fd4e5da5Sopenharmony_ci R"(OpCapability Shader 125fd4e5da5Sopenharmony_ciOpCapability Linkage 126fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 127fd4e5da5Sopenharmony_ciOpSource HLSL 630 128fd4e5da5Sopenharmony_ciOpName %main "main" 129fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 130fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry" 131fd4e5da5Sopenharmony_ciOpName %v "v" 132fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export 133fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 134fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 135fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 136fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %v4float %_ptr_Function_v4float 137fd4e5da5Sopenharmony_ci%main = OpFunction %v4float None %8 138fd4e5da5Sopenharmony_ci%BaseColor = OpFunctionParameter %_ptr_Function_v4float 139fd4e5da5Sopenharmony_ci%bb_entry = OpLabel 140fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 141fd4e5da5Sopenharmony_ci%9 = OpLoad %v4float %BaseColor 142fd4e5da5Sopenharmony_ciOpStore %v %9 143fd4e5da5Sopenharmony_ci%11 = OpLoad %v4float %v 144fd4e5da5Sopenharmony_ciOpReturnValue %11 145fd4e5da5Sopenharmony_ciOpFunctionEnd 146fd4e5da5Sopenharmony_ci)"; 147fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(before, after, true, true); 148fd4e5da5Sopenharmony_ci} 149fd4e5da5Sopenharmony_ci 150fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, EmptyBlock) { 151fd4e5da5Sopenharmony_ci // Note: SPIR-V hand edited to insert empty block 152fd4e5da5Sopenharmony_ci // after two statements in main. 153fd4e5da5Sopenharmony_ci // 154fd4e5da5Sopenharmony_ci // #version 140 155fd4e5da5Sopenharmony_ci // 156fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 157fd4e5da5Sopenharmony_ci // 158fd4e5da5Sopenharmony_ci // void main() 159fd4e5da5Sopenharmony_ci // { 160fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 161fd4e5da5Sopenharmony_ci // gl_FragColor = v; 162fd4e5da5Sopenharmony_ci // } 163fd4e5da5Sopenharmony_ci 164fd4e5da5Sopenharmony_ci const std::string predefs = 165fd4e5da5Sopenharmony_ci R"(OpCapability Shader 166fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 167fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 168fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 169fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 170fd4e5da5Sopenharmony_ciOpSource GLSL 140 171fd4e5da5Sopenharmony_ciOpName %main "main" 172fd4e5da5Sopenharmony_ciOpName %v "v" 173fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 174fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 175fd4e5da5Sopenharmony_ci%void = OpTypeVoid 176fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 177fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 178fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 179fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 180fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 181fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 182fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 183fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 184fd4e5da5Sopenharmony_ci)"; 185fd4e5da5Sopenharmony_ci 186fd4e5da5Sopenharmony_ci const std::string before = 187fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 188fd4e5da5Sopenharmony_ci%13 = OpLabel 189fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 190fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor 191fd4e5da5Sopenharmony_ciOpStore %v %14 192fd4e5da5Sopenharmony_ciOpBranch %15 193fd4e5da5Sopenharmony_ci%15 = OpLabel 194fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %v 195fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %16 196fd4e5da5Sopenharmony_ciOpBranch %17 197fd4e5da5Sopenharmony_ci%17 = OpLabel 198fd4e5da5Sopenharmony_ciOpBranch %18 199fd4e5da5Sopenharmony_ci%18 = OpLabel 200fd4e5da5Sopenharmony_ciOpReturn 201fd4e5da5Sopenharmony_ciOpFunctionEnd 202fd4e5da5Sopenharmony_ci)"; 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci const std::string after = 205fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 206fd4e5da5Sopenharmony_ci%13 = OpLabel 207fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 208fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor 209fd4e5da5Sopenharmony_ciOpStore %v %14 210fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %v 211fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %16 212fd4e5da5Sopenharmony_ciOpReturn 213fd4e5da5Sopenharmony_ciOpFunctionEnd 214fd4e5da5Sopenharmony_ci)"; 215fd4e5da5Sopenharmony_ci 216fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(predefs + before, predefs + after, true, 217fd4e5da5Sopenharmony_ci true); 218fd4e5da5Sopenharmony_ci} 219fd4e5da5Sopenharmony_ci 220fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, NestedInControlFlow) { 221fd4e5da5Sopenharmony_ci // Note: SPIR-V hand edited to insert block boundary 222fd4e5da5Sopenharmony_ci // between OpFMul and OpStore in then-part. 223fd4e5da5Sopenharmony_ci // 224fd4e5da5Sopenharmony_ci // #version 140 225fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 226fd4e5da5Sopenharmony_ci // 227fd4e5da5Sopenharmony_ci // layout(std140) uniform U_t 228fd4e5da5Sopenharmony_ci // { 229fd4e5da5Sopenharmony_ci // bool g_B ; 230fd4e5da5Sopenharmony_ci // } ; 231fd4e5da5Sopenharmony_ci // 232fd4e5da5Sopenharmony_ci // void main() 233fd4e5da5Sopenharmony_ci // { 234fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 235fd4e5da5Sopenharmony_ci // if (g_B) 236fd4e5da5Sopenharmony_ci // vec4 v = v * 0.25; 237fd4e5da5Sopenharmony_ci // gl_FragColor = v; 238fd4e5da5Sopenharmony_ci // } 239fd4e5da5Sopenharmony_ci 240fd4e5da5Sopenharmony_ci const std::string predefs = 241fd4e5da5Sopenharmony_ci R"(OpCapability Shader 242fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 243fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 244fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 245fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 246fd4e5da5Sopenharmony_ciOpSource GLSL 140 247fd4e5da5Sopenharmony_ciOpName %main "main" 248fd4e5da5Sopenharmony_ciOpName %v "v" 249fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 250fd4e5da5Sopenharmony_ciOpName %U_t "U_t" 251fd4e5da5Sopenharmony_ciOpMemberName %U_t 0 "g_B" 252fd4e5da5Sopenharmony_ciOpName %_ "" 253fd4e5da5Sopenharmony_ciOpName %v_0 "v" 254fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 255fd4e5da5Sopenharmony_ciOpMemberDecorate %U_t 0 Offset 0 256fd4e5da5Sopenharmony_ciOpDecorate %U_t Block 257fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0 258fd4e5da5Sopenharmony_ci%void = OpTypeVoid 259fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 260fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 261fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 262fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 263fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 264fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 265fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 266fd4e5da5Sopenharmony_ci%U_t = OpTypeStruct %uint 267fd4e5da5Sopenharmony_ci%_ptr_Uniform_U_t = OpTypePointer Uniform %U_t 268fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform_U_t Uniform 269fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 270fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 271fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 272fd4e5da5Sopenharmony_ci%bool = OpTypeBool 273fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 274fd4e5da5Sopenharmony_ci%float_0_25 = OpConstant %float 0.25 275fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 276fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 277fd4e5da5Sopenharmony_ci)"; 278fd4e5da5Sopenharmony_ci 279fd4e5da5Sopenharmony_ci const std::string before = 280fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %10 281fd4e5da5Sopenharmony_ci%24 = OpLabel 282fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 283fd4e5da5Sopenharmony_ci%v_0 = OpVariable %_ptr_Function_v4float Function 284fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %BaseColor 285fd4e5da5Sopenharmony_ciOpStore %v %25 286fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 287fd4e5da5Sopenharmony_ci%27 = OpLoad %uint %26 288fd4e5da5Sopenharmony_ci%28 = OpINotEqual %bool %27 %uint_0 289fd4e5da5Sopenharmony_ciOpSelectionMerge %29 None 290fd4e5da5Sopenharmony_ciOpBranchConditional %28 %30 %29 291fd4e5da5Sopenharmony_ci%30 = OpLabel 292fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %v 293fd4e5da5Sopenharmony_ci%32 = OpVectorTimesScalar %v4float %31 %float_0_25 294fd4e5da5Sopenharmony_ciOpBranch %33 295fd4e5da5Sopenharmony_ci%33 = OpLabel 296fd4e5da5Sopenharmony_ciOpStore %v_0 %32 297fd4e5da5Sopenharmony_ciOpBranch %29 298fd4e5da5Sopenharmony_ci%29 = OpLabel 299fd4e5da5Sopenharmony_ci%34 = OpLoad %v4float %v 300fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %34 301fd4e5da5Sopenharmony_ciOpReturn 302fd4e5da5Sopenharmony_ciOpFunctionEnd 303fd4e5da5Sopenharmony_ci)"; 304fd4e5da5Sopenharmony_ci 305fd4e5da5Sopenharmony_ci const std::string after = 306fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %10 307fd4e5da5Sopenharmony_ci%24 = OpLabel 308fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 309fd4e5da5Sopenharmony_ci%v_0 = OpVariable %_ptr_Function_v4float Function 310fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %BaseColor 311fd4e5da5Sopenharmony_ciOpStore %v %25 312fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 313fd4e5da5Sopenharmony_ci%27 = OpLoad %uint %26 314fd4e5da5Sopenharmony_ci%28 = OpINotEqual %bool %27 %uint_0 315fd4e5da5Sopenharmony_ciOpSelectionMerge %29 None 316fd4e5da5Sopenharmony_ciOpBranchConditional %28 %30 %29 317fd4e5da5Sopenharmony_ci%30 = OpLabel 318fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %v 319fd4e5da5Sopenharmony_ci%32 = OpVectorTimesScalar %v4float %31 %float_0_25 320fd4e5da5Sopenharmony_ciOpStore %v_0 %32 321fd4e5da5Sopenharmony_ciOpBranch %29 322fd4e5da5Sopenharmony_ci%29 = OpLabel 323fd4e5da5Sopenharmony_ci%34 = OpLoad %v4float %v 324fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %34 325fd4e5da5Sopenharmony_ciOpReturn 326fd4e5da5Sopenharmony_ciOpFunctionEnd 327fd4e5da5Sopenharmony_ci)"; 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(predefs + before, predefs + after, true, 330fd4e5da5Sopenharmony_ci true); 331fd4e5da5Sopenharmony_ci} 332fd4e5da5Sopenharmony_ci 333fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, PhiInSuccessorOfMergedBlock) { 334fd4e5da5Sopenharmony_ci const std::string text = R"( 335fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] None 336fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[then:%\w+]] [[else:%\w+]] 337fd4e5da5Sopenharmony_ci; CHECK: [[then]] = OpLabel 338fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 339fd4e5da5Sopenharmony_ci; CHECK: [[else]] = OpLabel 340fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 341fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 342fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpPhi {{%\w+}} %true [[then]] %false [[else]] 343fd4e5da5Sopenharmony_ciOpCapability Shader 344fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 345fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 346fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 347fd4e5da5Sopenharmony_ci%void = OpTypeVoid 348fd4e5da5Sopenharmony_ci%bool = OpTypeBool 349fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 350fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 351fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 352fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 353fd4e5da5Sopenharmony_ci%entry = OpLabel 354fd4e5da5Sopenharmony_ciOpSelectionMerge %merge None 355fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %else 356fd4e5da5Sopenharmony_ci%then = OpLabel 357fd4e5da5Sopenharmony_ciOpBranch %then_next 358fd4e5da5Sopenharmony_ci%then_next = OpLabel 359fd4e5da5Sopenharmony_ciOpBranch %merge 360fd4e5da5Sopenharmony_ci%else = OpLabel 361fd4e5da5Sopenharmony_ciOpBranch %merge 362fd4e5da5Sopenharmony_ci%merge = OpLabel 363fd4e5da5Sopenharmony_ci%phi = OpPhi %bool %true %then_next %false %else 364fd4e5da5Sopenharmony_ciOpReturn 365fd4e5da5Sopenharmony_ciOpFunctionEnd 366fd4e5da5Sopenharmony_ci)"; 367fd4e5da5Sopenharmony_ci 368fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 369fd4e5da5Sopenharmony_ci} 370fd4e5da5Sopenharmony_ci 371fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, UpdateMergeInstruction) { 372fd4e5da5Sopenharmony_ci const std::string text = R"( 373fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] None 374fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[then:%\w+]] [[else:%\w+]] 375fd4e5da5Sopenharmony_ci; CHECK: [[then]] = OpLabel 376fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 377fd4e5da5Sopenharmony_ci; CHECK: [[else]] = OpLabel 378fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 379fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 380fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 381fd4e5da5Sopenharmony_ciOpCapability Shader 382fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 383fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 384fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 385fd4e5da5Sopenharmony_ci%void = OpTypeVoid 386fd4e5da5Sopenharmony_ci%bool = OpTypeBool 387fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 388fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 389fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 390fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 391fd4e5da5Sopenharmony_ci%entry = OpLabel 392fd4e5da5Sopenharmony_ciOpSelectionMerge %real_merge None 393fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %else 394fd4e5da5Sopenharmony_ci%then = OpLabel 395fd4e5da5Sopenharmony_ciOpBranch %merge 396fd4e5da5Sopenharmony_ci%else = OpLabel 397fd4e5da5Sopenharmony_ciOpBranch %merge 398fd4e5da5Sopenharmony_ci%merge = OpLabel 399fd4e5da5Sopenharmony_ciOpBranch %real_merge 400fd4e5da5Sopenharmony_ci%real_merge = OpLabel 401fd4e5da5Sopenharmony_ciOpReturn 402fd4e5da5Sopenharmony_ciOpFunctionEnd 403fd4e5da5Sopenharmony_ci)"; 404fd4e5da5Sopenharmony_ci 405fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 406fd4e5da5Sopenharmony_ci} 407fd4e5da5Sopenharmony_ci 408fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, TwoMergeBlocksCannotBeMerged) { 409fd4e5da5Sopenharmony_ci const std::string text = R"( 410fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[outer_merge:%\w+]] None 411fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[inner_merge:%\w+]] None 412fd4e5da5Sopenharmony_ci; CHECK: [[inner_merge]] = OpLabel 413fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[outer_merge]] 414fd4e5da5Sopenharmony_ci; CHECK: [[outer_merge]] = OpLabel 415fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 416fd4e5da5Sopenharmony_ciOpCapability Shader 417fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 418fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 419fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 420fd4e5da5Sopenharmony_ci%void = OpTypeVoid 421fd4e5da5Sopenharmony_ci%bool = OpTypeBool 422fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 423fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 424fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 425fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 426fd4e5da5Sopenharmony_ci%entry = OpLabel 427fd4e5da5Sopenharmony_ciOpSelectionMerge %outer_merge None 428fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %else 429fd4e5da5Sopenharmony_ci%then = OpLabel 430fd4e5da5Sopenharmony_ciOpBranch %inner_header 431fd4e5da5Sopenharmony_ci%else = OpLabel 432fd4e5da5Sopenharmony_ciOpBranch %inner_header 433fd4e5da5Sopenharmony_ci%inner_header = OpLabel 434fd4e5da5Sopenharmony_ciOpSelectionMerge %inner_merge None 435fd4e5da5Sopenharmony_ciOpBranchConditional %true %inner_then %inner_else 436fd4e5da5Sopenharmony_ci%inner_then = OpLabel 437fd4e5da5Sopenharmony_ciOpBranch %inner_merge 438fd4e5da5Sopenharmony_ci%inner_else = OpLabel 439fd4e5da5Sopenharmony_ciOpBranch %inner_merge 440fd4e5da5Sopenharmony_ci%inner_merge = OpLabel 441fd4e5da5Sopenharmony_ciOpBranch %outer_merge 442fd4e5da5Sopenharmony_ci%outer_merge = OpLabel 443fd4e5da5Sopenharmony_ciOpReturn 444fd4e5da5Sopenharmony_ciOpFunctionEnd 445fd4e5da5Sopenharmony_ci)"; 446fd4e5da5Sopenharmony_ci 447fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 448fd4e5da5Sopenharmony_ci} 449fd4e5da5Sopenharmony_ci 450fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, MergeContinue) { 451fd4e5da5Sopenharmony_ci const std::string text = R"( 452fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header:%\w+]] 453fd4e5da5Sopenharmony_ci; CHECK: [[header]] = OpLabel 454fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalAnd 455fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge {{%\w+}} [[header]] None 456fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 457fd4e5da5Sopenharmony_ciOpCapability Shader 458fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 459fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 460fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 461fd4e5da5Sopenharmony_ci%void = OpTypeVoid 462fd4e5da5Sopenharmony_ci%bool = OpTypeBool 463fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 464fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 465fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 466fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 467fd4e5da5Sopenharmony_ci%entry = OpLabel 468fd4e5da5Sopenharmony_ciOpBranch %header 469fd4e5da5Sopenharmony_ci%header = OpLabel 470fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 471fd4e5da5Sopenharmony_ciOpBranch %continue 472fd4e5da5Sopenharmony_ci%continue = OpLabel 473fd4e5da5Sopenharmony_ci%op = OpLogicalAnd %bool %true %false 474fd4e5da5Sopenharmony_ciOpBranch %header 475fd4e5da5Sopenharmony_ci%merge = OpLabel 476fd4e5da5Sopenharmony_ciOpUnreachable 477fd4e5da5Sopenharmony_ciOpFunctionEnd 478fd4e5da5Sopenharmony_ci)"; 479fd4e5da5Sopenharmony_ci 480fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 481fd4e5da5Sopenharmony_ci} 482fd4e5da5Sopenharmony_ci 483fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, MergeContinueWithOpLine) { 484fd4e5da5Sopenharmony_ci const std::string text = R"( 485fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header:%\w+]] 486fd4e5da5Sopenharmony_ci; CHECK: [[header]] = OpLabel 487fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalAnd 488fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\w+}} 1 1 489fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge {{%\w+}} [[header]] None 490fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 491fd4e5da5Sopenharmony_ciOpCapability Shader 492fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 493fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 494fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 495fd4e5da5Sopenharmony_ci%src = OpString "test.shader" 496fd4e5da5Sopenharmony_ci%void = OpTypeVoid 497fd4e5da5Sopenharmony_ci%bool = OpTypeBool 498fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 499fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 500fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 501fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 502fd4e5da5Sopenharmony_ci%entry = OpLabel 503fd4e5da5Sopenharmony_ciOpBranch %header 504fd4e5da5Sopenharmony_ci%header = OpLabel 505fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 506fd4e5da5Sopenharmony_ciOpBranch %continue 507fd4e5da5Sopenharmony_ci%continue = OpLabel 508fd4e5da5Sopenharmony_ci%op = OpLogicalAnd %bool %true %false 509fd4e5da5Sopenharmony_ciOpLine %src 1 1 510fd4e5da5Sopenharmony_ciOpBranch %header 511fd4e5da5Sopenharmony_ci%merge = OpLabel 512fd4e5da5Sopenharmony_ciOpUnreachable 513fd4e5da5Sopenharmony_ciOpFunctionEnd 514fd4e5da5Sopenharmony_ci)"; 515fd4e5da5Sopenharmony_ci 516fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 517fd4e5da5Sopenharmony_ci} 518fd4e5da5Sopenharmony_ci 519fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, TwoHeadersCannotBeMerged) { 520fd4e5da5Sopenharmony_ci const std::string text = R"( 521fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[loop_header:%\w+]] 522fd4e5da5Sopenharmony_ci; CHECK: [[loop_header]] = OpLabel 523fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge 524fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[if_header:%\w+]] 525fd4e5da5Sopenharmony_ci; CHECK: [[if_header]] = OpLabel 526fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge 527fd4e5da5Sopenharmony_ciOpCapability Shader 528fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 529fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 530fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 531fd4e5da5Sopenharmony_ci%void = OpTypeVoid 532fd4e5da5Sopenharmony_ci%bool = OpTypeBool 533fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 534fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 535fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 536fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 537fd4e5da5Sopenharmony_ci%entry = OpLabel 538fd4e5da5Sopenharmony_ciOpBranch %header 539fd4e5da5Sopenharmony_ci%header = OpLabel 540fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 541fd4e5da5Sopenharmony_ciOpBranch %inner_header 542fd4e5da5Sopenharmony_ci%inner_header = OpLabel 543fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None 544fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %if_merge 545fd4e5da5Sopenharmony_ci%then = OpLabel 546fd4e5da5Sopenharmony_ciOpBranch %continue 547fd4e5da5Sopenharmony_ci%if_merge = OpLabel 548fd4e5da5Sopenharmony_ciOpBranch %continue 549fd4e5da5Sopenharmony_ci%continue = OpLabel 550fd4e5da5Sopenharmony_ciOpBranchConditional %false %merge %header 551fd4e5da5Sopenharmony_ci%merge = OpLabel 552fd4e5da5Sopenharmony_ciOpReturn 553fd4e5da5Sopenharmony_ciOpFunctionEnd 554fd4e5da5Sopenharmony_ci)"; 555fd4e5da5Sopenharmony_ci 556fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 557fd4e5da5Sopenharmony_ci} 558fd4e5da5Sopenharmony_ci 559fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, CannotMergeContinue) { 560fd4e5da5Sopenharmony_ci const std::string text = R"( 561fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[loop_header:%\w+]] 562fd4e5da5Sopenharmony_ci; CHECK: [[loop_header]] = OpLabel 563fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge {{%\w+}} [[continue:%\w+]] 564fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[if_header:%\w+]] 565fd4e5da5Sopenharmony_ci; CHECK: [[if_header]] = OpLabel 566fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge 567fd4e5da5Sopenharmony_ci; CHECK: [[continue]] = OpLabel 568fd4e5da5Sopenharmony_ciOpCapability Shader 569fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 570fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 571fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 572fd4e5da5Sopenharmony_ci%void = OpTypeVoid 573fd4e5da5Sopenharmony_ci%bool = OpTypeBool 574fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 575fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 576fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 577fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 578fd4e5da5Sopenharmony_ci%entry = OpLabel 579fd4e5da5Sopenharmony_ciOpBranch %header 580fd4e5da5Sopenharmony_ci%header = OpLabel 581fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 582fd4e5da5Sopenharmony_ciOpBranchConditional %true %inner_header %merge 583fd4e5da5Sopenharmony_ci%inner_header = OpLabel 584fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None 585fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %if_merge 586fd4e5da5Sopenharmony_ci%then = OpLabel 587fd4e5da5Sopenharmony_ciOpBranch %continue 588fd4e5da5Sopenharmony_ci%if_merge = OpLabel 589fd4e5da5Sopenharmony_ciOpBranch %continue 590fd4e5da5Sopenharmony_ci%continue = OpLabel 591fd4e5da5Sopenharmony_ciOpBranchConditional %false %merge %header 592fd4e5da5Sopenharmony_ci%merge = OpLabel 593fd4e5da5Sopenharmony_ciOpReturn 594fd4e5da5Sopenharmony_ciOpFunctionEnd 595fd4e5da5Sopenharmony_ci)"; 596fd4e5da5Sopenharmony_ci 597fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 598fd4e5da5Sopenharmony_ci} 599fd4e5da5Sopenharmony_ci 600fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, RemoveStructuredDeclaration) { 601fd4e5da5Sopenharmony_ci // Note: SPIR-V hand edited remove dead branch and add block 602fd4e5da5Sopenharmony_ci // before continue block 603fd4e5da5Sopenharmony_ci // 604fd4e5da5Sopenharmony_ci // #version 140 605fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 606fd4e5da5Sopenharmony_ci // 607fd4e5da5Sopenharmony_ci // void main() 608fd4e5da5Sopenharmony_ci // { 609fd4e5da5Sopenharmony_ci // while (true) { 610fd4e5da5Sopenharmony_ci // break; 611fd4e5da5Sopenharmony_ci // } 612fd4e5da5Sopenharmony_ci // gl_FragColor = BaseColor; 613fd4e5da5Sopenharmony_ci // } 614fd4e5da5Sopenharmony_ci 615fd4e5da5Sopenharmony_ci const std::string assembly = 616fd4e5da5Sopenharmony_ci R"( 617fd4e5da5Sopenharmony_ci; CHECK: OpLabel 618fd4e5da5Sopenharmony_ci; CHECK: [[header:%\w+]] = OpLabel 619fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLoopMerge 620fd4e5da5Sopenharmony_ci; CHECK: OpReturn 621fd4e5da5Sopenharmony_ci; CHECK: [[continue:%\w+]] = OpLabel 622fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[block:%\w+]] 623fd4e5da5Sopenharmony_ci; CHECK: [[block]] = OpLabel 624fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 625fd4e5da5Sopenharmony_ciOpCapability Shader 626fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 627fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 628fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor 629fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 630fd4e5da5Sopenharmony_ciOpSource GLSL 140 631fd4e5da5Sopenharmony_ciOpName %main "main" 632fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 633fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 634fd4e5da5Sopenharmony_ci%void = OpTypeVoid 635fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 636fd4e5da5Sopenharmony_ci%bool = OpTypeBool 637fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 638fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 639fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 640fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 641fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 642fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 643fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 644fd4e5da5Sopenharmony_ci%main = OpFunction %void None %6 645fd4e5da5Sopenharmony_ci%13 = OpLabel 646fd4e5da5Sopenharmony_ciOpBranch %14 647fd4e5da5Sopenharmony_ci%14 = OpLabel 648fd4e5da5Sopenharmony_ciOpLoopMerge %15 %16 None 649fd4e5da5Sopenharmony_ciOpBranch %17 650fd4e5da5Sopenharmony_ci%17 = OpLabel 651fd4e5da5Sopenharmony_ciOpBranch %15 652fd4e5da5Sopenharmony_ci%18 = OpLabel 653fd4e5da5Sopenharmony_ciOpBranch %16 654fd4e5da5Sopenharmony_ci%16 = OpLabel 655fd4e5da5Sopenharmony_ciOpBranch %14 656fd4e5da5Sopenharmony_ci%15 = OpLabel 657fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor 658fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %19 659fd4e5da5Sopenharmony_ciOpReturn 660fd4e5da5Sopenharmony_ciOpFunctionEnd 661fd4e5da5Sopenharmony_ci)"; 662fd4e5da5Sopenharmony_ci 663fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(assembly, true); 664fd4e5da5Sopenharmony_ci} 665fd4e5da5Sopenharmony_ci 666fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeKill) { 667fd4e5da5Sopenharmony_ci const std::string text = R"( 668fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 669fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 670fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 671fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpKill 672fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 673fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 674fd4e5da5Sopenharmony_ciOpCapability Shader 675fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 676fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 677fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 678fd4e5da5Sopenharmony_ci%void = OpTypeVoid 679fd4e5da5Sopenharmony_ci%bool = OpTypeBool 680fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 681fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 682fd4e5da5Sopenharmony_ci%1 = OpLabel 683fd4e5da5Sopenharmony_ciOpBranch %2 684fd4e5da5Sopenharmony_ci%2 = OpLabel 685fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 686fd4e5da5Sopenharmony_ciOpBranch %5 687fd4e5da5Sopenharmony_ci%5 = OpLabel 688fd4e5da5Sopenharmony_ciOpKill 689fd4e5da5Sopenharmony_ci%4 = OpLabel 690fd4e5da5Sopenharmony_ciOpBranch %2 691fd4e5da5Sopenharmony_ci%3 = OpLabel 692fd4e5da5Sopenharmony_ciOpUnreachable 693fd4e5da5Sopenharmony_ciOpFunctionEnd 694fd4e5da5Sopenharmony_ci)"; 695fd4e5da5Sopenharmony_ci 696fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 697fd4e5da5Sopenharmony_ci} 698fd4e5da5Sopenharmony_ci 699fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeTerminateInvocation) { 700fd4e5da5Sopenharmony_ci const std::string text = R"( 701fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 702fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 703fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 704fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpTerminateInvocation 705fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 706fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 707fd4e5da5Sopenharmony_ciOpCapability Shader 708fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation" 709fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 710fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 711fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 712fd4e5da5Sopenharmony_ci%void = OpTypeVoid 713fd4e5da5Sopenharmony_ci%bool = OpTypeBool 714fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 715fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 716fd4e5da5Sopenharmony_ci%1 = OpLabel 717fd4e5da5Sopenharmony_ciOpBranch %2 718fd4e5da5Sopenharmony_ci%2 = OpLabel 719fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 720fd4e5da5Sopenharmony_ciOpBranch %5 721fd4e5da5Sopenharmony_ci%5 = OpLabel 722fd4e5da5Sopenharmony_ciOpTerminateInvocation 723fd4e5da5Sopenharmony_ci%4 = OpLabel 724fd4e5da5Sopenharmony_ciOpBranch %2 725fd4e5da5Sopenharmony_ci%3 = OpLabel 726fd4e5da5Sopenharmony_ciOpUnreachable 727fd4e5da5Sopenharmony_ciOpFunctionEnd 728fd4e5da5Sopenharmony_ci)"; 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 731fd4e5da5Sopenharmony_ci} 732fd4e5da5Sopenharmony_ci 733fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeUnreachable) { 734fd4e5da5Sopenharmony_ci const std::string text = R"( 735fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 736fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 737fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 738fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 739fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 740fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 741fd4e5da5Sopenharmony_ciOpCapability Shader 742fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 743fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 744fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 745fd4e5da5Sopenharmony_ci%void = OpTypeVoid 746fd4e5da5Sopenharmony_ci%bool = OpTypeBool 747fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 748fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 749fd4e5da5Sopenharmony_ci%1 = OpLabel 750fd4e5da5Sopenharmony_ciOpBranch %2 751fd4e5da5Sopenharmony_ci%2 = OpLabel 752fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 753fd4e5da5Sopenharmony_ciOpBranch %5 754fd4e5da5Sopenharmony_ci%5 = OpLabel 755fd4e5da5Sopenharmony_ciOpUnreachable 756fd4e5da5Sopenharmony_ci%4 = OpLabel 757fd4e5da5Sopenharmony_ciOpBranch %2 758fd4e5da5Sopenharmony_ci%3 = OpLabel 759fd4e5da5Sopenharmony_ciOpUnreachable 760fd4e5da5Sopenharmony_ciOpFunctionEnd 761fd4e5da5Sopenharmony_ci)"; 762fd4e5da5Sopenharmony_ci 763fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, false); 764fd4e5da5Sopenharmony_ci} 765fd4e5da5Sopenharmony_ci 766fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeReturn) { 767fd4e5da5Sopenharmony_ci const std::string text = R"( 768fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 769fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 770fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 771fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 772fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 773fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 774fd4e5da5Sopenharmony_ciOpCapability Shader 775fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 776fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 777fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 778fd4e5da5Sopenharmony_ci%void = OpTypeVoid 779fd4e5da5Sopenharmony_ci%bool = OpTypeBool 780fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 781fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 782fd4e5da5Sopenharmony_ci%1 = OpLabel 783fd4e5da5Sopenharmony_ciOpBranch %2 784fd4e5da5Sopenharmony_ci%2 = OpLabel 785fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 786fd4e5da5Sopenharmony_ciOpBranch %5 787fd4e5da5Sopenharmony_ci%5 = OpLabel 788fd4e5da5Sopenharmony_ciOpReturn 789fd4e5da5Sopenharmony_ci%4 = OpLabel 790fd4e5da5Sopenharmony_ciOpBranch %2 791fd4e5da5Sopenharmony_ci%3 = OpLabel 792fd4e5da5Sopenharmony_ciOpUnreachable 793fd4e5da5Sopenharmony_ciOpFunctionEnd 794fd4e5da5Sopenharmony_ci)"; 795fd4e5da5Sopenharmony_ci 796fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 797fd4e5da5Sopenharmony_ci} 798fd4e5da5Sopenharmony_ci 799fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeSwitch) { 800fd4e5da5Sopenharmony_ci const std::string text = R"( 801fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 802fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 803fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 804fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge 805fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSwitch 806fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 807fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 808fd4e5da5Sopenharmony_ciOpCapability Shader 809fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 810fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 811fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 812fd4e5da5Sopenharmony_ci%void = OpTypeVoid 813fd4e5da5Sopenharmony_ci%bool = OpTypeBool 814fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 815fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 816fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 817fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 818fd4e5da5Sopenharmony_ci%1 = OpLabel 819fd4e5da5Sopenharmony_ciOpBranch %2 820fd4e5da5Sopenharmony_ci%2 = OpLabel 821fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 822fd4e5da5Sopenharmony_ciOpBranch %5 823fd4e5da5Sopenharmony_ci%5 = OpLabel 824fd4e5da5Sopenharmony_ciOpSelectionMerge %6 None 825fd4e5da5Sopenharmony_ciOpSwitch %int_0 %6 826fd4e5da5Sopenharmony_ci%6 = OpLabel 827fd4e5da5Sopenharmony_ciOpReturn 828fd4e5da5Sopenharmony_ci%4 = OpLabel 829fd4e5da5Sopenharmony_ciOpBranch %2 830fd4e5da5Sopenharmony_ci%3 = OpLabel 831fd4e5da5Sopenharmony_ciOpUnreachable 832fd4e5da5Sopenharmony_ciOpFunctionEnd 833fd4e5da5Sopenharmony_ci)"; 834fd4e5da5Sopenharmony_ci 835fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 836fd4e5da5Sopenharmony_ci} 837fd4e5da5Sopenharmony_ci 838fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontMergeReturnValue) { 839fd4e5da5Sopenharmony_ci const std::string text = R"( 840fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[cont:%\w+]] None 841fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 842fd4e5da5Sopenharmony_ci; CHECK: [[ret:%\w+]] = OpLabel 843fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 844fd4e5da5Sopenharmony_ci; CHECK-DAG: [[cont]] = OpLabel 845fd4e5da5Sopenharmony_ci; CHECK-DAG: [[merge]] = OpLabel 846fd4e5da5Sopenharmony_ciOpCapability Shader 847fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 848fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 849fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 850fd4e5da5Sopenharmony_ci%void = OpTypeVoid 851fd4e5da5Sopenharmony_ci%bool = OpTypeBool 852fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 853fd4e5da5Sopenharmony_ci%otherfuncty = OpTypeFunction %bool 854fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 855fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 856fd4e5da5Sopenharmony_ci%1 = OpLabel 857fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %bool %3 858fd4e5da5Sopenharmony_ciOpReturn 859fd4e5da5Sopenharmony_ciOpFunctionEnd 860fd4e5da5Sopenharmony_ci%3 = OpFunction %bool None %otherfuncty 861fd4e5da5Sopenharmony_ci%4 = OpLabel 862fd4e5da5Sopenharmony_ciOpBranch %5 863fd4e5da5Sopenharmony_ci%5 = OpLabel 864fd4e5da5Sopenharmony_ciOpLoopMerge %6 %7 None 865fd4e5da5Sopenharmony_ciOpBranch %8 866fd4e5da5Sopenharmony_ci%8 = OpLabel 867fd4e5da5Sopenharmony_ciOpReturnValue %true 868fd4e5da5Sopenharmony_ci%7 = OpLabel 869fd4e5da5Sopenharmony_ciOpBranch %5 870fd4e5da5Sopenharmony_ci%6 = OpLabel 871fd4e5da5Sopenharmony_ciOpUnreachable 872fd4e5da5Sopenharmony_ciOpFunctionEnd 873fd4e5da5Sopenharmony_ci)"; 874fd4e5da5Sopenharmony_ci 875fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 876fd4e5da5Sopenharmony_ci} 877fd4e5da5Sopenharmony_ci 878fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, MergeHeaders) { 879fd4e5da5Sopenharmony_ci // Merge two headers when the second is the merge block of the first. 880fd4e5da5Sopenharmony_ci const std::string text = R"( 881fd4e5da5Sopenharmony_ci; CHECK: OpFunction 882fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 883fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header:%\w+]] 884fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[header]] = OpLabel 885fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]] 886fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 887fd4e5da5Sopenharmony_ci; CHECK: OpReturn 888fd4e5da5Sopenharmony_ciOpCapability Shader 889fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 890fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 891fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 892fd4e5da5Sopenharmony_ci%void = OpTypeVoid 893fd4e5da5Sopenharmony_ci%bool = OpTypeBool 894fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 895fd4e5da5Sopenharmony_ci%otherfuncty = OpTypeFunction %bool 896fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 897fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 898fd4e5da5Sopenharmony_ci%1 = OpLabel 899fd4e5da5Sopenharmony_ciOpBranch %5 900fd4e5da5Sopenharmony_ci%5 = OpLabel 901fd4e5da5Sopenharmony_ciOpLoopMerge %8 %7 None 902fd4e5da5Sopenharmony_ciOpBranch %8 903fd4e5da5Sopenharmony_ci%7 = OpLabel 904fd4e5da5Sopenharmony_ciOpBranch %5 905fd4e5da5Sopenharmony_ci%8 = OpLabel 906fd4e5da5Sopenharmony_ciOpSelectionMerge %m None 907fd4e5da5Sopenharmony_ciOpBranchConditional %true %a %m 908fd4e5da5Sopenharmony_ci%a = OpLabel 909fd4e5da5Sopenharmony_ciOpBranch %m 910fd4e5da5Sopenharmony_ci%m = OpLabel 911fd4e5da5Sopenharmony_ciOpReturn 912fd4e5da5Sopenharmony_ciOpFunctionEnd 913fd4e5da5Sopenharmony_ci)"; 914fd4e5da5Sopenharmony_ci 915fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 916fd4e5da5Sopenharmony_ci} 917fd4e5da5Sopenharmony_ci 918fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, OpPhiInSuccessor) { 919fd4e5da5Sopenharmony_ci // Checks that when merging blocks A and B, the OpPhi at the start of B is 920fd4e5da5Sopenharmony_ci // removed and uses of its definition are replaced appropriately. 921fd4e5da5Sopenharmony_ci const std::string prefix = 922fd4e5da5Sopenharmony_ci R"(OpCapability Shader 923fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 924fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 925fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 926fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 927fd4e5da5Sopenharmony_ciOpSource ESSL 310 928fd4e5da5Sopenharmony_ciOpName %main "main" 929fd4e5da5Sopenharmony_ciOpName %x "x" 930fd4e5da5Sopenharmony_ciOpName %y "y" 931fd4e5da5Sopenharmony_ci%void = OpTypeVoid 932fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 933fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 934fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 935fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 936fd4e5da5Sopenharmony_ci%main = OpFunction %void None %6 937fd4e5da5Sopenharmony_ci%10 = OpLabel 938fd4e5da5Sopenharmony_ci%x = OpVariable %_ptr_Function_int Function 939fd4e5da5Sopenharmony_ci%y = OpVariable %_ptr_Function_int Function 940fd4e5da5Sopenharmony_ciOpStore %x %int_1 941fd4e5da5Sopenharmony_ci%11 = OpLoad %int %x 942fd4e5da5Sopenharmony_ci)"; 943fd4e5da5Sopenharmony_ci 944fd4e5da5Sopenharmony_ci const std::string suffix_before = 945fd4e5da5Sopenharmony_ci R"(OpBranch %12 946fd4e5da5Sopenharmony_ci%12 = OpLabel 947fd4e5da5Sopenharmony_ci%13 = OpPhi %int %11 %10 948fd4e5da5Sopenharmony_ciOpStore %y %13 949fd4e5da5Sopenharmony_ciOpReturn 950fd4e5da5Sopenharmony_ciOpFunctionEnd 951fd4e5da5Sopenharmony_ci)"; 952fd4e5da5Sopenharmony_ci 953fd4e5da5Sopenharmony_ci const std::string suffix_after = 954fd4e5da5Sopenharmony_ci R"(OpStore %y %11 955fd4e5da5Sopenharmony_ciOpReturn 956fd4e5da5Sopenharmony_ciOpFunctionEnd 957fd4e5da5Sopenharmony_ci)"; 958fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(prefix + suffix_before, 959fd4e5da5Sopenharmony_ci prefix + suffix_after, true, true); 960fd4e5da5Sopenharmony_ci} 961fd4e5da5Sopenharmony_ci 962fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, MultipleOpPhisInSuccessor) { 963fd4e5da5Sopenharmony_ci // Checks that when merging blocks A and B, the OpPhis at the start of B are 964fd4e5da5Sopenharmony_ci // removed and uses of their definitions are replaced appropriately. 965fd4e5da5Sopenharmony_ci const std::string prefix = 966fd4e5da5Sopenharmony_ci R"(OpCapability Shader 967fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 968fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 969fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 970fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 971fd4e5da5Sopenharmony_ciOpSource ESSL 310 972fd4e5da5Sopenharmony_ciOpName %main "main" 973fd4e5da5Sopenharmony_ciOpName %S "S" 974fd4e5da5Sopenharmony_ciOpMemberName %S 0 "x" 975fd4e5da5Sopenharmony_ciOpMemberName %S 1 "f" 976fd4e5da5Sopenharmony_ciOpName %s "s" 977fd4e5da5Sopenharmony_ciOpName %g "g" 978fd4e5da5Sopenharmony_ciOpName %y "y" 979fd4e5da5Sopenharmony_ciOpName %t "t" 980fd4e5da5Sopenharmony_ciOpName %z "z" 981fd4e5da5Sopenharmony_ci%void = OpTypeVoid 982fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 983fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 984fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 985fd4e5da5Sopenharmony_ci%S = OpTypeStruct %int %float 986fd4e5da5Sopenharmony_ci%_ptr_Function_S = OpTypePointer Function %S 987fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 988fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2 989fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %S %int_1 %float_2 990fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 991fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 992fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3 993fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 994fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 995fd4e5da5Sopenharmony_ci%21 = OpLabel 996fd4e5da5Sopenharmony_ci%s = OpVariable %_ptr_Function_S Function 997fd4e5da5Sopenharmony_ci%g = OpVariable %_ptr_Function_float Function 998fd4e5da5Sopenharmony_ci%y = OpVariable %_ptr_Function_int Function 999fd4e5da5Sopenharmony_ci%t = OpVariable %_ptr_Function_S Function 1000fd4e5da5Sopenharmony_ci%z = OpVariable %_ptr_Function_float Function 1001fd4e5da5Sopenharmony_ciOpStore %s %16 1002fd4e5da5Sopenharmony_ciOpStore %g %float_2 1003fd4e5da5Sopenharmony_ciOpStore %y %int_3 1004fd4e5da5Sopenharmony_ci%22 = OpLoad %S %s 1005fd4e5da5Sopenharmony_ciOpStore %t %22 1006fd4e5da5Sopenharmony_ci%23 = OpAccessChain %_ptr_Function_float %s %int_1 1007fd4e5da5Sopenharmony_ci%24 = OpLoad %float %23 1008fd4e5da5Sopenharmony_ci%25 = OpLoad %float %g 1009fd4e5da5Sopenharmony_ci)"; 1010fd4e5da5Sopenharmony_ci 1011fd4e5da5Sopenharmony_ci const std::string suffix_before = 1012fd4e5da5Sopenharmony_ci R"(OpBranch %26 1013fd4e5da5Sopenharmony_ci%26 = OpLabel 1014fd4e5da5Sopenharmony_ci%27 = OpPhi %float %24 %21 1015fd4e5da5Sopenharmony_ci%28 = OpPhi %float %25 %21 1016fd4e5da5Sopenharmony_ci%29 = OpFAdd %float %27 %28 1017fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Function_int %s %int_0 1018fd4e5da5Sopenharmony_ci%31 = OpLoad %int %30 1019fd4e5da5Sopenharmony_ciOpBranch %32 1020fd4e5da5Sopenharmony_ci%32 = OpLabel 1021fd4e5da5Sopenharmony_ci%33 = OpPhi %float %29 %26 1022fd4e5da5Sopenharmony_ci%34 = OpPhi %int %31 %26 1023fd4e5da5Sopenharmony_ci%35 = OpConvertSToF %float %34 1024fd4e5da5Sopenharmony_ciOpBranch %36 1025fd4e5da5Sopenharmony_ci%36 = OpLabel 1026fd4e5da5Sopenharmony_ci%37 = OpPhi %float %35 %32 1027fd4e5da5Sopenharmony_ci%38 = OpFSub %float %33 %37 1028fd4e5da5Sopenharmony_ci%39 = OpLoad %int %y 1029fd4e5da5Sopenharmony_ciOpBranch %40 1030fd4e5da5Sopenharmony_ci%40 = OpLabel 1031fd4e5da5Sopenharmony_ci%41 = OpPhi %float %38 %36 1032fd4e5da5Sopenharmony_ci%42 = OpPhi %int %39 %36 1033fd4e5da5Sopenharmony_ci%43 = OpConvertSToF %float %42 1034fd4e5da5Sopenharmony_ci%44 = OpFAdd %float %41 %43 1035fd4e5da5Sopenharmony_ciOpStore %z %44 1036fd4e5da5Sopenharmony_ciOpReturn 1037fd4e5da5Sopenharmony_ciOpFunctionEnd 1038fd4e5da5Sopenharmony_ci)"; 1039fd4e5da5Sopenharmony_ci 1040fd4e5da5Sopenharmony_ci const std::string suffix_after = 1041fd4e5da5Sopenharmony_ci R"(%29 = OpFAdd %float %24 %25 1042fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Function_int %s %int_0 1043fd4e5da5Sopenharmony_ci%31 = OpLoad %int %30 1044fd4e5da5Sopenharmony_ci%35 = OpConvertSToF %float %31 1045fd4e5da5Sopenharmony_ci%38 = OpFSub %float %29 %35 1046fd4e5da5Sopenharmony_ci%39 = OpLoad %int %y 1047fd4e5da5Sopenharmony_ci%43 = OpConvertSToF %float %39 1048fd4e5da5Sopenharmony_ci%44 = OpFAdd %float %38 %43 1049fd4e5da5Sopenharmony_ciOpStore %z %44 1050fd4e5da5Sopenharmony_ciOpReturn 1051fd4e5da5Sopenharmony_ciOpFunctionEnd 1052fd4e5da5Sopenharmony_ci)"; 1053fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(prefix + suffix_before, 1054fd4e5da5Sopenharmony_ci prefix + suffix_after, true, true); 1055fd4e5da5Sopenharmony_ci} 1056fd4e5da5Sopenharmony_ci 1057fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, UnreachableLoop) { 1058fd4e5da5Sopenharmony_ci const std::string spirv = R"(OpCapability Shader 1059fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1060fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1061fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 1062fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1063fd4e5da5Sopenharmony_ciOpSource ESSL 310 1064fd4e5da5Sopenharmony_ciOpName %main "main" 1065fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1066fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 1067fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1068fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1069fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1070fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1071fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4 1072fd4e5da5Sopenharmony_ci%9 = OpLabel 1073fd4e5da5Sopenharmony_ciOpBranch %10 1074fd4e5da5Sopenharmony_ci%11 = OpLabel 1075fd4e5da5Sopenharmony_ciOpLoopMerge %12 %13 None 1076fd4e5da5Sopenharmony_ciOpBranchConditional %false %13 %14 1077fd4e5da5Sopenharmony_ci%13 = OpLabel 1078fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None 1079fd4e5da5Sopenharmony_ciOpBranchConditional %false %16 %17 1080fd4e5da5Sopenharmony_ci%16 = OpLabel 1081fd4e5da5Sopenharmony_ciOpBranch %15 1082fd4e5da5Sopenharmony_ci%17 = OpLabel 1083fd4e5da5Sopenharmony_ciOpBranch %15 1084fd4e5da5Sopenharmony_ci%15 = OpLabel 1085fd4e5da5Sopenharmony_ciOpBranch %11 1086fd4e5da5Sopenharmony_ci%14 = OpLabel 1087fd4e5da5Sopenharmony_ciOpReturn 1088fd4e5da5Sopenharmony_ci%12 = OpLabel 1089fd4e5da5Sopenharmony_ciOpBranch %10 1090fd4e5da5Sopenharmony_ci%10 = OpLabel 1091fd4e5da5Sopenharmony_ciOpReturn 1092fd4e5da5Sopenharmony_ciOpFunctionEnd 1093fd4e5da5Sopenharmony_ci)"; 1094fd4e5da5Sopenharmony_ci 1095fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<BlockMergePass>(spirv, spirv, true, true); 1096fd4e5da5Sopenharmony_ci} 1097fd4e5da5Sopenharmony_ci 1098fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DebugMerge) { 1099fd4e5da5Sopenharmony_ci // Verify merge can be done completely, cleanly and validly in presence of 1100fd4e5da5Sopenharmony_ci // NonSemantic.Shader.DebugInfo.100 instructions 1101fd4e5da5Sopenharmony_ci const std::string text = R"( 1102fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge 1103fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch 1104fd4e5da5Sopenharmony_ci; CHECK-NOT: OpBranch 1105fd4e5da5Sopenharmony_ciOpCapability Shader 1106fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 1107fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" 1108fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1109fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET 1110fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1111fd4e5da5Sopenharmony_ci%5 = OpString "lexblock.hlsl" 1112fd4e5da5Sopenharmony_ci%20 = OpString "float" 1113fd4e5da5Sopenharmony_ci%32 = OpString "main" 1114fd4e5da5Sopenharmony_ci%33 = OpString "" 1115fd4e5da5Sopenharmony_ci%46 = OpString "b" 1116fd4e5da5Sopenharmony_ci%49 = OpString "a" 1117fd4e5da5Sopenharmony_ci%58 = OpString "c" 1118fd4e5da5Sopenharmony_ci%63 = OpString "color" 1119fd4e5da5Sopenharmony_ciOpName %in_var_COLOR "in.var.COLOR" 1120fd4e5da5Sopenharmony_ciOpName %out_var_SV_TARGET "out.var.SV_TARGET" 1121fd4e5da5Sopenharmony_ciOpName %main "main" 1122fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0 1123fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0 1124fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1125fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1126fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1127fd4e5da5Sopenharmony_ci%9 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1128fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 1129fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 1130fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1131fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 1132fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1133fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1134fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1135fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 1136fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1137fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4 1138fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 1139fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5 1140fd4e5da5Sopenharmony_ci%uint_12 = OpConstant %uint 12 1141fd4e5da5Sopenharmony_ci%uint_13 = OpConstant %uint 13 1142fd4e5da5Sopenharmony_ci%uint_20 = OpConstant %uint 20 1143fd4e5da5Sopenharmony_ci%uint_15 = OpConstant %uint 15 1144fd4e5da5Sopenharmony_ci%uint_17 = OpConstant %uint 17 1145fd4e5da5Sopenharmony_ci%uint_16 = OpConstant %uint 16 1146fd4e5da5Sopenharmony_ci%uint_14 = OpConstant %uint 14 1147fd4e5da5Sopenharmony_ci%uint_10 = OpConstant %uint 10 1148fd4e5da5Sopenharmony_ci%65 = OpTypeFunction %void 1149fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input 1150fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 1151fd4e5da5Sopenharmony_ci%62 = OpExtInst %void %1 DebugExpression 1152fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugTypeBasic %20 %uint_32 %uint_3 %uint_0 1153fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeVector %22 %uint_4 1154fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugTypeFunction %uint_3 %25 %25 1155fd4e5da5Sopenharmony_ci%28 = OpExtInst %void %1 DebugSource %5 1156fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %28 %uint_5 1157fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %1 DebugFunction %32 %27 %28 %uint_12 %uint_1 %29 %33 %uint_3 %uint_13 1158fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugLexicalBlock %28 %uint_13 %uint_1 %34 1159fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugLexicalBlock %28 %uint_15 %uint_12 %37 1160fd4e5da5Sopenharmony_ci%54 = OpExtInst %void %1 DebugLocalVariable %46 %25 %28 %uint_17 %uint_12 %52 %uint_4 1161fd4e5da5Sopenharmony_ci%56 = OpExtInst %void %1 DebugLocalVariable %49 %25 %28 %uint_16 %uint_12 %52 %uint_4 1162fd4e5da5Sopenharmony_ci%59 = OpExtInst %void %1 DebugLocalVariable %58 %25 %28 %uint_14 %uint_10 %37 %uint_4 1163fd4e5da5Sopenharmony_ci%64 = OpExtInst %void %1 DebugLocalVariable %63 %25 %28 %uint_12 %uint_20 %34 %uint_4 %uint_1 1164fd4e5da5Sopenharmony_ci%main = OpFunction %void None %65 1165fd4e5da5Sopenharmony_ci%66 = OpLabel 1166fd4e5da5Sopenharmony_ci%69 = OpLoad %v4float %in_var_COLOR 1167fd4e5da5Sopenharmony_ci%168 = OpExtInst %void %1 DebugValue %64 %69 %62 1168fd4e5da5Sopenharmony_ci%169 = OpExtInst %void %1 DebugScope %37 1169fd4e5da5Sopenharmony_ciOpLine %5 14 10 1170fd4e5da5Sopenharmony_ci%164 = OpExtInst %void %1 DebugValue %59 %9 %62 1171fd4e5da5Sopenharmony_ciOpLine %5 15 3 1172fd4e5da5Sopenharmony_ciOpBranch %150 1173fd4e5da5Sopenharmony_ci%150 = OpLabel 1174fd4e5da5Sopenharmony_ci%165 = OpPhi %v4float %9 %66 %158 %159 1175fd4e5da5Sopenharmony_ci%167 = OpExtInst %void %1 DebugValue %59 %165 %62 1176fd4e5da5Sopenharmony_ci%170 = OpExtInst %void %1 DebugScope %37 1177fd4e5da5Sopenharmony_ciOpLine %5 15 12 1178fd4e5da5Sopenharmony_ci%171 = OpExtInst %void %1 DebugNoScope 1179fd4e5da5Sopenharmony_ciOpLoopMerge %160 %159 None 1180fd4e5da5Sopenharmony_ciOpBranch %151 1181fd4e5da5Sopenharmony_ci%151 = OpLabel 1182fd4e5da5Sopenharmony_ciOpLine %5 16 12 1183fd4e5da5Sopenharmony_ci%162 = OpExtInst %void %1 DebugValue %56 %9 %62 1184fd4e5da5Sopenharmony_ciOpLine %5 17 12 1185fd4e5da5Sopenharmony_ci%163 = OpExtInst %void %1 DebugValue %54 %13 %62 1186fd4e5da5Sopenharmony_ciOpLine %5 18 15 1187fd4e5da5Sopenharmony_ci%158 = OpFAdd %v4float %165 %13 1188fd4e5da5Sopenharmony_ciOpLine %5 18 5 1189fd4e5da5Sopenharmony_ci%166 = OpExtInst %void %1 DebugValue %59 %158 %62 1190fd4e5da5Sopenharmony_ci%172 = OpExtInst %void %1 DebugScope %37 1191fd4e5da5Sopenharmony_ciOpLine %5 19 3 1192fd4e5da5Sopenharmony_ciOpBranch %159 1193fd4e5da5Sopenharmony_ci%159 = OpLabel 1194fd4e5da5Sopenharmony_ciOpLine %5 19 3 1195fd4e5da5Sopenharmony_ciOpBranch %150 1196fd4e5da5Sopenharmony_ci%160 = OpLabel 1197fd4e5da5Sopenharmony_ciOpUnreachable 1198fd4e5da5Sopenharmony_ciOpFunctionEnd 1199fd4e5da5Sopenharmony_ci)"; 1200fd4e5da5Sopenharmony_ci 1201fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 1202fd4e5da5Sopenharmony_ci} 1203fd4e5da5Sopenharmony_ci 1204fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontLoseCaseConstruct) { 1205fd4e5da5Sopenharmony_ci const std::string text = R"( 1206fd4e5da5Sopenharmony_ciOpCapability Shader 1207fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1208fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %func "func" 1209fd4e5da5Sopenharmony_ciOpExecutionMode %func LocalSize 1 1 1 1210fd4e5da5Sopenharmony_ciOpName %entry "entry"; 1211fd4e5da5Sopenharmony_ciOpName %loop "loop" 1212fd4e5da5Sopenharmony_ciOpName %loop_merge "loop_merge" 1213fd4e5da5Sopenharmony_ciOpName %loop_cont "loop_cont" 1214fd4e5da5Sopenharmony_ciOpName %switch "switch" 1215fd4e5da5Sopenharmony_ciOpName %switch_merge "switch_merge" 1216fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1217fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1218fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1219fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1220fd4e5da5Sopenharmony_ci%bool_undef = OpUndef %bool 1221fd4e5da5Sopenharmony_ci%int_undef = OpUndef %int 1222fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1223fd4e5da5Sopenharmony_ci%entry = OpLabel 1224fd4e5da5Sopenharmony_ciOpBranch %loop 1225fd4e5da5Sopenharmony_ci%loop = OpLabel 1226fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %loop_cont None 1227fd4e5da5Sopenharmony_ciOpBranch %switch 1228fd4e5da5Sopenharmony_ci%switch = OpLabel 1229fd4e5da5Sopenharmony_ciOpSelectionMerge %switch_merge None 1230fd4e5da5Sopenharmony_ciOpSwitch %int_undef %switch_merge 0 %break 1 %break 1231fd4e5da5Sopenharmony_ci%break = OpLabel 1232fd4e5da5Sopenharmony_ciOpBranch %loop_merge 1233fd4e5da5Sopenharmony_ci%switch_merge = OpLabel 1234fd4e5da5Sopenharmony_ciOpBranch %loop_cont 1235fd4e5da5Sopenharmony_ci%loop_cont = OpLabel 1236fd4e5da5Sopenharmony_ciOpBranch %loop 1237fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 1238fd4e5da5Sopenharmony_ciOpReturn 1239fd4e5da5Sopenharmony_ciOpFunctionEnd 1240fd4e5da5Sopenharmony_ci)"; 1241fd4e5da5Sopenharmony_ci 1242fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::BlockMergePass>( 1243fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1244fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1245fd4e5da5Sopenharmony_ci} 1246fd4e5da5Sopenharmony_ci 1247fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, DontLoseDefaultCaseConstruct) { 1248fd4e5da5Sopenharmony_ci const std::string text = R"( 1249fd4e5da5Sopenharmony_ciOpCapability Shader 1250fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1251fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %func "func" 1252fd4e5da5Sopenharmony_ciOpExecutionMode %func LocalSize 1 1 1 1253fd4e5da5Sopenharmony_ciOpName %entry "entry"; 1254fd4e5da5Sopenharmony_ciOpName %loop "loop" 1255fd4e5da5Sopenharmony_ciOpName %loop_merge "loop_merge" 1256fd4e5da5Sopenharmony_ciOpName %loop_cont "loop_cont" 1257fd4e5da5Sopenharmony_ciOpName %switch "switch" 1258fd4e5da5Sopenharmony_ciOpName %switch_merge "switch_merge" 1259fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1260fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1261fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1262fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1263fd4e5da5Sopenharmony_ci%bool_undef = OpUndef %bool 1264fd4e5da5Sopenharmony_ci%int_undef = OpUndef %int 1265fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1266fd4e5da5Sopenharmony_ci%entry = OpLabel 1267fd4e5da5Sopenharmony_ciOpBranch %loop 1268fd4e5da5Sopenharmony_ci%loop = OpLabel 1269fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %loop_cont None 1270fd4e5da5Sopenharmony_ciOpBranch %switch 1271fd4e5da5Sopenharmony_ci%switch = OpLabel 1272fd4e5da5Sopenharmony_ciOpSelectionMerge %switch_merge None 1273fd4e5da5Sopenharmony_ciOpSwitch %int_undef %cont 0 %switch_merge 1 %switch_merge 1274fd4e5da5Sopenharmony_ci%cont = OpLabel 1275fd4e5da5Sopenharmony_ciOpBranch %loop_cont 1276fd4e5da5Sopenharmony_ci%switch_merge = OpLabel 1277fd4e5da5Sopenharmony_ciOpBranch %loop_merge 1278fd4e5da5Sopenharmony_ci%loop_cont = OpLabel 1279fd4e5da5Sopenharmony_ciOpBranch %loop 1280fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 1281fd4e5da5Sopenharmony_ciOpReturn 1282fd4e5da5Sopenharmony_ciOpFunctionEnd 1283fd4e5da5Sopenharmony_ci)"; 1284fd4e5da5Sopenharmony_ci 1285fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::BlockMergePass>( 1286fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1287fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1288fd4e5da5Sopenharmony_ci} 1289fd4e5da5Sopenharmony_ci 1290fd4e5da5Sopenharmony_ciTEST_F(BlockMergeTest, RebuildStructuredCFG) { 1291fd4e5da5Sopenharmony_ci const std::string text = R"( 1292fd4e5da5Sopenharmony_ci; CHECK: = OpFunction 1293fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[entry:%\w+]] = OpLabel 1294fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]] None 1295fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSwitch {{%\w+}} [[merge]] 0 [[other:%\w+]] 1296fd4e5da5Sopenharmony_ci; CHECK [[other]] = OpLabel 1297fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[merge]] 1298fd4e5da5Sopenharmony_ci; CHECK [[merge]] = OpLabel 1299fd4e5da5Sopenharmony_ciOpCapability Shader 1300fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1301fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1302fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 1303fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1304fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1305fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1306fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1307fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 1308fd4e5da5Sopenharmony_ci%entry = OpLabel 1309fd4e5da5Sopenharmony_ciOpBranch %switch 1310fd4e5da5Sopenharmony_ci%switch = OpLabel 1311fd4e5da5Sopenharmony_ciOpSelectionMerge %merge None 1312fd4e5da5Sopenharmony_ciOpSwitch %int_1 %merge 0 %other 1313fd4e5da5Sopenharmony_ci%other = OpLabel 1314fd4e5da5Sopenharmony_ciOpBranch %merge 1315fd4e5da5Sopenharmony_ci%merge = OpLabel 1316fd4e5da5Sopenharmony_ciOpReturn 1317fd4e5da5Sopenharmony_ciOpFunctionEnd 1318fd4e5da5Sopenharmony_ci)"; 1319fd4e5da5Sopenharmony_ci 1320fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<BlockMergePass>(text, true); 1321fd4e5da5Sopenharmony_ci} 1322fd4e5da5Sopenharmony_ci 1323fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases: 1324fd4e5da5Sopenharmony_ci// 1325fd4e5da5Sopenharmony_ci// More complex control flow 1326fd4e5da5Sopenharmony_ci// Others? 1327fd4e5da5Sopenharmony_ci 1328fd4e5da5Sopenharmony_ci} // namespace 1329fd4e5da5Sopenharmony_ci} // namespace opt 1330fd4e5da5Sopenharmony_ci} // namespace spvtools 1331