From 048dcd38cecb0d9afa5f868d065a05b597e5a138 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Tue, 16 Apr 2019 14:31:36 -0400 Subject: [PATCH] Implement WebGPU->Vulkan initializer conversion for 'Function' variables (#2513) WebGPU requires certain variables to be initialized, whereas there are known issues with using initializers in Vulkan. This PR is the first of three implementing a pass to decompose initialized variables into a variable declaration followed by a store. This has been broken up into multiple PRs, because there 3 distinct cases that need to be handled, which require separate implementations. This first PR implements the basic infrastructure that is needed, and handling of Function storage class variables. Private and Output will be handled in future PRs. This is part of resolving #2388 --- Android.mk | 1 + BUILD.gn | 2 + include/spirv-tools/optimizer.hpp | 4 + source/opt/CMakeLists.txt | 2 + .../decompose_initialized_variables_pass.cpp | 77 +++++++++++++ .../decompose_initialized_variables_pass.h | 57 +++++++++ .../opt/generate_webgpu_initializers_pass.cpp | 2 +- .../opt/generate_webgpu_initializers_pass.h | 2 +- source/opt/legalize_vector_shuffle_pass.cpp | 2 +- source/opt/legalize_vector_shuffle_pass.h | 2 +- source/opt/optimizer.cpp | 9 +- source/opt/passes.h | 1 + .../opt/strip_atomic_counter_memory_pass.cpp | 2 +- source/opt/strip_atomic_counter_memory_pass.h | 2 +- ...selection_reduction_opportunity_finder.cpp | 2 +- test/opt/CMakeLists.txt | 1 + .../decompose_initialized_variables_test.cpp | 85 ++++++++++++++ .../opt/generate_webgpu_initializers_test.cpp | 2 +- test/opt/legalize_vector_shuffle_test.cpp | 2 +- test/opt/optimizer_test.cpp | 108 +++++++++++++++++- test/opt/strip_atomic_counter_memory_test.cpp | 2 +- 21 files changed, 352 insertions(+), 15 deletions(-) create mode 100644 source/opt/decompose_initialized_variables_pass.cpp create mode 100644 source/opt/decompose_initialized_variables_pass.h create mode 100644 test/opt/decompose_initialized_variables_test.cpp diff --git a/Android.mk b/Android.mk index ba54d6512..7c6a076d2 100644 --- a/Android.mk +++ b/Android.mk @@ -92,6 +92,7 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/dead_branch_elim_pass.cpp \ source/opt/dead_insert_elim_pass.cpp \ source/opt/dead_variable_elimination.cpp \ + source/opt/decompose_initialized_variables_pass.cpp \ source/opt/decoration_manager.cpp \ source/opt/def_use_manager.cpp \ source/opt/dominator_analysis.cpp \ diff --git a/BUILD.gn b/BUILD.gn index 7c869b09b..6c28118f6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -484,6 +484,8 @@ static_library("spvtools_opt") { "source/opt/dead_insert_elim_pass.h", "source/opt/dead_variable_elimination.cpp", "source/opt/dead_variable_elimination.h", + "source/opt/decompose_initialized_variables_pass.cpp", + "source/opt/decompose_initialized_variables_pass.h", "source/opt/decoration_manager.cpp", "source/opt/decoration_manager.h", "source/opt/def_use_manager.cpp", diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp index 213e50b3d..af9f3e54a 100644 --- a/include/spirv-tools/optimizer.hpp +++ b/include/spirv-tools/optimizer.hpp @@ -768,6 +768,10 @@ Optimizer::PassToken CreateFixStorageClassPass(); // converts those literals to 0. Optimizer::PassToken CreateLegalizeVectorShufflePass(); +// Create a pass to decompose initialized variables into a seperate variable +// declaration and an initial store. +Optimizer::PassToken CreateDecomposeInitializedVariablesPass(); + } // namespace spvtools #endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ diff --git a/source/opt/CMakeLists.txt b/source/opt/CMakeLists.txt index e270a9fae..b02485a71 100644 --- a/source/opt/CMakeLists.txt +++ b/source/opt/CMakeLists.txt @@ -31,6 +31,7 @@ set(SPIRV_TOOLS_OPT_SOURCES dead_branch_elim_pass.h dead_insert_elim_pass.h dead_variable_elimination.h + decompose_initialized_variables_pass.h decoration_manager.h def_use_manager.h dominator_analysis.h @@ -130,6 +131,7 @@ set(SPIRV_TOOLS_OPT_SOURCES dead_branch_elim_pass.cpp dead_insert_elim_pass.cpp dead_variable_elimination.cpp + decompose_initialized_variables_pass.cpp decoration_manager.cpp def_use_manager.cpp dominator_analysis.cpp diff --git a/source/opt/decompose_initialized_variables_pass.cpp b/source/opt/decompose_initialized_variables_pass.cpp new file mode 100644 index 000000000..b2471cad2 --- /dev/null +++ b/source/opt/decompose_initialized_variables_pass.cpp @@ -0,0 +1,77 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/decompose_initialized_variables_pass.h" + +#include "source/opt/ir_context.h" + +namespace spvtools { +namespace opt { + +using inst_iterator = InstructionList::iterator; + +namespace { + +bool HasInitializer(Instruction* inst) { + if (inst->opcode() != SpvOpVariable) return false; + if (inst->NumOperands() < 4) return false; + + return true; +} + +} // namespace + +Pass::Status DecomposeInitializedVariablesPass::Process() { + auto* module = context()->module(); + bool changed = false; + + // TODO(zoddicus): Handle 'Output' variables + // TODO(zoddicus): Handle 'Private' variables + + // Handle 'Function' variables + for (auto func = module->begin(); func != module->end(); ++func) { + auto block = func->entry().get(); + std::vector new_stores; + + auto last_var = block->begin(); + for (auto iter = block->begin(); + iter != block->end() && iter->opcode() == SpvOpVariable; ++iter) { + last_var = iter; + Instruction* inst = &(*iter); + if (!HasInitializer(inst)) continue; + + changed = true; + auto var_id = inst->result_id(); + auto val_id = inst->GetOperand(3).words[0]; + Instruction* store_inst = new Instruction( + context(), SpvOpStore, 0, 0, + {{SPV_OPERAND_TYPE_ID, {var_id}}, {SPV_OPERAND_TYPE_ID, {val_id}}}); + new_stores.push_back(store_inst); + iter->RemoveOperand(3); + get_def_use_mgr()->UpdateDefUse(&*iter); + } + + for (auto store = new_stores.begin(); store != new_stores.end(); ++store) { + context()->AnalyzeDefUse(*store); + context()->set_instr_block(*store, block); + (*store)->InsertAfter(&*last_var); + last_var = *store; + } + } + + return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/source/opt/decompose_initialized_variables_pass.h b/source/opt/decompose_initialized_variables_pass.h new file mode 100644 index 000000000..c0bd35e76 --- /dev/null +++ b/source/opt/decompose_initialized_variables_pass.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ +#define SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +// Converts variable declartions with initializers into seperate declaration and +// assignment statements. This is done due to known issues with some Vulkan +// implementations' handling of initialized variables. +// +// Only decomposes variables with storage classes that are valid in Vulkan +// execution environments; Output, Private, and Function. +// Currently only Function is implemented. +class DecomposeInitializedVariablesPass : public Pass { + public: + const char* name() const override { + return "decompose-initialized-variables"; + } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisScalarEvolution | + IRContext::kAnalysisRegisterPressure | + IRContext::kAnalysisValueNumberTable | + IRContext::kAnalysisStructuredCFG | + IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | + IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ diff --git a/source/opt/generate_webgpu_initializers_pass.cpp b/source/opt/generate_webgpu_initializers_pass.cpp index a8e00b666..9334b43ee 100644 --- a/source/opt/generate_webgpu_initializers_pass.cpp +++ b/source/opt/generate_webgpu_initializers_pass.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/opt/generate_webgpu_initializers_pass.h b/source/opt/generate_webgpu_initializers_pass.h index 9aa970dd9..f95e84c5b 100644 --- a/source/opt/generate_webgpu_initializers_pass.h +++ b/source/opt/generate_webgpu_initializers_pass.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/opt/legalize_vector_shuffle_pass.cpp b/source/opt/legalize_vector_shuffle_pass.cpp index dcaf26350..b5d5d5993 100644 --- a/source/opt/legalize_vector_shuffle_pass.cpp +++ b/source/opt/legalize_vector_shuffle_pass.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/opt/legalize_vector_shuffle_pass.h b/source/opt/legalize_vector_shuffle_pass.h index 20ccbd7f8..ca6e1dfbe 100644 --- a/source/opt/legalize_vector_shuffle_pass.h +++ b/source/opt/legalize_vector_shuffle_pass.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp index 29c5466e8..34ddedca7 100644 --- a/source/opt/optimizer.cpp +++ b/source/opt/optimizer.cpp @@ -231,7 +231,9 @@ Optimizer& Optimizer::RegisterVulkanToWebGPUPasses() { .RegisterPass(CreateDeadBranchElimPass()); } -Optimizer& Optimizer::RegisterWebGPUToVulkanPasses() { return *this; } +Optimizer& Optimizer::RegisterWebGPUToVulkanPasses() { + return RegisterPass(CreateDecomposeInitializedVariablesPass()); +} bool Optimizer::RegisterPassesFromFlags(const std::vector& flags) { for (const auto& flag : flags) { @@ -866,4 +868,9 @@ Optimizer::PassToken CreateLegalizeVectorShufflePass() { MakeUnique()); } +Optimizer::PassToken CreateDecomposeInitializedVariablesPass() { + return MakeUnique( + MakeUnique()); +} + } // namespace spvtools diff --git a/source/opt/passes.h b/source/opt/passes.h index c9f1ae840..06464b060 100644 --- a/source/opt/passes.h +++ b/source/opt/passes.h @@ -29,6 +29,7 @@ #include "source/opt/dead_branch_elim_pass.h" #include "source/opt/dead_insert_elim_pass.h" #include "source/opt/dead_variable_elimination.h" +#include "source/opt/decompose_initialized_variables_pass.h" #include "source/opt/eliminate_dead_constant_pass.h" #include "source/opt/eliminate_dead_functions_pass.h" #include "source/opt/eliminate_dead_members_pass.h" diff --git a/source/opt/strip_atomic_counter_memory_pass.cpp b/source/opt/strip_atomic_counter_memory_pass.cpp index 46a727cb7..47714b746 100644 --- a/source/opt/strip_atomic_counter_memory_pass.cpp +++ b/source/opt/strip_atomic_counter_memory_pass.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/opt/strip_atomic_counter_memory_pass.h b/source/opt/strip_atomic_counter_memory_pass.h index d94cf324b..62e274a19 100644 --- a/source/opt/strip_atomic_counter_memory_pass.h +++ b/source/opt/strip_atomic_counter_memory_pass.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/source/reduce/remove_selection_reduction_opportunity_finder.cpp b/source/reduce/remove_selection_reduction_opportunity_finder.cpp index 45cf26dd7..45821e2af 100644 --- a/source/reduce/remove_selection_reduction_opportunity_finder.cpp +++ b/source/reduce/remove_selection_reduction_opportunity_finder.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/test/opt/CMakeLists.txt b/test/opt/CMakeLists.txt index f67f9b643..c1b1b2745 100644 --- a/test/opt/CMakeLists.txt +++ b/test/opt/CMakeLists.txt @@ -30,6 +30,7 @@ add_spvtools_unittest(TARGET opt dead_branch_elim_test.cpp dead_insert_elim_test.cpp dead_variable_elim_test.cpp + decompose_initialized_variables_test.cpp decoration_manager_test.cpp def_use_test.cpp eliminate_dead_const_test.cpp diff --git a/test/opt/decompose_initialized_variables_test.cpp b/test/opt/decompose_initialized_variables_test.cpp new file mode 100644 index 000000000..188e8b232 --- /dev/null +++ b/test/opt/decompose_initialized_variables_test.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "test/opt/pass_fixture.h" +#include "test/opt/pass_utils.h" + +namespace spvtools { +namespace opt { +namespace { + +using DecomposeInitializedVariablesTest = PassTest<::testing::Test>; + +void operator+=(std::vector& lhs, + const std::vector rhs) { + for (auto elem : rhs) lhs.push_back(elem); +} + +std::vector header = { + "OpCapability Shader", + "OpCapability VulkanMemoryModelKHR", + "OpExtension \"SPV_KHR_vulkan_memory_model\"", + "OpMemoryModel Logical VulkanKHR", + "OpEntryPoint Vertex %1 \"shader\"", + "%uint = OpTypeInt 32 0", + "%uint_1 = OpConstant %uint 1", + "%4 = OpConstantNull %uint", + "%void = OpTypeVoid", + "%6 = OpTypeFunction %void"}; + +std::string GetFunctionTest(std::vector body) { + auto result = header; + result += {"%_ptr_Function_uint = OpTypePointer Function %uint", + "%1 = OpFunction %void None %6", "%8 = OpLabel"}; + result += body; + result += {"OpReturn", "OpFunctionEnd"}; + return JoinAllInsts(result); +} + +TEST_F(DecomposeInitializedVariablesTest, FunctionChanged) { + std::string input = + GetFunctionTest({"%9 = OpVariable %_ptr_Function_uint Function %uint_1"}); + std::string expected = GetFunctionTest( + {"%9 = OpVariable %_ptr_Function_uint Function", "OpStore %9 %uint_1"}); + + SinglePassRunAndCheck( + input, expected, /* skip_nop = */ false); +} + +TEST_F(DecomposeInitializedVariablesTest, FunctionUnchanged) { + std::string input = + GetFunctionTest({"%9 = OpVariable %_ptr_Function_uint Function"}); + + SinglePassRunAndCheck( + input, input, /* skip_nop = */ false); +} + +TEST_F(DecomposeInitializedVariablesTest, FunctionMultipleVariables) { + std::string input = + GetFunctionTest({"%9 = OpVariable %_ptr_Function_uint Function %uint_1", + "%10 = OpVariable %_ptr_Function_uint Function %4"}); + std::string expected = + GetFunctionTest({"%9 = OpVariable %_ptr_Function_uint Function", + "%10 = OpVariable %_ptr_Function_uint Function", + "OpStore %9 %uint_1", "OpStore %10 %4"}); + + SinglePassRunAndCheck( + input, expected, /* skip_nop = */ false); +} + +} // namespace +} // namespace opt +} // namespace spvtools diff --git a/test/opt/generate_webgpu_initializers_test.cpp b/test/opt/generate_webgpu_initializers_test.cpp index 3e4be55f9..f35cf56d4 100644 --- a/test/opt/generate_webgpu_initializers_test.cpp +++ b/test/opt/generate_webgpu_initializers_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/test/opt/legalize_vector_shuffle_test.cpp b/test/opt/legalize_vector_shuffle_test.cpp index 4d3d7a2ad..8b9695b9a 100644 --- a/test/opt/legalize_vector_shuffle_test.cpp +++ b/test/opt/legalize_vector_shuffle_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/test/opt/optimizer_test.cpp b/test/opt/optimizer_test.cpp index a3f695733..549335d88 100644 --- a/test/opt/optimizer_test.cpp +++ b/test/opt/optimizer_test.cpp @@ -222,7 +222,7 @@ TEST(Optimizer, CanRegisterPassesFromFlags) { EXPECT_EQ(msg_level, SPV_MSG_ERROR); } -TEST(Optimizer, VulkanToWebGPUModeSetsCorrectPasses) { +TEST(Optimizer, VulkanToWebGPUSetsCorrectPasses) { Optimizer opt(SPV_ENV_WEBGPU_0); opt.RegisterVulkanToWebGPUPasses(); std::vector pass_names = opt.GetPassNames(); @@ -260,9 +260,11 @@ using VulkanToWebGPUPassTest = PassTest<::testing::TestWithParam>; TEST_P(VulkanToWebGPUPassTest, Ran) { - SpirvTools tools(SPV_ENV_WEBGPU_0); std::vector binary; - tools.Assemble(GetParam().input, &binary); + { + SpirvTools tools(SPV_ENV_VULKAN_1_1); + tools.Assemble(GetParam().input, &binary); + } Optimizer opt(SPV_ENV_WEBGPU_0); opt.RegisterVulkanToWebGPUPasses(); @@ -272,7 +274,10 @@ TEST_P(VulkanToWebGPUPassTest, Ran) { ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, validator_options, true)); std::string disassembly; - tools.Disassemble(optimized.data(), optimized.size(), &disassembly); + { + SpirvTools tools(SPV_ENV_WEBGPU_0); + tools.Disassemble(optimized.data(), optimized.size(), &disassembly); + } EXPECT_EQ(GetParam().expected, disassembly) << "Was expecting pass '" << GetParam().pass << "' to have been run.\n"; @@ -521,6 +526,101 @@ INSTANTIATE_TEST_SUITE_P( // pass "legalize-vector-shuffle"}})); +TEST(Optimizer, WebGPUToVulkanSetsCorrectPasses) { + Optimizer opt(SPV_ENV_VULKAN_1_1); + opt.RegisterWebGPUToVulkanPasses(); + std::vector pass_names = opt.GetPassNames(); + + std::vector registered_passes; + for (auto name = pass_names.begin(); name != pass_names.end(); ++name) + registered_passes.push_back(*name); + + std::vector expected_passes = { + "decompose-initialized-variables"}; + std::sort(registered_passes.begin(), registered_passes.end()); + std::sort(expected_passes.begin(), expected_passes.end()); + + ASSERT_EQ(registered_passes.size(), expected_passes.size()); + for (size_t i = 0; i < registered_passes.size(); i++) + EXPECT_EQ(registered_passes[i], expected_passes[i]); +} + +struct WebGPUToVulkanPassCase { + // Input SPIR-V + std::string input; + // Expected result SPIR-V + std::string expected; + // Specific pass under test, used for logging messages. + std::string pass; +}; + +using WebGPUToVulkanPassTest = + PassTest<::testing::TestWithParam>; + +TEST_P(WebGPUToVulkanPassTest, Ran) { + std::vector binary; + { + SpirvTools tools(SPV_ENV_WEBGPU_0); + tools.Assemble(GetParam().input, &binary); + } + + Optimizer opt(SPV_ENV_VULKAN_1_1); + opt.RegisterWebGPUToVulkanPasses(); + + std::vector optimized; + class ValidatorOptions validator_options; + ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, + validator_options, true)); + std::string disassembly; + { + SpirvTools tools(SPV_ENV_VULKAN_1_1); + tools.Disassemble(optimized.data(), optimized.size(), &disassembly); + } + + EXPECT_EQ(GetParam().expected, disassembly) + << "Was expecting pass '" << GetParam().pass << "' to have been run.\n"; +} + +INSTANTIATE_TEST_SUITE_P( + Optimizer, WebGPUToVulkanPassTest, + ::testing::ValuesIn(std::vector{ + // Decompose Initialized Variables + {// input + "OpCapability Shader\n" + "OpCapability VulkanMemoryModelKHR\n" + "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" + "OpMemoryModel Logical VulkanKHR\n" + "OpEntryPoint Vertex %1 \"shader\"\n" + "%uint = OpTypeInt 32 0\n" + "%_ptr_Function_uint = OpTypePointer Function %uint\n" + "%4 = OpConstantNull %uint\n" + "%void = OpTypeVoid\n" + "%6 = OpTypeFunction %void\n" + "%1 = OpFunction %void None %6\n" + "%7 = OpLabel\n" + "%8 = OpVariable %_ptr_Function_uint Function %4\n" + "OpReturn\n" + "OpFunctionEnd\n", + // expected + "OpCapability Shader\n" + "OpCapability VulkanMemoryModelKHR\n" + "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" + "OpMemoryModel Logical VulkanKHR\n" + "OpEntryPoint Vertex %1 \"shader\"\n" + "%uint = OpTypeInt 32 0\n" + "%_ptr_Function_uint = OpTypePointer Function %uint\n" + "%4 = OpConstantNull %uint\n" + "%void = OpTypeVoid\n" + "%6 = OpTypeFunction %void\n" + "%1 = OpFunction %void None %6\n" + "%7 = OpLabel\n" + "%8 = OpVariable %_ptr_Function_uint Function\n" + "OpStore %8 %4\n" + "OpReturn\n" + "OpFunctionEnd\n", + // pass + "decompose-initialized-variables"}})); + } // namespace } // namespace opt } // namespace spvtools diff --git a/test/opt/strip_atomic_counter_memory_test.cpp b/test/opt/strip_atomic_counter_memory_test.cpp index 8756e815a..6287a13b0 100644 --- a/test/opt/strip_atomic_counter_memory_test.cpp +++ b/test/opt/strip_atomic_counter_memory_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Google Inc. +// Copyright (c) 2019 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License.