// Copyright (c) 2016 Google Inc. // // 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 "pass_fixture.h" #include "pass_utils.h" #include #include #include namespace { using namespace spvtools; struct FreezeSpecConstantValueTypeTestCase { const char* type_decl; const char* spec_const; const char* expected_frozen_const; }; using FreezeSpecConstantValueTypeTest = PassTest<::testing::TestWithParam>; TEST_P(FreezeSpecConstantValueTypeTest, PrimaryType) { auto& test_case = GetParam(); std::vector text = {"OpCapability Shader", "OpMemoryModel Logical GLSL450", test_case.type_decl, test_case.spec_const}; std::vector expected = { "OpCapability Shader", "OpMemoryModel Logical GLSL450", test_case.type_decl, test_case.expected_frozen_const}; SinglePassRunAndCheck( JoinAllInsts(text), JoinAllInsts(expected), /* skip_nop = */ false); } // Test each primary type. INSTANTIATE_TEST_CASE_P( PrimaryTypeSpecConst, FreezeSpecConstantValueTypeTest, ::testing::ValuesIn(std::vector({ // Type declaration, original spec constant definition, expected frozen // spec constants. {"%int = OpTypeInt 32 1", "%2 = OpSpecConstant %int 1", "%2 = OpConstant %int 1"}, {"%uint = OpTypeInt 32 0", "%2 = OpSpecConstant %uint 1", "%2 = OpConstant %uint 1"}, {"%float = OpTypeFloat 32", "%2 = OpSpecConstant %float 3.14", "%2 = OpConstant %float 3.14"}, {"%double = OpTypeFloat 64", "%2 = OpSpecConstant %double 3.1415926", "%2 = OpConstant %double 3.1415926"}, {"%bool = OpTypeBool", "%2 = OpSpecConstantTrue %bool", "%2 = OpConstantTrue %bool"}, {"%bool = OpTypeBool", "%2 = OpSpecConstantFalse %bool", "%2 = OpConstantFalse %bool"}, }))); using FreezeSpecConstantValueRemoveDecorationTest = PassTest<::testing::Test>; TEST_F(FreezeSpecConstantValueRemoveDecorationTest, RemoveDecorationInstWithSpecId) { std::vector text = { // clang-format off "OpCapability Shader", "OpCapability Float64", "%1 = OpExtInstImport \"GLSL.std.450\"", "OpMemoryModel Logical GLSL450", "OpEntryPoint Vertex %main \"main\"", "OpSource GLSL 450", "OpSourceExtension \"GL_GOOGLE_cpp_style_line_directive\"", "OpSourceExtension \"GL_GOOGLE_include_directive\"", "OpName %main \"main\"", "OpDecorate %3 SpecId 200", "OpDecorate %4 SpecId 201", "OpDecorate %5 SpecId 202", "OpDecorate %6 SpecId 203", "%void = OpTypeVoid", "%8 = OpTypeFunction %void", "%int = OpTypeInt 32 1", "%3 = OpSpecConstant %int 3", "%float = OpTypeFloat 32", "%4 = OpSpecConstant %float 3.14", "%double = OpTypeFloat 64", "%5 = OpSpecConstant %double 3.14159265358979", "%bool = OpTypeBool", "%6 = OpSpecConstantTrue %bool", "%13 = OpSpecConstantFalse %bool", "%main = OpFunction %void None %8", "%14 = OpLabel", "OpReturn", "OpFunctionEnd", // clang-format on }; std::string expected_disassembly = SelectiveJoin(text, [](const char* line) { return std::string(line).find("SpecId") != std::string::npos; }); std::vector> opcode_replacement_pairs = { {" OpSpecConstant ", " OpConstant "}, {" OpSpecConstantTrue ", " OpConstantTrue "}, {" OpSpecConstantFalse ", " OpConstantFalse "}, }; for (auto& p : opcode_replacement_pairs) { EXPECT_TRUE(FindAndReplace(&expected_disassembly, p.first, p.second)) << "text:\n" << expected_disassembly << "\n" << "find_str:\n" << p.first << "\n" << "replace_str:\n" << p.second << "\n"; } SinglePassRunAndCheck( JoinAllInsts(text), expected_disassembly, /* skip_nop = */ true); } } // anonymous namespace