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 DeadBranchElimTest = PassTest<::testing::Test>; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenElseTrue) { 28fd4e5da5Sopenharmony_ci // #version 140 29fd4e5da5Sopenharmony_ci // 30fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 31fd4e5da5Sopenharmony_ci // 32fd4e5da5Sopenharmony_ci // void main() 33fd4e5da5Sopenharmony_ci // { 34fd4e5da5Sopenharmony_ci // vec4 v; 35fd4e5da5Sopenharmony_ci // if (true) 36fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 37fd4e5da5Sopenharmony_ci // else 38fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 39fd4e5da5Sopenharmony_ci // gl_FragColor = v; 40fd4e5da5Sopenharmony_ci // } 41fd4e5da5Sopenharmony_ci 42fd4e5da5Sopenharmony_ci const std::string predefs = 43fd4e5da5Sopenharmony_ci R"(OpCapability Shader 44fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 45fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 46fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor 47fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 48fd4e5da5Sopenharmony_ciOpSource GLSL 140 49fd4e5da5Sopenharmony_ciOpName %main "main" 50fd4e5da5Sopenharmony_ciOpName %v "v" 51fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 52fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 53fd4e5da5Sopenharmony_ci%void = OpTypeVoid 54fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 55fd4e5da5Sopenharmony_ci%bool = OpTypeBool 56fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 57fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 58fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 59fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 60fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 61fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 62fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 63fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 64fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 65fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 66fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 67fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 68fd4e5da5Sopenharmony_ci)"; 69fd4e5da5Sopenharmony_ci 70fd4e5da5Sopenharmony_ci const std::string before = 71fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 72fd4e5da5Sopenharmony_ci%19 = OpLabel 73fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 74fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 75fd4e5da5Sopenharmony_ciOpBranchConditional %true %21 %22 76fd4e5da5Sopenharmony_ci%21 = OpLabel 77fd4e5da5Sopenharmony_ciOpStore %v %14 78fd4e5da5Sopenharmony_ciOpBranch %20 79fd4e5da5Sopenharmony_ci%22 = OpLabel 80fd4e5da5Sopenharmony_ciOpStore %v %16 81fd4e5da5Sopenharmony_ciOpBranch %20 82fd4e5da5Sopenharmony_ci%20 = OpLabel 83fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 84fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 85fd4e5da5Sopenharmony_ciOpReturn 86fd4e5da5Sopenharmony_ciOpFunctionEnd 87fd4e5da5Sopenharmony_ci)"; 88fd4e5da5Sopenharmony_ci 89fd4e5da5Sopenharmony_ci const std::string after = 90fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 91fd4e5da5Sopenharmony_ci%19 = OpLabel 92fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 93fd4e5da5Sopenharmony_ciOpBranch %21 94fd4e5da5Sopenharmony_ci%21 = OpLabel 95fd4e5da5Sopenharmony_ciOpStore %v %14 96fd4e5da5Sopenharmony_ciOpBranch %20 97fd4e5da5Sopenharmony_ci%20 = OpLabel 98fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 99fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 100fd4e5da5Sopenharmony_ciOpReturn 101fd4e5da5Sopenharmony_ciOpFunctionEnd 102fd4e5da5Sopenharmony_ci)"; 103fd4e5da5Sopenharmony_ci 104fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 105fd4e5da5Sopenharmony_ci true, true); 106fd4e5da5Sopenharmony_ci} 107fd4e5da5Sopenharmony_ci 108fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenElseFalse) { 109fd4e5da5Sopenharmony_ci // #version 140 110fd4e5da5Sopenharmony_ci // 111fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 112fd4e5da5Sopenharmony_ci // 113fd4e5da5Sopenharmony_ci // void main() 114fd4e5da5Sopenharmony_ci // { 115fd4e5da5Sopenharmony_ci // vec4 v; 116fd4e5da5Sopenharmony_ci // if (false) 117fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 118fd4e5da5Sopenharmony_ci // else 119fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 120fd4e5da5Sopenharmony_ci // gl_FragColor = v; 121fd4e5da5Sopenharmony_ci // } 122fd4e5da5Sopenharmony_ci 123fd4e5da5Sopenharmony_ci const std::string predefs = 124fd4e5da5Sopenharmony_ci R"(OpCapability Shader 125fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 126fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 127fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor 128fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 129fd4e5da5Sopenharmony_ciOpSource GLSL 140 130fd4e5da5Sopenharmony_ciOpName %main "main" 131fd4e5da5Sopenharmony_ciOpName %v "v" 132fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 133fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 134fd4e5da5Sopenharmony_ci%void = OpTypeVoid 135fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 136fd4e5da5Sopenharmony_ci%bool = OpTypeBool 137fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 138fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 139fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 140fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 141fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 142fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 143fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 144fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 145fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 146fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 147fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 148fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 149fd4e5da5Sopenharmony_ci)"; 150fd4e5da5Sopenharmony_ci 151fd4e5da5Sopenharmony_ci const std::string before = 152fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 153fd4e5da5Sopenharmony_ci%19 = OpLabel 154fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 155fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 156fd4e5da5Sopenharmony_ciOpBranchConditional %false %21 %22 157fd4e5da5Sopenharmony_ci%21 = OpLabel 158fd4e5da5Sopenharmony_ciOpStore %v %14 159fd4e5da5Sopenharmony_ciOpBranch %20 160fd4e5da5Sopenharmony_ci%22 = OpLabel 161fd4e5da5Sopenharmony_ciOpStore %v %16 162fd4e5da5Sopenharmony_ciOpBranch %20 163fd4e5da5Sopenharmony_ci%20 = OpLabel 164fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 165fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 166fd4e5da5Sopenharmony_ciOpReturn 167fd4e5da5Sopenharmony_ciOpFunctionEnd 168fd4e5da5Sopenharmony_ci)"; 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ci const std::string after = 171fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 172fd4e5da5Sopenharmony_ci%19 = OpLabel 173fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 174fd4e5da5Sopenharmony_ciOpBranch %22 175fd4e5da5Sopenharmony_ci%22 = OpLabel 176fd4e5da5Sopenharmony_ciOpStore %v %16 177fd4e5da5Sopenharmony_ciOpBranch %20 178fd4e5da5Sopenharmony_ci%20 = OpLabel 179fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 180fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 181fd4e5da5Sopenharmony_ciOpReturn 182fd4e5da5Sopenharmony_ciOpFunctionEnd 183fd4e5da5Sopenharmony_ci)"; 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 186fd4e5da5Sopenharmony_ci true, true); 187fd4e5da5Sopenharmony_ci} 188fd4e5da5Sopenharmony_ci 189fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenElseNull) { 190fd4e5da5Sopenharmony_ci // For booleans OpConstantNull should be treated similar to OpConstantFalse. 191fd4e5da5Sopenharmony_ci // 192fd4e5da5Sopenharmony_ci // From the SPIR-V spec: 193fd4e5da5Sopenharmony_ci // OpConstantNull: Declares a new null constant value. 194fd4e5da5Sopenharmony_ci // The null value is type dependent, defined as follows: 195fd4e5da5Sopenharmony_ci // - Scalar Boolean: false 196fd4e5da5Sopenharmony_ci // ... 197fd4e5da5Sopenharmony_ci 198fd4e5da5Sopenharmony_ci const std::string predefs = 199fd4e5da5Sopenharmony_ci R"(OpCapability Shader 200fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 201fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 202fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor 203fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 204fd4e5da5Sopenharmony_ciOpSource GLSL 140 205fd4e5da5Sopenharmony_ciOpName %main "main" 206fd4e5da5Sopenharmony_ciOpName %v "v" 207fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 208fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 209fd4e5da5Sopenharmony_ci%void = OpTypeVoid 210fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 211fd4e5da5Sopenharmony_ci%bool = OpTypeBool 212fd4e5da5Sopenharmony_ci%9 = OpConstantNull %bool 213fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 214fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 215fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 216fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 217fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 218fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 219fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 220fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 221fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 222fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 223fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 224fd4e5da5Sopenharmony_ci)"; 225fd4e5da5Sopenharmony_ci 226fd4e5da5Sopenharmony_ci const std::string before = 227fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 228fd4e5da5Sopenharmony_ci%19 = OpLabel 229fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 230fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 231fd4e5da5Sopenharmony_ciOpBranchConditional %9 %21 %22 232fd4e5da5Sopenharmony_ci%21 = OpLabel 233fd4e5da5Sopenharmony_ciOpStore %v %14 234fd4e5da5Sopenharmony_ciOpBranch %20 235fd4e5da5Sopenharmony_ci%22 = OpLabel 236fd4e5da5Sopenharmony_ciOpStore %v %16 237fd4e5da5Sopenharmony_ciOpBranch %20 238fd4e5da5Sopenharmony_ci%20 = OpLabel 239fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 240fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 241fd4e5da5Sopenharmony_ciOpReturn 242fd4e5da5Sopenharmony_ciOpFunctionEnd 243fd4e5da5Sopenharmony_ci)"; 244fd4e5da5Sopenharmony_ci 245fd4e5da5Sopenharmony_ci const std::string after = 246fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 247fd4e5da5Sopenharmony_ci%19 = OpLabel 248fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 249fd4e5da5Sopenharmony_ciOpBranch %22 250fd4e5da5Sopenharmony_ci%22 = OpLabel 251fd4e5da5Sopenharmony_ciOpStore %v %16 252fd4e5da5Sopenharmony_ciOpBranch %20 253fd4e5da5Sopenharmony_ci%20 = OpLabel 254fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 255fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 256fd4e5da5Sopenharmony_ciOpReturn 257fd4e5da5Sopenharmony_ciOpFunctionEnd 258fd4e5da5Sopenharmony_ci)"; 259fd4e5da5Sopenharmony_ci 260fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 261fd4e5da5Sopenharmony_ci true, true); 262fd4e5da5Sopenharmony_ci} 263fd4e5da5Sopenharmony_ci 264fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenTrue) { 265fd4e5da5Sopenharmony_ci // #version 140 266fd4e5da5Sopenharmony_ci // 267fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 268fd4e5da5Sopenharmony_ci // 269fd4e5da5Sopenharmony_ci // void main() 270fd4e5da5Sopenharmony_ci // { 271fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 272fd4e5da5Sopenharmony_ci // if (true) 273fd4e5da5Sopenharmony_ci // v = v * vec4(0.5,0.5,0.5,0.5); 274fd4e5da5Sopenharmony_ci // gl_FragColor = v; 275fd4e5da5Sopenharmony_ci // } 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ci const std::string predefs = 278fd4e5da5Sopenharmony_ci R"(OpCapability Shader 279fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 280fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 281fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 282fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 283fd4e5da5Sopenharmony_ciOpSource GLSL 140 284fd4e5da5Sopenharmony_ciOpName %main "main" 285fd4e5da5Sopenharmony_ciOpName %v "v" 286fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 287fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 288fd4e5da5Sopenharmony_ci%void = OpTypeVoid 289fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 290fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 291fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 292fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 293fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 294fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 295fd4e5da5Sopenharmony_ci%bool = OpTypeBool 296fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 297fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 298fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 299fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 300fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 301fd4e5da5Sopenharmony_ci)"; 302fd4e5da5Sopenharmony_ci 303fd4e5da5Sopenharmony_ci const std::string before = 304fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 305fd4e5da5Sopenharmony_ci%17 = OpLabel 306fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 307fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 308fd4e5da5Sopenharmony_ciOpStore %v %18 309fd4e5da5Sopenharmony_ciOpSelectionMerge %19 None 310fd4e5da5Sopenharmony_ciOpBranchConditional %true %20 %19 311fd4e5da5Sopenharmony_ci%20 = OpLabel 312fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %v 313fd4e5da5Sopenharmony_ci%22 = OpFMul %v4float %21 %15 314fd4e5da5Sopenharmony_ciOpStore %v %22 315fd4e5da5Sopenharmony_ciOpBranch %19 316fd4e5da5Sopenharmony_ci%19 = OpLabel 317fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 318fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 319fd4e5da5Sopenharmony_ciOpReturn 320fd4e5da5Sopenharmony_ciOpFunctionEnd 321fd4e5da5Sopenharmony_ci)"; 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ci const std::string after = 324fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 325fd4e5da5Sopenharmony_ci%17 = OpLabel 326fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 327fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 328fd4e5da5Sopenharmony_ciOpStore %v %18 329fd4e5da5Sopenharmony_ciOpBranch %20 330fd4e5da5Sopenharmony_ci%20 = OpLabel 331fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %v 332fd4e5da5Sopenharmony_ci%22 = OpFMul %v4float %21 %15 333fd4e5da5Sopenharmony_ciOpStore %v %22 334fd4e5da5Sopenharmony_ciOpBranch %19 335fd4e5da5Sopenharmony_ci%19 = OpLabel 336fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 337fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 338fd4e5da5Sopenharmony_ciOpReturn 339fd4e5da5Sopenharmony_ciOpFunctionEnd 340fd4e5da5Sopenharmony_ci)"; 341fd4e5da5Sopenharmony_ci 342fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 343fd4e5da5Sopenharmony_ci true, true); 344fd4e5da5Sopenharmony_ci} 345fd4e5da5Sopenharmony_ci 346fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenFalse) { 347fd4e5da5Sopenharmony_ci // #version 140 348fd4e5da5Sopenharmony_ci // 349fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 350fd4e5da5Sopenharmony_ci // 351fd4e5da5Sopenharmony_ci // void main() 352fd4e5da5Sopenharmony_ci // { 353fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 354fd4e5da5Sopenharmony_ci // if (false) 355fd4e5da5Sopenharmony_ci // v = v * vec4(0.5,0.5,0.5,0.5); 356fd4e5da5Sopenharmony_ci // gl_FragColor = v; 357fd4e5da5Sopenharmony_ci // } 358fd4e5da5Sopenharmony_ci 359fd4e5da5Sopenharmony_ci const std::string predefs = 360fd4e5da5Sopenharmony_ci R"(OpCapability Shader 361fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 362fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 363fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 364fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 365fd4e5da5Sopenharmony_ciOpSource GLSL 140 366fd4e5da5Sopenharmony_ciOpName %main "main" 367fd4e5da5Sopenharmony_ciOpName %v "v" 368fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 369fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 370fd4e5da5Sopenharmony_ci%void = OpTypeVoid 371fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 372fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 373fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 374fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 375fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 376fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 377fd4e5da5Sopenharmony_ci%bool = OpTypeBool 378fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 379fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 380fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 381fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 382fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 383fd4e5da5Sopenharmony_ci)"; 384fd4e5da5Sopenharmony_ci 385fd4e5da5Sopenharmony_ci const std::string before = 386fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 387fd4e5da5Sopenharmony_ci%17 = OpLabel 388fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 389fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 390fd4e5da5Sopenharmony_ciOpStore %v %18 391fd4e5da5Sopenharmony_ciOpSelectionMerge %19 None 392fd4e5da5Sopenharmony_ciOpBranchConditional %false %20 %19 393fd4e5da5Sopenharmony_ci%20 = OpLabel 394fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %v 395fd4e5da5Sopenharmony_ci%22 = OpFMul %v4float %21 %15 396fd4e5da5Sopenharmony_ciOpStore %v %22 397fd4e5da5Sopenharmony_ciOpBranch %19 398fd4e5da5Sopenharmony_ci%19 = OpLabel 399fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 400fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 401fd4e5da5Sopenharmony_ciOpReturn 402fd4e5da5Sopenharmony_ciOpFunctionEnd 403fd4e5da5Sopenharmony_ci)"; 404fd4e5da5Sopenharmony_ci 405fd4e5da5Sopenharmony_ci const std::string after = 406fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 407fd4e5da5Sopenharmony_ci%17 = OpLabel 408fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 409fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 410fd4e5da5Sopenharmony_ciOpStore %v %18 411fd4e5da5Sopenharmony_ciOpBranch %19 412fd4e5da5Sopenharmony_ci%19 = OpLabel 413fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 414fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 415fd4e5da5Sopenharmony_ciOpReturn 416fd4e5da5Sopenharmony_ciOpFunctionEnd 417fd4e5da5Sopenharmony_ci)"; 418fd4e5da5Sopenharmony_ci 419fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 420fd4e5da5Sopenharmony_ci true, true); 421fd4e5da5Sopenharmony_ci} 422fd4e5da5Sopenharmony_ci 423fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenElsePhiTrue) { 424fd4e5da5Sopenharmony_ci // Test handling of phi in merge block after dead branch elimination. 425fd4e5da5Sopenharmony_ci // Note: The SPIR-V has had store/load elimination and phi insertion 426fd4e5da5Sopenharmony_ci // 427fd4e5da5Sopenharmony_ci // #version 140 428fd4e5da5Sopenharmony_ci // 429fd4e5da5Sopenharmony_ci // void main() 430fd4e5da5Sopenharmony_ci // { 431fd4e5da5Sopenharmony_ci // vec4 v; 432fd4e5da5Sopenharmony_ci // if (true) 433fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 434fd4e5da5Sopenharmony_ci // else 435fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 436fd4e5da5Sopenharmony_ci // gl_FragColor = v; 437fd4e5da5Sopenharmony_ci // } 438fd4e5da5Sopenharmony_ci 439fd4e5da5Sopenharmony_ci const std::string predefs = 440fd4e5da5Sopenharmony_ci R"(OpCapability Shader 441fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 442fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 443fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor 444fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 445fd4e5da5Sopenharmony_ciOpSource GLSL 140 446fd4e5da5Sopenharmony_ciOpName %main "main" 447fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 448fd4e5da5Sopenharmony_ci%void = OpTypeVoid 449fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 450fd4e5da5Sopenharmony_ci%bool = OpTypeBool 451fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 452fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 453fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 454fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 455fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 456fd4e5da5Sopenharmony_ci%12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 457fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 458fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 459fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 460fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 461fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 462fd4e5da5Sopenharmony_ci)"; 463fd4e5da5Sopenharmony_ci 464fd4e5da5Sopenharmony_ci const std::string before = 465fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %5 466fd4e5da5Sopenharmony_ci%17 = OpLabel 467fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 468fd4e5da5Sopenharmony_ciOpBranchConditional %true %19 %20 469fd4e5da5Sopenharmony_ci%19 = OpLabel 470fd4e5da5Sopenharmony_ciOpBranch %18 471fd4e5da5Sopenharmony_ci%20 = OpLabel 472fd4e5da5Sopenharmony_ciOpBranch %18 473fd4e5da5Sopenharmony_ci%18 = OpLabel 474fd4e5da5Sopenharmony_ci%21 = OpPhi %v4float %12 %19 %14 %20 475fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 476fd4e5da5Sopenharmony_ciOpReturn 477fd4e5da5Sopenharmony_ciOpFunctionEnd 478fd4e5da5Sopenharmony_ci)"; 479fd4e5da5Sopenharmony_ci 480fd4e5da5Sopenharmony_ci const std::string after = 481fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %5 482fd4e5da5Sopenharmony_ci%17 = OpLabel 483fd4e5da5Sopenharmony_ciOpBranch %19 484fd4e5da5Sopenharmony_ci%19 = OpLabel 485fd4e5da5Sopenharmony_ciOpBranch %18 486fd4e5da5Sopenharmony_ci%18 = OpLabel 487fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %12 488fd4e5da5Sopenharmony_ciOpReturn 489fd4e5da5Sopenharmony_ciOpFunctionEnd 490fd4e5da5Sopenharmony_ci)"; 491fd4e5da5Sopenharmony_ci 492fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 493fd4e5da5Sopenharmony_ci true, true); 494fd4e5da5Sopenharmony_ci} 495fd4e5da5Sopenharmony_ci 496fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfThenElsePhiFalse) { 497fd4e5da5Sopenharmony_ci // Test handling of phi in merge block after dead branch elimination. 498fd4e5da5Sopenharmony_ci // Note: The SPIR-V has had store/load elimination and phi insertion 499fd4e5da5Sopenharmony_ci // 500fd4e5da5Sopenharmony_ci // #version 140 501fd4e5da5Sopenharmony_ci // 502fd4e5da5Sopenharmony_ci // void main() 503fd4e5da5Sopenharmony_ci // { 504fd4e5da5Sopenharmony_ci // vec4 v; 505fd4e5da5Sopenharmony_ci // if (true) 506fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 507fd4e5da5Sopenharmony_ci // else 508fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 509fd4e5da5Sopenharmony_ci // gl_FragColor = v; 510fd4e5da5Sopenharmony_ci // } 511fd4e5da5Sopenharmony_ci 512fd4e5da5Sopenharmony_ci const std::string predefs = 513fd4e5da5Sopenharmony_ci R"(OpCapability Shader 514fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 515fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 516fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor 517fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 518fd4e5da5Sopenharmony_ciOpSource GLSL 140 519fd4e5da5Sopenharmony_ciOpName %main "main" 520fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 521fd4e5da5Sopenharmony_ci%void = OpTypeVoid 522fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 523fd4e5da5Sopenharmony_ci%bool = OpTypeBool 524fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 525fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 526fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 527fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 528fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 529fd4e5da5Sopenharmony_ci%12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 530fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 531fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 532fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 533fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 534fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 535fd4e5da5Sopenharmony_ci)"; 536fd4e5da5Sopenharmony_ci 537fd4e5da5Sopenharmony_ci const std::string before = 538fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %5 539fd4e5da5Sopenharmony_ci%17 = OpLabel 540fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 541fd4e5da5Sopenharmony_ciOpBranchConditional %false %19 %20 542fd4e5da5Sopenharmony_ci%19 = OpLabel 543fd4e5da5Sopenharmony_ciOpBranch %18 544fd4e5da5Sopenharmony_ci%20 = OpLabel 545fd4e5da5Sopenharmony_ciOpBranch %18 546fd4e5da5Sopenharmony_ci%18 = OpLabel 547fd4e5da5Sopenharmony_ci%21 = OpPhi %v4float %12 %19 %14 %20 548fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 549fd4e5da5Sopenharmony_ciOpReturn 550fd4e5da5Sopenharmony_ciOpFunctionEnd 551fd4e5da5Sopenharmony_ci)"; 552fd4e5da5Sopenharmony_ci 553fd4e5da5Sopenharmony_ci const std::string after = 554fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %5 555fd4e5da5Sopenharmony_ci%17 = OpLabel 556fd4e5da5Sopenharmony_ciOpBranch %20 557fd4e5da5Sopenharmony_ci%20 = OpLabel 558fd4e5da5Sopenharmony_ciOpBranch %18 559fd4e5da5Sopenharmony_ci%18 = OpLabel 560fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %14 561fd4e5da5Sopenharmony_ciOpReturn 562fd4e5da5Sopenharmony_ciOpFunctionEnd 563fd4e5da5Sopenharmony_ci)"; 564fd4e5da5Sopenharmony_ci 565fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 566fd4e5da5Sopenharmony_ci true, true); 567fd4e5da5Sopenharmony_ci} 568fd4e5da5Sopenharmony_ci 569fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, CompoundIfThenElseFalse) { 570fd4e5da5Sopenharmony_ci // #version 140 571fd4e5da5Sopenharmony_ci // 572fd4e5da5Sopenharmony_ci // layout(std140) uniform U_t 573fd4e5da5Sopenharmony_ci // { 574fd4e5da5Sopenharmony_ci // bool g_B ; 575fd4e5da5Sopenharmony_ci // } ; 576fd4e5da5Sopenharmony_ci // 577fd4e5da5Sopenharmony_ci // void main() 578fd4e5da5Sopenharmony_ci // { 579fd4e5da5Sopenharmony_ci // vec4 v; 580fd4e5da5Sopenharmony_ci // if (false) { 581fd4e5da5Sopenharmony_ci // if (g_B) 582fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 583fd4e5da5Sopenharmony_ci // else 584fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 585fd4e5da5Sopenharmony_ci // } else { 586fd4e5da5Sopenharmony_ci // if (g_B) 587fd4e5da5Sopenharmony_ci // v = vec4(1.0,1.0,1.0,1.0); 588fd4e5da5Sopenharmony_ci // else 589fd4e5da5Sopenharmony_ci // v = vec4(0.0,0.0,0.0,0.0); 590fd4e5da5Sopenharmony_ci // } 591fd4e5da5Sopenharmony_ci // gl_FragColor = v; 592fd4e5da5Sopenharmony_ci // } 593fd4e5da5Sopenharmony_ci 594fd4e5da5Sopenharmony_ci const std::string predefs = 595fd4e5da5Sopenharmony_ci R"(OpCapability Shader 596fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 597fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 598fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor 599fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 600fd4e5da5Sopenharmony_ciOpSource GLSL 140 601fd4e5da5Sopenharmony_ciOpName %main "main" 602fd4e5da5Sopenharmony_ciOpName %U_t "U_t" 603fd4e5da5Sopenharmony_ciOpMemberName %U_t 0 "g_B" 604fd4e5da5Sopenharmony_ciOpName %_ "" 605fd4e5da5Sopenharmony_ciOpName %v "v" 606fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 607fd4e5da5Sopenharmony_ciOpMemberDecorate %U_t 0 Offset 0 608fd4e5da5Sopenharmony_ciOpDecorate %U_t Block 609fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0 610fd4e5da5Sopenharmony_ci%void = OpTypeVoid 611fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 612fd4e5da5Sopenharmony_ci%bool = OpTypeBool 613fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 614fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 615fd4e5da5Sopenharmony_ci%U_t = OpTypeStruct %uint 616fd4e5da5Sopenharmony_ci%_ptr_Uniform_U_t = OpTypePointer Uniform %U_t 617fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform_U_t Uniform 618fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 619fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 620fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint 621fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 622fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 623fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 624fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 625fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 626fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 627fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 628fd4e5da5Sopenharmony_ci%23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 629fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 630fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 631fd4e5da5Sopenharmony_ci)"; 632fd4e5da5Sopenharmony_ci 633fd4e5da5Sopenharmony_ci const std::string before = 634fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %8 635fd4e5da5Sopenharmony_ci%25 = OpLabel 636fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 637fd4e5da5Sopenharmony_ciOpSelectionMerge %26 None 638fd4e5da5Sopenharmony_ciOpBranchConditional %false %27 %28 639fd4e5da5Sopenharmony_ci%27 = OpLabel 640fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 641fd4e5da5Sopenharmony_ci%30 = OpLoad %uint %29 642fd4e5da5Sopenharmony_ci%31 = OpINotEqual %bool %30 %uint_0 643fd4e5da5Sopenharmony_ciOpSelectionMerge %32 None 644fd4e5da5Sopenharmony_ciOpBranchConditional %31 %33 %34 645fd4e5da5Sopenharmony_ci%33 = OpLabel 646fd4e5da5Sopenharmony_ciOpStore %v %21 647fd4e5da5Sopenharmony_ciOpBranch %32 648fd4e5da5Sopenharmony_ci%34 = OpLabel 649fd4e5da5Sopenharmony_ciOpStore %v %23 650fd4e5da5Sopenharmony_ciOpBranch %32 651fd4e5da5Sopenharmony_ci%32 = OpLabel 652fd4e5da5Sopenharmony_ciOpBranch %26 653fd4e5da5Sopenharmony_ci%28 = OpLabel 654fd4e5da5Sopenharmony_ci%35 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 655fd4e5da5Sopenharmony_ci%36 = OpLoad %uint %35 656fd4e5da5Sopenharmony_ci%37 = OpINotEqual %bool %36 %uint_0 657fd4e5da5Sopenharmony_ciOpSelectionMerge %38 None 658fd4e5da5Sopenharmony_ciOpBranchConditional %37 %39 %40 659fd4e5da5Sopenharmony_ci%39 = OpLabel 660fd4e5da5Sopenharmony_ciOpStore %v %23 661fd4e5da5Sopenharmony_ciOpBranch %38 662fd4e5da5Sopenharmony_ci%40 = OpLabel 663fd4e5da5Sopenharmony_ciOpStore %v %21 664fd4e5da5Sopenharmony_ciOpBranch %38 665fd4e5da5Sopenharmony_ci%38 = OpLabel 666fd4e5da5Sopenharmony_ciOpBranch %26 667fd4e5da5Sopenharmony_ci%26 = OpLabel 668fd4e5da5Sopenharmony_ci%41 = OpLoad %v4float %v 669fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %41 670fd4e5da5Sopenharmony_ciOpReturn 671fd4e5da5Sopenharmony_ciOpFunctionEnd 672fd4e5da5Sopenharmony_ci)"; 673fd4e5da5Sopenharmony_ci 674fd4e5da5Sopenharmony_ci const std::string after = 675fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %8 676fd4e5da5Sopenharmony_ci%25 = OpLabel 677fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 678fd4e5da5Sopenharmony_ciOpBranch %28 679fd4e5da5Sopenharmony_ci%28 = OpLabel 680fd4e5da5Sopenharmony_ci%35 = OpAccessChain %_ptr_Uniform_uint %_ %int_0 681fd4e5da5Sopenharmony_ci%36 = OpLoad %uint %35 682fd4e5da5Sopenharmony_ci%37 = OpINotEqual %bool %36 %uint_0 683fd4e5da5Sopenharmony_ciOpSelectionMerge %38 None 684fd4e5da5Sopenharmony_ciOpBranchConditional %37 %39 %40 685fd4e5da5Sopenharmony_ci%40 = OpLabel 686fd4e5da5Sopenharmony_ciOpStore %v %21 687fd4e5da5Sopenharmony_ciOpBranch %38 688fd4e5da5Sopenharmony_ci%39 = OpLabel 689fd4e5da5Sopenharmony_ciOpStore %v %23 690fd4e5da5Sopenharmony_ciOpBranch %38 691fd4e5da5Sopenharmony_ci%38 = OpLabel 692fd4e5da5Sopenharmony_ciOpBranch %26 693fd4e5da5Sopenharmony_ci%26 = OpLabel 694fd4e5da5Sopenharmony_ci%41 = OpLoad %v4float %v 695fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %41 696fd4e5da5Sopenharmony_ciOpReturn 697fd4e5da5Sopenharmony_ciOpFunctionEnd 698fd4e5da5Sopenharmony_ci)"; 699fd4e5da5Sopenharmony_ci 700fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 701fd4e5da5Sopenharmony_ci true, true); 702fd4e5da5Sopenharmony_ci} 703fd4e5da5Sopenharmony_ci 704fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, PreventOrphanMerge) { 705fd4e5da5Sopenharmony_ci const std::string predefs = 706fd4e5da5Sopenharmony_ci R"(OpCapability Shader 707fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 708fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 709fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 710fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 711fd4e5da5Sopenharmony_ciOpSource GLSL 140 712fd4e5da5Sopenharmony_ciOpName %main "main" 713fd4e5da5Sopenharmony_ciOpName %v "v" 714fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 715fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 716fd4e5da5Sopenharmony_ci%void = OpTypeVoid 717fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 718fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 719fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 720fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 721fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 722fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 723fd4e5da5Sopenharmony_ci%bool = OpTypeBool 724fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 725fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 726fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 727fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 728fd4e5da5Sopenharmony_ci)"; 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ci const std::string before = 731fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 732fd4e5da5Sopenharmony_ci%16 = OpLabel 733fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 734fd4e5da5Sopenharmony_ci%17 = OpLoad %v4float %BaseColor 735fd4e5da5Sopenharmony_ciOpStore %v %17 736fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 737fd4e5da5Sopenharmony_ciOpBranchConditional %true %19 %20 738fd4e5da5Sopenharmony_ci%19 = OpLabel 739fd4e5da5Sopenharmony_ciOpKill 740fd4e5da5Sopenharmony_ci%20 = OpLabel 741fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %v 742fd4e5da5Sopenharmony_ci%22 = OpVectorTimesScalar %v4float %21 %float_0_5 743fd4e5da5Sopenharmony_ciOpStore %v %22 744fd4e5da5Sopenharmony_ciOpBranch %18 745fd4e5da5Sopenharmony_ci%18 = OpLabel 746fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 747fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 748fd4e5da5Sopenharmony_ciOpReturn 749fd4e5da5Sopenharmony_ciOpFunctionEnd 750fd4e5da5Sopenharmony_ci)"; 751fd4e5da5Sopenharmony_ci 752fd4e5da5Sopenharmony_ci const std::string after = 753fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 754fd4e5da5Sopenharmony_ci%16 = OpLabel 755fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 756fd4e5da5Sopenharmony_ci%17 = OpLoad %v4float %BaseColor 757fd4e5da5Sopenharmony_ciOpStore %v %17 758fd4e5da5Sopenharmony_ciOpBranch %19 759fd4e5da5Sopenharmony_ci%19 = OpLabel 760fd4e5da5Sopenharmony_ciOpKill 761fd4e5da5Sopenharmony_ciOpFunctionEnd 762fd4e5da5Sopenharmony_ci)"; 763fd4e5da5Sopenharmony_ci 764fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 765fd4e5da5Sopenharmony_ci true, true); 766fd4e5da5Sopenharmony_ci} 767fd4e5da5Sopenharmony_ci 768fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, HandleOrphanMerge) { 769fd4e5da5Sopenharmony_ci const std::string predefs = 770fd4e5da5Sopenharmony_ci R"(OpCapability Shader 771fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 772fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 773fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor 774fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 775fd4e5da5Sopenharmony_ciOpSource GLSL 140 776fd4e5da5Sopenharmony_ciOpName %main "main" 777fd4e5da5Sopenharmony_ciOpName %foo_ "foo(" 778fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 779fd4e5da5Sopenharmony_ciOpDecorate %gl_FragColor Location 0 780fd4e5da5Sopenharmony_ci%void = OpTypeVoid 781fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 782fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 783fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 784fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %v4float 785fd4e5da5Sopenharmony_ci%bool = OpTypeBool 786fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 787fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 788fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 789fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 790fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 791fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 792fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 793fd4e5da5Sopenharmony_ci%main = OpFunction %void None %6 794fd4e5da5Sopenharmony_ci%17 = OpLabel 795fd4e5da5Sopenharmony_ci%18 = OpFunctionCall %v4float %foo_ 796fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %18 797fd4e5da5Sopenharmony_ciOpReturn 798fd4e5da5Sopenharmony_ciOpFunctionEnd 799fd4e5da5Sopenharmony_ci)"; 800fd4e5da5Sopenharmony_ci 801fd4e5da5Sopenharmony_ci const std::string before = 802fd4e5da5Sopenharmony_ci R"(%foo_ = OpFunction %v4float None %9 803fd4e5da5Sopenharmony_ci%19 = OpLabel 804fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 805fd4e5da5Sopenharmony_ciOpBranchConditional %true %21 %22 806fd4e5da5Sopenharmony_ci%21 = OpLabel 807fd4e5da5Sopenharmony_ciOpReturnValue %13 808fd4e5da5Sopenharmony_ci%22 = OpLabel 809fd4e5da5Sopenharmony_ciOpReturnValue %15 810fd4e5da5Sopenharmony_ci%20 = OpLabel 811fd4e5da5Sopenharmony_ci%23 = OpUndef %v4float 812fd4e5da5Sopenharmony_ciOpReturnValue %23 813fd4e5da5Sopenharmony_ciOpFunctionEnd 814fd4e5da5Sopenharmony_ci)"; 815fd4e5da5Sopenharmony_ci 816fd4e5da5Sopenharmony_ci const std::string after = 817fd4e5da5Sopenharmony_ci R"(%foo_ = OpFunction %v4float None %9 818fd4e5da5Sopenharmony_ci%19 = OpLabel 819fd4e5da5Sopenharmony_ciOpBranch %21 820fd4e5da5Sopenharmony_ci%21 = OpLabel 821fd4e5da5Sopenharmony_ciOpReturnValue %13 822fd4e5da5Sopenharmony_ciOpFunctionEnd 823fd4e5da5Sopenharmony_ci)"; 824fd4e5da5Sopenharmony_ci 825fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 826fd4e5da5Sopenharmony_ci true, true); 827fd4e5da5Sopenharmony_ci} 828fd4e5da5Sopenharmony_ci 829fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, KeepContinueTargetWhenKillAfterMerge) { 830fd4e5da5Sopenharmony_ci // #version 450 831fd4e5da5Sopenharmony_ci // void main() { 832fd4e5da5Sopenharmony_ci // bool c; 833fd4e5da5Sopenharmony_ci // bool d; 834fd4e5da5Sopenharmony_ci // while(c) { 835fd4e5da5Sopenharmony_ci // if(d) { 836fd4e5da5Sopenharmony_ci // continue; 837fd4e5da5Sopenharmony_ci // } 838fd4e5da5Sopenharmony_ci // if(false) { 839fd4e5da5Sopenharmony_ci // continue; 840fd4e5da5Sopenharmony_ci // } 841fd4e5da5Sopenharmony_ci // discard; 842fd4e5da5Sopenharmony_ci // } 843fd4e5da5Sopenharmony_ci // } 844fd4e5da5Sopenharmony_ci 845fd4e5da5Sopenharmony_ci const std::string predefs = 846fd4e5da5Sopenharmony_ci R"(OpCapability Shader 847fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 848fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 849fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 850fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 851fd4e5da5Sopenharmony_ciOpSource GLSL 450 852fd4e5da5Sopenharmony_ciOpName %main "main" 853fd4e5da5Sopenharmony_ciOpName %c "c" 854fd4e5da5Sopenharmony_ciOpName %d "d" 855fd4e5da5Sopenharmony_ci%void = OpTypeVoid 856fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 857fd4e5da5Sopenharmony_ci%bool = OpTypeBool 858fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 859fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 860fd4e5da5Sopenharmony_ci)"; 861fd4e5da5Sopenharmony_ci 862fd4e5da5Sopenharmony_ci const std::string before = 863fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 864fd4e5da5Sopenharmony_ci%10 = OpLabel 865fd4e5da5Sopenharmony_ci%c = OpVariable %_ptr_Function_bool Function 866fd4e5da5Sopenharmony_ci%d = OpVariable %_ptr_Function_bool Function 867fd4e5da5Sopenharmony_ciOpBranch %11 868fd4e5da5Sopenharmony_ci%11 = OpLabel 869fd4e5da5Sopenharmony_ciOpLoopMerge %12 %13 None 870fd4e5da5Sopenharmony_ciOpBranch %14 871fd4e5da5Sopenharmony_ci%14 = OpLabel 872fd4e5da5Sopenharmony_ci%15 = OpLoad %bool %c 873fd4e5da5Sopenharmony_ciOpBranchConditional %15 %16 %12 874fd4e5da5Sopenharmony_ci%16 = OpLabel 875fd4e5da5Sopenharmony_ci%17 = OpLoad %bool %d 876fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 877fd4e5da5Sopenharmony_ciOpBranchConditional %17 %19 %18 878fd4e5da5Sopenharmony_ci%19 = OpLabel 879fd4e5da5Sopenharmony_ciOpBranch %13 880fd4e5da5Sopenharmony_ci%18 = OpLabel 881fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 882fd4e5da5Sopenharmony_ciOpBranchConditional %false %21 %20 883fd4e5da5Sopenharmony_ci%21 = OpLabel 884fd4e5da5Sopenharmony_ciOpBranch %13 885fd4e5da5Sopenharmony_ci%20 = OpLabel 886fd4e5da5Sopenharmony_ciOpKill 887fd4e5da5Sopenharmony_ci%13 = OpLabel 888fd4e5da5Sopenharmony_ciOpBranch %11 889fd4e5da5Sopenharmony_ci%12 = OpLabel 890fd4e5da5Sopenharmony_ciOpReturn 891fd4e5da5Sopenharmony_ciOpFunctionEnd 892fd4e5da5Sopenharmony_ci)"; 893fd4e5da5Sopenharmony_ci 894fd4e5da5Sopenharmony_ci const std::string after = 895fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 896fd4e5da5Sopenharmony_ci%10 = OpLabel 897fd4e5da5Sopenharmony_ci%c = OpVariable %_ptr_Function_bool Function 898fd4e5da5Sopenharmony_ci%d = OpVariable %_ptr_Function_bool Function 899fd4e5da5Sopenharmony_ciOpBranch %11 900fd4e5da5Sopenharmony_ci%11 = OpLabel 901fd4e5da5Sopenharmony_ciOpLoopMerge %12 %13 None 902fd4e5da5Sopenharmony_ciOpBranch %14 903fd4e5da5Sopenharmony_ci%14 = OpLabel 904fd4e5da5Sopenharmony_ci%15 = OpLoad %bool %c 905fd4e5da5Sopenharmony_ciOpBranchConditional %15 %16 %12 906fd4e5da5Sopenharmony_ci%16 = OpLabel 907fd4e5da5Sopenharmony_ci%17 = OpLoad %bool %d 908fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 909fd4e5da5Sopenharmony_ciOpBranchConditional %17 %19 %18 910fd4e5da5Sopenharmony_ci%19 = OpLabel 911fd4e5da5Sopenharmony_ciOpBranch %13 912fd4e5da5Sopenharmony_ci%18 = OpLabel 913fd4e5da5Sopenharmony_ciOpBranch %20 914fd4e5da5Sopenharmony_ci%20 = OpLabel 915fd4e5da5Sopenharmony_ciOpKill 916fd4e5da5Sopenharmony_ci%13 = OpLabel 917fd4e5da5Sopenharmony_ciOpBranch %11 918fd4e5da5Sopenharmony_ci%12 = OpLabel 919fd4e5da5Sopenharmony_ciOpReturn 920fd4e5da5Sopenharmony_ciOpFunctionEnd 921fd4e5da5Sopenharmony_ci)"; 922fd4e5da5Sopenharmony_ci 923fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 924fd4e5da5Sopenharmony_ci true, true); 925fd4e5da5Sopenharmony_ci} 926fd4e5da5Sopenharmony_ci 927fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, DecorateDeleted) { 928fd4e5da5Sopenharmony_ci // Note: SPIR-V hand-edited to add decoration 929fd4e5da5Sopenharmony_ci // #version 140 930fd4e5da5Sopenharmony_ci // 931fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 932fd4e5da5Sopenharmony_ci // 933fd4e5da5Sopenharmony_ci // void main() 934fd4e5da5Sopenharmony_ci // { 935fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 936fd4e5da5Sopenharmony_ci // if (false) 937fd4e5da5Sopenharmony_ci // v = v * vec4(0.5,0.5,0.5,0.5); 938fd4e5da5Sopenharmony_ci // gl_FragColor = v; 939fd4e5da5Sopenharmony_ci // } 940fd4e5da5Sopenharmony_ci 941fd4e5da5Sopenharmony_ci const std::string predefs_before = 942fd4e5da5Sopenharmony_ci R"(OpCapability Shader 943fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 944fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 945fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 946fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 947fd4e5da5Sopenharmony_ciOpSource GLSL 140 948fd4e5da5Sopenharmony_ciOpName %main "main" 949fd4e5da5Sopenharmony_ciOpName %v "v" 950fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 951fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 952fd4e5da5Sopenharmony_ciOpDecorate %22 RelaxedPrecision 953fd4e5da5Sopenharmony_ci%void = OpTypeVoid 954fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 955fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 956fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 957fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 958fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 959fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 960fd4e5da5Sopenharmony_ci%bool = OpTypeBool 961fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 962fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 963fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 964fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 965fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 966fd4e5da5Sopenharmony_ci)"; 967fd4e5da5Sopenharmony_ci 968fd4e5da5Sopenharmony_ci const std::string predefs_after = 969fd4e5da5Sopenharmony_ci R"(OpCapability Shader 970fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 971fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 972fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 973fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 974fd4e5da5Sopenharmony_ciOpSource GLSL 140 975fd4e5da5Sopenharmony_ciOpName %main "main" 976fd4e5da5Sopenharmony_ciOpName %v "v" 977fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 978fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 979fd4e5da5Sopenharmony_ci%void = OpTypeVoid 980fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 981fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 982fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 983fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 984fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 985fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 986fd4e5da5Sopenharmony_ci%bool = OpTypeBool 987fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 988fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 989fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5 990fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 991fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 992fd4e5da5Sopenharmony_ci)"; 993fd4e5da5Sopenharmony_ci 994fd4e5da5Sopenharmony_ci const std::string before = 995fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 996fd4e5da5Sopenharmony_ci%17 = OpLabel 997fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 998fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 999fd4e5da5Sopenharmony_ciOpStore %v %18 1000fd4e5da5Sopenharmony_ciOpSelectionMerge %19 None 1001fd4e5da5Sopenharmony_ciOpBranchConditional %false %20 %19 1002fd4e5da5Sopenharmony_ci%20 = OpLabel 1003fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %v 1004fd4e5da5Sopenharmony_ci%22 = OpFMul %v4float %21 %15 1005fd4e5da5Sopenharmony_ciOpStore %v %22 1006fd4e5da5Sopenharmony_ciOpBranch %19 1007fd4e5da5Sopenharmony_ci%19 = OpLabel 1008fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 1009fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 1010fd4e5da5Sopenharmony_ciOpReturn 1011fd4e5da5Sopenharmony_ciOpFunctionEnd 1012fd4e5da5Sopenharmony_ci)"; 1013fd4e5da5Sopenharmony_ci 1014fd4e5da5Sopenharmony_ci const std::string after = 1015fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %8 1016fd4e5da5Sopenharmony_ci%18 = OpLabel 1017fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 1018fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor 1019fd4e5da5Sopenharmony_ciOpStore %v %19 1020fd4e5da5Sopenharmony_ciOpBranch %20 1021fd4e5da5Sopenharmony_ci%20 = OpLabel 1022fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v 1023fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 1024fd4e5da5Sopenharmony_ciOpReturn 1025fd4e5da5Sopenharmony_ciOpFunctionEnd 1026fd4e5da5Sopenharmony_ci)"; 1027fd4e5da5Sopenharmony_ci 1028fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs_before + before, 1029fd4e5da5Sopenharmony_ci predefs_after + after, true, true); 1030fd4e5da5Sopenharmony_ci} 1031fd4e5da5Sopenharmony_ci 1032fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, LoopInDeadBranch) { 1033fd4e5da5Sopenharmony_ci // #version 450 1034fd4e5da5Sopenharmony_ci // 1035fd4e5da5Sopenharmony_ci // layout(location = 0) in vec4 BaseColor; 1036fd4e5da5Sopenharmony_ci // layout(location = 0) out vec4 OutColor; 1037fd4e5da5Sopenharmony_ci // 1038fd4e5da5Sopenharmony_ci // void main() 1039fd4e5da5Sopenharmony_ci // { 1040fd4e5da5Sopenharmony_ci // vec4 v = BaseColor; 1041fd4e5da5Sopenharmony_ci // if (false) 1042fd4e5da5Sopenharmony_ci // for (int i=0; i<3; i++) 1043fd4e5da5Sopenharmony_ci // v = v * 0.5; 1044fd4e5da5Sopenharmony_ci // OutColor = v; 1045fd4e5da5Sopenharmony_ci // } 1046fd4e5da5Sopenharmony_ci 1047fd4e5da5Sopenharmony_ci const std::string predefs = 1048fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1049fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1050fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1051fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %OutColor 1052fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1053fd4e5da5Sopenharmony_ciOpSource GLSL 450 1054fd4e5da5Sopenharmony_ciOpName %main "main" 1055fd4e5da5Sopenharmony_ciOpName %v "v" 1056fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1057fd4e5da5Sopenharmony_ciOpName %i "i" 1058fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor" 1059fd4e5da5Sopenharmony_ciOpDecorate %BaseColor Location 0 1060fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0 1061fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1062fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 1063fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1064fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1065fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1066fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1067fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1068fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1069fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1070fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1071fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1072fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 1073fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3 1074fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5 1075fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1076fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1077fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output 1078fd4e5da5Sopenharmony_ci)"; 1079fd4e5da5Sopenharmony_ci 1080fd4e5da5Sopenharmony_ci const std::string before = 1081fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %8 1082fd4e5da5Sopenharmony_ci%22 = OpLabel 1083fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 1084fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 1085fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 1086fd4e5da5Sopenharmony_ciOpStore %v %23 1087fd4e5da5Sopenharmony_ciOpSelectionMerge %24 None 1088fd4e5da5Sopenharmony_ciOpBranchConditional %false %25 %24 1089fd4e5da5Sopenharmony_ci%25 = OpLabel 1090fd4e5da5Sopenharmony_ciOpStore %i %int_0 1091fd4e5da5Sopenharmony_ciOpBranch %26 1092fd4e5da5Sopenharmony_ci%26 = OpLabel 1093fd4e5da5Sopenharmony_ciOpLoopMerge %27 %28 None 1094fd4e5da5Sopenharmony_ciOpBranch %29 1095fd4e5da5Sopenharmony_ci%29 = OpLabel 1096fd4e5da5Sopenharmony_ci%30 = OpLoad %int %i 1097fd4e5da5Sopenharmony_ci%31 = OpSLessThan %bool %30 %int_3 1098fd4e5da5Sopenharmony_ciOpBranchConditional %31 %32 %27 1099fd4e5da5Sopenharmony_ci%32 = OpLabel 1100fd4e5da5Sopenharmony_ci%33 = OpLoad %v4float %v 1101fd4e5da5Sopenharmony_ci%34 = OpVectorTimesScalar %v4float %33 %float_0_5 1102fd4e5da5Sopenharmony_ciOpStore %v %34 1103fd4e5da5Sopenharmony_ciOpBranch %28 1104fd4e5da5Sopenharmony_ci%28 = OpLabel 1105fd4e5da5Sopenharmony_ci%35 = OpLoad %int %i 1106fd4e5da5Sopenharmony_ci%36 = OpIAdd %int %35 %int_1 1107fd4e5da5Sopenharmony_ciOpStore %i %36 1108fd4e5da5Sopenharmony_ciOpBranch %26 1109fd4e5da5Sopenharmony_ci%27 = OpLabel 1110fd4e5da5Sopenharmony_ciOpBranch %24 1111fd4e5da5Sopenharmony_ci%24 = OpLabel 1112fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %v 1113fd4e5da5Sopenharmony_ciOpStore %OutColor %37 1114fd4e5da5Sopenharmony_ciOpReturn 1115fd4e5da5Sopenharmony_ciOpFunctionEnd 1116fd4e5da5Sopenharmony_ci)"; 1117fd4e5da5Sopenharmony_ci 1118fd4e5da5Sopenharmony_ci const std::string after = 1119fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %8 1120fd4e5da5Sopenharmony_ci%22 = OpLabel 1121fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function 1122fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 1123fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 1124fd4e5da5Sopenharmony_ciOpStore %v %23 1125fd4e5da5Sopenharmony_ciOpBranch %24 1126fd4e5da5Sopenharmony_ci%24 = OpLabel 1127fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %v 1128fd4e5da5Sopenharmony_ciOpStore %OutColor %37 1129fd4e5da5Sopenharmony_ciOpReturn 1130fd4e5da5Sopenharmony_ciOpFunctionEnd 1131fd4e5da5Sopenharmony_ci)"; 1132fd4e5da5Sopenharmony_ci 1133fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 1134fd4e5da5Sopenharmony_ci true, true); 1135fd4e5da5Sopenharmony_ci} 1136fd4e5da5Sopenharmony_ci 1137fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SwitchLiveCase) { 1138fd4e5da5Sopenharmony_ci // #version 450 1139fd4e5da5Sopenharmony_ci // 1140fd4e5da5Sopenharmony_ci // layout (location=0) in vec4 BaseColor; 1141fd4e5da5Sopenharmony_ci // layout (location=0) out vec4 OutColor; 1142fd4e5da5Sopenharmony_ci // 1143fd4e5da5Sopenharmony_ci // void main() 1144fd4e5da5Sopenharmony_ci // { 1145fd4e5da5Sopenharmony_ci // switch (1) { 1146fd4e5da5Sopenharmony_ci // case 0: 1147fd4e5da5Sopenharmony_ci // OutColor = vec4(0.0,0.0,0.0,0.0); 1148fd4e5da5Sopenharmony_ci // break; 1149fd4e5da5Sopenharmony_ci // case 1: 1150fd4e5da5Sopenharmony_ci // OutColor = vec4(0.125,0.125,0.125,0.125); 1151fd4e5da5Sopenharmony_ci // break; 1152fd4e5da5Sopenharmony_ci // case 2: 1153fd4e5da5Sopenharmony_ci // OutColor = vec4(0.25,0.25,0.25,0.25); 1154fd4e5da5Sopenharmony_ci // break; 1155fd4e5da5Sopenharmony_ci // default: 1156fd4e5da5Sopenharmony_ci // OutColor = vec4(1.0,1.0,1.0,1.0); 1157fd4e5da5Sopenharmony_ci // } 1158fd4e5da5Sopenharmony_ci // } 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ci const std::string predefs = 1161fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1162fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1163fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1164fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %OutColor %BaseColor 1165fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1166fd4e5da5Sopenharmony_ciOpSource GLSL 450 1167fd4e5da5Sopenharmony_ciOpName %main "main" 1168fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor" 1169fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1170fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0 1171fd4e5da5Sopenharmony_ciOpDecorate %BaseColor Location 0 1172fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1173fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 1174fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1175fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1176fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1177fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1178fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1179fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output 1180fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1181fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1182fd4e5da5Sopenharmony_ci%float_0_125 = OpConstant %float 0.125 1183fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_0_125 %float_0_125 %float_0_125 %float_0_125 1184fd4e5da5Sopenharmony_ci%float_0_25 = OpConstant %float 0.25 1185fd4e5da5Sopenharmony_ci%17 = OpConstantComposite %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25 1186fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 1187fd4e5da5Sopenharmony_ci%19 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 1188fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1189fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1190fd4e5da5Sopenharmony_ci)"; 1191fd4e5da5Sopenharmony_ci 1192fd4e5da5Sopenharmony_ci const std::string before = 1193fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 1194fd4e5da5Sopenharmony_ci%21 = OpLabel 1195fd4e5da5Sopenharmony_ciOpSelectionMerge %22 None 1196fd4e5da5Sopenharmony_ciOpSwitch %int_1 %23 0 %24 1 %25 2 %26 1197fd4e5da5Sopenharmony_ci%23 = OpLabel 1198fd4e5da5Sopenharmony_ciOpStore %OutColor %19 1199fd4e5da5Sopenharmony_ciOpBranch %22 1200fd4e5da5Sopenharmony_ci%24 = OpLabel 1201fd4e5da5Sopenharmony_ciOpStore %OutColor %13 1202fd4e5da5Sopenharmony_ciOpBranch %22 1203fd4e5da5Sopenharmony_ci%25 = OpLabel 1204fd4e5da5Sopenharmony_ciOpStore %OutColor %15 1205fd4e5da5Sopenharmony_ciOpBranch %22 1206fd4e5da5Sopenharmony_ci%26 = OpLabel 1207fd4e5da5Sopenharmony_ciOpStore %OutColor %17 1208fd4e5da5Sopenharmony_ciOpBranch %22 1209fd4e5da5Sopenharmony_ci%22 = OpLabel 1210fd4e5da5Sopenharmony_ciOpReturn 1211fd4e5da5Sopenharmony_ciOpFunctionEnd 1212fd4e5da5Sopenharmony_ci)"; 1213fd4e5da5Sopenharmony_ci 1214fd4e5da5Sopenharmony_ci const std::string after = 1215fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 1216fd4e5da5Sopenharmony_ci%21 = OpLabel 1217fd4e5da5Sopenharmony_ciOpBranch %25 1218fd4e5da5Sopenharmony_ci%25 = OpLabel 1219fd4e5da5Sopenharmony_ciOpStore %OutColor %15 1220fd4e5da5Sopenharmony_ciOpBranch %22 1221fd4e5da5Sopenharmony_ci%22 = OpLabel 1222fd4e5da5Sopenharmony_ciOpReturn 1223fd4e5da5Sopenharmony_ciOpFunctionEnd 1224fd4e5da5Sopenharmony_ci)"; 1225fd4e5da5Sopenharmony_ci 1226fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 1227fd4e5da5Sopenharmony_ci true, true); 1228fd4e5da5Sopenharmony_ci} 1229fd4e5da5Sopenharmony_ci 1230fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SwitchLiveDefault) { 1231fd4e5da5Sopenharmony_ci // #version 450 1232fd4e5da5Sopenharmony_ci // 1233fd4e5da5Sopenharmony_ci // layout (location=0) in vec4 BaseColor; 1234fd4e5da5Sopenharmony_ci // layout (location=0) out vec4 OutColor; 1235fd4e5da5Sopenharmony_ci // 1236fd4e5da5Sopenharmony_ci // void main() 1237fd4e5da5Sopenharmony_ci // { 1238fd4e5da5Sopenharmony_ci // switch (7) { 1239fd4e5da5Sopenharmony_ci // case 0: 1240fd4e5da5Sopenharmony_ci // OutColor = vec4(0.0,0.0,0.0,0.0); 1241fd4e5da5Sopenharmony_ci // break; 1242fd4e5da5Sopenharmony_ci // case 1: 1243fd4e5da5Sopenharmony_ci // OutColor = vec4(0.125,0.125,0.125,0.125); 1244fd4e5da5Sopenharmony_ci // break; 1245fd4e5da5Sopenharmony_ci // case 2: 1246fd4e5da5Sopenharmony_ci // OutColor = vec4(0.25,0.25,0.25,0.25); 1247fd4e5da5Sopenharmony_ci // break; 1248fd4e5da5Sopenharmony_ci // default: 1249fd4e5da5Sopenharmony_ci // OutColor = vec4(1.0,1.0,1.0,1.0); 1250fd4e5da5Sopenharmony_ci // } 1251fd4e5da5Sopenharmony_ci // } 1252fd4e5da5Sopenharmony_ci 1253fd4e5da5Sopenharmony_ci const std::string predefs = 1254fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1255fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1256fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1257fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %OutColor %BaseColor 1258fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1259fd4e5da5Sopenharmony_ciOpSource GLSL 450 1260fd4e5da5Sopenharmony_ciOpName %main "main" 1261fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor" 1262fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1263fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0 1264fd4e5da5Sopenharmony_ciOpDecorate %BaseColor Location 0 1265fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1266fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void 1267fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1268fd4e5da5Sopenharmony_ci%int_7 = OpConstant %int 7 1269fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1270fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1271fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1272fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output 1273fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1274fd4e5da5Sopenharmony_ci%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1275fd4e5da5Sopenharmony_ci%float_0_125 = OpConstant %float 0.125 1276fd4e5da5Sopenharmony_ci%15 = OpConstantComposite %v4float %float_0_125 %float_0_125 %float_0_125 %float_0_125 1277fd4e5da5Sopenharmony_ci%float_0_25 = OpConstant %float 0.25 1278fd4e5da5Sopenharmony_ci%17 = OpConstantComposite %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25 1279fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 1280fd4e5da5Sopenharmony_ci%19 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 1281fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1282fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1283fd4e5da5Sopenharmony_ci)"; 1284fd4e5da5Sopenharmony_ci 1285fd4e5da5Sopenharmony_ci const std::string before = 1286fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 1287fd4e5da5Sopenharmony_ci%21 = OpLabel 1288fd4e5da5Sopenharmony_ciOpSelectionMerge %22 None 1289fd4e5da5Sopenharmony_ciOpSwitch %int_7 %23 0 %24 1 %25 2 %26 1290fd4e5da5Sopenharmony_ci%23 = OpLabel 1291fd4e5da5Sopenharmony_ciOpStore %OutColor %19 1292fd4e5da5Sopenharmony_ciOpBranch %22 1293fd4e5da5Sopenharmony_ci%24 = OpLabel 1294fd4e5da5Sopenharmony_ciOpStore %OutColor %13 1295fd4e5da5Sopenharmony_ciOpBranch %22 1296fd4e5da5Sopenharmony_ci%25 = OpLabel 1297fd4e5da5Sopenharmony_ciOpStore %OutColor %15 1298fd4e5da5Sopenharmony_ciOpBranch %22 1299fd4e5da5Sopenharmony_ci%26 = OpLabel 1300fd4e5da5Sopenharmony_ciOpStore %OutColor %17 1301fd4e5da5Sopenharmony_ciOpBranch %22 1302fd4e5da5Sopenharmony_ci%22 = OpLabel 1303fd4e5da5Sopenharmony_ciOpReturn 1304fd4e5da5Sopenharmony_ciOpFunctionEnd 1305fd4e5da5Sopenharmony_ci)"; 1306fd4e5da5Sopenharmony_ci 1307fd4e5da5Sopenharmony_ci const std::string after = 1308fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %6 1309fd4e5da5Sopenharmony_ci%21 = OpLabel 1310fd4e5da5Sopenharmony_ciOpBranch %23 1311fd4e5da5Sopenharmony_ci%23 = OpLabel 1312fd4e5da5Sopenharmony_ciOpStore %OutColor %19 1313fd4e5da5Sopenharmony_ciOpBranch %22 1314fd4e5da5Sopenharmony_ci%22 = OpLabel 1315fd4e5da5Sopenharmony_ciOpReturn 1316fd4e5da5Sopenharmony_ciOpFunctionEnd 1317fd4e5da5Sopenharmony_ci)"; 1318fd4e5da5Sopenharmony_ci 1319fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 1320fd4e5da5Sopenharmony_ci true, true); 1321fd4e5da5Sopenharmony_ci} 1322fd4e5da5Sopenharmony_ci 1323fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SwitchLiveCaseBreakFromLoop) { 1324fd4e5da5Sopenharmony_ci // This sample does not directly translate to GLSL/HLSL as 1325fd4e5da5Sopenharmony_ci // direct breaks from a loop cannot be made from a switch. 1326fd4e5da5Sopenharmony_ci // This construct is currently formed by inlining a function 1327fd4e5da5Sopenharmony_ci // containing early returns from the cases of a switch. The 1328fd4e5da5Sopenharmony_ci // function is wrapped in a one-trip loop and returns are 1329fd4e5da5Sopenharmony_ci // translated to branches to the loop's merge block. 1330fd4e5da5Sopenharmony_ci 1331fd4e5da5Sopenharmony_ci const std::string predefs = 1332fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1333fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1334fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1335fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %OutColor %BaseColor 1336fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 1337fd4e5da5Sopenharmony_ciOpSource GLSL 450 1338fd4e5da5Sopenharmony_ciOpName %main "main" 1339fd4e5da5Sopenharmony_ciOpName %oc "oc" 1340fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor" 1341fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 1342fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0 1343fd4e5da5Sopenharmony_ciOpDecorate %BaseColor Location 0 1344fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1345fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void 1346fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1347fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1348fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1349fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1350fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1351fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1352fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1353fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1354fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1355fd4e5da5Sopenharmony_ci%17 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1356fd4e5da5Sopenharmony_ci%float_0_125 = OpConstant %float 0.125 1357fd4e5da5Sopenharmony_ci%19 = OpConstantComposite %v4float %float_0_125 %float_0_125 %float_0_125 %float_0_125 1358fd4e5da5Sopenharmony_ci%float_0_25 = OpConstant %float 0.25 1359fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25 1360fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 1361fd4e5da5Sopenharmony_ci%23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 1362fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1363fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output 1364fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 1365fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 1366fd4e5da5Sopenharmony_ci)"; 1367fd4e5da5Sopenharmony_ci 1368fd4e5da5Sopenharmony_ci const std::string before = 1369fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 1370fd4e5da5Sopenharmony_ci%26 = OpLabel 1371fd4e5da5Sopenharmony_ci%oc = OpVariable %_ptr_Function_v4float Function 1372fd4e5da5Sopenharmony_ciOpBranch %27 1373fd4e5da5Sopenharmony_ci%27 = OpLabel 1374fd4e5da5Sopenharmony_ciOpLoopMerge %28 %29 None 1375fd4e5da5Sopenharmony_ciOpBranch %30 1376fd4e5da5Sopenharmony_ci%30 = OpLabel 1377fd4e5da5Sopenharmony_ciOpSelectionMerge %31 None 1378fd4e5da5Sopenharmony_ciOpSwitch %int_1 %31 0 %32 1 %33 2 %34 1379fd4e5da5Sopenharmony_ci%32 = OpLabel 1380fd4e5da5Sopenharmony_ciOpStore %oc %17 1381fd4e5da5Sopenharmony_ciOpBranch %28 1382fd4e5da5Sopenharmony_ci%33 = OpLabel 1383fd4e5da5Sopenharmony_ciOpStore %oc %19 1384fd4e5da5Sopenharmony_ciOpBranch %28 1385fd4e5da5Sopenharmony_ci%34 = OpLabel 1386fd4e5da5Sopenharmony_ciOpStore %oc %21 1387fd4e5da5Sopenharmony_ciOpBranch %28 1388fd4e5da5Sopenharmony_ci%31 = OpLabel 1389fd4e5da5Sopenharmony_ciOpStore %oc %23 1390fd4e5da5Sopenharmony_ciOpBranch %28 1391fd4e5da5Sopenharmony_ci%29 = OpLabel 1392fd4e5da5Sopenharmony_ciOpBranchConditional %false %27 %28 1393fd4e5da5Sopenharmony_ci%28 = OpLabel 1394fd4e5da5Sopenharmony_ci%35 = OpLoad %v4float %oc 1395fd4e5da5Sopenharmony_ciOpStore %OutColor %35 1396fd4e5da5Sopenharmony_ciOpReturn 1397fd4e5da5Sopenharmony_ciOpFunctionEnd 1398fd4e5da5Sopenharmony_ci)"; 1399fd4e5da5Sopenharmony_ci 1400fd4e5da5Sopenharmony_ci const std::string after = 1401fd4e5da5Sopenharmony_ci R"(%main = OpFunction %void None %7 1402fd4e5da5Sopenharmony_ci%26 = OpLabel 1403fd4e5da5Sopenharmony_ci%oc = OpVariable %_ptr_Function_v4float Function 1404fd4e5da5Sopenharmony_ciOpBranch %27 1405fd4e5da5Sopenharmony_ci%27 = OpLabel 1406fd4e5da5Sopenharmony_ciOpLoopMerge %28 %29 None 1407fd4e5da5Sopenharmony_ciOpBranch %30 1408fd4e5da5Sopenharmony_ci%30 = OpLabel 1409fd4e5da5Sopenharmony_ciOpBranch %33 1410fd4e5da5Sopenharmony_ci%33 = OpLabel 1411fd4e5da5Sopenharmony_ciOpStore %oc %19 1412fd4e5da5Sopenharmony_ciOpBranch %28 1413fd4e5da5Sopenharmony_ci%29 = OpLabel 1414fd4e5da5Sopenharmony_ciOpBranch %27 1415fd4e5da5Sopenharmony_ci%28 = OpLabel 1416fd4e5da5Sopenharmony_ci%35 = OpLoad %v4float %oc 1417fd4e5da5Sopenharmony_ciOpStore %OutColor %35 1418fd4e5da5Sopenharmony_ciOpReturn 1419fd4e5da5Sopenharmony_ciOpFunctionEnd 1420fd4e5da5Sopenharmony_ci)"; 1421fd4e5da5Sopenharmony_ci 1422fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(predefs + before, predefs + after, 1423fd4e5da5Sopenharmony_ci true, true); 1424fd4e5da5Sopenharmony_ci} 1425fd4e5da5Sopenharmony_ci 1426fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, LeaveContinueBackedge) { 1427fd4e5da5Sopenharmony_ci const std::string text = R"( 1428fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1429fd4e5da5Sopenharmony_ci; CHECK: [[continue]] = OpLabel 1430fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} {{%\w+}} [[merge]] 1431fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[merge]] = OpLabel 1432fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1433fd4e5da5Sopenharmony_ciOpCapability Kernel 1434fd4e5da5Sopenharmony_ciOpCapability Linkage 1435fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1436fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1437fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1438fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1439fd4e5da5Sopenharmony_ci%funcTy = OpTypeFunction %void 1440fd4e5da5Sopenharmony_ci%func = OpFunction %void None %funcTy 1441fd4e5da5Sopenharmony_ci%1 = OpLabel 1442fd4e5da5Sopenharmony_ciOpBranch %2 1443fd4e5da5Sopenharmony_ci%2 = OpLabel 1444fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 1445fd4e5da5Sopenharmony_ciOpBranch %4 1446fd4e5da5Sopenharmony_ci%4 = OpLabel 1447fd4e5da5Sopenharmony_ci; Be careful we don't remove the backedge to %2 despite never taking it. 1448fd4e5da5Sopenharmony_ciOpBranchConditional %false %2 %3 1449fd4e5da5Sopenharmony_ci%3 = OpLabel 1450fd4e5da5Sopenharmony_ciOpReturn 1451fd4e5da5Sopenharmony_ciOpFunctionEnd 1452fd4e5da5Sopenharmony_ci)"; 1453fd4e5da5Sopenharmony_ci 1454fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1455fd4e5da5Sopenharmony_ci} 1456fd4e5da5Sopenharmony_ci 1457fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, LeaveContinueBackedgeExtraBlock) { 1458fd4e5da5Sopenharmony_ci const std::string text = R"( 1459fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header:%\w+]] 1460fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1461fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[continue]] 1462fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[continue]] = OpLabel 1463fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[extra:%\w+]] [[merge]] 1464fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[extra]] = OpLabel 1465fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1466fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[merge]] = OpLabel 1467fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1468fd4e5da5Sopenharmony_ciOpCapability Kernel 1469fd4e5da5Sopenharmony_ciOpCapability Linkage 1470fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1471fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1472fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1473fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1474fd4e5da5Sopenharmony_ci%funcTy = OpTypeFunction %void 1475fd4e5da5Sopenharmony_ci%func = OpFunction %void None %funcTy 1476fd4e5da5Sopenharmony_ci%1 = OpLabel 1477fd4e5da5Sopenharmony_ciOpBranch %2 1478fd4e5da5Sopenharmony_ci%2 = OpLabel 1479fd4e5da5Sopenharmony_ciOpLoopMerge %3 %4 None 1480fd4e5da5Sopenharmony_ciOpBranch %4 1481fd4e5da5Sopenharmony_ci%4 = OpLabel 1482fd4e5da5Sopenharmony_ci; Be careful we don't remove the backedge to %2 despite never taking it. 1483fd4e5da5Sopenharmony_ciOpBranchConditional %false %5 %3 1484fd4e5da5Sopenharmony_ci; This block remains live despite being unreachable. 1485fd4e5da5Sopenharmony_ci%5 = OpLabel 1486fd4e5da5Sopenharmony_ciOpBranch %2 1487fd4e5da5Sopenharmony_ci%3 = OpLabel 1488fd4e5da5Sopenharmony_ciOpReturn 1489fd4e5da5Sopenharmony_ciOpFunctionEnd 1490fd4e5da5Sopenharmony_ci)"; 1491fd4e5da5Sopenharmony_ci 1492fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1493fd4e5da5Sopenharmony_ci} 1494fd4e5da5Sopenharmony_ci 1495fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, RemovePhiWithUnreachableContinue) { 1496fd4e5da5Sopenharmony_ci const std::string text = R"( 1497fd4e5da5Sopenharmony_ci; CHECK: [[entry:%\w+]] = OpLabel 1498fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header:%\w+]] 1499fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1500fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 1501fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[ret]] = OpLabel 1502fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1503fd4e5da5Sopenharmony_ci; CHECK: [[continue]] = OpLabel 1504fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1505fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 1506fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 1507fd4e5da5Sopenharmony_ciOpCapability Kernel 1508fd4e5da5Sopenharmony_ciOpCapability Linkage 1509fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1510fd4e5da5Sopenharmony_ciOpName %func "func" 1511fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1512fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1513fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1514fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1515fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1516fd4e5da5Sopenharmony_ci%funcTy = OpTypeFunction %void 1517fd4e5da5Sopenharmony_ci%func = OpFunction %void None %funcTy 1518fd4e5da5Sopenharmony_ci%1 = OpLabel 1519fd4e5da5Sopenharmony_ciOpBranch %2 1520fd4e5da5Sopenharmony_ci%2 = OpLabel 1521fd4e5da5Sopenharmony_ci%phi = OpPhi %bool %false %1 %true %continue 1522fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 1523fd4e5da5Sopenharmony_ciOpBranch %3 1524fd4e5da5Sopenharmony_ci%3 = OpLabel 1525fd4e5da5Sopenharmony_ciOpReturn 1526fd4e5da5Sopenharmony_ci%continue = OpLabel 1527fd4e5da5Sopenharmony_ciOpBranch %2 1528fd4e5da5Sopenharmony_ci%merge = OpLabel 1529fd4e5da5Sopenharmony_ciOpReturn 1530fd4e5da5Sopenharmony_ciOpFunctionEnd 1531fd4e5da5Sopenharmony_ci)"; 1532fd4e5da5Sopenharmony_ci 1533fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1534fd4e5da5Sopenharmony_ci} 1535fd4e5da5Sopenharmony_ci 1536fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, UnreachableLoopMergeAndContinueTargets) { 1537fd4e5da5Sopenharmony_ci const std::string text = R"( 1538fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef %bool 1539fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[header:%\w+]] 1540fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[if_lab:%\w+]] [[else_lab:%\w+]] 1541fd4e5da5Sopenharmony_ci; CHECK: OpPhi %bool %false [[if_lab]] %false [[else_lab]] [[undef]] [[continue:%\w+]] 1542fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge [[merge:%\w+]] [[continue]] None 1543fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[ret:%\w+]] 1544fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[ret]] = OpLabel 1545fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1546fd4e5da5Sopenharmony_ci; CHECK: [[continue]] = OpLabel 1547fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1548fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 1549fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 1550fd4e5da5Sopenharmony_ciOpCapability Kernel 1551fd4e5da5Sopenharmony_ciOpCapability Linkage 1552fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1553fd4e5da5Sopenharmony_ciOpName %func "func" 1554fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1555fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1556fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1557fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1558fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1559fd4e5da5Sopenharmony_ci%funcTy = OpTypeFunction %void 1560fd4e5da5Sopenharmony_ci%func = OpFunction %void None %funcTy 1561fd4e5da5Sopenharmony_ci%1 = OpLabel 1562fd4e5da5Sopenharmony_ci%c = OpUndef %bool 1563fd4e5da5Sopenharmony_ciOpSelectionMerge %2 None 1564fd4e5da5Sopenharmony_ciOpBranchConditional %c %if %else 1565fd4e5da5Sopenharmony_ci%if = OpLabel 1566fd4e5da5Sopenharmony_ciOpBranch %2 1567fd4e5da5Sopenharmony_ci%else = OpLabel 1568fd4e5da5Sopenharmony_ciOpBranch %2 1569fd4e5da5Sopenharmony_ci%2 = OpLabel 1570fd4e5da5Sopenharmony_ci%phi = OpPhi %bool %false %if %false %else %true %continue 1571fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 1572fd4e5da5Sopenharmony_ciOpBranch %3 1573fd4e5da5Sopenharmony_ci%3 = OpLabel 1574fd4e5da5Sopenharmony_ciOpReturn 1575fd4e5da5Sopenharmony_ci%continue = OpLabel 1576fd4e5da5Sopenharmony_ciOpBranch %2 1577fd4e5da5Sopenharmony_ci%merge = OpLabel 1578fd4e5da5Sopenharmony_ciOpReturn 1579fd4e5da5Sopenharmony_ciOpFunctionEnd 1580fd4e5da5Sopenharmony_ci)"; 1581fd4e5da5Sopenharmony_ci 1582fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1583fd4e5da5Sopenharmony_ci} 1584fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, EarlyReconvergence) { 1585fd4e5da5Sopenharmony_ci const std::string text = R"( 1586fd4e5da5Sopenharmony_ci; CHECK-NOT: OpBranchConditional 1587fd4e5da5Sopenharmony_ci; CHECK: [[logical:%\w+]] = OpLogicalOr 1588fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 1589fd4e5da5Sopenharmony_ci; CHECK: OpLogicalAnd {{%\w+}} {{%\w+}} [[logical]] 1590fd4e5da5Sopenharmony_ciOpCapability Shader 1591fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1592fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1593fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 1594fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1595fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1596fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1597fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1598fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 1599fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 1600fd4e5da5Sopenharmony_ci%1 = OpLabel 1601fd4e5da5Sopenharmony_ciOpSelectionMerge %2 None 1602fd4e5da5Sopenharmony_ciOpBranchConditional %false %3 %4 1603fd4e5da5Sopenharmony_ci%3 = OpLabel 1604fd4e5da5Sopenharmony_ci%12 = OpLogicalNot %bool %true 1605fd4e5da5Sopenharmony_ciOpBranch %2 1606fd4e5da5Sopenharmony_ci%4 = OpLabel 1607fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 1608fd4e5da5Sopenharmony_ciOpBranchConditional %false %5 %6 1609fd4e5da5Sopenharmony_ci%5 = OpLabel 1610fd4e5da5Sopenharmony_ci%10 = OpLogicalAnd %bool %true %false 1611fd4e5da5Sopenharmony_ciOpBranch %7 1612fd4e5da5Sopenharmony_ci%6 = OpLabel 1613fd4e5da5Sopenharmony_ci%11 = OpLogicalOr %bool %true %false 1614fd4e5da5Sopenharmony_ciOpBranch %7 1615fd4e5da5Sopenharmony_ci%7 = OpLabel 1616fd4e5da5Sopenharmony_ci; This phi is in a block preceding the merge %14! 1617fd4e5da5Sopenharmony_ci%8 = OpPhi %bool %10 %5 %11 %6 1618fd4e5da5Sopenharmony_ciOpBranch %14 1619fd4e5da5Sopenharmony_ci%14 = OpLabel 1620fd4e5da5Sopenharmony_ciOpBranch %2 1621fd4e5da5Sopenharmony_ci%2 = OpLabel 1622fd4e5da5Sopenharmony_ci%9 = OpPhi %bool %12 %3 %8 %14 1623fd4e5da5Sopenharmony_ci%13 = OpLogicalAnd %bool %true %9 1624fd4e5da5Sopenharmony_ciOpReturn 1625fd4e5da5Sopenharmony_ciOpFunctionEnd 1626fd4e5da5Sopenharmony_ci)"; 1627fd4e5da5Sopenharmony_ci 1628fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1629fd4e5da5Sopenharmony_ci} 1630fd4e5da5Sopenharmony_ci 1631fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, RemoveUnreachableBlocksFloating) { 1632fd4e5da5Sopenharmony_ci const std::string text = R"( 1633fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1634fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 1635fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1636fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd 1637fd4e5da5Sopenharmony_ciOpCapability Kernel 1638fd4e5da5Sopenharmony_ciOpCapability Linkage 1639fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1640fd4e5da5Sopenharmony_ciOpName %func "func" 1641fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1642fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1643fd4e5da5Sopenharmony_ci%1 = OpTypeFunction %void 1644fd4e5da5Sopenharmony_ci%func = OpFunction %void None %1 1645fd4e5da5Sopenharmony_ci%2 = OpLabel 1646fd4e5da5Sopenharmony_ciOpReturn 1647fd4e5da5Sopenharmony_ci%3 = OpLabel 1648fd4e5da5Sopenharmony_ciOpReturn 1649fd4e5da5Sopenharmony_ciOpFunctionEnd 1650fd4e5da5Sopenharmony_ci)"; 1651fd4e5da5Sopenharmony_ci 1652fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1653fd4e5da5Sopenharmony_ci} 1654fd4e5da5Sopenharmony_ci 1655fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, RemoveUnreachableBlocksFloatingJoin) { 1656fd4e5da5Sopenharmony_ci const std::string text = R"( 1657fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1658fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionParameter 1659fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 1660fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1661fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd 1662fd4e5da5Sopenharmony_ciOpCapability Kernel 1663fd4e5da5Sopenharmony_ciOpCapability Linkage 1664fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1665fd4e5da5Sopenharmony_ciOpName %func "func" 1666fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1667fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1668fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1669fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1670fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1671fd4e5da5Sopenharmony_ci%1 = OpTypeFunction %void %bool 1672fd4e5da5Sopenharmony_ci%func = OpFunction %void None %1 1673fd4e5da5Sopenharmony_ci%bool_param = OpFunctionParameter %bool 1674fd4e5da5Sopenharmony_ci%2 = OpLabel 1675fd4e5da5Sopenharmony_ciOpReturn 1676fd4e5da5Sopenharmony_ci%3 = OpLabel 1677fd4e5da5Sopenharmony_ciOpSelectionMerge %6 None 1678fd4e5da5Sopenharmony_ciOpBranchConditional %bool_param %4 %5 1679fd4e5da5Sopenharmony_ci%4 = OpLabel 1680fd4e5da5Sopenharmony_ciOpBranch %6 1681fd4e5da5Sopenharmony_ci%5 = OpLabel 1682fd4e5da5Sopenharmony_ciOpBranch %6 1683fd4e5da5Sopenharmony_ci%6 = OpLabel 1684fd4e5da5Sopenharmony_ci%7 = OpPhi %bool %true %4 %false %6 1685fd4e5da5Sopenharmony_ciOpReturn 1686fd4e5da5Sopenharmony_ciOpFunctionEnd 1687fd4e5da5Sopenharmony_ci)"; 1688fd4e5da5Sopenharmony_ci 1689fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1690fd4e5da5Sopenharmony_ci} 1691fd4e5da5Sopenharmony_ci 1692fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, RemoveUnreachableBlocksDeadPhi) { 1693fd4e5da5Sopenharmony_ci const std::string text = R"( 1694fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1695fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionParameter 1696fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 1697fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[label:%\w+]] 1698fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[label]] = OpLabel 1699fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalNot %bool %true 1700fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1701fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd 1702fd4e5da5Sopenharmony_ciOpCapability Kernel 1703fd4e5da5Sopenharmony_ciOpCapability Linkage 1704fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1705fd4e5da5Sopenharmony_ciOpName %func "func" 1706fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1707fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1708fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1709fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1710fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1711fd4e5da5Sopenharmony_ci%1 = OpTypeFunction %void %bool 1712fd4e5da5Sopenharmony_ci%func = OpFunction %void None %1 1713fd4e5da5Sopenharmony_ci%bool_param = OpFunctionParameter %bool 1714fd4e5da5Sopenharmony_ci%2 = OpLabel 1715fd4e5da5Sopenharmony_ciOpBranch %3 1716fd4e5da5Sopenharmony_ci%4 = OpLabel 1717fd4e5da5Sopenharmony_ciOpBranch %3 1718fd4e5da5Sopenharmony_ci%3 = OpLabel 1719fd4e5da5Sopenharmony_ci%5 = OpPhi %bool %true %2 %false %4 1720fd4e5da5Sopenharmony_ci%6 = OpLogicalNot %bool %5 1721fd4e5da5Sopenharmony_ciOpReturn 1722fd4e5da5Sopenharmony_ciOpFunctionEnd 1723fd4e5da5Sopenharmony_ci)"; 1724fd4e5da5Sopenharmony_ci 1725fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1726fd4e5da5Sopenharmony_ci} 1727fd4e5da5Sopenharmony_ci 1728fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, RemoveUnreachableBlocksPartiallyDeadPhi) { 1729fd4e5da5Sopenharmony_ci const std::string text = R"( 1730fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1731fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[param:%\w+]] = OpFunctionParameter 1732fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 1733fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional [[param]] [[merge:%\w+]] [[br:%\w+]] 1734fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[merge]] = OpLabel 1735fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[phi:%\w+]] = OpPhi %bool %true %2 %false [[br]] 1736fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalNot %bool [[phi]] 1737fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1738fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[br]] = OpLabel 1739fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 1740fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd 1741fd4e5da5Sopenharmony_ciOpCapability Kernel 1742fd4e5da5Sopenharmony_ciOpCapability Linkage 1743fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1744fd4e5da5Sopenharmony_ciOpName %func "func" 1745fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1746fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1747fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1748fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1749fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1750fd4e5da5Sopenharmony_ci%1 = OpTypeFunction %void %bool 1751fd4e5da5Sopenharmony_ci%func = OpFunction %void None %1 1752fd4e5da5Sopenharmony_ci%bool_param = OpFunctionParameter %bool 1753fd4e5da5Sopenharmony_ci%2 = OpLabel 1754fd4e5da5Sopenharmony_ciOpBranchConditional %bool_param %3 %7 1755fd4e5da5Sopenharmony_ci%7 = OpLabel 1756fd4e5da5Sopenharmony_ciOpBranch %3 1757fd4e5da5Sopenharmony_ci%4 = OpLabel 1758fd4e5da5Sopenharmony_ciOpBranch %3 1759fd4e5da5Sopenharmony_ci%3 = OpLabel 1760fd4e5da5Sopenharmony_ci%5 = OpPhi %bool %true %2 %false %7 %false %4 1761fd4e5da5Sopenharmony_ci%6 = OpLogicalNot %bool %5 1762fd4e5da5Sopenharmony_ciOpReturn 1763fd4e5da5Sopenharmony_ciOpFunctionEnd 1764fd4e5da5Sopenharmony_ci)"; 1765fd4e5da5Sopenharmony_ci 1766fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1767fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1768fd4e5da5Sopenharmony_ci} 1769fd4e5da5Sopenharmony_ci 1770fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, LiveHeaderDeadPhi) { 1771fd4e5da5Sopenharmony_ci const std::string text = R"( 1772fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1773fd4e5da5Sopenharmony_ci; CHECK-NOT: OpBranchConditional 1774fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 1775fd4e5da5Sopenharmony_ci; CHECK: OpLogicalNot %bool %false 1776fd4e5da5Sopenharmony_ciOpCapability Kernel 1777fd4e5da5Sopenharmony_ciOpCapability Linkage 1778fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1779fd4e5da5Sopenharmony_ciOpName %func "func" 1780fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1781fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1782fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1783fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1784fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1785fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 1786fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 1787fd4e5da5Sopenharmony_ci%1 = OpLabel 1788fd4e5da5Sopenharmony_ciOpSelectionMerge %3 None 1789fd4e5da5Sopenharmony_ciOpBranchConditional %true %2 %3 1790fd4e5da5Sopenharmony_ci%2 = OpLabel 1791fd4e5da5Sopenharmony_ciOpBranch %3 1792fd4e5da5Sopenharmony_ci%3 = OpLabel 1793fd4e5da5Sopenharmony_ci%5 = OpPhi %bool %true %3 %false %2 1794fd4e5da5Sopenharmony_ci%6 = OpLogicalNot %bool %5 1795fd4e5da5Sopenharmony_ciOpReturn 1796fd4e5da5Sopenharmony_ciOpFunctionEnd 1797fd4e5da5Sopenharmony_ci)"; 1798fd4e5da5Sopenharmony_ci 1799fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1800fd4e5da5Sopenharmony_ci} 1801fd4e5da5Sopenharmony_ci 1802fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ExtraBackedgeBlocksLive) { 1803fd4e5da5Sopenharmony_ci const std::string text = R"( 1804fd4e5da5Sopenharmony_ci; CHECK: [[entry:%\w+]] = OpLabel 1805fd4e5da5Sopenharmony_ci; CHECK-NOT: OpSelectionMerge 1806fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header:%\w+]] 1807fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[header]] = OpLabel 1808fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpPhi %bool %true [[entry]] %false [[backedge:%\w+]] 1809fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge 1810fd4e5da5Sopenharmony_ciOpCapability Kernel 1811fd4e5da5Sopenharmony_ciOpCapability Linkage 1812fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1813fd4e5da5Sopenharmony_ciOpName %func "func" 1814fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1815fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1816fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1817fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1818fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1819fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void %bool 1820fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 1821fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %bool 1822fd4e5da5Sopenharmony_ci%entry = OpLabel 1823fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None 1824fd4e5da5Sopenharmony_ci; This dead branch is included to ensure the pass does work. 1825fd4e5da5Sopenharmony_ciOpBranchConditional %false %if_merge %loop_header 1826fd4e5da5Sopenharmony_ci%loop_header = OpLabel 1827fd4e5da5Sopenharmony_ci; Both incoming edges are live, so the phi should be untouched. 1828fd4e5da5Sopenharmony_ci%phi = OpPhi %bool %true %entry %false %backedge 1829fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %continue None 1830fd4e5da5Sopenharmony_ciOpBranchConditional %param %loop_merge %continue 1831fd4e5da5Sopenharmony_ci%continue = OpLabel 1832fd4e5da5Sopenharmony_ciOpBranch %backedge 1833fd4e5da5Sopenharmony_ci%backedge = OpLabel 1834fd4e5da5Sopenharmony_ciOpBranch %loop_header 1835fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 1836fd4e5da5Sopenharmony_ciOpBranch %if_merge 1837fd4e5da5Sopenharmony_ci%if_merge = OpLabel 1838fd4e5da5Sopenharmony_ciOpReturn 1839fd4e5da5Sopenharmony_ciOpFunctionEnd 1840fd4e5da5Sopenharmony_ci)"; 1841fd4e5da5Sopenharmony_ci 1842fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1843fd4e5da5Sopenharmony_ci} 1844fd4e5da5Sopenharmony_ci 1845fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ExtraBackedgeBlocksUnreachable) { 1846fd4e5da5Sopenharmony_ci const std::string text = R"( 1847fd4e5da5Sopenharmony_ci; CHECK: [[entry:%\w+]] = OpLabel 1848fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header:%\w+]] 1849fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[header]] = OpLabel 1850fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1851fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 1852fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[merge]] = OpLabel 1853fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 1854fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[continue]] = OpLabel 1855fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1856fd4e5da5Sopenharmony_ciOpCapability Kernel 1857fd4e5da5Sopenharmony_ciOpCapability Linkage 1858fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1859fd4e5da5Sopenharmony_ciOpName %func "func" 1860fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1861fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1862fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1863fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1864fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1865fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void %bool 1866fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 1867fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %bool 1868fd4e5da5Sopenharmony_ci%entry = OpLabel 1869fd4e5da5Sopenharmony_ciOpBranch %loop_header 1870fd4e5da5Sopenharmony_ci%loop_header = OpLabel 1871fd4e5da5Sopenharmony_ci; Since the continue is unreachable, %backedge will be removed. The phi will 1872fd4e5da5Sopenharmony_ci; instead require an edge from %continue. 1873fd4e5da5Sopenharmony_ci%phi = OpPhi %bool %true %entry %false %backedge 1874fd4e5da5Sopenharmony_ciOpLoopMerge %merge %continue None 1875fd4e5da5Sopenharmony_ciOpBranch %merge 1876fd4e5da5Sopenharmony_ci%continue = OpLabel 1877fd4e5da5Sopenharmony_ciOpBranch %backedge 1878fd4e5da5Sopenharmony_ci%backedge = OpLabel 1879fd4e5da5Sopenharmony_ciOpBranch %loop_header 1880fd4e5da5Sopenharmony_ci%merge = OpLabel 1881fd4e5da5Sopenharmony_ciOpReturn 1882fd4e5da5Sopenharmony_ciOpFunctionEnd 1883fd4e5da5Sopenharmony_ci)"; 1884fd4e5da5Sopenharmony_ci 1885fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1886fd4e5da5Sopenharmony_ci} 1887fd4e5da5Sopenharmony_ci 1888fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, NoUnnecessaryChanges) { 1889fd4e5da5Sopenharmony_ci const std::string text = R"( 1890fd4e5da5Sopenharmony_ciOpCapability Shader 1891fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1892fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 1893fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1894fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1895fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1896fd4e5da5Sopenharmony_ci%undef = OpUndef %bool 1897fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 1898fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 1899fd4e5da5Sopenharmony_ci%1 = OpLabel 1900fd4e5da5Sopenharmony_ciOpBranch %2 1901fd4e5da5Sopenharmony_ci%2 = OpLabel 1902fd4e5da5Sopenharmony_ciOpLoopMerge %4 %5 None 1903fd4e5da5Sopenharmony_ciOpBranch %6 1904fd4e5da5Sopenharmony_ci%6 = OpLabel 1905fd4e5da5Sopenharmony_ciOpReturn 1906fd4e5da5Sopenharmony_ci%5 = OpLabel 1907fd4e5da5Sopenharmony_ciOpBranch %2 1908fd4e5da5Sopenharmony_ci%4 = OpLabel 1909fd4e5da5Sopenharmony_ciOpUnreachable 1910fd4e5da5Sopenharmony_ciOpFunctionEnd 1911fd4e5da5Sopenharmony_ci)"; 1912fd4e5da5Sopenharmony_ci 1913fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<DeadBranchElimPass>(text, true); 1914fd4e5da5Sopenharmony_ci EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); 1915fd4e5da5Sopenharmony_ci} 1916fd4e5da5Sopenharmony_ci 1917fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ExtraBackedgePartiallyDead) { 1918fd4e5da5Sopenharmony_ci const std::string text = R"( 1919fd4e5da5Sopenharmony_ci; CHECK: OpLabel 1920fd4e5da5Sopenharmony_ci; CHECK: [[header:%\w+]] = OpLabel 1921fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1922fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 1923fd4e5da5Sopenharmony_ci; CHECK: [[continue]] = OpLabel 1924fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[extra:%\w+]] 1925fd4e5da5Sopenharmony_ci; CHECK: [[extra]] = OpLabel 1926fd4e5da5Sopenharmony_ci; CHECK-NOT: OpSelectionMerge 1927fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[else:%\w+]] 1928fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[else]] = OpLabel 1929fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalOr 1930fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[backedge:%\w+]] 1931fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[backedge:%\w+]] = OpLabel 1932fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1933fd4e5da5Sopenharmony_ciOpCapability Kernel 1934fd4e5da5Sopenharmony_ciOpCapability Linkage 1935fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1936fd4e5da5Sopenharmony_ciOpName %func "func" 1937fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 1938fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1939fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1940fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 1941fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 1942fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void %bool 1943fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 1944fd4e5da5Sopenharmony_ci%param = OpFunctionParameter %bool 1945fd4e5da5Sopenharmony_ci%entry = OpLabel 1946fd4e5da5Sopenharmony_ciOpBranch %loop_header 1947fd4e5da5Sopenharmony_ci%loop_header = OpLabel 1948fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %continue None 1949fd4e5da5Sopenharmony_ciOpBranchConditional %param %loop_merge %continue 1950fd4e5da5Sopenharmony_ci%continue = OpLabel 1951fd4e5da5Sopenharmony_ciOpBranch %extra 1952fd4e5da5Sopenharmony_ci%extra = OpLabel 1953fd4e5da5Sopenharmony_ciOpSelectionMerge %backedge None 1954fd4e5da5Sopenharmony_ciOpBranchConditional %false %then %else 1955fd4e5da5Sopenharmony_ci%then = OpLabel 1956fd4e5da5Sopenharmony_ci%and = OpLogicalAnd %bool %true %false 1957fd4e5da5Sopenharmony_ciOpBranch %backedge 1958fd4e5da5Sopenharmony_ci%else = OpLabel 1959fd4e5da5Sopenharmony_ci%or = OpLogicalOr %bool %true %false 1960fd4e5da5Sopenharmony_ciOpBranch %backedge 1961fd4e5da5Sopenharmony_ci%backedge = OpLabel 1962fd4e5da5Sopenharmony_ciOpBranch %loop_header 1963fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 1964fd4e5da5Sopenharmony_ciOpReturn 1965fd4e5da5Sopenharmony_ciOpFunctionEnd 1966fd4e5da5Sopenharmony_ci)"; 1967fd4e5da5Sopenharmony_ci 1968fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 1969fd4e5da5Sopenharmony_ci} 1970fd4e5da5Sopenharmony_ci 1971fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, UnreachableContinuePhiInMerge) { 1972fd4e5da5Sopenharmony_ci const std::string text = R"( 1973fd4e5da5Sopenharmony_ci; CHECK: [[entry:%\w+]] = OpLabel 1974fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header:%\w+]] 1975fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[header]] = OpLabel 1976fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]] None 1977fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[label:%\w+]] 1978fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[label]] = OpLabel 1979fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[fadd:%\w+]] = OpFAdd 1980fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[label:%\w+]] 1981fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[label]] = OpLabel 1982fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[merge]] 1983fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[continue]] = OpLabel 1984fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[header]] 1985fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[merge]] = OpLabel 1986fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore {{%\w+}} [[fadd]] 1987fd4e5da5Sopenharmony_ci OpCapability Shader 1988fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1989fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1990fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %o 1991fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 1992fd4e5da5Sopenharmony_ci OpSource GLSL 430 1993fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 1994fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_include_directive" 1995fd4e5da5Sopenharmony_ci OpName %main "main" 1996fd4e5da5Sopenharmony_ci OpName %o "o" 1997fd4e5da5Sopenharmony_ci OpName %S "S" 1998fd4e5da5Sopenharmony_ci OpMemberName %S 0 "a" 1999fd4e5da5Sopenharmony_ci OpName %U_t "U_t" 2000fd4e5da5Sopenharmony_ci OpMemberName %U_t 0 "g_F" 2001fd4e5da5Sopenharmony_ci OpMemberName %U_t 1 "g_F2" 2002fd4e5da5Sopenharmony_ci OpDecorate %o Location 0 2003fd4e5da5Sopenharmony_ci OpMemberDecorate %S 0 Offset 0 2004fd4e5da5Sopenharmony_ci OpMemberDecorate %U_t 0 Volatile 2005fd4e5da5Sopenharmony_ci OpMemberDecorate %U_t 0 Offset 0 2006fd4e5da5Sopenharmony_ci OpMemberDecorate %U_t 1 Offset 4 2007fd4e5da5Sopenharmony_ci OpDecorate %U_t BufferBlock 2008fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2009fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void 2010fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 2011fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 2012fd4e5da5Sopenharmony_ci %float_0 = OpConstant %float 0 2013fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2014fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 2015fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 2016fd4e5da5Sopenharmony_ci %int_10 = OpConstant %int 10 2017fd4e5da5Sopenharmony_ci %bool = OpTypeBool 2018fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 2019fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 2020fd4e5da5Sopenharmony_ci %float_5 = OpConstant %float 5 2021fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 2022fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 2023fd4e5da5Sopenharmony_ci %o = OpVariable %_ptr_Output_float Output 2024fd4e5da5Sopenharmony_ci %S = OpTypeStruct %float 2025fd4e5da5Sopenharmony_ci %U_t = OpTypeStruct %S %S 2026fd4e5da5Sopenharmony_ci%_ptr_Uniform_U_t = OpTypePointer Uniform %U_t 2027fd4e5da5Sopenharmony_ci %main = OpFunction %void None %7 2028fd4e5da5Sopenharmony_ci %22 = OpLabel 2029fd4e5da5Sopenharmony_ci OpBranch %23 2030fd4e5da5Sopenharmony_ci %23 = OpLabel 2031fd4e5da5Sopenharmony_ci %24 = OpPhi %float %float_0 %22 %25 %26 2032fd4e5da5Sopenharmony_ci %27 = OpPhi %int %int_0 %22 %28 %26 2033fd4e5da5Sopenharmony_ci OpLoopMerge %29 %26 None 2034fd4e5da5Sopenharmony_ci OpBranch %40 2035fd4e5da5Sopenharmony_ci %40 = OpLabel 2036fd4e5da5Sopenharmony_ci %25 = OpFAdd %float %24 %float_1 2037fd4e5da5Sopenharmony_ci OpSelectionMerge %30 None 2038fd4e5da5Sopenharmony_ci OpBranchConditional %true %31 %30 2039fd4e5da5Sopenharmony_ci %31 = OpLabel 2040fd4e5da5Sopenharmony_ci OpBranch %29 2041fd4e5da5Sopenharmony_ci %30 = OpLabel 2042fd4e5da5Sopenharmony_ci OpBranch %26 2043fd4e5da5Sopenharmony_ci %26 = OpLabel 2044fd4e5da5Sopenharmony_ci %28 = OpIAdd %int %27 %int_1 2045fd4e5da5Sopenharmony_ci %32 = OpSLessThan %bool %27 %int_10 2046fd4e5da5Sopenharmony_ci; continue block branches to the header or another none dead block. 2047fd4e5da5Sopenharmony_ci OpBranchConditional %32 %23 %29 2048fd4e5da5Sopenharmony_ci %29 = OpLabel 2049fd4e5da5Sopenharmony_ci %33 = OpPhi %float %24 %26 %25 %31 2050fd4e5da5Sopenharmony_ci OpStore %o %33 2051fd4e5da5Sopenharmony_ci OpReturn 2052fd4e5da5Sopenharmony_ci OpFunctionEnd 2053fd4e5da5Sopenharmony_ci)"; 2054fd4e5da5Sopenharmony_ci 2055fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 2056fd4e5da5Sopenharmony_ci} 2057fd4e5da5Sopenharmony_ci 2058fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, NonStructuredIf) { 2059fd4e5da5Sopenharmony_ci const std::string text = R"( 2060fd4e5da5Sopenharmony_ci; CHECK-NOT: OpBranchConditional 2061fd4e5da5Sopenharmony_ciOpCapability Kernel 2062fd4e5da5Sopenharmony_ciOpCapability Linkage 2063fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 2064fd4e5da5Sopenharmony_ciOpDecorate %func LinkageAttributes "func" Export 2065fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2066fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2067fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2068fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void 2069fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy 2070fd4e5da5Sopenharmony_ci%entry = OpLabel 2071fd4e5da5Sopenharmony_ciOpBranchConditional %true %then %else 2072fd4e5da5Sopenharmony_ci%then = OpLabel 2073fd4e5da5Sopenharmony_ciOpBranch %final 2074fd4e5da5Sopenharmony_ci%else = OpLabel 2075fd4e5da5Sopenharmony_ciOpBranch %final 2076fd4e5da5Sopenharmony_ci%final = OpLabel 2077fd4e5da5Sopenharmony_ciOpReturn 2078fd4e5da5Sopenharmony_ciOpFunctionEnd 2079fd4e5da5Sopenharmony_ci)"; 2080fd4e5da5Sopenharmony_ci 2081fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 2082fd4e5da5Sopenharmony_ci} 2083fd4e5da5Sopenharmony_ci 2084fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ReorderBlocks) { 2085fd4e5da5Sopenharmony_ci const std::string text = R"( 2086fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2087fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[label:%\w+]] 2088fd4e5da5Sopenharmony_ci; CHECK: [[label:%\w+]] = OpLabel 2089fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLogicalNot 2090fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[label:%\w+]] 2091fd4e5da5Sopenharmony_ci; CHECK: [[label]] = OpLabel 2092fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2093fd4e5da5Sopenharmony_ciOpCapability Shader 2094fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2095fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 2096fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 2097fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2098fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2099fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2100fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 2101fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 2102fd4e5da5Sopenharmony_ci%1 = OpLabel 2103fd4e5da5Sopenharmony_ciOpSelectionMerge %3 None 2104fd4e5da5Sopenharmony_ciOpBranchConditional %true %2 %3 2105fd4e5da5Sopenharmony_ci%3 = OpLabel 2106fd4e5da5Sopenharmony_ciOpReturn 2107fd4e5da5Sopenharmony_ci%2 = OpLabel 2108fd4e5da5Sopenharmony_ci%not = OpLogicalNot %bool %true 2109fd4e5da5Sopenharmony_ciOpBranch %3 2110fd4e5da5Sopenharmony_ciOpFunctionEnd 2111fd4e5da5Sopenharmony_ci)"; 2112fd4e5da5Sopenharmony_ci 2113fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 2114fd4e5da5Sopenharmony_ci} 2115fd4e5da5Sopenharmony_ci 2116fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ReorderBlocksMultiple) { 2117fd4e5da5Sopenharmony_ci // Checks are not important. The validation post optimization is the 2118fd4e5da5Sopenharmony_ci // important part. 2119fd4e5da5Sopenharmony_ci const std::string text = R"( 2120fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2121fd4e5da5Sopenharmony_ciOpCapability Shader 2122fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2123fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 2124fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 2125fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2126fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2127fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2128fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 2129fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 2130fd4e5da5Sopenharmony_ci%1 = OpLabel 2131fd4e5da5Sopenharmony_ciOpSelectionMerge %3 None 2132fd4e5da5Sopenharmony_ciOpBranchConditional %true %2 %3 2133fd4e5da5Sopenharmony_ci%3 = OpLabel 2134fd4e5da5Sopenharmony_ciOpReturn 2135fd4e5da5Sopenharmony_ci%2 = OpLabel 2136fd4e5da5Sopenharmony_ciOpBranch %4 2137fd4e5da5Sopenharmony_ci%4 = OpLabel 2138fd4e5da5Sopenharmony_ciOpBranch %3 2139fd4e5da5Sopenharmony_ciOpFunctionEnd 2140fd4e5da5Sopenharmony_ci)"; 2141fd4e5da5Sopenharmony_ci 2142fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 2143fd4e5da5Sopenharmony_ci} 2144fd4e5da5Sopenharmony_ci 2145fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, ReorderBlocksMultiple2) { 2146fd4e5da5Sopenharmony_ci // Checks are not important. The validation post optimization is the 2147fd4e5da5Sopenharmony_ci // important part. 2148fd4e5da5Sopenharmony_ci const std::string text = R"( 2149fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2150fd4e5da5Sopenharmony_ciOpCapability Shader 2151fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2152fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 2153fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 2154fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2155fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2156fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2157fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void 2158fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty 2159fd4e5da5Sopenharmony_ci%1 = OpLabel 2160fd4e5da5Sopenharmony_ciOpSelectionMerge %3 None 2161fd4e5da5Sopenharmony_ciOpBranchConditional %true %2 %3 2162fd4e5da5Sopenharmony_ci%3 = OpLabel 2163fd4e5da5Sopenharmony_ciOpBranch %5 2164fd4e5da5Sopenharmony_ci%5 = OpLabel 2165fd4e5da5Sopenharmony_ciOpReturn 2166fd4e5da5Sopenharmony_ci%2 = OpLabel 2167fd4e5da5Sopenharmony_ciOpBranch %4 2168fd4e5da5Sopenharmony_ci%4 = OpLabel 2169fd4e5da5Sopenharmony_ciOpBranch %3 2170fd4e5da5Sopenharmony_ciOpFunctionEnd 2171fd4e5da5Sopenharmony_ci)"; 2172fd4e5da5Sopenharmony_ci 2173fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 2174fd4e5da5Sopenharmony_ci} 2175fd4e5da5Sopenharmony_ci 2176fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithEarlyExit1) { 2177fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2178fd4e5da5Sopenharmony_ci // to the merge node, then the OpSelectionMerge instruction is positioned 2179fd4e5da5Sopenharmony_ci // correctly. 2180fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2181fd4e5da5Sopenharmony_ciOpCapability Shader 2182fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2183fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2184fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2185fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2186fd4e5da5Sopenharmony_ciOpSource GLSL 140 2187fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2188fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2189fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2190fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2191fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2192fd4e5da5Sopenharmony_ci)"; 2193fd4e5da5Sopenharmony_ci 2194fd4e5da5Sopenharmony_ci const std::string body = 2195fd4e5da5Sopenharmony_ci R"( 2196fd4e5da5Sopenharmony_ci; CHECK: OpFunction 2197fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 2198fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[taken_branch:%\w+]] 2199fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[taken_branch]] = OpLabel 2200fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]] 2201fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[merge]] {{%\w+}} 2202fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2203fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2204fd4e5da5Sopenharmony_ciOpSelectionMerge %outer_merge None 2205fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb1 %bb3 2206fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2207fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %outer_merge %bb2 2208fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2209fd4e5da5Sopenharmony_ciOpBranch %outer_merge 2210fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2211fd4e5da5Sopenharmony_ciOpBranch %outer_merge 2212fd4e5da5Sopenharmony_ci%outer_merge = OpLabel 2213fd4e5da5Sopenharmony_ciOpReturn 2214fd4e5da5Sopenharmony_ciOpFunctionEnd 2215fd4e5da5Sopenharmony_ci)"; 2216fd4e5da5Sopenharmony_ci 2217fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2218fd4e5da5Sopenharmony_ci} 2219fd4e5da5Sopenharmony_ci 2220fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithEarlyExit2) { 2221fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2222fd4e5da5Sopenharmony_ci // to the merge node, then the OpSelectionMerge instruction is positioned 2223fd4e5da5Sopenharmony_ci // correctly. 2224fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2225fd4e5da5Sopenharmony_ciOpCapability Shader 2226fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2227fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2228fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2229fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2230fd4e5da5Sopenharmony_ciOpSource GLSL 140 2231fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2232fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2233fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2234fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2235fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2236fd4e5da5Sopenharmony_ci)"; 2237fd4e5da5Sopenharmony_ci 2238fd4e5da5Sopenharmony_ci const std::string body = 2239fd4e5da5Sopenharmony_ci R"( 2240fd4e5da5Sopenharmony_ci; CHECK: OpFunction 2241fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 2242fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2243fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[bb1]] = OpLabel 2244fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[inner_merge:%\w+]] 2245fd4e5da5Sopenharmony_ci; CHECK: [[inner_merge]] = OpLabel 2246fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[outer_merge:%\w+]] 2247fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[outer_merge]:%\w+]] {{%\w+}} 2248fd4e5da5Sopenharmony_ci; CHECK: [[outer_merge]] = OpLabel 2249fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2250fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2251fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2252fd4e5da5Sopenharmony_ciOpSelectionMerge %outer_merge None 2253fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb1 %bb5 2254fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2255fd4e5da5Sopenharmony_ciOpSelectionMerge %inner_merge None 2256fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %bb2 %bb3 2257fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2258fd4e5da5Sopenharmony_ciOpBranch %inner_merge 2259fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2260fd4e5da5Sopenharmony_ciOpBranch %inner_merge 2261fd4e5da5Sopenharmony_ci%inner_merge = OpLabel 2262fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %outer_merge %bb4 2263fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2264fd4e5da5Sopenharmony_ciOpBranch %outer_merge 2265fd4e5da5Sopenharmony_ci%bb5 = OpLabel 2266fd4e5da5Sopenharmony_ciOpBranch %outer_merge 2267fd4e5da5Sopenharmony_ci%outer_merge = OpLabel 2268fd4e5da5Sopenharmony_ciOpReturn 2269fd4e5da5Sopenharmony_ciOpFunctionEnd 2270fd4e5da5Sopenharmony_ci)"; 2271fd4e5da5Sopenharmony_ci 2272fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2273fd4e5da5Sopenharmony_ci} 2274fd4e5da5Sopenharmony_ci 2275fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithConditionalExit) { 2276fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2277fd4e5da5Sopenharmony_ci // to the merge node, then we keep the OpSelectionMerge on that branch. 2278fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2279fd4e5da5Sopenharmony_ciOpCapability Shader 2280fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2281fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2282fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2283fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2284fd4e5da5Sopenharmony_ciOpSource GLSL 140 2285fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2286fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2287fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2288fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2289fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2290fd4e5da5Sopenharmony_ci%undef_int = OpUndef %uint 2291fd4e5da5Sopenharmony_ci)"; 2292fd4e5da5Sopenharmony_ci 2293fd4e5da5Sopenharmony_ci const std::string body = 2294fd4e5da5Sopenharmony_ci R"( 2295fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] 2296fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2297fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2298fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2299fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2300fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[sel_merge:%\w+]] None 2301fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSwitch {{%\w+}} [[sel_merge]] 1 [[bb3:%\w+]] 2302fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2303fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[sel_merge]] 2304fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2305fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2306fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2307fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2308fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2309fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2310fd4e5da5Sopenharmony_ciOpBranch %loop_header 2311fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2312fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2313fd4e5da5Sopenharmony_ciOpBranch %bb1 2314fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2315fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2316fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2317fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2318fd4e5da5Sopenharmony_ciOpSwitch %undef_int %sel_merge 1 %bb3 2319fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2320fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2321fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2322fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2323fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2324fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2325fd4e5da5Sopenharmony_ci%cont = OpLabel 2326fd4e5da5Sopenharmony_ciOpBranch %loop_header 2327fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2328fd4e5da5Sopenharmony_ciOpReturn 2329fd4e5da5Sopenharmony_ciOpFunctionEnd 2330fd4e5da5Sopenharmony_ci)"; 2331fd4e5da5Sopenharmony_ci 2332fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2333fd4e5da5Sopenharmony_ci} 2334fd4e5da5Sopenharmony_ci 2335fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoop) { 2336fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2337fd4e5da5Sopenharmony_ci // to a loop surrounding the selection merge, then we do not keep the 2338fd4e5da5Sopenharmony_ci // OpSelectionMerge instruction. 2339fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2340fd4e5da5Sopenharmony_ciOpCapability Shader 2341fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2342fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2343fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2344fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2345fd4e5da5Sopenharmony_ciOpSource GLSL 140 2346fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2347fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2348fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2349fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2350fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2351fd4e5da5Sopenharmony_ci)"; 2352fd4e5da5Sopenharmony_ci 2353fd4e5da5Sopenharmony_ci const std::string body = 2354fd4e5da5Sopenharmony_ci R"( 2355fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] 2356fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2357fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2358fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2359fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2360fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[bb3:%\w+]] [[loop_merge]] 2361fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2362fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[sel_merge:%\w+]] 2363fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2364fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2365fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2366fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2367fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2368fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2369fd4e5da5Sopenharmony_ciOpBranch %loop_header 2370fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2371fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2372fd4e5da5Sopenharmony_ciOpBranch %bb1 2373fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2374fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2375fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2376fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2377fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %bb3 %loop_merge 2378fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2379fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2380fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2381fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2382fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2383fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2384fd4e5da5Sopenharmony_ci%cont = OpLabel 2385fd4e5da5Sopenharmony_ciOpBranch %loop_header 2386fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2387fd4e5da5Sopenharmony_ciOpReturn 2388fd4e5da5Sopenharmony_ciOpFunctionEnd 2389fd4e5da5Sopenharmony_ci)"; 2390fd4e5da5Sopenharmony_ci 2391fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2392fd4e5da5Sopenharmony_ci} 2393fd4e5da5Sopenharmony_ci 2394fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoopContinue) { 2395fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2396fd4e5da5Sopenharmony_ci // to continue of a loop surrounding the selection merge, then we do not keep 2397fd4e5da5Sopenharmony_ci // the OpSelectionMerge instruction. 2398fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2399fd4e5da5Sopenharmony_ciOpCapability Shader 2400fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2401fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2402fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2403fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2404fd4e5da5Sopenharmony_ciOpSource GLSL 140 2405fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2406fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2407fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2408fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2409fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2410fd4e5da5Sopenharmony_ci)"; 2411fd4e5da5Sopenharmony_ci 2412fd4e5da5Sopenharmony_ci const std::string body = 2413fd4e5da5Sopenharmony_ci R"(; 2414fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2415fd4e5da5Sopenharmony_ci; CHECK: [[loop_header:%\w+]] = OpLabel 2416fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] 2417fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2418fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2419fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2420fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2421fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[bb3:%\w+]] [[loop_cont]] 2422fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2423fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[sel_merge:%\w+]] 2424fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2425fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2426fd4e5da5Sopenharmony_ci; CHECK: [[loop_cont]] = OpLabel 2427fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_header]] 2428fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2429fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2430fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2431fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2432fd4e5da5Sopenharmony_ciOpBranch %loop_header 2433fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2434fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2435fd4e5da5Sopenharmony_ciOpBranch %bb1 2436fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2437fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2438fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2439fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2440fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %bb3 %cont 2441fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2442fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2443fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2444fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2445fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2446fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2447fd4e5da5Sopenharmony_ci%cont = OpLabel 2448fd4e5da5Sopenharmony_ciOpBranch %loop_header 2449fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2450fd4e5da5Sopenharmony_ciOpReturn 2451fd4e5da5Sopenharmony_ciOpFunctionEnd 2452fd4e5da5Sopenharmony_ci)"; 2453fd4e5da5Sopenharmony_ci 2454fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2455fd4e5da5Sopenharmony_ci} 2456fd4e5da5Sopenharmony_ci 2457fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoop2) { 2458fd4e5da5Sopenharmony_ci // Same as |SelectionMergeWithExitToLoop|, except the switch goes to the loop 2459fd4e5da5Sopenharmony_ci // merge or the selection merge. In this case, we do not need an 2460fd4e5da5Sopenharmony_ci // OpSelectionMerge either. 2461fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2462fd4e5da5Sopenharmony_ciOpCapability Shader 2463fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2464fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2465fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2466fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2467fd4e5da5Sopenharmony_ciOpSource GLSL 140 2468fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2469fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2470fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2471fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2472fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2473fd4e5da5Sopenharmony_ci)"; 2474fd4e5da5Sopenharmony_ci 2475fd4e5da5Sopenharmony_ci const std::string body = 2476fd4e5da5Sopenharmony_ci R"( 2477fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] 2478fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2479fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2480fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2481fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2482fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[sel_merge:%\w+]] [[loop_merge]] 2483fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2484fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2485fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2486fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2487fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2488fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2489fd4e5da5Sopenharmony_ciOpBranch %loop_header 2490fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2491fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2492fd4e5da5Sopenharmony_ciOpBranch %bb1 2493fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2494fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2495fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2496fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2497fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %sel_merge %loop_merge 2498fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2499fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2500fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2501fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2502fd4e5da5Sopenharmony_ci%cont = OpLabel 2503fd4e5da5Sopenharmony_ciOpBranch %loop_header 2504fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2505fd4e5da5Sopenharmony_ciOpReturn 2506fd4e5da5Sopenharmony_ciOpFunctionEnd 2507fd4e5da5Sopenharmony_ci)"; 2508fd4e5da5Sopenharmony_ci 2509fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2510fd4e5da5Sopenharmony_ci} 2511fd4e5da5Sopenharmony_ci 2512fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoopContinue2) { 2513fd4e5da5Sopenharmony_ci // Same as |SelectionMergeWithExitToLoopContinue|, except the branch goes to 2514fd4e5da5Sopenharmony_ci // the loop continue or the selection merge. In this case, we do not need an 2515fd4e5da5Sopenharmony_ci // OpSelectionMerge either. 2516fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2517fd4e5da5Sopenharmony_ciOpCapability Shader 2518fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2519fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2520fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2521fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2522fd4e5da5Sopenharmony_ciOpSource GLSL 140 2523fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2524fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2525fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2526fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2527fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2528fd4e5da5Sopenharmony_ci)"; 2529fd4e5da5Sopenharmony_ci 2530fd4e5da5Sopenharmony_ci const std::string body = 2531fd4e5da5Sopenharmony_ci R"( 2532fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2533fd4e5da5Sopenharmony_ci; CHECK: [[loop_header:%\w+]] = OpLabel 2534fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] 2535fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2536fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2537fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2538fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2539fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[sel_merge:%\w+]] [[loop_cont]] 2540fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2541fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2542fd4e5da5Sopenharmony_ci; CHECK: [[loop_cont]] = OpLabel 2543fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[loop_header]] 2544fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2545fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2546fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2547fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2548fd4e5da5Sopenharmony_ciOpBranch %loop_header 2549fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2550fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2551fd4e5da5Sopenharmony_ciOpBranch %bb1 2552fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2553fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2554fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2555fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2556fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %sel_merge %cont 2557fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2558fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2559fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2560fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2561fd4e5da5Sopenharmony_ci%cont = OpLabel 2562fd4e5da5Sopenharmony_ciOpBranch %loop_header 2563fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2564fd4e5da5Sopenharmony_ciOpReturn 2565fd4e5da5Sopenharmony_ciOpFunctionEnd 2566fd4e5da5Sopenharmony_ci)"; 2567fd4e5da5Sopenharmony_ci 2568fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2569fd4e5da5Sopenharmony_ci} 2570fd4e5da5Sopenharmony_ci 2571fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoop3) { 2572fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2573fd4e5da5Sopenharmony_ci // to the selection merge, and another block inside the selection merge, 2574fd4e5da5Sopenharmony_ci // then we must keep the OpSelectionMerge instruction on that branch. 2575fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2576fd4e5da5Sopenharmony_ciOpCapability Shader 2577fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2578fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2579fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2580fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2581fd4e5da5Sopenharmony_ciOpSource GLSL 140 2582fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2583fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2584fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2585fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2586fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2587fd4e5da5Sopenharmony_ci%undef_int = OpUndef %uint 2588fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2589fd4e5da5Sopenharmony_ci)"; 2590fd4e5da5Sopenharmony_ci 2591fd4e5da5Sopenharmony_ci const std::string body = 2592fd4e5da5Sopenharmony_ci R"( 2593fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] 2594fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2595fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2596fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2597fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2598fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[sel_merge:%\w+]] None 2599fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[sel_merge]] [[bb3:%\w+]] 2600fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2601fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[sel_merge]] 2602fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2603fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2604fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2605fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2606fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2607fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2608fd4e5da5Sopenharmony_ciOpBranch %loop_header 2609fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2610fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2611fd4e5da5Sopenharmony_ciOpBranch %bb1 2612fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2613fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2614fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2615fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2616fd4e5da5Sopenharmony_ci;OpSwitch %undef_int %sel_merge 0 %loop_merge 1 %bb3 2617fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %sel_merge %bb3 2618fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2619fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2620fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2621fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2622fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2623fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2624fd4e5da5Sopenharmony_ci%cont = OpLabel 2625fd4e5da5Sopenharmony_ciOpBranch %loop_header 2626fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2627fd4e5da5Sopenharmony_ciOpReturn 2628fd4e5da5Sopenharmony_ciOpFunctionEnd 2629fd4e5da5Sopenharmony_ci)"; 2630fd4e5da5Sopenharmony_ci 2631fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2632fd4e5da5Sopenharmony_ci} 2633fd4e5da5Sopenharmony_ci 2634fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithExitToLoopContinue3) { 2635fd4e5da5Sopenharmony_ci // Checks that if a selection merge construct contains a conditional branch 2636fd4e5da5Sopenharmony_ci // the selection merge, and another block inside the selection merge, then we 2637fd4e5da5Sopenharmony_ci // must keep the OpSelectionMerge instruction on that branch. 2638fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2639fd4e5da5Sopenharmony_ciOpCapability Shader 2640fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2641fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2642fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2643fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2644fd4e5da5Sopenharmony_ciOpSource GLSL 140 2645fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2646fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2647fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2648fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2649fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2650fd4e5da5Sopenharmony_ci%undef_int = OpUndef %uint 2651fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2652fd4e5da5Sopenharmony_ci)"; 2653fd4e5da5Sopenharmony_ci 2654fd4e5da5Sopenharmony_ci const std::string body = 2655fd4e5da5Sopenharmony_ci R"( 2656fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2657fd4e5da5Sopenharmony_ci; CHECK: [[loop_header:%\w+]] = OpLabel 2658fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] [[loop_continue:%\w+]] 2659fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2660fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2661fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2662fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2663fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[sel_merge:%\w+]] None 2664fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[sel_merge]] [[bb3:%\w+]] 2665fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2666fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[sel_merge]] 2667fd4e5da5Sopenharmony_ci; CHECK: [[sel_merge]] = OpLabel 2668fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_merge]] 2669fd4e5da5Sopenharmony_ci; CHECK: [[loop_continue]] = OpLabel 2670fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_header]] 2671fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2672fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2673fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2674fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2675fd4e5da5Sopenharmony_ciOpBranch %loop_header 2676fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2677fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2678fd4e5da5Sopenharmony_ciOpBranch %bb1 2679fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2680fd4e5da5Sopenharmony_ciOpSelectionMerge %sel_merge None 2681fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2682fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2683fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %sel_merge %bb3 2684fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2685fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2686fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2687fd4e5da5Sopenharmony_ciOpBranch %sel_merge 2688fd4e5da5Sopenharmony_ci%sel_merge = OpLabel 2689fd4e5da5Sopenharmony_ciOpBranch %loop_merge 2690fd4e5da5Sopenharmony_ci%cont = OpLabel 2691fd4e5da5Sopenharmony_ciOpBranch %loop_header 2692fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2693fd4e5da5Sopenharmony_ciOpReturn 2694fd4e5da5Sopenharmony_ciOpFunctionEnd 2695fd4e5da5Sopenharmony_ci)"; 2696fd4e5da5Sopenharmony_ci 2697fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, true); 2698fd4e5da5Sopenharmony_ci} 2699fd4e5da5Sopenharmony_ci 2700fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeSameAsLoopContinue) { 2701fd4e5da5Sopenharmony_ci // Same as |SelectionMergeWithExitToLoopContinue|, except the branch in the 2702fd4e5da5Sopenharmony_ci // selection construct is an |OpSwitch| instead of an |OpConditionalBranch|. 2703fd4e5da5Sopenharmony_ci // The OpSelectionMerge instruction is not needed in this case either. 2704fd4e5da5Sopenharmony_ci const std::string predefs = R"( 2705fd4e5da5Sopenharmony_ciOpCapability Shader 2706fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2707fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2708fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 2709fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 2710fd4e5da5Sopenharmony_ciOpSource GLSL 140 2711fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2712fd4e5da5Sopenharmony_ci%func_type = OpTypeFunction %void 2713fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2714fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2715fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 2716fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 2717fd4e5da5Sopenharmony_ci)"; 2718fd4e5da5Sopenharmony_ci 2719fd4e5da5Sopenharmony_ci const std::string body = 2720fd4e5da5Sopenharmony_ci R"( 2721fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2722fd4e5da5Sopenharmony_ci; CHECK: [[loop_header:%\w+]] = OpLabel 2723fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] 2724fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb1:%\w+]] 2725fd4e5da5Sopenharmony_ci; CHECK: [[bb1]] = OpLabel 2726fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 2727fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 2728fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge [[loop_cont]] 2729fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[bb3:%\w+]] [[loop_cont]] 2730fd4e5da5Sopenharmony_ci; CHECK: [[bb3]] = OpLabel 2731fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[loop_cont]] 2732fd4e5da5Sopenharmony_ci; CHECK: [[loop_cont]] = OpLabel 2733fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional {{%\w+}} [[loop_header]] [[loop_merge]] 2734fd4e5da5Sopenharmony_ci; CHECK: [[loop_merge]] = OpLabel 2735fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn 2736fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func_type 2737fd4e5da5Sopenharmony_ci%entry_bb = OpLabel 2738fd4e5da5Sopenharmony_ciOpBranch %loop_header 2739fd4e5da5Sopenharmony_ci%loop_header = OpLabel 2740fd4e5da5Sopenharmony_ciOpLoopMerge %loop_merge %cont None 2741fd4e5da5Sopenharmony_ciOpBranch %bb1 2742fd4e5da5Sopenharmony_ci%bb1 = OpLabel 2743fd4e5da5Sopenharmony_ciOpSelectionMerge %cont None 2744fd4e5da5Sopenharmony_ciOpBranchConditional %true %bb2 %bb4 2745fd4e5da5Sopenharmony_ci%bb2 = OpLabel 2746fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %bb3 %cont 2747fd4e5da5Sopenharmony_ci%bb3 = OpLabel 2748fd4e5da5Sopenharmony_ciOpBranch %cont 2749fd4e5da5Sopenharmony_ci%bb4 = OpLabel 2750fd4e5da5Sopenharmony_ciOpBranch %cont 2751fd4e5da5Sopenharmony_ci%cont = OpLabel 2752fd4e5da5Sopenharmony_ciOpBranchConditional %undef_bool %loop_header %loop_merge 2753fd4e5da5Sopenharmony_ci%loop_merge = OpLabel 2754fd4e5da5Sopenharmony_ciOpReturn 2755fd4e5da5Sopenharmony_ciOpFunctionEnd 2756fd4e5da5Sopenharmony_ci)"; 2757fd4e5da5Sopenharmony_ci 2758fd4e5da5Sopenharmony_ci // The selection merge in the loop naming the continue target as merge is 2759fd4e5da5Sopenharmony_ci // invalid, but handled by this pass so validation is disabled. 2760fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(predefs + body, false); 2761fd4e5da5Sopenharmony_ci} 2762fd4e5da5Sopenharmony_ci 2763fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, SelectionMergeWithNestedLoop) { 2764fd4e5da5Sopenharmony_ci const std::string body = 2765fd4e5da5Sopenharmony_ci R"( 2766fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge1:%\w+]] 2767fd4e5da5Sopenharmony_ci; CHECK: [[merge1]] = OpLabel 2768fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[preheader:%\w+]] 2769fd4e5da5Sopenharmony_ci; CHECK: [[preheader]] = OpLabel 2770fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 2771fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header:%\w+]] 2772fd4e5da5Sopenharmony_ci; CHECK: [[header]] = OpLabel 2773fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 2774fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[merge2:%\w+]] 2775fd4e5da5Sopenharmony_ci; CHECK: [[merge2]] = OpLabel 2776fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 2777fd4e5da5Sopenharmony_ci OpCapability Shader 2778fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2779fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2780fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" 2781fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 2782fd4e5da5Sopenharmony_ci OpSource ESSL 310 2783fd4e5da5Sopenharmony_ci OpName %main "main" 2784fd4e5da5Sopenharmony_ci OpName %h "h" 2785fd4e5da5Sopenharmony_ci OpName %i "i" 2786fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2787fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 2788fd4e5da5Sopenharmony_ci %bool = OpTypeBool 2789fd4e5da5Sopenharmony_ci %_ptr_Function_bool = OpTypePointer Function %bool 2790fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 2791fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2792fd4e5da5Sopenharmony_ci %_ptr_Function_int = OpTypePointer Function %int 2793fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 2794fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 2795fd4e5da5Sopenharmony_ci %27 = OpUndef %bool 2796fd4e5da5Sopenharmony_ci %main = OpFunction %void None %3 2797fd4e5da5Sopenharmony_ci %5 = OpLabel 2798fd4e5da5Sopenharmony_ci %h = OpVariable %_ptr_Function_bool Function 2799fd4e5da5Sopenharmony_ci %i = OpVariable %_ptr_Function_int Function 2800fd4e5da5Sopenharmony_ci OpSelectionMerge %11 None 2801fd4e5da5Sopenharmony_ci OpBranchConditional %27 %10 %11 2802fd4e5da5Sopenharmony_ci %10 = OpLabel 2803fd4e5da5Sopenharmony_ci OpBranch %11 2804fd4e5da5Sopenharmony_ci %11 = OpLabel 2805fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2806fd4e5da5Sopenharmony_ci OpBranchConditional %true %13 %14 2807fd4e5da5Sopenharmony_ci %13 = OpLabel 2808fd4e5da5Sopenharmony_ci OpStore %i %int_1 2809fd4e5da5Sopenharmony_ci OpBranch %19 2810fd4e5da5Sopenharmony_ci %19 = OpLabel 2811fd4e5da5Sopenharmony_ci OpLoopMerge %21 %22 None 2812fd4e5da5Sopenharmony_ci OpBranch %23 2813fd4e5da5Sopenharmony_ci %23 = OpLabel 2814fd4e5da5Sopenharmony_ci %26 = OpSGreaterThan %bool %int_1 %int_0 2815fd4e5da5Sopenharmony_ci OpBranchConditional %true %20 %21 2816fd4e5da5Sopenharmony_ci %20 = OpLabel 2817fd4e5da5Sopenharmony_ci OpBranch %22 2818fd4e5da5Sopenharmony_ci %22 = OpLabel 2819fd4e5da5Sopenharmony_ci OpBranch %19 2820fd4e5da5Sopenharmony_ci %21 = OpLabel 2821fd4e5da5Sopenharmony_ci OpBranch %14 2822fd4e5da5Sopenharmony_ci %14 = OpLabel 2823fd4e5da5Sopenharmony_ci OpReturn 2824fd4e5da5Sopenharmony_ci OpFunctionEnd 2825fd4e5da5Sopenharmony_ci)"; 2826fd4e5da5Sopenharmony_ci 2827fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(body, true); 2828fd4e5da5Sopenharmony_ci} 2829fd4e5da5Sopenharmony_ci 2830fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, DontFoldBackedge) { 2831fd4e5da5Sopenharmony_ci const std::string body = 2832fd4e5da5Sopenharmony_ci R"(OpCapability Shader 2833fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2834fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2835fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 2836fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 2837fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2838fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 2839fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2840fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 2841fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4 2842fd4e5da5Sopenharmony_ci%7 = OpLabel 2843fd4e5da5Sopenharmony_ciOpBranch %8 2844fd4e5da5Sopenharmony_ci%8 = OpLabel 2845fd4e5da5Sopenharmony_ciOpLoopMerge %9 %10 None 2846fd4e5da5Sopenharmony_ciOpBranch %11 2847fd4e5da5Sopenharmony_ci%11 = OpLabel 2848fd4e5da5Sopenharmony_ci%12 = OpUndef %bool 2849fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 2850fd4e5da5Sopenharmony_ciOpBranchConditional %12 %13 %10 2851fd4e5da5Sopenharmony_ci%13 = OpLabel 2852fd4e5da5Sopenharmony_ciOpBranch %9 2853fd4e5da5Sopenharmony_ci%10 = OpLabel 2854fd4e5da5Sopenharmony_ciOpBranch %14 2855fd4e5da5Sopenharmony_ci%14 = OpLabel 2856fd4e5da5Sopenharmony_ciOpBranchConditional %false %8 %9 2857fd4e5da5Sopenharmony_ci%9 = OpLabel 2858fd4e5da5Sopenharmony_ciOpReturn 2859fd4e5da5Sopenharmony_ciOpFunctionEnd 2860fd4e5da5Sopenharmony_ci)"; 2861fd4e5da5Sopenharmony_ci 2862fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(body, body, true); 2863fd4e5da5Sopenharmony_ci} 2864fd4e5da5Sopenharmony_ci 2865fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, FoldBackedgeToHeader) { 2866fd4e5da5Sopenharmony_ci const std::string body = 2867fd4e5da5Sopenharmony_ci R"( 2868fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2869fd4e5da5Sopenharmony_ci; CHECK: [[header:%\w+]] = OpLabel 2870fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge {{%\w+}} [[cont:%\w+]] 2871fd4e5da5Sopenharmony_ci; CHECK: [[cont]] = OpLabel 2872fd4e5da5Sopenharmony_ci; This branch may not be in the continue block, but must come after it. 2873fd4e5da5Sopenharmony_ci; CHECK: OpBranch [[header]] 2874fd4e5da5Sopenharmony_ciOpCapability Shader 2875fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 2876fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2877fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 2878fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 2879fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2880fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 2881fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2882fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2883fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4 2884fd4e5da5Sopenharmony_ci%7 = OpLabel 2885fd4e5da5Sopenharmony_ciOpBranch %8 2886fd4e5da5Sopenharmony_ci%8 = OpLabel 2887fd4e5da5Sopenharmony_ciOpLoopMerge %9 %10 None 2888fd4e5da5Sopenharmony_ciOpBranch %11 2889fd4e5da5Sopenharmony_ci%11 = OpLabel 2890fd4e5da5Sopenharmony_ci%12 = OpUndef %bool 2891fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 2892fd4e5da5Sopenharmony_ciOpBranchConditional %12 %13 %10 2893fd4e5da5Sopenharmony_ci%13 = OpLabel 2894fd4e5da5Sopenharmony_ciOpBranch %9 2895fd4e5da5Sopenharmony_ci%10 = OpLabel 2896fd4e5da5Sopenharmony_ciOpBranch %14 2897fd4e5da5Sopenharmony_ci%14 = OpLabel 2898fd4e5da5Sopenharmony_ciOpBranchConditional %true %8 %9 2899fd4e5da5Sopenharmony_ci%9 = OpLabel 2900fd4e5da5Sopenharmony_ciOpReturn 2901fd4e5da5Sopenharmony_ciOpFunctionEnd 2902fd4e5da5Sopenharmony_ci)"; 2903fd4e5da5Sopenharmony_ci 2904fd4e5da5Sopenharmony_ci // The selection merge in the loop naming the continue target as merge is 2905fd4e5da5Sopenharmony_ci // invalid, but handled by this pass so validation is disabled. 2906fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(body, false); 2907fd4e5da5Sopenharmony_ci} 2908fd4e5da5Sopenharmony_ci 2909fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, UnreachableMergeAndContinueSameBlock) { 2910fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2911fd4e5da5Sopenharmony_ci; CHECK: OpLabel 2912fd4e5da5Sopenharmony_ci; CHECK: [[outer:%\w+]] = OpLabel 2913fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLoopMerge [[outer_merge:%\w+]] [[outer_cont:%\w+]] None 2914fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[inner:%\w+]] 2915fd4e5da5Sopenharmony_ci; CHECK: [[inner]] = OpLabel 2916fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[inner_merge:%\w+]] [[inner_cont:%\w+]] None 2917fd4e5da5Sopenharmony_ci; CHECK: [[inner_cont]] = OpLabel 2918fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[inner]] 2919fd4e5da5Sopenharmony_ci; CHECK: [[inner_merge]] = OpLabel 2920fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 2921fd4e5da5Sopenharmony_ci; CHECK: [[outer_cont]] = OpLabel 2922fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[outer]] 2923fd4e5da5Sopenharmony_ci; CHECK: [[outer_merge]] = OpLabel 2924fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUnreachable 2925fd4e5da5Sopenharmony_ciOpCapability Shader 2926fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2927fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 2928fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 2929fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2930fd4e5da5Sopenharmony_ci%bool = OpTypeBool 2931fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 2932fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2933fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 2934fd4e5da5Sopenharmony_ci%entry = OpLabel 2935fd4e5da5Sopenharmony_ciOpBranch %outer_loop 2936fd4e5da5Sopenharmony_ci%outer_loop = OpLabel 2937fd4e5da5Sopenharmony_ciOpLoopMerge %outer_merge %outer_continue None 2938fd4e5da5Sopenharmony_ciOpBranch %inner_loop 2939fd4e5da5Sopenharmony_ci%inner_loop = OpLabel 2940fd4e5da5Sopenharmony_ciOpLoopMerge %inner_merge %inner_continue None 2941fd4e5da5Sopenharmony_ciOpBranch %inner_body 2942fd4e5da5Sopenharmony_ci%inner_body = OpLabel 2943fd4e5da5Sopenharmony_ciOpSelectionMerge %inner_continue None 2944fd4e5da5Sopenharmony_ciOpBranchConditional %true %ret %inner_continue 2945fd4e5da5Sopenharmony_ci%ret = OpLabel 2946fd4e5da5Sopenharmony_ciOpReturn 2947fd4e5da5Sopenharmony_ci%inner_continue = OpLabel 2948fd4e5da5Sopenharmony_ciOpBranchConditional %true %inner_merge %inner_loop 2949fd4e5da5Sopenharmony_ci%inner_merge = OpLabel 2950fd4e5da5Sopenharmony_ciOpBranch %outer_continue 2951fd4e5da5Sopenharmony_ci%outer_continue = OpLabel 2952fd4e5da5Sopenharmony_ciOpBranchConditional %true %outer_merge %outer_loop 2953fd4e5da5Sopenharmony_ci%outer_merge = OpLabel 2954fd4e5da5Sopenharmony_ciOpReturn 2955fd4e5da5Sopenharmony_ciOpFunctionEnd 2956fd4e5da5Sopenharmony_ci)"; 2957fd4e5da5Sopenharmony_ci 2958fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(spirv, true); 2959fd4e5da5Sopenharmony_ci} 2960fd4e5da5Sopenharmony_ci 2961fd4e5da5Sopenharmony_ci// Fold a switch with a nested break. The only case should be the default. 2962fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, FoldSwitchWithNestedBreak) { 2963fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2964fd4e5da5Sopenharmony_ci; CHECK: OpSwitch %int_3 [[case_bb:%\w+]]{{[[:space:]]}} 2965fd4e5da5Sopenharmony_ci; CHECK: [[case_bb]] = OpLabel 2966fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpUndef 2967fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSelectionMerge 2968fd4e5da5Sopenharmony_ci OpCapability Shader 2969fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2970fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2971fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %2 "main" 2972fd4e5da5Sopenharmony_ci OpSource GLSL 450 2973fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2974fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 2975fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2976fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 2977fd4e5da5Sopenharmony_ci %int_3 = OpConstant %int 3 2978fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 2979fd4e5da5Sopenharmony_ci %bool = OpTypeBool 2980fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 2981fd4e5da5Sopenharmony_ci %10 = OpLabel 2982fd4e5da5Sopenharmony_ci OpSelectionMerge %11 None 2983fd4e5da5Sopenharmony_ci OpSwitch %int_3 %12 3 %13 2984fd4e5da5Sopenharmony_ci %12 = OpLabel 2985fd4e5da5Sopenharmony_ci OpBranch %11 2986fd4e5da5Sopenharmony_ci %13 = OpLabel 2987fd4e5da5Sopenharmony_ci %14 = OpUndef %bool 2988fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2989fd4e5da5Sopenharmony_ci OpBranchConditional %14 %16 %15 2990fd4e5da5Sopenharmony_ci %16 = OpLabel 2991fd4e5da5Sopenharmony_ci OpBranch %11 2992fd4e5da5Sopenharmony_ci %15 = OpLabel 2993fd4e5da5Sopenharmony_ci OpBranch %11 2994fd4e5da5Sopenharmony_ci %11 = OpLabel 2995fd4e5da5Sopenharmony_ci OpReturn 2996fd4e5da5Sopenharmony_ci OpFunctionEnd 2997fd4e5da5Sopenharmony_ci)"; 2998fd4e5da5Sopenharmony_ci 2999fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(spirv, true); 3000fd4e5da5Sopenharmony_ci} 3001fd4e5da5Sopenharmony_ci 3002fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, FoldBranchWithBreakToSwitch) { 3003fd4e5da5Sopenharmony_ci const std::string spirv = R"( 3004fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[sel_merge:%\w+]] 3005fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSwitch {{%\w+}} {{%\w+}} 3 [[bb:%\w+]] 3006fd4e5da5Sopenharmony_ci; CHECK: [[bb]] = OpLabel 3007fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranch [[bb2:%\w+]] 3008fd4e5da5Sopenharmony_ci; CHECK: [[bb2]] = OpLabel 3009fd4e5da5Sopenharmony_ci; CHECK-NOT: OpSelectionMerge 3010fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd 3011fd4e5da5Sopenharmony_ci OpCapability Shader 3012fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3013fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3014fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %2 "main" 3015fd4e5da5Sopenharmony_ci OpSource GLSL 450 3016fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3017fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 3018fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 3019fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 3020fd4e5da5Sopenharmony_ci %int_3 = OpConstant %int 3 3021fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 3022fd4e5da5Sopenharmony_ci %bool = OpTypeBool 3023fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 3024fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 3025fd4e5da5Sopenharmony_ci %10 = OpLabel 3026fd4e5da5Sopenharmony_ci %undef_int = OpUndef %int 3027fd4e5da5Sopenharmony_ci OpSelectionMerge %11 None 3028fd4e5da5Sopenharmony_ci OpSwitch %undef_int %12 3 %13 3029fd4e5da5Sopenharmony_ci %12 = OpLabel 3030fd4e5da5Sopenharmony_ci OpBranch %11 3031fd4e5da5Sopenharmony_ci %13 = OpLabel 3032fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 3033fd4e5da5Sopenharmony_ci OpBranchConditional %true %16 %15 3034fd4e5da5Sopenharmony_ci %16 = OpLabel 3035fd4e5da5Sopenharmony_ci %14 = OpUndef %bool 3036fd4e5da5Sopenharmony_ci OpBranchConditional %14 %11 %17 3037fd4e5da5Sopenharmony_ci %17 = OpLabel 3038fd4e5da5Sopenharmony_ci OpBranch %15 3039fd4e5da5Sopenharmony_ci %15 = OpLabel 3040fd4e5da5Sopenharmony_ci OpBranch %11 3041fd4e5da5Sopenharmony_ci %11 = OpLabel 3042fd4e5da5Sopenharmony_ci OpReturn 3043fd4e5da5Sopenharmony_ci OpFunctionEnd 3044fd4e5da5Sopenharmony_ci)"; 3045fd4e5da5Sopenharmony_ci 3046fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(spirv, true); 3047fd4e5da5Sopenharmony_ci} 3048fd4e5da5Sopenharmony_ci 3049fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, IfInSwitch) { 3050fd4e5da5Sopenharmony_ci // #version 310 es 3051fd4e5da5Sopenharmony_ci // 3052fd4e5da5Sopenharmony_ci // void main() 3053fd4e5da5Sopenharmony_ci // { 3054fd4e5da5Sopenharmony_ci // switch(0) 3055fd4e5da5Sopenharmony_ci // { 3056fd4e5da5Sopenharmony_ci // case 0: 3057fd4e5da5Sopenharmony_ci // if(false) 3058fd4e5da5Sopenharmony_ci // { 3059fd4e5da5Sopenharmony_ci // } 3060fd4e5da5Sopenharmony_ci // else 3061fd4e5da5Sopenharmony_ci // { 3062fd4e5da5Sopenharmony_ci // } 3063fd4e5da5Sopenharmony_ci // } 3064fd4e5da5Sopenharmony_ci // } 3065fd4e5da5Sopenharmony_ci 3066fd4e5da5Sopenharmony_ci const std::string before = 3067fd4e5da5Sopenharmony_ci R"(OpCapability Shader 3068fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3069fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3070fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 3071fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3072fd4e5da5Sopenharmony_ciOpSource ESSL 310 3073fd4e5da5Sopenharmony_ciOpName %main "main" 3074fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3075fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 3076fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 3077fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 3078fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3079fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 3080fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 3081fd4e5da5Sopenharmony_ci%5 = OpLabel 3082fd4e5da5Sopenharmony_ciOpSelectionMerge %9 None 3083fd4e5da5Sopenharmony_ciOpSwitch %int_0 %9 0 %8 3084fd4e5da5Sopenharmony_ci%8 = OpLabel 3085fd4e5da5Sopenharmony_ciOpSelectionMerge %13 None 3086fd4e5da5Sopenharmony_ciOpBranchConditional %false %12 %13 3087fd4e5da5Sopenharmony_ci%12 = OpLabel 3088fd4e5da5Sopenharmony_ciOpBranch %13 3089fd4e5da5Sopenharmony_ci%13 = OpLabel 3090fd4e5da5Sopenharmony_ciOpBranch %9 3091fd4e5da5Sopenharmony_ci%9 = OpLabel 3092fd4e5da5Sopenharmony_ciOpReturn 3093fd4e5da5Sopenharmony_ciOpFunctionEnd 3094fd4e5da5Sopenharmony_ci)"; 3095fd4e5da5Sopenharmony_ci 3096fd4e5da5Sopenharmony_ci const std::string after = 3097fd4e5da5Sopenharmony_ci R"(OpCapability Shader 3098fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3099fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3100fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 3101fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3102fd4e5da5Sopenharmony_ciOpSource ESSL 310 3103fd4e5da5Sopenharmony_ciOpName %main "main" 3104fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3105fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 3106fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 3107fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 3108fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3109fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool 3110fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4 3111fd4e5da5Sopenharmony_ci%9 = OpLabel 3112fd4e5da5Sopenharmony_ciOpBranch %11 3113fd4e5da5Sopenharmony_ci%11 = OpLabel 3114fd4e5da5Sopenharmony_ciOpBranch %12 3115fd4e5da5Sopenharmony_ci%12 = OpLabel 3116fd4e5da5Sopenharmony_ciOpBranch %10 3117fd4e5da5Sopenharmony_ci%10 = OpLabel 3118fd4e5da5Sopenharmony_ciOpReturn 3119fd4e5da5Sopenharmony_ciOpFunctionEnd 3120fd4e5da5Sopenharmony_ci)"; 3121fd4e5da5Sopenharmony_ci 3122fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(before, after, true, true); 3123fd4e5da5Sopenharmony_ci} 3124fd4e5da5Sopenharmony_ci 3125fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, BreakInNestedHeaderWithSingleCase) { 3126fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 3127fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3128fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3129fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 3130fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3131fd4e5da5Sopenharmony_ciOpSource GLSL 450 3132fd4e5da5Sopenharmony_ciOpName %main "main" 3133fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3134fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 3135fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3136fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3137fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 3138fd4e5da5Sopenharmony_ci%8 = OpUndef %bool 3139fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4 3140fd4e5da5Sopenharmony_ci%9 = OpLabel 3141fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 3142fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %11 3143fd4e5da5Sopenharmony_ci%11 = OpLabel 3144fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None 3145fd4e5da5Sopenharmony_ciOpBranchConditional %8 %10 %12 3146fd4e5da5Sopenharmony_ci%12 = OpLabel 3147fd4e5da5Sopenharmony_ciOpBranch %10 3148fd4e5da5Sopenharmony_ci%10 = OpLabel 3149fd4e5da5Sopenharmony_ciOpReturn 3150fd4e5da5Sopenharmony_ciOpFunctionEnd 3151fd4e5da5Sopenharmony_ci)"; 3152fd4e5da5Sopenharmony_ci 3153fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(text, text, true, true); 3154fd4e5da5Sopenharmony_ci} 3155fd4e5da5Sopenharmony_ci 3156fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, BreakInNestedHeaderWithTwoCases) { 3157fd4e5da5Sopenharmony_ci const std::string text = R"( 3158fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] None 3159fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpSwitch %uint_0 [[bb:%\w+\n]] 3160fd4e5da5Sopenharmony_ciOpCapability Shader 3161fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3162fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3163fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 3164fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3165fd4e5da5Sopenharmony_ciOpSource GLSL 450 3166fd4e5da5Sopenharmony_ciOpName %main "main" 3167fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3168fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 3169fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3170fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3171fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 3172fd4e5da5Sopenharmony_ci%8 = OpUndef %bool 3173fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4 3174fd4e5da5Sopenharmony_ci%9 = OpLabel 3175fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 3176fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %11 1 %12 3177fd4e5da5Sopenharmony_ci%11 = OpLabel 3178fd4e5da5Sopenharmony_ciOpSelectionMerge %13 None 3179fd4e5da5Sopenharmony_ciOpBranchConditional %8 %10 %13 3180fd4e5da5Sopenharmony_ci%13 = OpLabel 3181fd4e5da5Sopenharmony_ciOpBranch %10 3182fd4e5da5Sopenharmony_ci%12 = OpLabel 3183fd4e5da5Sopenharmony_ciOpBranch %10 3184fd4e5da5Sopenharmony_ci%10 = OpLabel 3185fd4e5da5Sopenharmony_ciOpReturn 3186fd4e5da5Sopenharmony_ciOpFunctionEnd 3187fd4e5da5Sopenharmony_ci)"; 3188fd4e5da5Sopenharmony_ci 3189fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 3190fd4e5da5Sopenharmony_ci} 3191fd4e5da5Sopenharmony_ci 3192fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, DebugInformation) { 3193fd4e5da5Sopenharmony_ci const std::string text = R"( 3194fd4e5da5Sopenharmony_ciOpCapability Shader 3195fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 3196fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 3197fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 3198fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor 3199fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 3200fd4e5da5Sopenharmony_ciOpSource GLSL 140 3201fd4e5da5Sopenharmony_ci%name = OpString "test" 3202fd4e5da5Sopenharmony_ciOpName %main "main" 3203fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 3204fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3205fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 3206fd4e5da5Sopenharmony_ci%bool = OpTypeBool 3207fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 3208fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 3209fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 3210fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 3211fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 3212fd4e5da5Sopenharmony_ci 3213fd4e5da5Sopenharmony_ci; CHECK: [[value:%\w+]] = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 3214fd4e5da5Sopenharmony_ci%12 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 3215fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 3216fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 3217fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 3218fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 3219fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 3220fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 3221fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 3222fd4e5da5Sopenharmony_ci 3223fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 3224fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %name 3225fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 3226fd4e5da5Sopenharmony_ci%ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void 3227fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %name %ty %src 0 0 %cu %name FlagIsProtected|FlagIsPrivate 0 %main 3228fd4e5da5Sopenharmony_ci 3229fd4e5da5Sopenharmony_ci; CHECK: [[bb1:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugLexicalBlock [[src:%\w+]] 1 0 [[dbg_main:%\w+]] 3230fd4e5da5Sopenharmony_ci; CHECK: [[bb2:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock [[src]] 2 0 [[dbg_main]] 3231fd4e5da5Sopenharmony_ci; CHECK: [[bb3:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock [[src]] 3 0 [[dbg_main]] 3232fd4e5da5Sopenharmony_ci%bb1 = OpExtInst %void %ext DebugLexicalBlock %src 1 0 %dbg_main 3233fd4e5da5Sopenharmony_ci%bb2 = OpExtInst %void %ext DebugLexicalBlock %src 2 0 %dbg_main 3234fd4e5da5Sopenharmony_ci%bb3 = OpExtInst %void %ext DebugLexicalBlock %src 3 0 %dbg_main 3235fd4e5da5Sopenharmony_ci 3236fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %name %uint_32 Float 3237fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable {{%\w+}} [[ty:%\w+]] [[src]] 0 0 [[dbg_main]] 3238fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugLocalVariable %name %dbg_f %src 0 0 %dbg_main FlagIsLocal 3239fd4e5da5Sopenharmony_ci; CHECK: [[dbg_bar:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable {{%\w+}} [[ty]] [[src]] 1 0 [[bb3]] 3240fd4e5da5Sopenharmony_ci%dbg_bar = OpExtInst %void %ext DebugLocalVariable %name %dbg_f %src 1 0 %bb3 FlagIsLocal 3241fd4e5da5Sopenharmony_ci 3242fd4e5da5Sopenharmony_ci%main = OpFunction %void None %5 3243fd4e5da5Sopenharmony_ci%17 = OpLabel 3244fd4e5da5Sopenharmony_ci; CHECK-NOT: DebugScope [[dbg_main]] 3245fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLine {{%\w+}} 0 0 3246fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main 3247fd4e5da5Sopenharmony_ciOpLine %name 0 0 3248fd4e5da5Sopenharmony_ciOpSelectionMerge %18 None 3249fd4e5da5Sopenharmony_ciOpBranchConditional %true %19 %20 3250fd4e5da5Sopenharmony_ci%19 = OpLabel 3251fd4e5da5Sopenharmony_ci; CHECK: DebugScope [[bb1]] 3252fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 1 0 3253fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %bb1 3254fd4e5da5Sopenharmony_ciOpLine %name 1 0 3255fd4e5da5Sopenharmony_ciOpBranch %18 3256fd4e5da5Sopenharmony_ci%20 = OpLabel 3257fd4e5da5Sopenharmony_ci; CHECK-NOT: DebugScope [[bb2]] 3258fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLine {{%\w+}} 2 0 3259fd4e5da5Sopenharmony_ci%scope2 = OpExtInst %void %ext DebugScope %bb2 3260fd4e5da5Sopenharmony_ciOpLine %name 2 0 3261fd4e5da5Sopenharmony_ciOpBranch %18 3262fd4e5da5Sopenharmony_ci%18 = OpLabel 3263fd4e5da5Sopenharmony_ci 3264fd4e5da5Sopenharmony_ci; CHECK: DebugScope [[bb3]] 3265fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 3 0 3266fd4e5da5Sopenharmony_ci; CHECK: DebugValue [[dbg_foo]] [[value]] 3267fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 4 0 3268fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[value]] 3269fd4e5da5Sopenharmony_ci; CHECK: DebugDeclare [[dbg_bar]] %gl_FragColor 3270fd4e5da5Sopenharmony_ci; CHECK: DebugValue [[dbg_bar]] [[value]] 3271fd4e5da5Sopenharmony_ci%scope3 = OpExtInst %void %ext DebugScope %bb3 3272fd4e5da5Sopenharmony_ciOpLine %name 3 0 3273fd4e5da5Sopenharmony_ci%21 = OpPhi %v4float %12 %19 %14 %20 3274fd4e5da5Sopenharmony_ci%decl0 = OpExtInst %void %ext DebugValue %dbg_foo %21 %null_expr 3275fd4e5da5Sopenharmony_ciOpLine %name 4 0 3276fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 3277fd4e5da5Sopenharmony_ci%decl1 = OpExtInst %void %ext DebugDeclare %dbg_bar %gl_FragColor %null_expr 3278fd4e5da5Sopenharmony_ci%decl2 = OpExtInst %void %ext DebugValue %dbg_bar %21 %null_expr 3279fd4e5da5Sopenharmony_ciOpLine %name 5 0 3280fd4e5da5Sopenharmony_ciOpReturn 3281fd4e5da5Sopenharmony_ciOpFunctionEnd 3282fd4e5da5Sopenharmony_ci)"; 3283fd4e5da5Sopenharmony_ci 3284fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 3285fd4e5da5Sopenharmony_ci} 3286fd4e5da5Sopenharmony_ci 3287fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, DontTransferDecorations) { 3288fd4e5da5Sopenharmony_ci // When replacing %4 with %14, we don't want %14 to inherit %4's decorations. 3289fd4e5da5Sopenharmony_ci const std::string text = R"( 3290fd4e5da5Sopenharmony_ci; CHECK-NOT: OpDecorate {{%\w+}} RelaxedPrecision 3291fd4e5da5Sopenharmony_ci; CHECK: [[div:%\w+]] = OpFDiv 3292fd4e5da5Sopenharmony_ci; CHECK: {{%\w+}} = OpCopyObject %float [[div]] 3293fd4e5da5Sopenharmony_ci OpCapability Shader 3294fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3295fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3296fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3297fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3298fd4e5da5Sopenharmony_ci %3 = OpString "STEVEN" 3299fd4e5da5Sopenharmony_ci OpDecorate %4 RelaxedPrecision 3300fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 3301fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 3302fd4e5da5Sopenharmony_ci %void = OpTypeVoid 3303fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 3304fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 3305fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %void 3306fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %10 3307fd4e5da5Sopenharmony_ci %11 = OpLabel 3308fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 3309fd4e5da5Sopenharmony_ci OpSwitch %uint_0 %13 3310fd4e5da5Sopenharmony_ci %13 = OpLabel 3311fd4e5da5Sopenharmony_ci %14 = OpFDiv %float %float_1 %float_1 3312fd4e5da5Sopenharmony_ci OpLine %3 0 0 3313fd4e5da5Sopenharmony_ci OpBranch %12 3314fd4e5da5Sopenharmony_ci %15 = OpLabel 3315fd4e5da5Sopenharmony_ci OpBranch %12 3316fd4e5da5Sopenharmony_ci %12 = OpLabel 3317fd4e5da5Sopenharmony_ci %4 = OpPhi %float %float_1 %15 %14 %13 3318fd4e5da5Sopenharmony_ci %16 = OpCopyObject %float %4 3319fd4e5da5Sopenharmony_ci OpReturn 3320fd4e5da5Sopenharmony_ci OpFunctionEnd 3321fd4e5da5Sopenharmony_ci)"; 3322fd4e5da5Sopenharmony_ci 3323fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<DeadBranchElimPass>(text, true); 3324fd4e5da5Sopenharmony_ci} 3325fd4e5da5Sopenharmony_ci 3326fd4e5da5Sopenharmony_ciTEST_F(DeadBranchElimTest, FunctionDeclaration) { 3327fd4e5da5Sopenharmony_ci // Make sure the pass works with a function declaration that is called. 3328fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Addresses 3329fd4e5da5Sopenharmony_ciOpCapability Linkage 3330fd4e5da5Sopenharmony_ciOpCapability Kernel 3331fd4e5da5Sopenharmony_ciOpCapability Int8 3332fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.std" 3333fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL 3334fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool" 3335fd4e5da5Sopenharmony_ciOpExecutionMode %2 ContractionOff 3336fd4e5da5Sopenharmony_ciOpSource Unknown 0 3337fd4e5da5Sopenharmony_ciOpDecorate %3 LinkageAttributes "julia_error_7712" Import 3338fd4e5da5Sopenharmony_ci%void = OpTypeVoid 3339fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 3340fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %5 3341fd4e5da5Sopenharmony_ciOpFunctionEnd 3342fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 3343fd4e5da5Sopenharmony_ci%6 = OpLabel 3344fd4e5da5Sopenharmony_ci%7 = OpFunctionCall %void %3 3345fd4e5da5Sopenharmony_ciOpReturn 3346fd4e5da5Sopenharmony_ciOpFunctionEnd 3347fd4e5da5Sopenharmony_ci)"; 3348fd4e5da5Sopenharmony_ci 3349fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<DeadBranchElimPass>(text, text, false); 3350fd4e5da5Sopenharmony_ci} 3351fd4e5da5Sopenharmony_ci 3352fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases: 3353fd4e5da5Sopenharmony_ci// 3354fd4e5da5Sopenharmony_ci// More complex control flow 3355fd4e5da5Sopenharmony_ci// Others? 3356fd4e5da5Sopenharmony_ci 3357fd4e5da5Sopenharmony_ci} // namespace 3358fd4e5da5Sopenharmony_ci} // namespace opt 3359fd4e5da5Sopenharmony_ci} // namespace spvtools 3360