1fd4e5da5Sopenharmony_ci// Copyright (c) 2016 Google Inc.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include <string>
16fd4e5da5Sopenharmony_ci#include <utility>
17fd4e5da5Sopenharmony_ci#include <vector>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
20fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
21fd4e5da5Sopenharmony_ci#include "spirv-tools/optimizer.hpp"
22fd4e5da5Sopenharmony_ci#include "spirv/unified1/spirv.hpp11"
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_cinamespace spvtools {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing ::testing::ContainerEq;
28fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ci// Return a string that contains the minimum instructions needed to form
31fd4e5da5Sopenharmony_ci// a valid module.  Other instructions can be appended to this string.
32fd4e5da5Sopenharmony_cistd::string Header() {
33fd4e5da5Sopenharmony_ci  return R"(OpCapability Shader
34fd4e5da5Sopenharmony_ciOpCapability Linkage
35fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
36fd4e5da5Sopenharmony_ci)";
37fd4e5da5Sopenharmony_ci}
38fd4e5da5Sopenharmony_ci
39fd4e5da5Sopenharmony_ci// When we assemble with a target environment of SPIR-V 1.1, we expect
40fd4e5da5Sopenharmony_ci// the following in the module header version word.
41fd4e5da5Sopenharmony_ciconst uint32_t kExpectedSpvVersion = 0x10100;
42fd4e5da5Sopenharmony_ci
43fd4e5da5Sopenharmony_ciTEST(CppInterface, SuccessfulRoundTrip) {
44fd4e5da5Sopenharmony_ci  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
45fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
46fd4e5da5Sopenharmony_ci
47fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
48fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(input_text, &binary));
49fd4e5da5Sopenharmony_ci  EXPECT_TRUE(binary.size() > 5u);
50fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MagicNumber, binary[0]);
51fd4e5da5Sopenharmony_ci  EXPECT_EQ(kExpectedSpvVersion, binary[1]);
52fd4e5da5Sopenharmony_ci
53fd4e5da5Sopenharmony_ci  // This cannot pass validation since %1 is not defined.
54fd4e5da5Sopenharmony_ci  t.SetMessageConsumer([](spv_message_level_t level, const char* source,
55fd4e5da5Sopenharmony_ci                          const spv_position_t& position, const char* message) {
56fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_MSG_ERROR, level);
57fd4e5da5Sopenharmony_ci    EXPECT_STREQ("input", source);
58fd4e5da5Sopenharmony_ci    EXPECT_EQ(0u, position.line);
59fd4e5da5Sopenharmony_ci    EXPECT_EQ(0u, position.column);
60fd4e5da5Sopenharmony_ci    EXPECT_EQ(1u, position.index);
61fd4e5da5Sopenharmony_ci    EXPECT_STREQ("ID '1[%1]' has not been defined\n  %2 = OpSizeOf %1 %3\n",
62fd4e5da5Sopenharmony_ci                 message);
63fd4e5da5Sopenharmony_ci  });
64fd4e5da5Sopenharmony_ci  EXPECT_FALSE(t.Validate(binary));
65fd4e5da5Sopenharmony_ci
66fd4e5da5Sopenharmony_ci  std::string output_text;
67fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &output_text));
68fd4e5da5Sopenharmony_ci  EXPECT_EQ(input_text, output_text);
69fd4e5da5Sopenharmony_ci}
70fd4e5da5Sopenharmony_ci
71fd4e5da5Sopenharmony_ciTEST(CppInterface, AssembleEmptyModule) {
72fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary(10, 42);
73fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
74fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble("", &binary));
75fd4e5da5Sopenharmony_ci  // We only have the header.
76fd4e5da5Sopenharmony_ci  EXPECT_EQ(5u, binary.size());
77fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MagicNumber, binary[0]);
78fd4e5da5Sopenharmony_ci  EXPECT_EQ(kExpectedSpvVersion, binary[1]);
79fd4e5da5Sopenharmony_ci}
80fd4e5da5Sopenharmony_ci
81fd4e5da5Sopenharmony_ciTEST(CppInterface, AssembleOverloads) {
82fd4e5da5Sopenharmony_ci  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
83fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
84fd4e5da5Sopenharmony_ci  {
85fd4e5da5Sopenharmony_ci    std::vector<uint32_t> binary;
86fd4e5da5Sopenharmony_ci    EXPECT_TRUE(t.Assemble(input_text, &binary));
87fd4e5da5Sopenharmony_ci    EXPECT_TRUE(binary.size() > 5u);
88fd4e5da5Sopenharmony_ci    EXPECT_EQ(spv::MagicNumber, binary[0]);
89fd4e5da5Sopenharmony_ci    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
90fd4e5da5Sopenharmony_ci  }
91fd4e5da5Sopenharmony_ci  {
92fd4e5da5Sopenharmony_ci    std::vector<uint32_t> binary;
93fd4e5da5Sopenharmony_ci    EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size(), &binary));
94fd4e5da5Sopenharmony_ci    EXPECT_TRUE(binary.size() > 5u);
95fd4e5da5Sopenharmony_ci    EXPECT_EQ(spv::MagicNumber, binary[0]);
96fd4e5da5Sopenharmony_ci    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
97fd4e5da5Sopenharmony_ci  }
98fd4e5da5Sopenharmony_ci  {  // Ignore the last newline.
99fd4e5da5Sopenharmony_ci    std::vector<uint32_t> binary;
100fd4e5da5Sopenharmony_ci    EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size() - 1, &binary));
101fd4e5da5Sopenharmony_ci    EXPECT_TRUE(binary.size() > 5u);
102fd4e5da5Sopenharmony_ci    EXPECT_EQ(spv::MagicNumber, binary[0]);
103fd4e5da5Sopenharmony_ci    EXPECT_EQ(kExpectedSpvVersion, binary[1]);
104fd4e5da5Sopenharmony_ci  }
105fd4e5da5Sopenharmony_ci}
106fd4e5da5Sopenharmony_ci
107fd4e5da5Sopenharmony_ciTEST(CppInterface, DisassembleEmptyModule) {
108fd4e5da5Sopenharmony_ci  std::string text(10, 'x');
109fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
110fd4e5da5Sopenharmony_ci  int invocation_count = 0;
111fd4e5da5Sopenharmony_ci  t.SetMessageConsumer(
112fd4e5da5Sopenharmony_ci      [&invocation_count](spv_message_level_t level, const char* source,
113fd4e5da5Sopenharmony_ci                          const spv_position_t& position, const char* message) {
114fd4e5da5Sopenharmony_ci        ++invocation_count;
115fd4e5da5Sopenharmony_ci        EXPECT_EQ(SPV_MSG_ERROR, level);
116fd4e5da5Sopenharmony_ci        EXPECT_STREQ("input", source);
117fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.line);
118fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.column);
119fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.index);
120fd4e5da5Sopenharmony_ci        EXPECT_STREQ("Missing module.", message);
121fd4e5da5Sopenharmony_ci      });
122fd4e5da5Sopenharmony_ci  EXPECT_FALSE(t.Disassemble({}, &text));
123fd4e5da5Sopenharmony_ci  EXPECT_EQ("xxxxxxxxxx", text);  // The original string is unmodified.
124fd4e5da5Sopenharmony_ci  EXPECT_EQ(1, invocation_count);
125fd4e5da5Sopenharmony_ci}
126fd4e5da5Sopenharmony_ci
127fd4e5da5Sopenharmony_ciTEST(CppInterface, DisassembleOverloads) {
128fd4e5da5Sopenharmony_ci  const std::string input_text = "%2 = OpSizeOf %1 %3\n";
129fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
130fd4e5da5Sopenharmony_ci
131fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
132fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(input_text, &binary));
133fd4e5da5Sopenharmony_ci
134fd4e5da5Sopenharmony_ci  {
135fd4e5da5Sopenharmony_ci    std::string output_text;
136fd4e5da5Sopenharmony_ci    EXPECT_TRUE(t.Disassemble(binary, &output_text));
137fd4e5da5Sopenharmony_ci    EXPECT_EQ(input_text, output_text);
138fd4e5da5Sopenharmony_ci  }
139fd4e5da5Sopenharmony_ci  {
140fd4e5da5Sopenharmony_ci    std::string output_text;
141fd4e5da5Sopenharmony_ci    EXPECT_TRUE(t.Disassemble(binary.data(), binary.size(), &output_text));
142fd4e5da5Sopenharmony_ci    EXPECT_EQ(input_text, output_text);
143fd4e5da5Sopenharmony_ci  }
144fd4e5da5Sopenharmony_ci}
145fd4e5da5Sopenharmony_ci
146fd4e5da5Sopenharmony_ciTEST(CppInterface, SuccessfulValidation) {
147fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
148fd4e5da5Sopenharmony_ci  int invocation_count = 0;
149fd4e5da5Sopenharmony_ci  t.SetMessageConsumer([&invocation_count](spv_message_level_t, const char*,
150fd4e5da5Sopenharmony_ci                                           const spv_position_t&, const char*) {
151fd4e5da5Sopenharmony_ci    ++invocation_count;
152fd4e5da5Sopenharmony_ci  });
153fd4e5da5Sopenharmony_ci
154fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
155fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(Header(), &binary));
156fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Validate(binary));
157fd4e5da5Sopenharmony_ci  EXPECT_EQ(0, invocation_count);
158fd4e5da5Sopenharmony_ci}
159fd4e5da5Sopenharmony_ci
160fd4e5da5Sopenharmony_ciTEST(CppInterface, ValidateOverloads) {
161fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
162fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
163fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(Header(), &binary));
164fd4e5da5Sopenharmony_ci
165fd4e5da5Sopenharmony_ci  { EXPECT_TRUE(t.Validate(binary)); }
166fd4e5da5Sopenharmony_ci  { EXPECT_TRUE(t.Validate(binary.data(), binary.size())); }
167fd4e5da5Sopenharmony_ci}
168fd4e5da5Sopenharmony_ci
169fd4e5da5Sopenharmony_ciTEST(CppInterface, ValidateEmptyModule) {
170fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
171fd4e5da5Sopenharmony_ci  int invocation_count = 0;
172fd4e5da5Sopenharmony_ci  t.SetMessageConsumer(
173fd4e5da5Sopenharmony_ci      [&invocation_count](spv_message_level_t level, const char* source,
174fd4e5da5Sopenharmony_ci                          const spv_position_t& position, const char* message) {
175fd4e5da5Sopenharmony_ci        ++invocation_count;
176fd4e5da5Sopenharmony_ci        EXPECT_EQ(SPV_MSG_ERROR, level);
177fd4e5da5Sopenharmony_ci        EXPECT_STREQ("input", source);
178fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.line);
179fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.column);
180fd4e5da5Sopenharmony_ci        EXPECT_EQ(0u, position.index);
181fd4e5da5Sopenharmony_ci        EXPECT_STREQ("Invalid SPIR-V magic number.", message);
182fd4e5da5Sopenharmony_ci      });
183fd4e5da5Sopenharmony_ci  EXPECT_FALSE(t.Validate({}));
184fd4e5da5Sopenharmony_ci  EXPECT_EQ(1, invocation_count);
185fd4e5da5Sopenharmony_ci}
186fd4e5da5Sopenharmony_ci
187fd4e5da5Sopenharmony_ci// Returns the assembly for a SPIR-V module with a struct declaration
188fd4e5da5Sopenharmony_ci// with the given number of members.
189fd4e5da5Sopenharmony_cistd::string MakeModuleHavingStruct(int num_members) {
190fd4e5da5Sopenharmony_ci  std::stringstream os;
191fd4e5da5Sopenharmony_ci  os << Header();
192fd4e5da5Sopenharmony_ci  os << R"(%1 = OpTypeInt 32 0
193fd4e5da5Sopenharmony_ci           %2 = OpTypeStruct)";
194fd4e5da5Sopenharmony_ci  for (int i = 0; i < num_members; i++) os << " %1";
195fd4e5da5Sopenharmony_ci  return os.str();
196fd4e5da5Sopenharmony_ci}
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ciTEST(CppInterface, ValidateWithOptionsPass) {
199fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
200fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
201fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
202fd4e5da5Sopenharmony_ci  const ValidatorOptions opts;
203fd4e5da5Sopenharmony_ci
204fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Validate(binary.data(), binary.size(), opts));
205fd4e5da5Sopenharmony_ci}
206fd4e5da5Sopenharmony_ci
207fd4e5da5Sopenharmony_ciTEST(CppInterface, ValidateWithOptionsFail) {
208fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
209fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
210fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
211fd4e5da5Sopenharmony_ci  ValidatorOptions opts;
212fd4e5da5Sopenharmony_ci  opts.SetUniversalLimit(spv_validator_limit_max_struct_members, 9);
213fd4e5da5Sopenharmony_ci  std::stringstream os;
214fd4e5da5Sopenharmony_ci  t.SetMessageConsumer([&os](spv_message_level_t, const char*,
215fd4e5da5Sopenharmony_ci                             const spv_position_t&,
216fd4e5da5Sopenharmony_ci                             const char* message) { os << message; });
217fd4e5da5Sopenharmony_ci
218fd4e5da5Sopenharmony_ci  EXPECT_FALSE(t.Validate(binary.data(), binary.size(), opts));
219fd4e5da5Sopenharmony_ci  EXPECT_THAT(
220fd4e5da5Sopenharmony_ci      os.str(),
221fd4e5da5Sopenharmony_ci      HasSubstr(
222fd4e5da5Sopenharmony_ci          "Number of OpTypeStruct members (10) has exceeded the limit (9)"));
223fd4e5da5Sopenharmony_ci}
224fd4e5da5Sopenharmony_ci
225fd4e5da5Sopenharmony_ci// Checks that after running the given optimizer |opt| on the given |original|
226fd4e5da5Sopenharmony_ci// source code, we can get the given |optimized| source code.
227fd4e5da5Sopenharmony_civoid CheckOptimization(const std::string& original,
228fd4e5da5Sopenharmony_ci                       const std::string& optimized, const Optimizer& opt) {
229fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
230fd4e5da5Sopenharmony_ci  std::vector<uint32_t> original_binary;
231fd4e5da5Sopenharmony_ci  ASSERT_TRUE(t.Assemble(original, &original_binary));
232fd4e5da5Sopenharmony_ci
233fd4e5da5Sopenharmony_ci  std::vector<uint32_t> optimized_binary;
234fd4e5da5Sopenharmony_ci  EXPECT_TRUE(opt.Run(original_binary.data(), original_binary.size(),
235fd4e5da5Sopenharmony_ci                      &optimized_binary));
236fd4e5da5Sopenharmony_ci
237fd4e5da5Sopenharmony_ci  std::string optimized_text;
238fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(optimized_binary, &optimized_text));
239fd4e5da5Sopenharmony_ci  EXPECT_EQ(optimized, optimized_text);
240fd4e5da5Sopenharmony_ci}
241fd4e5da5Sopenharmony_ci
242fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeEmptyModule) {
243fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
244fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
245fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Assemble("", &binary));
246fd4e5da5Sopenharmony_ci
247fd4e5da5Sopenharmony_ci  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
248fd4e5da5Sopenharmony_ci  o.RegisterPass(CreateStripDebugInfoPass());
249fd4e5da5Sopenharmony_ci
250fd4e5da5Sopenharmony_ci  // Fails to validate.
251fd4e5da5Sopenharmony_ci  EXPECT_FALSE(o.Run(binary.data(), binary.size(), &binary));
252fd4e5da5Sopenharmony_ci}
253fd4e5da5Sopenharmony_ci
254fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeModifiedModule) {
255fd4e5da5Sopenharmony_ci  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
256fd4e5da5Sopenharmony_ci  o.RegisterPass(CreateStripDebugInfoPass());
257fd4e5da5Sopenharmony_ci  CheckOptimization(Header() + "OpSource GLSL 450", Header(), o);
258fd4e5da5Sopenharmony_ci}
259fd4e5da5Sopenharmony_ci
260fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeMulitplePasses) {
261fd4e5da5Sopenharmony_ci  std::string original_text = Header() +
262fd4e5da5Sopenharmony_ci                              "OpSource GLSL 450 "
263fd4e5da5Sopenharmony_ci                              "OpDecorate %true SpecId 1 "
264fd4e5da5Sopenharmony_ci                              "%bool = OpTypeBool "
265fd4e5da5Sopenharmony_ci                              "%true = OpSpecConstantTrue %bool";
266fd4e5da5Sopenharmony_ci
267fd4e5da5Sopenharmony_ci  Optimizer o(SPV_ENV_UNIVERSAL_1_1);
268fd4e5da5Sopenharmony_ci  o.RegisterPass(CreateStripDebugInfoPass())
269fd4e5da5Sopenharmony_ci      .RegisterPass(CreateFreezeSpecConstantValuePass());
270fd4e5da5Sopenharmony_ci
271fd4e5da5Sopenharmony_ci  std::string expected_text = Header() +
272fd4e5da5Sopenharmony_ci                              "%bool = OpTypeBool\n"
273fd4e5da5Sopenharmony_ci                              "%true = OpConstantTrue %bool\n";
274fd4e5da5Sopenharmony_ci
275fd4e5da5Sopenharmony_ci  CheckOptimization(original_text, expected_text, o);
276fd4e5da5Sopenharmony_ci}
277fd4e5da5Sopenharmony_ci
278fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeDoNothingWithPassToken) {
279fd4e5da5Sopenharmony_ci  CreateFreezeSpecConstantValuePass();
280fd4e5da5Sopenharmony_ci  auto token = CreateUnifyConstantPass();
281fd4e5da5Sopenharmony_ci}
282fd4e5da5Sopenharmony_ci
283fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeReassignPassToken) {
284fd4e5da5Sopenharmony_ci  auto token = CreateNullPass();
285fd4e5da5Sopenharmony_ci  token = CreateStripDebugInfoPass();
286fd4e5da5Sopenharmony_ci
287fd4e5da5Sopenharmony_ci  CheckOptimization(
288fd4e5da5Sopenharmony_ci      Header() + "OpSource GLSL 450", Header(),
289fd4e5da5Sopenharmony_ci      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token)));
290fd4e5da5Sopenharmony_ci}
291fd4e5da5Sopenharmony_ci
292fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeMoveConstructPassToken) {
293fd4e5da5Sopenharmony_ci  auto token1 = CreateStripDebugInfoPass();
294fd4e5da5Sopenharmony_ci  Optimizer::PassToken token2(std::move(token1));
295fd4e5da5Sopenharmony_ci
296fd4e5da5Sopenharmony_ci  CheckOptimization(
297fd4e5da5Sopenharmony_ci      Header() + "OpSource GLSL 450", Header(),
298fd4e5da5Sopenharmony_ci      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token2)));
299fd4e5da5Sopenharmony_ci}
300fd4e5da5Sopenharmony_ci
301fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeMoveAssignPassToken) {
302fd4e5da5Sopenharmony_ci  auto token1 = CreateStripDebugInfoPass();
303fd4e5da5Sopenharmony_ci  auto token2 = CreateNullPass();
304fd4e5da5Sopenharmony_ci  token2 = std::move(token1);
305fd4e5da5Sopenharmony_ci
306fd4e5da5Sopenharmony_ci  CheckOptimization(
307fd4e5da5Sopenharmony_ci      Header() + "OpSource GLSL 450", Header(),
308fd4e5da5Sopenharmony_ci      Optimizer(SPV_ENV_UNIVERSAL_1_1).RegisterPass(std::move(token2)));
309fd4e5da5Sopenharmony_ci}
310fd4e5da5Sopenharmony_ci
311fd4e5da5Sopenharmony_ciTEST(CppInterface, OptimizeSameAddressForOriginalOptimizedBinary) {
312fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
313fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
314fd4e5da5Sopenharmony_ci  ASSERT_TRUE(t.Assemble(Header() + "OpSource GLSL 450", &binary));
315fd4e5da5Sopenharmony_ci
316fd4e5da5Sopenharmony_ci  EXPECT_TRUE(Optimizer(SPV_ENV_UNIVERSAL_1_1)
317fd4e5da5Sopenharmony_ci                  .RegisterPass(CreateStripDebugInfoPass())
318fd4e5da5Sopenharmony_ci                  .Run(binary.data(), binary.size(), &binary));
319fd4e5da5Sopenharmony_ci
320fd4e5da5Sopenharmony_ci  std::string optimized_text;
321fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &optimized_text));
322fd4e5da5Sopenharmony_ci  EXPECT_EQ(Header(), optimized_text);
323fd4e5da5Sopenharmony_ci}
324fd4e5da5Sopenharmony_ci
325fd4e5da5Sopenharmony_ciTEST(SpirvHeadersCpp, BitwiseOrMemoryAccessMask) {
326fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask(6), spv::MemoryAccessMask::Aligned |
327fd4e5da5Sopenharmony_ci                                          spv::MemoryAccessMask::Nontemporal);
328fd4e5da5Sopenharmony_ci}
329fd4e5da5Sopenharmony_ci
330fd4e5da5Sopenharmony_ciTEST(SpirvHeadersCpp, BitwiseAndMemoryAccessMask) {
331fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask::Aligned,
332fd4e5da5Sopenharmony_ci            spv::MemoryAccessMask::Aligned & spv::MemoryAccessMask(6));
333fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask::Nontemporal,
334fd4e5da5Sopenharmony_ci            spv::MemoryAccessMask::Nontemporal & spv::MemoryAccessMask(6));
335fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask(0), spv::MemoryAccessMask::Nontemporal &
336fd4e5da5Sopenharmony_ci                                          spv::MemoryAccessMask::Aligned);
337fd4e5da5Sopenharmony_ci}
338fd4e5da5Sopenharmony_ci
339fd4e5da5Sopenharmony_ciTEST(SpirvHeadersCpp, BitwiseXorMemoryAccessMask) {
340fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask::Nontemporal,
341fd4e5da5Sopenharmony_ci            spv::MemoryAccessMask::Aligned ^ spv::MemoryAccessMask(6));
342fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask::Aligned,
343fd4e5da5Sopenharmony_ci            spv::MemoryAccessMask::Nontemporal ^ spv::MemoryAccessMask(6));
344fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask(6), spv::MemoryAccessMask::Nontemporal ^
345fd4e5da5Sopenharmony_ci                                          spv::MemoryAccessMask::Aligned);
346fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask(0), spv::MemoryAccessMask::Nontemporal ^
347fd4e5da5Sopenharmony_ci                                          spv::MemoryAccessMask::Nontemporal);
348fd4e5da5Sopenharmony_ci}
349fd4e5da5Sopenharmony_ci
350fd4e5da5Sopenharmony_ciTEST(SpirvHeadersCpp, BitwiseNegateMemoryAccessMask) {
351fd4e5da5Sopenharmony_ci  EXPECT_EQ(spv::MemoryAccessMask(~(uint32_t(4))),
352fd4e5da5Sopenharmony_ci            ~spv::MemoryAccessMask::Nontemporal);
353fd4e5da5Sopenharmony_ci}
354fd4e5da5Sopenharmony_ci
355fd4e5da5Sopenharmony_ci// TODO(antiagainst): tests for SetMessageConsumer().
356fd4e5da5Sopenharmony_ci
357fd4e5da5Sopenharmony_ci}  // namespace
358fd4e5da5Sopenharmony_ci}  // namespace spvtools
359