1 // Copyright (c) 2017 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 BinaryVersion = spvtest::LinkerTest;
25 
CreateBinary(uint32_t version)26 spvtest::Binary CreateBinary(uint32_t version) {
27   return {
28       // clang-format off
29       // Header
30       static_cast<uint32_t>(spv::MagicNumber),
31       version,
32       SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS, 0),
33       1u,  // NOTE: Bound
34       0u,  // NOTE: Schema; reserved
35 
36       // OpCapability Shader
37       static_cast<uint32_t>(spv::Op::OpCapability) | 2u << spv::WordCountShift,
38       static_cast<uint32_t>(spv::Capability::Shader),
39 
40       // OpMemoryModel Logical Simple
41       static_cast<uint32_t>(spv::Op::OpMemoryModel) | 3u << spv::WordCountShift,
42       static_cast<uint32_t>(spv::AddressingModel::Logical),
43       static_cast<uint32_t>(spv::MemoryModel::Simple)
44       // clang-format on
45   };
46 }
47 
TEST_F(BinaryVersion,Match)48 TEST_F(BinaryVersion, Match) {
49   // clang-format off
50   spvtest::Binaries binaries = {
51       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)),
52       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)),
53   };
54   // clang-format on
55   spvtest::Binary linked_binary;
56   ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary)) << GetErrorMessage();
57   EXPECT_THAT(GetErrorMessage(), std::string());
58   EXPECT_EQ(SPV_SPIRV_VERSION_WORD(1, 3), linked_binary[1]);
59 }
60 
TEST_F(BinaryVersion,Mismatch)61 TEST_F(BinaryVersion, Mismatch) {
62   // clang-format off
63   spvtest::Binaries binaries = {
64       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)),
65       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 5)),
66   };
67   // clang-format on
68   spvtest::Binary linked_binary;
69   ASSERT_EQ(SPV_ERROR_INTERNAL, Link(binaries, &linked_binary))
70       << GetErrorMessage();
71   EXPECT_THAT(GetErrorMessage(),
72               HasSubstr("Conflicting SPIR-V versions: 1.3 (input modules 1 "
73                         "through 1) vs 1.5 (input module 2)."));
74 }
75 
TEST_F(BinaryVersion,UseHighest)76 TEST_F(BinaryVersion, UseHighest) {
77   // clang-format off
78   spvtest::Binaries binaries = {
79       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)),
80       CreateBinary(SPV_SPIRV_VERSION_WORD(1, 5)),
81   };
82   // clang-format on
83   LinkerOptions options;
84   options.SetUseHighestVersion(true);
85   spvtest::Binary linked_binary;
86   ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary, options))
87       << GetErrorMessage();
88   EXPECT_THAT(GetErrorMessage(), std::string());
89   EXPECT_EQ(SPV_SPIRV_VERSION_WORD(1, 5), linked_binary[1]);
90 }
91 
92 }  // namespace
93 }  // namespace spvtools
94