1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 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 <string> 16fd4e5da5Sopenharmony_ci#include <vector> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 19fd4e5da5Sopenharmony_ci#include "spirv-tools/libspirv.hpp" 20fd4e5da5Sopenharmony_ci#include "spirv-tools/optimizer.hpp" 21fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace opt { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ::testing::Eq; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ci// Return a string that contains the minimum instructions needed to form 30fd4e5da5Sopenharmony_ci// a valid module. Other instructions can be appended to this string. 31fd4e5da5Sopenharmony_cistd::string Header() { 32fd4e5da5Sopenharmony_ci return R"(OpCapability Shader 33fd4e5da5Sopenharmony_ciOpCapability Linkage 34fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 35fd4e5da5Sopenharmony_ci)"; 36fd4e5da5Sopenharmony_ci} 37fd4e5da5Sopenharmony_ci 38fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRunNullPassWithDistinctInputOutputVectors) { 39fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 40fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary_in; 41fd4e5da5Sopenharmony_ci tools.Assemble(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid", 42fd4e5da5Sopenharmony_ci &binary_in); 43fd4e5da5Sopenharmony_ci 44fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 45fd4e5da5Sopenharmony_ci opt.RegisterPass(CreateNullPass()); 46fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary_out; 47fd4e5da5Sopenharmony_ci opt.Run(binary_in.data(), binary_in.size(), &binary_out); 48fd4e5da5Sopenharmony_ci 49fd4e5da5Sopenharmony_ci std::string disassembly; 50fd4e5da5Sopenharmony_ci tools.Disassemble(binary_out.data(), binary_out.size(), &disassembly); 51fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, 52fd4e5da5Sopenharmony_ci Eq(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid\n")); 53fd4e5da5Sopenharmony_ci} 54fd4e5da5Sopenharmony_ci 55fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRunTransformingPassWithDistinctInputOutputVectors) { 56fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 57fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary_in; 58fd4e5da5Sopenharmony_ci tools.Assemble(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid", 59fd4e5da5Sopenharmony_ci &binary_in); 60fd4e5da5Sopenharmony_ci 61fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 62fd4e5da5Sopenharmony_ci opt.RegisterPass(CreateStripDebugInfoPass()); 63fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary_out; 64fd4e5da5Sopenharmony_ci opt.Run(binary_in.data(), binary_in.size(), &binary_out); 65fd4e5da5Sopenharmony_ci 66fd4e5da5Sopenharmony_ci std::string disassembly; 67fd4e5da5Sopenharmony_ci tools.Disassemble(binary_out.data(), binary_out.size(), &disassembly); 68fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(Header() + "%void = OpTypeVoid\n")); 69fd4e5da5Sopenharmony_ci} 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRunNullPassWithAliasedVectors) { 72fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 73fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 74fd4e5da5Sopenharmony_ci tools.Assemble("OpName %foo \"foo\"\n%foo = OpTypeVoid", &binary); 75fd4e5da5Sopenharmony_ci 76fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 77fd4e5da5Sopenharmony_ci opt.RegisterPass(CreateNullPass()); 78fd4e5da5Sopenharmony_ci opt.Run(binary.data(), binary.size(), &binary); // This is the key. 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci std::string disassembly; 81fd4e5da5Sopenharmony_ci tools.Disassemble(binary.data(), binary.size(), &disassembly); 82fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq("OpName %foo \"foo\"\n%foo = OpTypeVoid\n")); 83fd4e5da5Sopenharmony_ci} 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRunNullPassWithAliasedVectorDataButDifferentSize) { 86fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 87fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 88fd4e5da5Sopenharmony_ci tools.Assemble(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid", &binary); 89fd4e5da5Sopenharmony_ci 90fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 91fd4e5da5Sopenharmony_ci opt.RegisterPass(CreateNullPass()); 92fd4e5da5Sopenharmony_ci auto orig_size = binary.size(); 93fd4e5da5Sopenharmony_ci // Now change the size. Add a word that will be ignored 94fd4e5da5Sopenharmony_ci // by the optimizer. 95fd4e5da5Sopenharmony_ci binary.push_back(42); 96fd4e5da5Sopenharmony_ci EXPECT_THAT(orig_size + 1, Eq(binary.size())); 97fd4e5da5Sopenharmony_ci opt.Run(binary.data(), orig_size, &binary); // This is the key. 98fd4e5da5Sopenharmony_ci // The binary vector should have been rewritten. 99fd4e5da5Sopenharmony_ci EXPECT_THAT(binary.size(), Eq(orig_size)); 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ci std::string disassembly; 102fd4e5da5Sopenharmony_ci tools.Disassemble(binary.data(), binary.size(), &disassembly); 103fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, 104fd4e5da5Sopenharmony_ci Eq(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid\n")); 105fd4e5da5Sopenharmony_ci} 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRunTransformingPassWithAliasedVectors) { 108fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 109fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 110fd4e5da5Sopenharmony_ci tools.Assemble(Header() + "OpName %foo \"foo\"\n%foo = OpTypeVoid", &binary); 111fd4e5da5Sopenharmony_ci 112fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 113fd4e5da5Sopenharmony_ci opt.RegisterPass(CreateStripDebugInfoPass()); 114fd4e5da5Sopenharmony_ci opt.Run(binary.data(), binary.size(), &binary); // This is the key 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci std::string disassembly; 117fd4e5da5Sopenharmony_ci tools.Disassemble(binary.data(), binary.size(), &disassembly); 118fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(Header() + "%void = OpTypeVoid\n")); 119fd4e5da5Sopenharmony_ci} 120fd4e5da5Sopenharmony_ci 121fd4e5da5Sopenharmony_ciTEST(Optimizer, CanValidateFlags) { 122fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 123fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.FlagHasValidForm("bad-flag")); 124fd4e5da5Sopenharmony_ci EXPECT_TRUE(opt.FlagHasValidForm("-O")); 125fd4e5da5Sopenharmony_ci EXPECT_TRUE(opt.FlagHasValidForm("-Os")); 126fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.FlagHasValidForm("-O2")); 127fd4e5da5Sopenharmony_ci EXPECT_TRUE(opt.FlagHasValidForm("--this_flag")); 128fd4e5da5Sopenharmony_ci} 129fd4e5da5Sopenharmony_ci 130fd4e5da5Sopenharmony_ciTEST(Optimizer, CanRegisterPassesFromFlags) { 131fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_UNIVERSAL_1_0); 132fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_UNIVERSAL_1_0); 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci spv_message_level_t msg_level; 135fd4e5da5Sopenharmony_ci const char* msg_fname; 136fd4e5da5Sopenharmony_ci spv_position_t msg_position; 137fd4e5da5Sopenharmony_ci const char* msg; 138fd4e5da5Sopenharmony_ci auto examine_message = [&msg_level, &msg_fname, &msg_position, &msg]( 139fd4e5da5Sopenharmony_ci spv_message_level_t ml, const char* f, 140fd4e5da5Sopenharmony_ci const spv_position_t& p, const char* m) { 141fd4e5da5Sopenharmony_ci msg_level = ml; 142fd4e5da5Sopenharmony_ci msg_fname = f; 143fd4e5da5Sopenharmony_ci msg_position = p; 144fd4e5da5Sopenharmony_ci msg = m; 145fd4e5da5Sopenharmony_ci }; 146fd4e5da5Sopenharmony_ci opt.SetMessageConsumer(examine_message); 147fd4e5da5Sopenharmony_ci 148fd4e5da5Sopenharmony_ci std::vector<std::string> pass_flags = { 149fd4e5da5Sopenharmony_ci "--strip-debug", 150fd4e5da5Sopenharmony_ci "--strip-nonsemantic", 151fd4e5da5Sopenharmony_ci "--set-spec-const-default-value=23:42 21:12", 152fd4e5da5Sopenharmony_ci "--if-conversion", 153fd4e5da5Sopenharmony_ci "--freeze-spec-const", 154fd4e5da5Sopenharmony_ci "--inline-entry-points-exhaustive", 155fd4e5da5Sopenharmony_ci "--inline-entry-points-opaque", 156fd4e5da5Sopenharmony_ci "--convert-local-access-chains", 157fd4e5da5Sopenharmony_ci "--eliminate-dead-code-aggressive", 158fd4e5da5Sopenharmony_ci "--eliminate-insert-extract", 159fd4e5da5Sopenharmony_ci "--eliminate-local-single-block", 160fd4e5da5Sopenharmony_ci "--eliminate-local-single-store", 161fd4e5da5Sopenharmony_ci "--merge-blocks", 162fd4e5da5Sopenharmony_ci "--merge-return", 163fd4e5da5Sopenharmony_ci "--eliminate-dead-branches", 164fd4e5da5Sopenharmony_ci "--eliminate-dead-functions", 165fd4e5da5Sopenharmony_ci "--eliminate-local-multi-store", 166fd4e5da5Sopenharmony_ci "--eliminate-dead-const", 167fd4e5da5Sopenharmony_ci "--eliminate-dead-inserts", 168fd4e5da5Sopenharmony_ci "--eliminate-dead-variables", 169fd4e5da5Sopenharmony_ci "--fold-spec-const-op-composite", 170fd4e5da5Sopenharmony_ci "--loop-unswitch", 171fd4e5da5Sopenharmony_ci "--scalar-replacement=300", 172fd4e5da5Sopenharmony_ci "--scalar-replacement", 173fd4e5da5Sopenharmony_ci "--strength-reduction", 174fd4e5da5Sopenharmony_ci "--unify-const", 175fd4e5da5Sopenharmony_ci "--flatten-decorations", 176fd4e5da5Sopenharmony_ci "--compact-ids", 177fd4e5da5Sopenharmony_ci "--cfg-cleanup", 178fd4e5da5Sopenharmony_ci "--local-redundancy-elimination", 179fd4e5da5Sopenharmony_ci "--loop-invariant-code-motion", 180fd4e5da5Sopenharmony_ci "--reduce-load-size", 181fd4e5da5Sopenharmony_ci "--redundancy-elimination", 182fd4e5da5Sopenharmony_ci "--private-to-local", 183fd4e5da5Sopenharmony_ci "--remove-duplicates", 184fd4e5da5Sopenharmony_ci "--workaround-1209", 185fd4e5da5Sopenharmony_ci "--replace-invalid-opcode", 186fd4e5da5Sopenharmony_ci "--simplify-instructions", 187fd4e5da5Sopenharmony_ci "--ssa-rewrite", 188fd4e5da5Sopenharmony_ci "--copy-propagate-arrays", 189fd4e5da5Sopenharmony_ci "--loop-fission=20", 190fd4e5da5Sopenharmony_ci "--loop-fusion=2", 191fd4e5da5Sopenharmony_ci "--loop-unroll", 192fd4e5da5Sopenharmony_ci "--vector-dce", 193fd4e5da5Sopenharmony_ci "--loop-unroll-partial=3", 194fd4e5da5Sopenharmony_ci "--loop-peeling", 195fd4e5da5Sopenharmony_ci "--ccp", 196fd4e5da5Sopenharmony_ci "-O", 197fd4e5da5Sopenharmony_ci "-Os", 198fd4e5da5Sopenharmony_ci "--legalize-hlsl"}; 199fd4e5da5Sopenharmony_ci EXPECT_TRUE(opt.RegisterPassesFromFlags(pass_flags)); 200fd4e5da5Sopenharmony_ci 201fd4e5da5Sopenharmony_ci // Test some invalid flags. 202fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("-O2")); 203fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 204fd4e5da5Sopenharmony_ci 205fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("-loop-unroll")); 206fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("--set-spec-const-default-value")); 209fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("--scalar-replacement=s")); 212fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 213fd4e5da5Sopenharmony_ci 214fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("--loop-fission=-4")); 215fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("--loop-fusion=xx")); 218fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 219fd4e5da5Sopenharmony_ci 220fd4e5da5Sopenharmony_ci EXPECT_FALSE(opt.RegisterPassFromFlag("--loop-unroll-partial")); 221fd4e5da5Sopenharmony_ci EXPECT_EQ(msg_level, SPV_MSG_ERROR); 222fd4e5da5Sopenharmony_ci} 223fd4e5da5Sopenharmony_ci 224fd4e5da5Sopenharmony_ci 225fd4e5da5Sopenharmony_ciTEST(Optimizer, RemoveNop) { 226fd4e5da5Sopenharmony_ci // Test that OpNops are removed even if no optimizations are run. 227fd4e5da5Sopenharmony_ci const std::string before = R"(OpCapability Shader 228fd4e5da5Sopenharmony_ciOpCapability Linkage 229fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 230fd4e5da5Sopenharmony_ci%void = OpTypeVoid 231fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %void 232fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %2 233fd4e5da5Sopenharmony_ci%4 = OpLabel 234fd4e5da5Sopenharmony_ciOpNop 235fd4e5da5Sopenharmony_ciOpReturn 236fd4e5da5Sopenharmony_ciOpFunctionEnd 237fd4e5da5Sopenharmony_ci)"; 238fd4e5da5Sopenharmony_ci 239fd4e5da5Sopenharmony_ci const std::string after = R"(OpCapability Shader 240fd4e5da5Sopenharmony_ciOpCapability Linkage 241fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 242fd4e5da5Sopenharmony_ci%void = OpTypeVoid 243fd4e5da5Sopenharmony_ci%2 = OpTypeFunction %void 244fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %2 245fd4e5da5Sopenharmony_ci%4 = OpLabel 246fd4e5da5Sopenharmony_ciOpReturn 247fd4e5da5Sopenharmony_ciOpFunctionEnd 248fd4e5da5Sopenharmony_ci)"; 249fd4e5da5Sopenharmony_ci 250fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 251fd4e5da5Sopenharmony_ci { 252fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_VULKAN_1_1); 253fd4e5da5Sopenharmony_ci tools.Assemble(before, &binary); 254fd4e5da5Sopenharmony_ci } 255fd4e5da5Sopenharmony_ci 256fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_VULKAN_1_1); 257fd4e5da5Sopenharmony_ci 258fd4e5da5Sopenharmony_ci std::vector<uint32_t> optimized; 259fd4e5da5Sopenharmony_ci class ValidatorOptions validator_options; 260fd4e5da5Sopenharmony_ci ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, 261fd4e5da5Sopenharmony_ci validator_options, true)) 262fd4e5da5Sopenharmony_ci << before << "\n"; 263fd4e5da5Sopenharmony_ci std::string disassembly; 264fd4e5da5Sopenharmony_ci { 265fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_VULKAN_1_1); 266fd4e5da5Sopenharmony_ci tools.Disassemble(optimized.data(), optimized.size(), &disassembly); 267fd4e5da5Sopenharmony_ci } 268fd4e5da5Sopenharmony_ci 269fd4e5da5Sopenharmony_ci EXPECT_EQ(after, disassembly) 270fd4e5da5Sopenharmony_ci << "Was expecting the OpNop to have been removed."; 271fd4e5da5Sopenharmony_ci} 272fd4e5da5Sopenharmony_ci 273fd4e5da5Sopenharmony_ciTEST(Optimizer, AvoidIntegrityCheckForExtraLineInfo) { 274fd4e5da5Sopenharmony_ci // Test that it avoids the integrity check when no optimizations are run and 275fd4e5da5Sopenharmony_ci // OpLines are propagated. 276fd4e5da5Sopenharmony_ci const std::string before = R"(OpCapability Shader 277fd4e5da5Sopenharmony_ciOpCapability Linkage 278fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 279fd4e5da5Sopenharmony_ci%1 = OpString "Test" 280fd4e5da5Sopenharmony_ci%void = OpTypeVoid 281fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 282fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 283fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint 284fd4e5da5Sopenharmony_ci%6 = OpFunction %void None %3 285fd4e5da5Sopenharmony_ci%7 = OpLabel 286fd4e5da5Sopenharmony_ciOpLine %1 10 0 287fd4e5da5Sopenharmony_ci%8 = OpVariable %_ptr_Function_uint Function 288fd4e5da5Sopenharmony_ciOpLine %1 10 0 289fd4e5da5Sopenharmony_ci%9 = OpVariable %_ptr_Function_uint Function 290fd4e5da5Sopenharmony_ciOpLine %1 20 0 291fd4e5da5Sopenharmony_ciOpReturn 292fd4e5da5Sopenharmony_ciOpFunctionEnd 293fd4e5da5Sopenharmony_ci)"; 294fd4e5da5Sopenharmony_ci 295fd4e5da5Sopenharmony_ci const std::string after = R"(OpCapability Shader 296fd4e5da5Sopenharmony_ciOpCapability Linkage 297fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 298fd4e5da5Sopenharmony_ci%1 = OpString "Test" 299fd4e5da5Sopenharmony_ci%void = OpTypeVoid 300fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 301fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 302fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint 303fd4e5da5Sopenharmony_ci%6 = OpFunction %void None %3 304fd4e5da5Sopenharmony_ci%7 = OpLabel 305fd4e5da5Sopenharmony_ciOpLine %1 10 0 306fd4e5da5Sopenharmony_ci%8 = OpVariable %_ptr_Function_uint Function 307fd4e5da5Sopenharmony_ci%9 = OpVariable %_ptr_Function_uint Function 308fd4e5da5Sopenharmony_ciOpLine %1 20 0 309fd4e5da5Sopenharmony_ciOpReturn 310fd4e5da5Sopenharmony_ciOpFunctionEnd 311fd4e5da5Sopenharmony_ci)"; 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 314fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_VULKAN_1_1); 315fd4e5da5Sopenharmony_ci tools.Assemble(before, &binary); 316fd4e5da5Sopenharmony_ci 317fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_VULKAN_1_1); 318fd4e5da5Sopenharmony_ci 319fd4e5da5Sopenharmony_ci std::vector<uint32_t> optimized; 320fd4e5da5Sopenharmony_ci class ValidatorOptions validator_options; 321fd4e5da5Sopenharmony_ci ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, 322fd4e5da5Sopenharmony_ci validator_options, true)) 323fd4e5da5Sopenharmony_ci << before << "\n"; 324fd4e5da5Sopenharmony_ci 325fd4e5da5Sopenharmony_ci std::string disassembly; 326fd4e5da5Sopenharmony_ci tools.Disassemble(optimized.data(), optimized.size(), &disassembly); 327fd4e5da5Sopenharmony_ci 328fd4e5da5Sopenharmony_ci EXPECT_EQ(after, disassembly) 329fd4e5da5Sopenharmony_ci << "Was expecting the OpLine to have been propagated."; 330fd4e5da5Sopenharmony_ci} 331fd4e5da5Sopenharmony_ci 332fd4e5da5Sopenharmony_ciTEST(Optimizer, AvoidIntegrityCheckForDebugScope) { 333fd4e5da5Sopenharmony_ci // Test that it avoids the integrity check when the code contains DebugScope. 334fd4e5da5Sopenharmony_ci const std::string before = R"(OpCapability Shader 335fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100" 336fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 337fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 338fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 339fd4e5da5Sopenharmony_ci%3 = OpString "simple_vs.hlsl" 340fd4e5da5Sopenharmony_ciOpSource HLSL 600 %3 341fd4e5da5Sopenharmony_ciOpName %main "main" 342fd4e5da5Sopenharmony_ci%void = OpTypeVoid 343fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 344fd4e5da5Sopenharmony_ci%6 = OpExtInst %void %1 DebugSource %3 345fd4e5da5Sopenharmony_ci%7 = OpExtInst %void %1 DebugCompilationUnit 2 4 %6 HLSL 346fd4e5da5Sopenharmony_ci%main = OpFunction %void None %5 347fd4e5da5Sopenharmony_ci%14 = OpLabel 348fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %1 DebugScope %7 349fd4e5da5Sopenharmony_ciOpReturn 350fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugNoScope 351fd4e5da5Sopenharmony_ciOpFunctionEnd 352fd4e5da5Sopenharmony_ci)"; 353fd4e5da5Sopenharmony_ci 354fd4e5da5Sopenharmony_ci const std::string after = R"(OpCapability Shader 355fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100" 356fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 357fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 358fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 359fd4e5da5Sopenharmony_ci%3 = OpString "simple_vs.hlsl" 360fd4e5da5Sopenharmony_ciOpSource HLSL 600 %3 361fd4e5da5Sopenharmony_ciOpName %main "main" 362fd4e5da5Sopenharmony_ci%void = OpTypeVoid 363fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 364fd4e5da5Sopenharmony_ci%6 = OpExtInst %void %1 DebugSource %3 365fd4e5da5Sopenharmony_ci%7 = OpExtInst %void %1 DebugCompilationUnit 2 4 %6 HLSL 366fd4e5da5Sopenharmony_ci%main = OpFunction %void None %5 367fd4e5da5Sopenharmony_ci%8 = OpLabel 368fd4e5da5Sopenharmony_ci%11 = OpExtInst %void %1 DebugScope %7 369fd4e5da5Sopenharmony_ciOpReturn 370fd4e5da5Sopenharmony_ci%12 = OpExtInst %void %1 DebugNoScope 371fd4e5da5Sopenharmony_ciOpFunctionEnd 372fd4e5da5Sopenharmony_ci)"; 373fd4e5da5Sopenharmony_ci 374fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary; 375fd4e5da5Sopenharmony_ci SpirvTools tools(SPV_ENV_VULKAN_1_1); 376fd4e5da5Sopenharmony_ci tools.Assemble(before, &binary); 377fd4e5da5Sopenharmony_ci 378fd4e5da5Sopenharmony_ci Optimizer opt(SPV_ENV_VULKAN_1_1); 379fd4e5da5Sopenharmony_ci 380fd4e5da5Sopenharmony_ci std::vector<uint32_t> optimized; 381fd4e5da5Sopenharmony_ci ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized)) 382fd4e5da5Sopenharmony_ci << before << "\n"; 383fd4e5da5Sopenharmony_ci 384fd4e5da5Sopenharmony_ci std::string disassembly; 385fd4e5da5Sopenharmony_ci tools.Disassemble(optimized.data(), optimized.size(), &disassembly); 386fd4e5da5Sopenharmony_ci 387fd4e5da5Sopenharmony_ci EXPECT_EQ(after, disassembly) 388fd4e5da5Sopenharmony_ci << "Was expecting the result id of DebugScope to have been changed."; 389fd4e5da5Sopenharmony_ci} 390fd4e5da5Sopenharmony_ci 391fd4e5da5Sopenharmony_ci} // namespace 392fd4e5da5Sopenharmony_ci} // namespace opt 393fd4e5da5Sopenharmony_ci} // namespace spvtools 394