1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <string> 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 18fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_cinamespace spvtools { 21fd4e5da5Sopenharmony_cinamespace opt { 22fd4e5da5Sopenharmony_cinamespace { 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_ciusing IfConversionTest = PassTest<::testing::Test>; 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TestSimpleIfThenElse) { 27fd4e5da5Sopenharmony_ci const std::string text = R"( 28fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 29fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 30fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 31fd4e5da5Sopenharmony_ci; CHECK: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1 32fd4e5da5Sopenharmony_ci; CHECK OpStore {{%\w+}} [[sel]] 33fd4e5da5Sopenharmony_ciOpCapability Shader 34fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 35fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 36fd4e5da5Sopenharmony_ci%void = OpTypeVoid 37fd4e5da5Sopenharmony_ci%bool = OpTypeBool 38fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 39fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 40fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 41fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 42fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 43fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 44fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 45fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 46fd4e5da5Sopenharmony_ci%12 = OpLabel 47fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 48fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %16 49fd4e5da5Sopenharmony_ci%15 = OpLabel 50fd4e5da5Sopenharmony_ciOpBranch %14 51fd4e5da5Sopenharmony_ci%16 = OpLabel 52fd4e5da5Sopenharmony_ciOpBranch %14 53fd4e5da5Sopenharmony_ci%14 = OpLabel 54fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %15 %uint_1 %16 55fd4e5da5Sopenharmony_ciOpStore %2 %18 56fd4e5da5Sopenharmony_ciOpReturn 57fd4e5da5Sopenharmony_ciOpFunctionEnd 58fd4e5da5Sopenharmony_ci)"; 59fd4e5da5Sopenharmony_ci 60fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 61fd4e5da5Sopenharmony_ci} 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TestSimpleHalfIfTrue) { 64fd4e5da5Sopenharmony_ci const std::string text = R"( 65fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 66fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 67fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 68fd4e5da5Sopenharmony_ci; CHECK: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1 69fd4e5da5Sopenharmony_ci; CHECK OpStore {{%\w+}} [[sel]] 70fd4e5da5Sopenharmony_ciOpCapability Shader 71fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 72fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 73fd4e5da5Sopenharmony_ci%void = OpTypeVoid 74fd4e5da5Sopenharmony_ci%bool = OpTypeBool 75fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 76fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 77fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 78fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 79fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 80fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 81fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 82fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 83fd4e5da5Sopenharmony_ci%12 = OpLabel 84fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 85fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %14 86fd4e5da5Sopenharmony_ci%15 = OpLabel 87fd4e5da5Sopenharmony_ciOpBranch %14 88fd4e5da5Sopenharmony_ci%14 = OpLabel 89fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %15 %uint_1 %12 90fd4e5da5Sopenharmony_ciOpStore %2 %18 91fd4e5da5Sopenharmony_ciOpReturn 92fd4e5da5Sopenharmony_ciOpFunctionEnd 93fd4e5da5Sopenharmony_ci)"; 94fd4e5da5Sopenharmony_ci 95fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 96fd4e5da5Sopenharmony_ci} 97fd4e5da5Sopenharmony_ci 98fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TestSimpleHalfIfExtraBlock) { 99fd4e5da5Sopenharmony_ci const std::string text = R"( 100fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 101fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 102fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 103fd4e5da5Sopenharmony_ci; CHECK: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1 104fd4e5da5Sopenharmony_ci; CHECK OpStore {{%\w+}} [[sel]] 105fd4e5da5Sopenharmony_ciOpCapability Shader 106fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 107fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 108fd4e5da5Sopenharmony_ci%void = OpTypeVoid 109fd4e5da5Sopenharmony_ci%bool = OpTypeBool 110fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 111fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 112fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 113fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 114fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 115fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 116fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 117fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 118fd4e5da5Sopenharmony_ci%12 = OpLabel 119fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 120fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %14 121fd4e5da5Sopenharmony_ci%15 = OpLabel 122fd4e5da5Sopenharmony_ciOpBranch %16 123fd4e5da5Sopenharmony_ci%16 = OpLabel 124fd4e5da5Sopenharmony_ciOpBranch %14 125fd4e5da5Sopenharmony_ci%14 = OpLabel 126fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %15 %uint_1 %12 127fd4e5da5Sopenharmony_ciOpStore %2 %18 128fd4e5da5Sopenharmony_ciOpReturn 129fd4e5da5Sopenharmony_ciOpFunctionEnd 130fd4e5da5Sopenharmony_ci)"; 131fd4e5da5Sopenharmony_ci 132fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 133fd4e5da5Sopenharmony_ci} 134fd4e5da5Sopenharmony_ci 135fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TestSimpleHalfIfFalse) { 136fd4e5da5Sopenharmony_ci const std::string text = R"( 137fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 138fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 139fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 140fd4e5da5Sopenharmony_ci; CHECK: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1 141fd4e5da5Sopenharmony_ci; CHECK OpStore {{%\w+}} [[sel]] 142fd4e5da5Sopenharmony_ciOpCapability Shader 143fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 144fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 145fd4e5da5Sopenharmony_ci%void = OpTypeVoid 146fd4e5da5Sopenharmony_ci%bool = OpTypeBool 147fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 148fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 149fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 150fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 151fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 152fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 153fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 154fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 155fd4e5da5Sopenharmony_ci%12 = OpLabel 156fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 157fd4e5da5Sopenharmony_ciOpBranchConditional %true %14 %15 158fd4e5da5Sopenharmony_ci%15 = OpLabel 159fd4e5da5Sopenharmony_ciOpBranch %14 160fd4e5da5Sopenharmony_ci%14 = OpLabel 161fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %12 %uint_1 %15 162fd4e5da5Sopenharmony_ciOpStore %2 %18 163fd4e5da5Sopenharmony_ciOpReturn 164fd4e5da5Sopenharmony_ciOpFunctionEnd 165fd4e5da5Sopenharmony_ci)"; 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 168fd4e5da5Sopenharmony_ci} 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TestVectorSplat) { 171fd4e5da5Sopenharmony_ci const std::string text = R"( 172fd4e5da5Sopenharmony_ci; CHECK: [[bool_vec:%\w+]] = OpTypeVector %bool 2 173fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 174fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 175fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 176fd4e5da5Sopenharmony_ci; CHECK: [[comp:%\w+]] = OpCompositeConstruct [[bool_vec]] %true %true 177fd4e5da5Sopenharmony_ci; CHECK: [[sel:%\w+]] = OpSelect {{%\w+}} [[comp]] 178fd4e5da5Sopenharmony_ci; CHECK OpStore {{%\w+}} [[sel]] 179fd4e5da5Sopenharmony_ciOpCapability Shader 180fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 181fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 182fd4e5da5Sopenharmony_ci%void = OpTypeVoid 183fd4e5da5Sopenharmony_ci%bool = OpTypeBool 184fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 185fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 186fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 187fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 188fd4e5da5Sopenharmony_ci%uint_vec2 = OpTypeVector %uint 2 189fd4e5da5Sopenharmony_ci%vec2_01 = OpConstantComposite %uint_vec2 %uint_0 %uint_1 190fd4e5da5Sopenharmony_ci%vec2_10 = OpConstantComposite %uint_vec2 %uint_1 %uint_0 191fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint_vec2 192fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 193fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 194fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 195fd4e5da5Sopenharmony_ci%12 = OpLabel 196fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 197fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %16 198fd4e5da5Sopenharmony_ci%15 = OpLabel 199fd4e5da5Sopenharmony_ciOpBranch %14 200fd4e5da5Sopenharmony_ci%16 = OpLabel 201fd4e5da5Sopenharmony_ciOpBranch %14 202fd4e5da5Sopenharmony_ci%14 = OpLabel 203fd4e5da5Sopenharmony_ci%18 = OpPhi %uint_vec2 %vec2_01 %15 %vec2_10 %16 204fd4e5da5Sopenharmony_ciOpStore %2 %18 205fd4e5da5Sopenharmony_ciOpReturn 206fd4e5da5Sopenharmony_ciOpFunctionEnd 207fd4e5da5Sopenharmony_ci)"; 208fd4e5da5Sopenharmony_ci 209fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 210fd4e5da5Sopenharmony_ci} 211fd4e5da5Sopenharmony_ci 212fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, CodeMotionSameValue) { 213fd4e5da5Sopenharmony_ci const std::string text = R"( 214fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 215fd4e5da5Sopenharmony_ci; CHECK: OpFunction 216fd4e5da5Sopenharmony_ci; CHECK: OpLabel 217fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 218fd4e5da5Sopenharmony_ci; CHECK: [[add:%\w+]] = OpIAdd %uint %uint_0 %uint_1 219fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge_lab:%\w+]] None 220fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional 221fd4e5da5Sopenharmony_ci; CHECK: [[merge_lab]] = OpLabel 222fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 223fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] [[add]] 224fd4e5da5Sopenharmony_ci OpCapability Shader 225fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 226fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "func" %2 227fd4e5da5Sopenharmony_ci %void = OpTypeVoid 228fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 229fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 230fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 231fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 232fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Output_uint Output 233fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 234fd4e5da5Sopenharmony_ci %bool = OpTypeBool 235fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 236fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %8 237fd4e5da5Sopenharmony_ci %11 = OpLabel 238fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 239fd4e5da5Sopenharmony_ci OpBranchConditional %true %13 %15 240fd4e5da5Sopenharmony_ci %13 = OpLabel 241fd4e5da5Sopenharmony_ci %14 = OpIAdd %uint %uint_0 %uint_1 242fd4e5da5Sopenharmony_ci OpBranch %12 243fd4e5da5Sopenharmony_ci %15 = OpLabel 244fd4e5da5Sopenharmony_ci %16 = OpIAdd %uint %uint_0 %uint_1 245fd4e5da5Sopenharmony_ci OpBranch %12 246fd4e5da5Sopenharmony_ci %12 = OpLabel 247fd4e5da5Sopenharmony_ci %17 = OpPhi %uint %16 %15 %14 %13 248fd4e5da5Sopenharmony_ci OpStore %2 %17 249fd4e5da5Sopenharmony_ci OpReturn 250fd4e5da5Sopenharmony_ci OpFunctionEnd 251fd4e5da5Sopenharmony_ci)"; 252fd4e5da5Sopenharmony_ci 253fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 254fd4e5da5Sopenharmony_ci} 255fd4e5da5Sopenharmony_ci 256fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, CodeMotionMultipleInstructions) { 257fd4e5da5Sopenharmony_ci const std::string text = R"( 258fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 259fd4e5da5Sopenharmony_ci; CHECK: OpFunction 260fd4e5da5Sopenharmony_ci; CHECK: OpLabel 261fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 262fd4e5da5Sopenharmony_ci; CHECK: [[a1:%\w+]] = OpIAdd %uint %uint_0 %uint_1 263fd4e5da5Sopenharmony_ci; CHECK: [[a2:%\w+]] = OpIAdd %uint [[a1]] %uint_1 264fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge_lab:%\w+]] None 265fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpBranchConditional 266fd4e5da5Sopenharmony_ci; CHECK: [[merge_lab]] = OpLabel 267fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLabel 268fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] [[a2]] 269fd4e5da5Sopenharmony_ci OpCapability Shader 270fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 271fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "func" %2 272fd4e5da5Sopenharmony_ci %void = OpTypeVoid 273fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 274fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 275fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 276fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 277fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Output_uint Output 278fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 279fd4e5da5Sopenharmony_ci %bool = OpTypeBool 280fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 281fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %8 282fd4e5da5Sopenharmony_ci %11 = OpLabel 283fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 284fd4e5da5Sopenharmony_ci OpBranchConditional %true %13 %15 285fd4e5da5Sopenharmony_ci %13 = OpLabel 286fd4e5da5Sopenharmony_ci %a1 = OpIAdd %uint %uint_0 %uint_1 287fd4e5da5Sopenharmony_ci %a2 = OpIAdd %uint %a1 %uint_1 288fd4e5da5Sopenharmony_ci OpBranch %12 289fd4e5da5Sopenharmony_ci %15 = OpLabel 290fd4e5da5Sopenharmony_ci %b1 = OpIAdd %uint %uint_0 %uint_1 291fd4e5da5Sopenharmony_ci %b2 = OpIAdd %uint %b1 %uint_1 292fd4e5da5Sopenharmony_ci OpBranch %12 293fd4e5da5Sopenharmony_ci %12 = OpLabel 294fd4e5da5Sopenharmony_ci %17 = OpPhi %uint %b2 %15 %a2 %13 295fd4e5da5Sopenharmony_ci OpStore %2 %17 296fd4e5da5Sopenharmony_ci OpReturn 297fd4e5da5Sopenharmony_ci OpFunctionEnd 298fd4e5da5Sopenharmony_ci)"; 299fd4e5da5Sopenharmony_ci 300fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 301fd4e5da5Sopenharmony_ci} 302fd4e5da5Sopenharmony_ci 303fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, NoCommonDominator) { 304fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 305fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 306fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 307fd4e5da5Sopenharmony_ci%void = OpTypeVoid 308fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 309fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 310fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 311fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 312fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 313fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 314fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %8 315fd4e5da5Sopenharmony_ci%9 = OpLabel 316fd4e5da5Sopenharmony_ciOpBranch %10 317fd4e5da5Sopenharmony_ci%11 = OpLabel 318fd4e5da5Sopenharmony_ciOpBranch %10 319fd4e5da5Sopenharmony_ci%10 = OpLabel 320fd4e5da5Sopenharmony_ci%12 = OpPhi %uint %uint_0 %9 %uint_1 %11 321fd4e5da5Sopenharmony_ciOpStore %2 %12 322fd4e5da5Sopenharmony_ciOpReturn 323fd4e5da5Sopenharmony_ciOpFunctionEnd 324fd4e5da5Sopenharmony_ci)"; 325fd4e5da5Sopenharmony_ci 326fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 327fd4e5da5Sopenharmony_ci} 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, DontFlatten) { 330fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 331fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 332fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 333fd4e5da5Sopenharmony_ci%void = OpTypeVoid 334fd4e5da5Sopenharmony_ci%bool = OpTypeBool 335fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 336fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 337fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 338fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 339fd4e5da5Sopenharmony_ci%v2uint = OpTypeVector %uint 2 340fd4e5da5Sopenharmony_ci%10 = OpConstantComposite %v2uint %uint_0 %uint_1 341fd4e5da5Sopenharmony_ci%11 = OpConstantComposite %v2uint %uint_1 %uint_0 342fd4e5da5Sopenharmony_ci%_ptr_Output_v2uint = OpTypePointer Output %v2uint 343fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_v2uint Output 344fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void 345fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %13 346fd4e5da5Sopenharmony_ci%14 = OpLabel 347fd4e5da5Sopenharmony_ciOpSelectionMerge %15 DontFlatten 348fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %17 349fd4e5da5Sopenharmony_ci%16 = OpLabel 350fd4e5da5Sopenharmony_ciOpBranch %15 351fd4e5da5Sopenharmony_ci%17 = OpLabel 352fd4e5da5Sopenharmony_ciOpBranch %15 353fd4e5da5Sopenharmony_ci%15 = OpLabel 354fd4e5da5Sopenharmony_ci%18 = OpPhi %v2uint %10 %16 %11 %17 355fd4e5da5Sopenharmony_ciOpStore %2 %18 356fd4e5da5Sopenharmony_ciOpReturn 357fd4e5da5Sopenharmony_ciOpFunctionEnd 358fd4e5da5Sopenharmony_ci)"; 359fd4e5da5Sopenharmony_ci 360fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 361fd4e5da5Sopenharmony_ci} 362fd4e5da5Sopenharmony_ci 363fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, LoopUntouched) { 364fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 365fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 366fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 367fd4e5da5Sopenharmony_ci%void = OpTypeVoid 368fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 369fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 370fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 371fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 372fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 373fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 374fd4e5da5Sopenharmony_ci%bool = OpTypeBool 375fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 376fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %8 377fd4e5da5Sopenharmony_ci%11 = OpLabel 378fd4e5da5Sopenharmony_ciOpBranch %12 379fd4e5da5Sopenharmony_ci%12 = OpLabel 380fd4e5da5Sopenharmony_ci%13 = OpPhi %uint %uint_0 %11 %uint_1 %12 381fd4e5da5Sopenharmony_ciOpLoopMerge %14 %12 None 382fd4e5da5Sopenharmony_ciOpBranchConditional %true %14 %12 383fd4e5da5Sopenharmony_ci%14 = OpLabel 384fd4e5da5Sopenharmony_ciOpStore %2 %13 385fd4e5da5Sopenharmony_ciOpReturn 386fd4e5da5Sopenharmony_ciOpFunctionEnd 387fd4e5da5Sopenharmony_ci)"; 388fd4e5da5Sopenharmony_ci 389fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 390fd4e5da5Sopenharmony_ci} 391fd4e5da5Sopenharmony_ci 392fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, TooManyPredecessors) { 393fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 394fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 395fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 396fd4e5da5Sopenharmony_ci%void = OpTypeVoid 397fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 398fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 399fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 400fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 401fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 402fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 403fd4e5da5Sopenharmony_ci%bool = OpTypeBool 404fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 405fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %8 406fd4e5da5Sopenharmony_ci%11 = OpLabel 407fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None 408fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %12 409fd4e5da5Sopenharmony_ci%13 = OpLabel 410fd4e5da5Sopenharmony_ciOpBranchConditional %true %14 %12 411fd4e5da5Sopenharmony_ci%14 = OpLabel 412fd4e5da5Sopenharmony_ciOpBranch %12 413fd4e5da5Sopenharmony_ci%12 = OpLabel 414fd4e5da5Sopenharmony_ci%15 = OpPhi %uint %uint_0 %11 %uint_0 %13 %uint_1 %14 415fd4e5da5Sopenharmony_ciOpStore %2 %15 416fd4e5da5Sopenharmony_ciOpReturn 417fd4e5da5Sopenharmony_ciOpFunctionEnd 418fd4e5da5Sopenharmony_ci)"; 419fd4e5da5Sopenharmony_ci 420fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 421fd4e5da5Sopenharmony_ci} 422fd4e5da5Sopenharmony_ci 423fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, NoCodeMotion) { 424fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 425fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 426fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 427fd4e5da5Sopenharmony_ci%void = OpTypeVoid 428fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 429fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 430fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 431fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 432fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 433fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 434fd4e5da5Sopenharmony_ci%bool = OpTypeBool 435fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 436fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %8 437fd4e5da5Sopenharmony_ci%11 = OpLabel 438fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None 439fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %12 440fd4e5da5Sopenharmony_ci%13 = OpLabel 441fd4e5da5Sopenharmony_ci%14 = OpIAdd %uint %uint_0 %uint_1 442fd4e5da5Sopenharmony_ciOpBranch %12 443fd4e5da5Sopenharmony_ci%12 = OpLabel 444fd4e5da5Sopenharmony_ci%15 = OpPhi %uint %uint_0 %11 %14 %13 445fd4e5da5Sopenharmony_ciOpStore %2 %15 446fd4e5da5Sopenharmony_ciOpReturn 447fd4e5da5Sopenharmony_ciOpFunctionEnd 448fd4e5da5Sopenharmony_ci)"; 449fd4e5da5Sopenharmony_ci 450fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 451fd4e5da5Sopenharmony_ci} 452fd4e5da5Sopenharmony_ci 453fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, NoCodeMotionImmovableInst) { 454fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 455fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 456fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 457fd4e5da5Sopenharmony_ci%void = OpTypeVoid 458fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 459fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 460fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 461fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 462fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 463fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 464fd4e5da5Sopenharmony_ci%bool = OpTypeBool 465fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 466fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %8 467fd4e5da5Sopenharmony_ci%11 = OpLabel 468fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None 469fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %14 470fd4e5da5Sopenharmony_ci%13 = OpLabel 471fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None 472fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %15 473fd4e5da5Sopenharmony_ci%16 = OpLabel 474fd4e5da5Sopenharmony_ci%17 = OpIAdd %uint %uint_0 %uint_1 475fd4e5da5Sopenharmony_ciOpBranch %15 476fd4e5da5Sopenharmony_ci%15 = OpLabel 477fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %13 %17 %16 478fd4e5da5Sopenharmony_ci%19 = OpIAdd %uint %18 %uint_1 479fd4e5da5Sopenharmony_ciOpBranch %12 480fd4e5da5Sopenharmony_ci%14 = OpLabel 481fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None 482fd4e5da5Sopenharmony_ciOpBranchConditional %true %21 %20 483fd4e5da5Sopenharmony_ci%21 = OpLabel 484fd4e5da5Sopenharmony_ci%22 = OpIAdd %uint %uint_0 %uint_1 485fd4e5da5Sopenharmony_ciOpBranch %20 486fd4e5da5Sopenharmony_ci%20 = OpLabel 487fd4e5da5Sopenharmony_ci%23 = OpPhi %uint %uint_0 %14 %22 %21 488fd4e5da5Sopenharmony_ci%24 = OpIAdd %uint %23 %uint_1 489fd4e5da5Sopenharmony_ciOpBranch %12 490fd4e5da5Sopenharmony_ci%12 = OpLabel 491fd4e5da5Sopenharmony_ci%25 = OpPhi %uint %24 %20 %19 %15 492fd4e5da5Sopenharmony_ciOpStore %2 %25 493fd4e5da5Sopenharmony_ciOpReturn 494fd4e5da5Sopenharmony_ciOpFunctionEnd 495fd4e5da5Sopenharmony_ci)"; 496fd4e5da5Sopenharmony_ci 497fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 498fd4e5da5Sopenharmony_ci} 499fd4e5da5Sopenharmony_ci 500fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, InvalidCommonDominator) { 501fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 502fd4e5da5Sopenharmony_ciOpCapability Linkage 503fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 504fd4e5da5Sopenharmony_ci%void = OpTypeVoid 505fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 506fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 507fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 508fd4e5da5Sopenharmony_ci%bool = OpTypeBool 509fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 510fd4e5da5Sopenharmony_ci%1 = OpTypeFunction %void 511fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %1 512fd4e5da5Sopenharmony_ci%3 = OpLabel 513fd4e5da5Sopenharmony_ciOpBranch %4 514fd4e5da5Sopenharmony_ci%4 = OpLabel 515fd4e5da5Sopenharmony_ciOpLoopMerge %5 %6 None 516fd4e5da5Sopenharmony_ciOpBranch %7 517fd4e5da5Sopenharmony_ci%7 = OpLabel 518fd4e5da5Sopenharmony_ciOpSelectionMerge %8 None 519fd4e5da5Sopenharmony_ciOpBranchConditional %true %8 %9 520fd4e5da5Sopenharmony_ci%9 = OpLabel 521fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None 522fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %5 523fd4e5da5Sopenharmony_ci%10 = OpLabel 524fd4e5da5Sopenharmony_ciOpBranch %8 525fd4e5da5Sopenharmony_ci%8 = OpLabel 526fd4e5da5Sopenharmony_ciOpBranch %6 527fd4e5da5Sopenharmony_ci%6 = OpLabel 528fd4e5da5Sopenharmony_ciOpBranchConditional %true %4 %5 529fd4e5da5Sopenharmony_ci%5 = OpLabel 530fd4e5da5Sopenharmony_ci%11 = OpPhi %float %float_0 %6 %float_1 %9 531fd4e5da5Sopenharmony_ciOpReturn 532fd4e5da5Sopenharmony_ciOpFunctionEnd 533fd4e5da5Sopenharmony_ci)"; 534fd4e5da5Sopenharmony_ci 535fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 536fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 537fd4e5da5Sopenharmony_ci} 538fd4e5da5Sopenharmony_ci 539fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, DebugInfoSimpleIfThenElse) { 540fd4e5da5Sopenharmony_ci // When it replaces an OpPhi with OpSelect, the new OpSelect must have 541fd4e5da5Sopenharmony_ci // the same scope and line information with the OpPhi. 542fd4e5da5Sopenharmony_ci const std::string text = R"( 543fd4e5da5Sopenharmony_ci; CHECK: OpSelectionMerge [[merge:%\w+]] 544fd4e5da5Sopenharmony_ci; CHECK: [[merge]] = OpLabel 545fd4e5da5Sopenharmony_ci; CHECK-NOT: OpPhi 546fd4e5da5Sopenharmony_ci; CHECK: DebugScope 547fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\w+}} 3 7 548fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[sel:%\w+]] = OpSelect %uint %true %uint_0 %uint_1 549fd4e5da5Sopenharmony_ci; CHECK-NEXT: DebugValue {{%\w+}} [[sel]] 550fd4e5da5Sopenharmony_ci; CHECK: OpStore {{%\w+}} [[sel]] 551fd4e5da5Sopenharmony_ciOpCapability Shader 552fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 553fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 554fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "func" %2 555fd4e5da5Sopenharmony_ci%name = OpString "test" 556fd4e5da5Sopenharmony_ci%void = OpTypeVoid 557fd4e5da5Sopenharmony_ci%bool = OpTypeBool 558fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 559fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 560fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 561fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 562fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 563fd4e5da5Sopenharmony_ci%_ptr_Output_uint = OpTypePointer Output %uint 564fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_uint Output 565fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void 566fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 567fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %name 568fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL 569fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %void %ext DebugTypeBasic %name %uint_32 Float 570fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugLocalVariable %name %dbg_tf %src 0 0 %cu FlagIsLocal 571fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11 572fd4e5da5Sopenharmony_ci%12 = OpLabel 573fd4e5da5Sopenharmony_ciOpSelectionMerge %14 None 574fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %16 575fd4e5da5Sopenharmony_ci%15 = OpLabel 576fd4e5da5Sopenharmony_ciOpBranch %14 577fd4e5da5Sopenharmony_ci%16 = OpLabel 578fd4e5da5Sopenharmony_ciOpBranch %14 579fd4e5da5Sopenharmony_ci%14 = OpLabel 580fd4e5da5Sopenharmony_ci%scope = OpExtInst %void %ext DebugScope %cu 581fd4e5da5Sopenharmony_ciOpLine %name 3 7 582fd4e5da5Sopenharmony_ci%18 = OpPhi %uint %uint_0 %15 %uint_1 %16 583fd4e5da5Sopenharmony_ci%value = OpExtInst %void %ext DebugValue %dbg_f %18 %null_expr 584fd4e5da5Sopenharmony_ciOpStore %2 %18 585fd4e5da5Sopenharmony_ciOpReturn 586fd4e5da5Sopenharmony_ciOpFunctionEnd 587fd4e5da5Sopenharmony_ci)"; 588fd4e5da5Sopenharmony_ci 589fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<IfConversion>(text, true); 590fd4e5da5Sopenharmony_ci} 591fd4e5da5Sopenharmony_ci 592fd4e5da5Sopenharmony_ciTEST_F(IfConversionTest, MultipleEdgesFromSameBlock) { 593fd4e5da5Sopenharmony_ci // If a block has two out going edges that go to the same block, then there 594fd4e5da5Sopenharmony_ci // can be an OpPhi instruction with fewer entries than the number of incoming 595fd4e5da5Sopenharmony_ci // edges. This must be handled. 596fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 597fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 598fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 599fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 600fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 601fd4e5da5Sopenharmony_ci%void = OpTypeVoid 602fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 603fd4e5da5Sopenharmony_ci%bool = OpTypeBool 604fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 605fd4e5da5Sopenharmony_ci%true_0 = OpConstantTrue %bool 606fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4 607fd4e5da5Sopenharmony_ci%8 = OpLabel 608fd4e5da5Sopenharmony_ciOpSelectionMerge %9 None 609fd4e5da5Sopenharmony_ciOpBranchConditional %true_0 %9 %9 610fd4e5da5Sopenharmony_ci%9 = OpLabel 611fd4e5da5Sopenharmony_ci%10 = OpPhi %bool %true %8 612fd4e5da5Sopenharmony_ciOpReturn 613fd4e5da5Sopenharmony_ciOpFunctionEnd 614fd4e5da5Sopenharmony_ci)"; 615fd4e5da5Sopenharmony_ci 616fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<IfConversion>(text, text, true, true); 617fd4e5da5Sopenharmony_ci} 618fd4e5da5Sopenharmony_ci 619fd4e5da5Sopenharmony_ci} // namespace 620fd4e5da5Sopenharmony_ci} // namespace opt 621fd4e5da5Sopenharmony_ci} // namespace spvtools 622