// Copyright (c) 2017 Pierre Moreau // // 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 #include #include #include "gmock/gmock.h" #include "source/opt/build_module.h" #include "source/opt/decoration_manager.h" #include "source/opt/ir_context.h" #include "source/spirv_constant.h" #include "source/util/string_utils.h" #include "test/unit_spirv.h" namespace spvtools { namespace opt { namespace analysis { namespace { using utils::MakeVector; class DecorationManagerTest : public ::testing::Test { public: DecorationManagerTest() : tools_(SPV_ENV_UNIVERSAL_1_2), context_(), consumer_([this](spv_message_level_t level, const char*, const spv_position_t& position, const char* message) { if (!error_message_.empty()) error_message_ += "\n"; switch (level) { case SPV_MSG_FATAL: case SPV_MSG_INTERNAL_ERROR: case SPV_MSG_ERROR: error_message_ += "ERROR"; break; case SPV_MSG_WARNING: error_message_ += "WARNING"; break; case SPV_MSG_INFO: error_message_ += "INFO"; break; case SPV_MSG_DEBUG: error_message_ += "DEBUG"; break; } error_message_ += ": " + std::to_string(position.index) + ": " + message; }), disassemble_options_(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER), error_message_() { tools_.SetMessageConsumer(consumer_); } void TearDown() override { error_message_.clear(); } DecorationManager* GetDecorationManager(const std::string& text) { context_ = BuildModule(SPV_ENV_UNIVERSAL_1_2, consumer_, text); if (context_.get()) return context_->get_decoration_mgr(); else return nullptr; } // Disassembles |binary| and outputs the result in |text|. If |text| is a // null pointer, SPV_ERROR_INVALID_POINTER is returned. spv_result_t Disassemble(const std::vector& binary, std::string* text) { if (!text) return SPV_ERROR_INVALID_POINTER; return tools_.Disassemble(binary, text, disassemble_options_) ? SPV_SUCCESS : SPV_ERROR_INVALID_BINARY; } // Returns the accumulated error messages for the test. std::string GetErrorMessage() const { return error_message_; } std::string ToText(const std::vector& inst) { std::vector binary = {spv::MagicNumber, 0x10200, 0u, 2u, 0u}; for (const Instruction* i : inst) i->ToBinaryWithoutAttachedDebugInsts(&binary); std::string text; Disassemble(binary, &text); return text; } std::string ModuleToText() { std::vector binary; context_->module()->ToBinary(&binary, false); std::string text; Disassemble(binary, &text); return text; } spvtools::MessageConsumer GetConsumer() { return consumer_; } private: // An instance for calling SPIRV-Tools functionalities. spvtools::SpirvTools tools_; std::unique_ptr context_; spvtools::MessageConsumer consumer_; uint32_t disassemble_options_; std::string error_message_; }; TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffOpcodesDecorateDecorateId) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // This parameter can be interpreted both as { spv::Decoration::Constant } // and also as a list of IDs: { 22 } const std::vector param{ static_cast(spv::Decoration::Constant)}; // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}}); // OpDecorateId %1 %22 ; 'Constant' is decoration number 22 Instruction inst2( &ir_context, spv::Op::OpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, param}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffOpcodesDecorateDecorateString) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // This parameter can be interpreted both as { spv::Decoration::Constant } // and also as a null-terminated string with a single character with value 22. const std::vector param{ static_cast(spv::Decoration::Constant)}; // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}}); // OpDecorateStringGOOGLE %1 !22 Instruction inst2( &ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, param}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpDecorate %1 Restrict Instruction inst2( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Restrict)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateIdParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {555}}}); // OpDecorate %1 Restrict Instruction inst2( &ir_context, spv::Op::OpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {666}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateStringParam) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hello!")}}); // OpDecorate %1 Restrict Instruction inst2(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hellx")}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpDecorate %2 Constant Instruction inst2( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameDecorationIdsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); Instruction inst1( &ir_context, spv::Op::OpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}}); Instruction inst2( &ir_context, spv::Op::OpDecorateId, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameDecorationStringsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); Instruction inst1(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}}); Instruction inst2(&ir_context, spv::Op::OpDecorateStringGOOGLE, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpDecorate %1 Constant Instruction inst1( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpDecorate %2 Constant Instruction inst2( &ir_context, spv::Op::OpDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false)); } TEST_F(DecorationManagerTest, ComparingMemberDecorationsOnSameTypeDiffMember) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant Instruction inst1( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpMemberDecorate %1 1 Constant Instruction inst2( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameMemberDecorationsOnDiffTargetAllowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant Instruction inst1( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpMemberDecorate %2 0 Constant Instruction inst2( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true)); } TEST_F(DecorationManagerTest, ComparingSameMemberDecorationsOnDiffTargetDisallowed) { IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer()); // OpMemberDecorate %1 0 Constant Instruction inst1( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); // OpMemberDecorate %2 0 Constant Instruction inst2( &ir_context, spv::Op::OpMemberDecorate, 0u, 0u, {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}}, {SPV_OPERAND_TYPE_DECORATION, {uint32_t(spv::Decoration::Constant)}}}); DecorationManager* decoManager = ir_context.get_decoration_mgr(); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false)); } TEST_F(DecorationManagerTest, RemoveDecorationFromVariable) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 %3 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decorations = decoManager->GetDecorationsFor(3u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %3 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveDecorationStringFromVariable) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello world" OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 %3 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decorations = decoManager->GetDecorationsFor(3u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %3 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveDecorationFromDecorationGroup) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 %3 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(2u); auto decorations = decoManager->GetDecorationsFor(2u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %1 Constant )"; EXPECT_THAT(ToText(decorations), expected_decorations); decorations = decoManager->GetDecorationsFor(3u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_THAT(ToText(decorations), ""); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant %2 = OpDecorationGroup %4 = OpTypeInt 32 0 %1 = OpVariable %4 Uniform %3 = OpVariable %4 Uniform )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveDecorationFromDecorationGroupKeepDeadDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 %3 = OpTypeInt 32 0 %1 = OpVariable %3 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decorations = decoManager->GetDecorationsFor(2u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %2 Restrict %2 = OpDecorationGroup %3 = OpTypeInt 32 0 %1 = OpVariable %3 Uniform )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveAllDecorationsAppliedByGroup) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 OpDecorate %3 BuiltIn VertexId %3 = OpDecorationGroup OpGroupDecorate %3 %1 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Input )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) { return inst.opcode() == spv::Op::OpDecorate && inst.GetSingleWordInOperand(0u) == 3u; }); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorate %1 Constant OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); decorations = decoManager->GetDecorationsFor(2u, false); EXPECT_THAT(GetErrorMessage(), ""); expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 OpDecorate %3 BuiltIn VertexId %3 = OpDecorationGroup %4 = OpTypeInt 32 0 %1 = OpVariable %4 Input )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveSomeDecorationsAppliedByGroup) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 OpDecorate %3 BuiltIn VertexId OpDecorate %3 Invariant %3 = OpDecorationGroup OpGroupDecorate %3 %1 %uint = OpTypeInt 32 0 %1 = OpVariable %uint Input )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) { return inst.opcode() == spv::Op::OpDecorate && inst.GetSingleWordInOperand(0u) == 3u && spv::Decoration(inst.GetSingleWordInOperand(1u)) == spv::Decoration::BuiltIn; }); auto decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorate %1 Constant OpDecorate %1 Invariant OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); decorations = decoManager->GetDecorationsFor(2u, false); EXPECT_THAT(GetErrorMessage(), ""); expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 OpDecorate %3 BuiltIn VertexId OpDecorate %3 Invariant %3 = OpDecorationGroup OpDecorate %1 Invariant %4 = OpTypeInt 32 0 %1 = OpVariable %4 Input )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, RemoveDecorationDecorate) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %1 Restrict %2 = OpTypeInt 32 0 %1 = OpVariable %2 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); auto decorations = decoManager->GetDecorationsFor(1u, false); decoManager->RemoveDecoration(decorations.front()); decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %1 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); } TEST_F(DecorationManagerTest, RemoveDecorationStringDecorate) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "foobar" OpDecorate %1 Restrict %2 = OpTypeInt 32 0 %1 = OpVariable %2 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); auto decorations = decoManager->GetDecorationsFor(1u, false); decoManager->RemoveDecoration(decorations.front()); decorations = decoManager->GetDecorationsFor(1u, false); EXPECT_THAT(GetErrorMessage(), ""); const std::string expected_decorations = R"(OpDecorate %1 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); } TEST_F(DecorationManagerTest, CloneDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 OpDecorate %3 BuiltIn VertexId OpDecorate %3 Invariant %3 = OpDecorationGroup OpGroupDecorate %3 %1 %4 = OpTypeInt 32 0 %1 = OpVariable %4 Input %5 = OpVariable %4 Input )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); // Check cloning OpDecorate including group decorations. auto decorations = decoManager->GetDecorationsFor(5u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decoManager->CloneDecorations(1u, 5u); decorations = decoManager->GetDecorationsFor(5u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorate %5 Constant OpDecorate %2 Restrict OpDecorate %3 BuiltIn VertexId OpDecorate %3 Invariant )"; EXPECT_THAT(ToText(decorations), expected_decorations); // Check that bookkeeping for ID 2 remains the same. decorations = decoManager->GetDecorationsFor(2u, false); EXPECT_THAT(GetErrorMessage(), ""); expected_decorations = R"(OpDecorate %2 Restrict )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Restrict %2 = OpDecorationGroup OpGroupDecorate %2 %1 %5 OpDecorate %3 BuiltIn VertexId OpDecorate %3 Invariant %3 = OpDecorationGroup OpGroupDecorate %3 %1 %5 OpDecorate %5 Constant %4 = OpTypeInt 32 0 %1 = OpVariable %4 Input %5 = OpVariable %4 Input )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, CloneDecorationsStringAndId) { const std::string spirv = R"(OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "blah" OpDecorateId %1 HlslCounterBufferGOOGLE %2 OpDecorate %1 Aliased %3 = OpTypeInt 32 0 %4 = OpTypePointer Uniform %3 %1 = OpVariable %4 Uniform %2 = OpVariable %4 Uniform %5 = OpVariable %4 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); // Check cloning OpDecorate including group decorations. auto decorations = decoManager->GetDecorationsFor(5u, false); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decoManager->CloneDecorations(1u, 5u); decorations = decoManager->GetDecorationsFor(5u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorateString %5 UserSemantic "blah" OpDecorateId %5 CounterBuffer %2 OpDecorate %5 Aliased )"; EXPECT_THAT(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateString %1 UserSemantic "blah" OpDecorateId %1 CounterBuffer %2 OpDecorate %1 Aliased OpDecorateString %5 UserSemantic "blah" OpDecorateId %5 CounterBuffer %2 OpDecorate %5 Aliased %3 = OpTypeInt 32 0 %4 = OpTypePointer Uniform %3 %1 = OpVariable %4 Uniform %2 = OpVariable %4 Uniform %5 = OpVariable %4 Uniform )"; EXPECT_THAT(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, CloneSomeDecorations) { const std::string spirv = R"(OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorate %1 RelaxedPrecision OpDecorate %1 Restrict %2 = OpTypeInt 32 0 %3 = OpTypePointer Function %2 %4 = OpTypeVoid %5 = OpTypeFunction %4 %6 = OpFunction %4 None %5 %7 = OpLabel %1 = OpVariable %3 Function %8 = OpUndef %2 OpReturn OpFunctionEnd )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_EQ(GetErrorMessage(), ""); // Check cloning OpDecorate including group decorations. auto decorations = decoManager->GetDecorationsFor(8u, false); EXPECT_EQ(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decoManager->CloneDecorations(1u, 8u, {spv::Decoration::RelaxedPrecision}); decorations = decoManager->GetDecorationsFor(8u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorate %8 RelaxedPrecision )"; EXPECT_EQ(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorate %1 RelaxedPrecision OpDecorate %1 Restrict OpDecorate %8 RelaxedPrecision %2 = OpTypeInt 32 0 %3 = OpTypePointer Function %2 %4 = OpTypeVoid %5 = OpTypeFunction %4 %6 = OpFunction %4 None %5 %7 = OpLabel %1 = OpVariable %3 Function %8 = OpUndef %2 OpReturn OpFunctionEnd )"; EXPECT_EQ(ModuleToText(), expected_binary); } // Test cloning decoration for an id that is decorated via a group decoration. TEST_F(DecorationManagerTest, CloneSomeGroupDecorations) { const std::string spirv = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 RelaxedPrecision OpDecorate %1 Restrict %1 = OpDecorationGroup OpGroupDecorate %1 %2 %3 = OpTypeInt 32 0 %4 = OpTypePointer Function %3 %5 = OpTypeVoid %6 = OpTypeFunction %5 %7 = OpFunction %5 None %6 %8 = OpLabel %2 = OpVariable %4 Function %9 = OpUndef %3 OpReturn OpFunctionEnd )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_EQ(GetErrorMessage(), ""); // Check cloning OpDecorate including group decorations. auto decorations = decoManager->GetDecorationsFor(9u, false); EXPECT_EQ(GetErrorMessage(), ""); EXPECT_TRUE(decorations.empty()); decoManager->CloneDecorations(2u, 9u, {spv::Decoration::RelaxedPrecision}); decorations = decoManager->GetDecorationsFor(9u, false); EXPECT_THAT(GetErrorMessage(), ""); std::string expected_decorations = R"(OpDecorate %9 RelaxedPrecision )"; EXPECT_EQ(ToText(decorations), expected_decorations); const std::string expected_binary = R"(OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 RelaxedPrecision OpDecorate %1 Restrict %1 = OpDecorationGroup OpGroupDecorate %1 %2 OpDecorate %9 RelaxedPrecision %3 = OpTypeInt 32 0 %4 = OpTypePointer Function %3 %5 = OpTypeVoid %6 = OpTypeFunction %5 %7 = OpFunction %5 None %6 %8 = OpLabel %2 = OpVariable %4 Function %9 = OpUndef %3 OpReturn OpFunctionEnd )"; EXPECT_EQ(ModuleToText(), expected_binary); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithoutGroupsTrue) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict OpDecorate %1 Constant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithoutGroupsFalse) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsIdWithoutGroupsTrue) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %nine OpDecorateId %3 MaxByteOffsetId %nine OpDecorateId %3 AlignmentId %nine OpDecorateId %1 MaxByteOffsetId %nine %u32 = OpTypeInt 32 0 %nine = OpConstant %u32 9 %1 = OpVariable %u32 Uniform %3 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 3u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsIdWithoutGroupsFalse) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %nine OpDecorateId %2 MaxByteOffsetId %nine OpDecorateId %2 AlignmentId %nine %u32 = OpTypeInt 32 0 %nine = OpConstant %u32 9 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsStringWithoutGroupsTrue) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "world" %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsStringWithoutGroupsFalse) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithGroupsTrue) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %1 Constant OpDecorate %3 Restrict %3 = OpDecorationGroup OpGroupDecorate %3 %2 OpDecorate %4 Invariant %4 = OpDecorationGroup OpGroupDecorate %4 %1 %2 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithGroupsFalse) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %1 Constant OpDecorate %4 Invariant %4 = OpDecorationGroup OpGroupDecorate %4 %1 %2 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Constant OpDecorate %2 Constant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentVariations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Location 0 OpDecorate %2 Location 1 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateMemberDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %1 0 Location 0 OpMemberDecorate %2 0 Location 0 OpMemberDecorate %2 0 Location 0 %u32 = OpTypeInt 32 0 %1 = OpTypeStruct %u32 %u32 %2 = OpTypeStruct %u32 %u32 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentMemberSameDecoration) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %1 0 Location 0 OpMemberDecorate %2 1 Location 0 %u32 = OpTypeInt 32 0 %1 = OpTypeStruct %u32 %u32 %2 = OpTypeStruct %u32 %u32 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentMemberVariations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %1 0 Location 0 OpMemberDecorate %2 0 Location 1 %u32 = OpTypeInt 32 0 %1 = OpTypeStruct %u32 %u32 %2 = OpTypeStruct %u32 %u32 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateIdDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %2 OpDecorateId %3 AlignmentId %2 OpDecorateId %3 AlignmentId %2 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %3 = OpVariable %u32 Uniform %2 = OpSpecConstant %u32 0 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 3u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateStringDecorations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentIdVariations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %2 OpDecorateId %3 AlignmentId %4 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %3 = OpVariable %u32 Uniform %2 = OpSpecConstant %u32 0 %4 = OpSpecConstant %u32 0 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentStringVariations) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world" )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsLeftSymmetry) { // Left being a subset of right is not enough. const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %1 Constant OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationsRightSymmetry) { // Right being a subset of left is not enough. const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Constant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationIdsLeftSymmetry) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %nine OpDecorateId %1 AlignmentId %nine OpDecorateId %2 AlignmentId %nine OpDecorateId %2 MaxByteOffsetId %nine %u32 = OpTypeInt 32 0 %nine = OpConstant %u32 9 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationIdsRightSymmetry) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %nine OpDecorateId %1 MaxByteOffsetId %nine OpDecorateId %2 AlignmentId %nine OpDecorateId %2 AlignmentId %nine %u32 = OpTypeInt 32 0 %nine = OpConstant %u32 9 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationStringsLeftSymmetry) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world" %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, HaveTheSameDecorationStringsRightSymmetry) { const std::string spirv = R"( OpCapability Kernel OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "world" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello" %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate1) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict OpDecorate %1 Constant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate2) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate3) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate4) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict OpDecorate %1 Constant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate5) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Restrict OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate6) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Constant OpDecorate %2 Restrict %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorate7) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %1 Constant OpDecorate %2 Constant OpDecorate %2 Restrict OpDecorate %1 Invariant %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %2 = OpVariable %u32 Uniform )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(2u, 1u)); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(1u, 2u)); } TEST_F(DecorationManagerTest, SubSetTestOpMemberDecorate1) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %1 0 Offset 0 OpMemberDecorate %1 0 Offset 4 OpMemberDecorate %2 0 Offset 0 OpMemberDecorate %2 0 Offset 4 %u32 = OpTypeInt 32 0 %1 = OpTypeStruct %u32 %u32 %u32 %2 = OpTypeStruct %u32 %u32 %u32 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(1u, 2u)); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpMemberDecorate2) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %1 0 Offset 0 OpMemberDecorate %2 0 Offset 0 OpMemberDecorate %2 0 Offset 4 %u32 = OpTypeInt 32 0 %1 = OpTypeStruct %u32 %u32 %u32 %2 = OpTypeStruct %u32 %u32 %u32 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(1u, 2u)); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorateId1) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %2 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %3 = OpVariable %u32 Uniform %2 = OpSpecConstant %u32 0 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(1u, 3u)); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(3u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorateId2) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorateId %1 AlignmentId %2 OpDecorateId %3 AlignmentId %4 %u32 = OpTypeInt 32 0 %1 = OpVariable %u32 Uniform %3 = OpVariable %u32 Uniform %2 = OpSpecConstant %u32 0 %4 = OpSpecConstant %u32 1 )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(1u, 3u)); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(3u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorateString1) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateString %1 HlslSemanticGOOGLE "hello" OpDecorateString %2 HlslSemanticGOOGLE "world" )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(1u, 2u)); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } TEST_F(DecorationManagerTest, SubSetTestOpDecorateString2) { const std::string spirv = R"( OpCapability Shader OpCapability Linkage OpExtension "SPV_GOOGLE_hlsl_functionality1" OpExtension "SPV_GOOGLE_decorate_string" OpMemoryModel Logical GLSL450 OpDecorateString %1 HlslSemanticGOOGLE "hello" )"; DecorationManager* decoManager = GetDecorationManager(spirv); EXPECT_THAT(GetErrorMessage(), ""); EXPECT_FALSE(decoManager->HaveSubsetOfDecorations(1u, 2u)); EXPECT_TRUE(decoManager->HaveSubsetOfDecorations(2u, 1u)); } } // namespace } // namespace analysis } // namespace opt } // namespace spvtools