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 <memory> 16fd4e5da5Sopenharmony_ci#include <vector> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "function_utils.h" 19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 20fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 21fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h" 22fd4e5da5Sopenharmony_ci#include "source/opt/ir_context.h" 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_cinamespace spvtools { 25fd4e5da5Sopenharmony_cinamespace opt { 26fd4e5da5Sopenharmony_cinamespace { 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciusing ::testing::Eq; 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciTEST(FunctionTest, HasEarlyReturn) { 31fd4e5da5Sopenharmony_ci std::string shader = R"( 32fd4e5da5Sopenharmony_ci OpCapability Shader 33fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 34fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 35fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %6 "main" 36fd4e5da5Sopenharmony_ci 37fd4e5da5Sopenharmony_ci; Types 38fd4e5da5Sopenharmony_ci %2 = OpTypeBool 39fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 40fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 41fd4e5da5Sopenharmony_ci 42fd4e5da5Sopenharmony_ci; Constants 43fd4e5da5Sopenharmony_ci %5 = OpConstantTrue %2 44fd4e5da5Sopenharmony_ci 45fd4e5da5Sopenharmony_ci; main function without early return 46fd4e5da5Sopenharmony_ci %6 = OpFunction %3 None %4 47fd4e5da5Sopenharmony_ci %7 = OpLabel 48fd4e5da5Sopenharmony_ci OpBranch %8 49fd4e5da5Sopenharmony_ci %8 = OpLabel 50fd4e5da5Sopenharmony_ci OpBranch %9 51fd4e5da5Sopenharmony_ci %9 = OpLabel 52fd4e5da5Sopenharmony_ci OpBranch %10 53fd4e5da5Sopenharmony_ci %10 = OpLabel 54fd4e5da5Sopenharmony_ci OpReturn 55fd4e5da5Sopenharmony_ci OpFunctionEnd 56fd4e5da5Sopenharmony_ci 57fd4e5da5Sopenharmony_ci; function with early return 58fd4e5da5Sopenharmony_ci %11 = OpFunction %3 None %4 59fd4e5da5Sopenharmony_ci %12 = OpLabel 60fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 61fd4e5da5Sopenharmony_ci OpBranchConditional %5 %13 %14 62fd4e5da5Sopenharmony_ci %13 = OpLabel 63fd4e5da5Sopenharmony_ci OpReturn 64fd4e5da5Sopenharmony_ci %14 = OpLabel 65fd4e5da5Sopenharmony_ci OpBranch %15 66fd4e5da5Sopenharmony_ci %15 = OpLabel 67fd4e5da5Sopenharmony_ci OpReturn 68fd4e5da5Sopenharmony_ci OpFunctionEnd 69fd4e5da5Sopenharmony_ci )"; 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ci const auto context = 72fd4e5da5Sopenharmony_ci BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, shader, 73fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci // Tests |function| without early return. 76fd4e5da5Sopenharmony_ci auto* function = spvtest::GetFunction(context->module(), 6); 77fd4e5da5Sopenharmony_ci ASSERT_FALSE(function->HasEarlyReturn()); 78fd4e5da5Sopenharmony_ci 79fd4e5da5Sopenharmony_ci // Tests |function| with early return. 80fd4e5da5Sopenharmony_ci function = spvtest::GetFunction(context->module(), 11); 81fd4e5da5Sopenharmony_ci ASSERT_TRUE(function->HasEarlyReturn()); 82fd4e5da5Sopenharmony_ci} 83fd4e5da5Sopenharmony_ci 84fd4e5da5Sopenharmony_ciTEST(FunctionTest, IsNotRecursive) { 85fd4e5da5Sopenharmony_ci const std::string text = R"( 86fd4e5da5Sopenharmony_ciOpCapability Shader 87fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 88fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 89fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 90fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 439418829 91fd4e5da5Sopenharmony_ci%void = OpTypeVoid 92fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 93fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 94fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 95fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 96fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 97fd4e5da5Sopenharmony_ci%8 = OpLabel 98fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 99fd4e5da5Sopenharmony_ciOpKill 100fd4e5da5Sopenharmony_ciOpFunctionEnd 101fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 102fd4e5da5Sopenharmony_ci%10 = OpLabel 103fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %12 104fd4e5da5Sopenharmony_ciOpUnreachable 105fd4e5da5Sopenharmony_ciOpFunctionEnd 106fd4e5da5Sopenharmony_ci%12 = OpFunction %_struct_6 None %7 107fd4e5da5Sopenharmony_ci%13 = OpLabel 108fd4e5da5Sopenharmony_ciOpUnreachable 109fd4e5da5Sopenharmony_ciOpFunctionEnd 110fd4e5da5Sopenharmony_ci)"; 111fd4e5da5Sopenharmony_ci 112fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 113fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 114fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 115fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 9); 116fd4e5da5Sopenharmony_ci EXPECT_FALSE(func->IsRecursive()); 117fd4e5da5Sopenharmony_ci 118fd4e5da5Sopenharmony_ci func = spvtest::GetFunction(ctx->module(), 12); 119fd4e5da5Sopenharmony_ci EXPECT_FALSE(func->IsRecursive()); 120fd4e5da5Sopenharmony_ci} 121fd4e5da5Sopenharmony_ci 122fd4e5da5Sopenharmony_ciTEST(FunctionTest, IsDirectlyRecursive) { 123fd4e5da5Sopenharmony_ci const std::string text = R"( 124fd4e5da5Sopenharmony_ciOpCapability Shader 125fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 126fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 127fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 128fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 439418829 129fd4e5da5Sopenharmony_ci%void = OpTypeVoid 130fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 131fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 132fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 133fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 134fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 135fd4e5da5Sopenharmony_ci%8 = OpLabel 136fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 137fd4e5da5Sopenharmony_ciOpKill 138fd4e5da5Sopenharmony_ciOpFunctionEnd 139fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 140fd4e5da5Sopenharmony_ci%10 = OpLabel 141fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %9 142fd4e5da5Sopenharmony_ciOpUnreachable 143fd4e5da5Sopenharmony_ciOpFunctionEnd 144fd4e5da5Sopenharmony_ci)"; 145fd4e5da5Sopenharmony_ci 146fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 147fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 148fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 149fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 9); 150fd4e5da5Sopenharmony_ci EXPECT_TRUE(func->IsRecursive()); 151fd4e5da5Sopenharmony_ci} 152fd4e5da5Sopenharmony_ci 153fd4e5da5Sopenharmony_ciTEST(FunctionTest, IsIndirectlyRecursive) { 154fd4e5da5Sopenharmony_ci const std::string text = R"( 155fd4e5da5Sopenharmony_ciOpCapability Shader 156fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 157fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 158fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 159fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 439418829 160fd4e5da5Sopenharmony_ci%void = OpTypeVoid 161fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 162fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 163fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 164fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 165fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 166fd4e5da5Sopenharmony_ci%8 = OpLabel 167fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 168fd4e5da5Sopenharmony_ciOpKill 169fd4e5da5Sopenharmony_ciOpFunctionEnd 170fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 171fd4e5da5Sopenharmony_ci%10 = OpLabel 172fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %12 173fd4e5da5Sopenharmony_ciOpUnreachable 174fd4e5da5Sopenharmony_ciOpFunctionEnd 175fd4e5da5Sopenharmony_ci%12 = OpFunction %_struct_6 None %7 176fd4e5da5Sopenharmony_ci%13 = OpLabel 177fd4e5da5Sopenharmony_ci%14 = OpFunctionCall %_struct_6 %9 178fd4e5da5Sopenharmony_ciOpUnreachable 179fd4e5da5Sopenharmony_ciOpFunctionEnd 180fd4e5da5Sopenharmony_ci)"; 181fd4e5da5Sopenharmony_ci 182fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 183fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 184fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 185fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 9); 186fd4e5da5Sopenharmony_ci EXPECT_TRUE(func->IsRecursive()); 187fd4e5da5Sopenharmony_ci 188fd4e5da5Sopenharmony_ci func = spvtest::GetFunction(ctx->module(), 12); 189fd4e5da5Sopenharmony_ci EXPECT_TRUE(func->IsRecursive()); 190fd4e5da5Sopenharmony_ci} 191fd4e5da5Sopenharmony_ci 192fd4e5da5Sopenharmony_ciTEST(FunctionTest, IsNotRecuriseCallingRecursive) { 193fd4e5da5Sopenharmony_ci const std::string text = R"( 194fd4e5da5Sopenharmony_ciOpCapability Shader 195fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 196fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" 197fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 198fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 439418829 199fd4e5da5Sopenharmony_ci%void = OpTypeVoid 200fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 201fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 202fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float 203fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6 204fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4 205fd4e5da5Sopenharmony_ci%8 = OpLabel 206fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9 207fd4e5da5Sopenharmony_ciOpKill 208fd4e5da5Sopenharmony_ciOpFunctionEnd 209fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7 210fd4e5da5Sopenharmony_ci%10 = OpLabel 211fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %9 212fd4e5da5Sopenharmony_ciOpUnreachable 213fd4e5da5Sopenharmony_ciOpFunctionEnd 214fd4e5da5Sopenharmony_ci)"; 215fd4e5da5Sopenharmony_ci 216fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 217fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 218fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 219fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 1); 220fd4e5da5Sopenharmony_ci EXPECT_FALSE(func->IsRecursive()); 221fd4e5da5Sopenharmony_ci} 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ciTEST(FunctionTest, NonSemanticInfoSkipIteration) { 224fd4e5da5Sopenharmony_ci const std::string text = R"( 225fd4e5da5Sopenharmony_ciOpCapability Shader 226fd4e5da5Sopenharmony_ciOpCapability Linkage 227fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 228fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Test" 229fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 230fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 231fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 232fd4e5da5Sopenharmony_ci%4 = OpFunction %2 None %3 233fd4e5da5Sopenharmony_ci%5 = OpLabel 234fd4e5da5Sopenharmony_ci%6 = OpExtInst %2 %1 1 235fd4e5da5Sopenharmony_ciOpReturn 236fd4e5da5Sopenharmony_ciOpFunctionEnd 237fd4e5da5Sopenharmony_ci%7 = OpExtInst %2 %1 2 238fd4e5da5Sopenharmony_ci%8 = OpExtInst %2 %1 3 239fd4e5da5Sopenharmony_ci)"; 240fd4e5da5Sopenharmony_ci 241fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 242fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 243fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 244fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 4); 245fd4e5da5Sopenharmony_ci ASSERT_TRUE(func != nullptr); 246fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> non_semantic_ids; 247fd4e5da5Sopenharmony_ci func->ForEachInst( 248fd4e5da5Sopenharmony_ci [&non_semantic_ids](const Instruction* inst) { 249fd4e5da5Sopenharmony_ci if (inst->opcode() == spv::Op::OpExtInst) { 250fd4e5da5Sopenharmony_ci non_semantic_ids.insert(inst->result_id()); 251fd4e5da5Sopenharmony_ci } 252fd4e5da5Sopenharmony_ci }, 253fd4e5da5Sopenharmony_ci true, false); 254fd4e5da5Sopenharmony_ci 255fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(6)); 256fd4e5da5Sopenharmony_ci EXPECT_EQ(0, non_semantic_ids.count(7)); 257fd4e5da5Sopenharmony_ci EXPECT_EQ(0, non_semantic_ids.count(8)); 258fd4e5da5Sopenharmony_ci} 259fd4e5da5Sopenharmony_ci 260fd4e5da5Sopenharmony_ciTEST(FunctionTest, NonSemanticInfoIncludeIteration) { 261fd4e5da5Sopenharmony_ci const std::string text = R"( 262fd4e5da5Sopenharmony_ciOpCapability Shader 263fd4e5da5Sopenharmony_ciOpCapability Linkage 264fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 265fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Test" 266fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 267fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 268fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 269fd4e5da5Sopenharmony_ci%4 = OpFunction %2 None %3 270fd4e5da5Sopenharmony_ci%5 = OpLabel 271fd4e5da5Sopenharmony_ci%6 = OpExtInst %2 %1 1 272fd4e5da5Sopenharmony_ciOpReturn 273fd4e5da5Sopenharmony_ciOpFunctionEnd 274fd4e5da5Sopenharmony_ci%7 = OpExtInst %2 %1 2 275fd4e5da5Sopenharmony_ci%8 = OpExtInst %2 %1 3 276fd4e5da5Sopenharmony_ci)"; 277fd4e5da5Sopenharmony_ci 278fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 279fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 280fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 281fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 4); 282fd4e5da5Sopenharmony_ci ASSERT_TRUE(func != nullptr); 283fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> non_semantic_ids; 284fd4e5da5Sopenharmony_ci func->ForEachInst( 285fd4e5da5Sopenharmony_ci [&non_semantic_ids](const Instruction* inst) { 286fd4e5da5Sopenharmony_ci if (inst->opcode() == spv::Op::OpExtInst) { 287fd4e5da5Sopenharmony_ci non_semantic_ids.insert(inst->result_id()); 288fd4e5da5Sopenharmony_ci } 289fd4e5da5Sopenharmony_ci }, 290fd4e5da5Sopenharmony_ci true, true); 291fd4e5da5Sopenharmony_ci 292fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(6)); 293fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(7)); 294fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(8)); 295fd4e5da5Sopenharmony_ci} 296fd4e5da5Sopenharmony_ci 297fd4e5da5Sopenharmony_ciTEST(FunctionTest, ReorderBlocksinStructuredOrder) { 298fd4e5da5Sopenharmony_ci // The spir-v has the basic block in a random order. We want to reorder them 299fd4e5da5Sopenharmony_ci // in structured order. 300fd4e5da5Sopenharmony_ci const std::string text = R"( 301fd4e5da5Sopenharmony_ci OpCapability Shader 302fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 303fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %100 "PSMain" 304fd4e5da5Sopenharmony_ci OpExecutionMode %PSMain OriginUpperLeft 305fd4e5da5Sopenharmony_ci OpSource HLSL 600 306fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 307fd4e5da5Sopenharmony_ci %void = OpTypeVoid 308fd4e5da5Sopenharmony_ci %19 = OpTypeFunction %void 309fd4e5da5Sopenharmony_ci %bool = OpTypeBool 310fd4e5da5Sopenharmony_ci%undef_bool = OpUndef %bool 311fd4e5da5Sopenharmony_ci%undef_int = OpUndef %int 312fd4e5da5Sopenharmony_ci %100 = OpFunction %void None %19 313fd4e5da5Sopenharmony_ci %11 = OpLabel 314fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 315fd4e5da5Sopenharmony_ci OpSwitch %undef_int %3 0 %2 10 %1 316fd4e5da5Sopenharmony_ci %2 = OpLabel 317fd4e5da5Sopenharmony_ci OpReturn 318fd4e5da5Sopenharmony_ci %7 = OpLabel 319fd4e5da5Sopenharmony_ci OpBranch %8 320fd4e5da5Sopenharmony_ci %3 = OpLabel 321fd4e5da5Sopenharmony_ci OpBranch %4 322fd4e5da5Sopenharmony_ci %10 = OpLabel 323fd4e5da5Sopenharmony_ci OpReturn 324fd4e5da5Sopenharmony_ci %9 = OpLabel 325fd4e5da5Sopenharmony_ci OpBranch %10 326fd4e5da5Sopenharmony_ci %8 = OpLabel 327fd4e5da5Sopenharmony_ci OpBranch %4 328fd4e5da5Sopenharmony_ci %4 = OpLabel 329fd4e5da5Sopenharmony_ci OpLoopMerge %9 %8 None 330fd4e5da5Sopenharmony_ci OpBranchConditional %undef_bool %5 %9 331fd4e5da5Sopenharmony_ci %1 = OpLabel 332fd4e5da5Sopenharmony_ci OpReturn 333fd4e5da5Sopenharmony_ci %6 = OpLabel 334fd4e5da5Sopenharmony_ci OpBranch %7 335fd4e5da5Sopenharmony_ci %5 = OpLabel 336fd4e5da5Sopenharmony_ci OpSelectionMerge %7 None 337fd4e5da5Sopenharmony_ci OpBranchConditional %undef_bool %6 %7 338fd4e5da5Sopenharmony_ci OpFunctionEnd 339fd4e5da5Sopenharmony_ci)"; 340fd4e5da5Sopenharmony_ci 341fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> ctx = 342fd4e5da5Sopenharmony_ci spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 343fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 344fd4e5da5Sopenharmony_ci ASSERT_TRUE(ctx); 345fd4e5da5Sopenharmony_ci auto* func = spvtest::GetFunction(ctx->module(), 100); 346fd4e5da5Sopenharmony_ci ASSERT_TRUE(func); 347fd4e5da5Sopenharmony_ci func->ReorderBasicBlocksInStructuredOrder(); 348fd4e5da5Sopenharmony_ci 349fd4e5da5Sopenharmony_ci auto first_block = func->begin(); 350fd4e5da5Sopenharmony_ci auto bb = first_block; 351fd4e5da5Sopenharmony_ci for (++bb; bb != func->end(); ++bb) { 352fd4e5da5Sopenharmony_ci EXPECT_EQ(bb->id(), (bb - first_block)); 353fd4e5da5Sopenharmony_ci } 354fd4e5da5Sopenharmony_ci} 355fd4e5da5Sopenharmony_ci 356fd4e5da5Sopenharmony_ci} // namespace 357fd4e5da5Sopenharmony_ci} // namespace opt 358fd4e5da5Sopenharmony_ci} // namespace spvtools 359