1fd4e5da5Sopenharmony_ci// Copyright (c) 2016 Google Inc. 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 "source/opt/module.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include <memory> 18fd4e5da5Sopenharmony_ci#include <vector> 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 21fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 22fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h" 23fd4e5da5Sopenharmony_ci#include "spirv-tools/libspirv.hpp" 24fd4e5da5Sopenharmony_ci#include "test/opt/module_utils.h" 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_cinamespace spvtools { 27fd4e5da5Sopenharmony_cinamespace opt { 28fd4e5da5Sopenharmony_cinamespace { 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciusing ::testing::Eq; 31fd4e5da5Sopenharmony_ciusing spvtest::GetIdBound; 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_ciTEST(ModuleTest, SetIdBound) { 34fd4e5da5Sopenharmony_ci Module m; 35fd4e5da5Sopenharmony_ci // It's initialized to 0. 36fd4e5da5Sopenharmony_ci EXPECT_EQ(0u, GetIdBound(m)); 37fd4e5da5Sopenharmony_ci 38fd4e5da5Sopenharmony_ci m.SetIdBound(19); 39fd4e5da5Sopenharmony_ci EXPECT_EQ(19u, GetIdBound(m)); 40fd4e5da5Sopenharmony_ci 41fd4e5da5Sopenharmony_ci m.SetIdBound(102); 42fd4e5da5Sopenharmony_ci EXPECT_EQ(102u, GetIdBound(m)); 43fd4e5da5Sopenharmony_ci} 44fd4e5da5Sopenharmony_ci 45fd4e5da5Sopenharmony_ci// Returns an IRContext owning the module formed by assembling the given text, 46fd4e5da5Sopenharmony_ci// then loading the result. 47fd4e5da5Sopenharmony_ciinline std::unique_ptr<IRContext> BuildModule(std::string text) { 48fd4e5da5Sopenharmony_ci return spvtools::BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text, 49fd4e5da5Sopenharmony_ci SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 50fd4e5da5Sopenharmony_ci} 51fd4e5da5Sopenharmony_ci 52fd4e5da5Sopenharmony_ciTEST(ModuleTest, ComputeIdBound) { 53fd4e5da5Sopenharmony_ci // Empty module case. 54fd4e5da5Sopenharmony_ci EXPECT_EQ(1u, BuildModule("")->module()->ComputeIdBound()); 55fd4e5da5Sopenharmony_ci // Sensitive to result id 56fd4e5da5Sopenharmony_ci EXPECT_EQ(2u, BuildModule("%void = OpTypeVoid")->module()->ComputeIdBound()); 57fd4e5da5Sopenharmony_ci // Sensitive to type id 58fd4e5da5Sopenharmony_ci EXPECT_EQ(1000u, 59fd4e5da5Sopenharmony_ci BuildModule("%a = OpTypeArray !999 3")->module()->ComputeIdBound()); 60fd4e5da5Sopenharmony_ci // Sensitive to a regular Id parameter 61fd4e5da5Sopenharmony_ci EXPECT_EQ(2000u, 62fd4e5da5Sopenharmony_ci BuildModule("OpDecorate !1999 0")->module()->ComputeIdBound()); 63fd4e5da5Sopenharmony_ci // Sensitive to a scope Id parameter. 64fd4e5da5Sopenharmony_ci EXPECT_EQ(3000u, 65fd4e5da5Sopenharmony_ci BuildModule("%f = OpFunction %void None %fntype %a = OpLabel " 66fd4e5da5Sopenharmony_ci "OpMemoryBarrier !2999 %b\n") 67fd4e5da5Sopenharmony_ci ->module() 68fd4e5da5Sopenharmony_ci ->ComputeIdBound()); 69fd4e5da5Sopenharmony_ci // Sensitive to a semantics Id parameter 70fd4e5da5Sopenharmony_ci EXPECT_EQ(4000u, 71fd4e5da5Sopenharmony_ci BuildModule("%f = OpFunction %void None %fntype %a = OpLabel " 72fd4e5da5Sopenharmony_ci "OpMemoryBarrier %b !3999\n") 73fd4e5da5Sopenharmony_ci ->module() 74fd4e5da5Sopenharmony_ci ->ComputeIdBound()); 75fd4e5da5Sopenharmony_ci} 76fd4e5da5Sopenharmony_ci 77fd4e5da5Sopenharmony_ciTEST(ModuleTest, OstreamOperator) { 78fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 79fd4e5da5Sopenharmony_ciOpCapability Linkage 80fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 81fd4e5da5Sopenharmony_ciOpName %7 "restrict" 82fd4e5da5Sopenharmony_ciOpDecorate %8 Restrict 83fd4e5da5Sopenharmony_ci%9 = OpTypeVoid 84fd4e5da5Sopenharmony_ci%10 = OpTypeInt 32 0 85fd4e5da5Sopenharmony_ci%11 = OpTypeStruct %10 %10 86fd4e5da5Sopenharmony_ci%12 = OpTypePointer Function %10 87fd4e5da5Sopenharmony_ci%13 = OpTypePointer Function %11 88fd4e5da5Sopenharmony_ci%14 = OpConstant %10 0 89fd4e5da5Sopenharmony_ci%15 = OpConstant %10 1 90fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %9 91fd4e5da5Sopenharmony_ci%1 = OpFunction %9 None %7 92fd4e5da5Sopenharmony_ci%2 = OpLabel 93fd4e5da5Sopenharmony_ci%8 = OpVariable %13 Function 94fd4e5da5Sopenharmony_ci%3 = OpAccessChain %12 %8 %14 95fd4e5da5Sopenharmony_ci%4 = OpLoad %10 %3 96fd4e5da5Sopenharmony_ci%5 = OpAccessChain %12 %8 %15 97fd4e5da5Sopenharmony_ci%6 = OpLoad %10 %5 98fd4e5da5Sopenharmony_ciOpReturn 99fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ci std::string s; 102fd4e5da5Sopenharmony_ci std::ostringstream str(s); 103fd4e5da5Sopenharmony_ci str << *BuildModule(text)->module(); 104fd4e5da5Sopenharmony_ci EXPECT_EQ(text, str.str()); 105fd4e5da5Sopenharmony_ci} 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ciTEST(ModuleTest, OstreamOperatorInt64) { 108fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 109fd4e5da5Sopenharmony_ciOpCapability Linkage 110fd4e5da5Sopenharmony_ciOpCapability Int64 111fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 112fd4e5da5Sopenharmony_ciOpName %7 "restrict" 113fd4e5da5Sopenharmony_ciOpDecorate %5 Restrict 114fd4e5da5Sopenharmony_ci%9 = OpTypeVoid 115fd4e5da5Sopenharmony_ci%10 = OpTypeInt 64 0 116fd4e5da5Sopenharmony_ci%11 = OpTypeStruct %10 %10 117fd4e5da5Sopenharmony_ci%12 = OpTypePointer Function %10 118fd4e5da5Sopenharmony_ci%13 = OpTypePointer Function %11 119fd4e5da5Sopenharmony_ci%14 = OpConstant %10 0 120fd4e5da5Sopenharmony_ci%15 = OpConstant %10 1 121fd4e5da5Sopenharmony_ci%16 = OpConstant %10 4294967297 122fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %9 123fd4e5da5Sopenharmony_ci%1 = OpFunction %9 None %7 124fd4e5da5Sopenharmony_ci%2 = OpLabel 125fd4e5da5Sopenharmony_ci%5 = OpVariable %12 Function 126fd4e5da5Sopenharmony_ci%6 = OpLoad %10 %5 127fd4e5da5Sopenharmony_ciOpSelectionMerge %3 None 128fd4e5da5Sopenharmony_ciOpSwitch %6 %3 4294967297 %4 129fd4e5da5Sopenharmony_ci%4 = OpLabel 130fd4e5da5Sopenharmony_ciOpBranch %3 131fd4e5da5Sopenharmony_ci%3 = OpLabel 132fd4e5da5Sopenharmony_ciOpReturn 133fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 134fd4e5da5Sopenharmony_ci 135fd4e5da5Sopenharmony_ci std::string s; 136fd4e5da5Sopenharmony_ci std::ostringstream str(s); 137fd4e5da5Sopenharmony_ci str << *BuildModule(text)->module(); 138fd4e5da5Sopenharmony_ci EXPECT_EQ(text, str.str()); 139fd4e5da5Sopenharmony_ci} 140fd4e5da5Sopenharmony_ci 141fd4e5da5Sopenharmony_ciTEST(ModuleTest, IdBoundTestAtLimit) { 142fd4e5da5Sopenharmony_ci const std::string text = R"( 143fd4e5da5Sopenharmony_ciOpCapability Shader 144fd4e5da5Sopenharmony_ciOpCapability Linkage 145fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 146fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 147fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %1 148fd4e5da5Sopenharmony_ci%3 = OpFunction %1 None %2 149fd4e5da5Sopenharmony_ci%4 = OpLabel 150fd4e5da5Sopenharmony_ciOpReturn 151fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 152fd4e5da5Sopenharmony_ci 153fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 154fd4e5da5Sopenharmony_ci uint32_t current_bound = context->module()->id_bound(); 155fd4e5da5Sopenharmony_ci context->set_max_id_bound(current_bound); 156fd4e5da5Sopenharmony_ci uint32_t next_id_bound = context->module()->TakeNextIdBound(); 157fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, 0); 158fd4e5da5Sopenharmony_ci EXPECT_EQ(current_bound, context->module()->id_bound()); 159fd4e5da5Sopenharmony_ci next_id_bound = context->module()->TakeNextIdBound(); 160fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, 0); 161fd4e5da5Sopenharmony_ci} 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ciTEST(ModuleTest, IdBoundTestBelowLimit) { 164fd4e5da5Sopenharmony_ci const std::string text = R"( 165fd4e5da5Sopenharmony_ciOpCapability Shader 166fd4e5da5Sopenharmony_ciOpCapability Linkage 167fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 168fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 169fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %1 170fd4e5da5Sopenharmony_ci%3 = OpFunction %1 None %2 171fd4e5da5Sopenharmony_ci%4 = OpLabel 172fd4e5da5Sopenharmony_ciOpReturn 173fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 174fd4e5da5Sopenharmony_ci 175fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 176fd4e5da5Sopenharmony_ci uint32_t current_bound = context->module()->id_bound(); 177fd4e5da5Sopenharmony_ci context->set_max_id_bound(current_bound + 100); 178fd4e5da5Sopenharmony_ci uint32_t next_id_bound = context->module()->TakeNextIdBound(); 179fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, current_bound); 180fd4e5da5Sopenharmony_ci EXPECT_EQ(current_bound + 1, context->module()->id_bound()); 181fd4e5da5Sopenharmony_ci next_id_bound = context->module()->TakeNextIdBound(); 182fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, current_bound + 1); 183fd4e5da5Sopenharmony_ci} 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ciTEST(ModuleTest, IdBoundTestNearLimit) { 186fd4e5da5Sopenharmony_ci const std::string text = R"( 187fd4e5da5Sopenharmony_ciOpCapability Shader 188fd4e5da5Sopenharmony_ciOpCapability Linkage 189fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 190fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 191fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %1 192fd4e5da5Sopenharmony_ci%3 = OpFunction %1 None %2 193fd4e5da5Sopenharmony_ci%4 = OpLabel 194fd4e5da5Sopenharmony_ciOpReturn 195fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 196fd4e5da5Sopenharmony_ci 197fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 198fd4e5da5Sopenharmony_ci uint32_t current_bound = context->module()->id_bound(); 199fd4e5da5Sopenharmony_ci context->set_max_id_bound(current_bound + 1); 200fd4e5da5Sopenharmony_ci uint32_t next_id_bound = context->module()->TakeNextIdBound(); 201fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, current_bound); 202fd4e5da5Sopenharmony_ci EXPECT_EQ(current_bound + 1, context->module()->id_bound()); 203fd4e5da5Sopenharmony_ci next_id_bound = context->module()->TakeNextIdBound(); 204fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, 0); 205fd4e5da5Sopenharmony_ci} 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ciTEST(ModuleTest, IdBoundTestUIntMax) { 208fd4e5da5Sopenharmony_ci const std::string text = R"( 209fd4e5da5Sopenharmony_ciOpCapability Shader 210fd4e5da5Sopenharmony_ciOpCapability Linkage 211fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 212fd4e5da5Sopenharmony_ci%1 = OpTypeVoid 213fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %1 214fd4e5da5Sopenharmony_ci%3 = OpFunction %1 None %2 215fd4e5da5Sopenharmony_ci%4294967294 = OpLabel ; ID is UINT_MAX-1 216fd4e5da5Sopenharmony_ciOpReturn 217fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 220fd4e5da5Sopenharmony_ci uint32_t current_bound = context->module()->id_bound(); 221fd4e5da5Sopenharmony_ci 222fd4e5da5Sopenharmony_ci // Expecting |BuildModule| to preserve the numeric ids. 223fd4e5da5Sopenharmony_ci EXPECT_EQ(current_bound, std::numeric_limits<uint32_t>::max()); 224fd4e5da5Sopenharmony_ci 225fd4e5da5Sopenharmony_ci context->set_max_id_bound(current_bound); 226fd4e5da5Sopenharmony_ci uint32_t next_id_bound = context->module()->TakeNextIdBound(); 227fd4e5da5Sopenharmony_ci EXPECT_EQ(next_id_bound, 0); 228fd4e5da5Sopenharmony_ci EXPECT_EQ(current_bound, context->module()->id_bound()); 229fd4e5da5Sopenharmony_ci} 230fd4e5da5Sopenharmony_ci 231fd4e5da5Sopenharmony_ci// Tests that "text" does not change when it is assembled, converted into a 232fd4e5da5Sopenharmony_ci// module, converted back to a binary, and then disassembled. 233fd4e5da5Sopenharmony_civoid AssembleAndDisassemble(const std::string& text) { 234fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 235fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 236fd4e5da5Sopenharmony_ci 237fd4e5da5Sopenharmony_ci context->module()->ToBinary(&binary, false); 238fd4e5da5Sopenharmony_ci 239fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_1); 240fd4e5da5Sopenharmony_ci std::string s; 241fd4e5da5Sopenharmony_ci tools.Disassemble(binary, &s); 242fd4e5da5Sopenharmony_ci EXPECT_EQ(s, text); 243fd4e5da5Sopenharmony_ci} 244fd4e5da5Sopenharmony_ci 245fd4e5da5Sopenharmony_ciTEST(ModuleTest, TrailingOpLine) { 246fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 247fd4e5da5Sopenharmony_ciOpCapability Linkage 248fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 249fd4e5da5Sopenharmony_ci%5 = OpString "file.ext" 250fd4e5da5Sopenharmony_ci%void = OpTypeVoid 251fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %void 252fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %2 253fd4e5da5Sopenharmony_ci%4 = OpLabel 254fd4e5da5Sopenharmony_ciOpReturn 255fd4e5da5Sopenharmony_ciOpFunctionEnd 256fd4e5da5Sopenharmony_ciOpLine %5 1 0 257fd4e5da5Sopenharmony_ci)"; 258fd4e5da5Sopenharmony_ci 259fd4e5da5Sopenharmony_ci AssembleAndDisassemble(text); 260fd4e5da5Sopenharmony_ci} 261fd4e5da5Sopenharmony_ci 262fd4e5da5Sopenharmony_ciTEST(ModuleTest, TrailingOpNoLine) { 263fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 264fd4e5da5Sopenharmony_ciOpCapability Linkage 265fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 266fd4e5da5Sopenharmony_ci%void = OpTypeVoid 267fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %void 268fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %2 269fd4e5da5Sopenharmony_ci%4 = OpLabel 270fd4e5da5Sopenharmony_ciOpReturn 271fd4e5da5Sopenharmony_ciOpFunctionEnd 272fd4e5da5Sopenharmony_ciOpNoLine 273fd4e5da5Sopenharmony_ci)"; 274fd4e5da5Sopenharmony_ci 275fd4e5da5Sopenharmony_ci AssembleAndDisassemble(text); 276fd4e5da5Sopenharmony_ci} 277fd4e5da5Sopenharmony_ci 278fd4e5da5Sopenharmony_ciTEST(ModuleTest, MulitpleTrailingOpLine) { 279fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 280fd4e5da5Sopenharmony_ciOpCapability Linkage 281fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 282fd4e5da5Sopenharmony_ci%5 = OpString "file.ext" 283fd4e5da5Sopenharmony_ci%void = OpTypeVoid 284fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %void 285fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %2 286fd4e5da5Sopenharmony_ci%4 = OpLabel 287fd4e5da5Sopenharmony_ciOpReturn 288fd4e5da5Sopenharmony_ciOpFunctionEnd 289fd4e5da5Sopenharmony_ciOpLine %5 1 0 290fd4e5da5Sopenharmony_ciOpNoLine 291fd4e5da5Sopenharmony_ciOpLine %5 1 1 292fd4e5da5Sopenharmony_ci)"; 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ci AssembleAndDisassemble(text); 295fd4e5da5Sopenharmony_ci} 296fd4e5da5Sopenharmony_ci 297fd4e5da5Sopenharmony_ciTEST(ModuleTest, NonSemanticInfoIteration) { 298fd4e5da5Sopenharmony_ci const std::string text = R"( 299fd4e5da5Sopenharmony_ciOpCapability Shader 300fd4e5da5Sopenharmony_ciOpCapability Linkage 301fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 302fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Test" 303fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 304fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 305fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2 306fd4e5da5Sopenharmony_ci%4 = OpExtInst %2 %1 1 307fd4e5da5Sopenharmony_ci%5 = OpFunction %2 None %3 308fd4e5da5Sopenharmony_ci%6 = OpLabel 309fd4e5da5Sopenharmony_ci%7 = OpExtInst %2 %1 1 310fd4e5da5Sopenharmony_ciOpReturn 311fd4e5da5Sopenharmony_ciOpFunctionEnd 312fd4e5da5Sopenharmony_ci%8 = OpExtInst %2 %1 1 313fd4e5da5Sopenharmony_ci%9 = OpFunction %2 None %3 314fd4e5da5Sopenharmony_ci%10 = OpLabel 315fd4e5da5Sopenharmony_ci%11 = OpExtInst %2 %1 1 316fd4e5da5Sopenharmony_ciOpReturn 317fd4e5da5Sopenharmony_ciOpFunctionEnd 318fd4e5da5Sopenharmony_ci%12 = OpExtInst %2 %1 1 319fd4e5da5Sopenharmony_ci)"; 320fd4e5da5Sopenharmony_ci 321fd4e5da5Sopenharmony_ci std::unique_ptr<IRContext> context = BuildModule(text); 322fd4e5da5Sopenharmony_ci std::unordered_set<uint32_t> non_semantic_ids; 323fd4e5da5Sopenharmony_ci context->module()->ForEachInst( 324fd4e5da5Sopenharmony_ci [&non_semantic_ids](const Instruction* inst) { 325fd4e5da5Sopenharmony_ci if (inst->opcode() == spv::Op::OpExtInst) { 326fd4e5da5Sopenharmony_ci non_semantic_ids.insert(inst->result_id()); 327fd4e5da5Sopenharmony_ci } 328fd4e5da5Sopenharmony_ci }, 329fd4e5da5Sopenharmony_ci false); 330fd4e5da5Sopenharmony_ci 331fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(4)); 332fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(7)); 333fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(8)); 334fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(11)); 335fd4e5da5Sopenharmony_ci EXPECT_EQ(1, non_semantic_ids.count(12)); 336fd4e5da5Sopenharmony_ci} 337fd4e5da5Sopenharmony_ci} // namespace 338fd4e5da5Sopenharmony_ci} // namespace opt 339fd4e5da5Sopenharmony_ci} // namespace spvtools 340