1 // Copyright (c) 2018 Pierre Moreau
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string>
16
17 #include "gmock/gmock.h"
18 #include "test/link/linker_fixture.h"
19
20 namespace spvtools {
21 namespace {
22
23 using ::testing::HasSubstr;
24 using PartialLinkage = spvtest::LinkerTest;
25
TEST_F(PartialLinkage,Allowed)26 TEST_F(PartialLinkage, Allowed) {
27 const std::string body1 = R"(
28 OpCapability Linkage
29 OpCapability Addresses
30 OpCapability Kernel
31 OpMemoryModel Physical64 OpenCL
32 OpDecorate %1 LinkageAttributes "foo" Import
33 OpDecorate %2 LinkageAttributes "bar" Import
34 %3 = OpTypeFloat 32
35 %1 = OpVariable %3 Uniform
36 %2 = OpVariable %3 Uniform
37 )";
38 const std::string body2 = R"(
39 OpCapability Linkage
40 OpCapability Addresses
41 OpCapability Kernel
42 OpMemoryModel Physical64 OpenCL
43 OpDecorate %1 LinkageAttributes "bar" Export
44 %2 = OpTypeFloat 32
45 %3 = OpConstant %2 3.1415
46 %1 = OpVariable %2 Uniform %3
47 )";
48
49 spvtest::Binary linked_binary;
50 LinkerOptions linker_options;
51 linker_options.SetAllowPartialLinkage(true);
52 ASSERT_EQ(SPV_SUCCESS,
53 AssembleAndLink({body1, body2}, &linked_binary, linker_options))
54 << GetErrorMessage();
55
56 const std::string expected_res = R"(OpCapability Linkage
57 OpCapability Addresses
58 OpCapability Kernel
59 OpMemoryModel Physical64 OpenCL
60 OpModuleProcessed "Linked by SPIR-V Tools Linker"
61 OpDecorate %1 LinkageAttributes "foo" Import
62 %2 = OpTypeFloat 32
63 %1 = OpVariable %2 Uniform
64 %3 = OpConstant %2 3.1415
65 %4 = OpVariable %2 Uniform %3
66 )";
67 std::string res_body;
68 SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
69 ASSERT_EQ(SPV_SUCCESS, Disassemble(linked_binary, &res_body))
70 << GetErrorMessage();
71 EXPECT_EQ(expected_res, res_body);
72 }
73
TEST_F(PartialLinkage,Disallowed)74 TEST_F(PartialLinkage, Disallowed) {
75 const std::string body1 = R"(
76 OpCapability Linkage
77 OpCapability Addresses
78 OpCapability Kernel
79 OpMemoryModel Physical64 OpenCL
80 OpDecorate %1 LinkageAttributes "foo" Import
81 OpDecorate %2 LinkageAttributes "bar" Import
82 %3 = OpTypeFloat 32
83 %1 = OpVariable %3 Uniform
84 %2 = OpVariable %3 Uniform
85 )";
86 const std::string body2 = R"(
87 OpCapability Linkage
88 OpCapability Addresses
89 OpCapability Kernel
90 OpMemoryModel Physical64 OpenCL
91 OpDecorate %1 LinkageAttributes "bar" Export
92 %2 = OpTypeFloat 32
93 %3 = OpConstant %2 3.1415
94 %1 = OpVariable %2 Uniform %3
95 )";
96
97 spvtest::Binary linked_binary;
98 EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
99 AssembleAndLink({body1, body2}, &linked_binary));
100 EXPECT_THAT(GetErrorMessage(),
101 HasSubstr("Unresolved external reference to \"foo\"."));
102 }
103
104 } // namespace
105 } // namespace spvtools
106