1fd4e5da5Sopenharmony_ci// Copyright (c) 2023 Nintendo
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 <iostream>
17fd4e5da5Sopenharmony_ci
18fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
19fd4e5da5Sopenharmony_ci#include "spirv-tools/libspirv.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace {
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForInvalidInput) {
25fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
26fd4e5da5Sopenharmony_ci      0xDEADFEED, // Invalid Magic
27fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
28fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
29fd4e5da5Sopenharmony_ci      0x01000000, // Bound
30fd4e5da5Sopenharmony_ci      0x00000000, // Schema
31fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
32fd4e5da5Sopenharmony_ci      0x00000001, // Shader
33fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
34fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
35fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
36fd4e5da5Sopenharmony_ci      0x00000000, // Logical
37fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
38fd4e5da5Sopenharmony_ci  };
39fd4e5da5Sopenharmony_ci
40fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
41fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
42fd4e5da5Sopenharmony_ci
43fd4e5da5Sopenharmony_ci  // Do not register any passes
44fd4e5da5Sopenharmony_ci
45fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
46fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
47fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, true);
48fd4e5da5Sopenharmony_ci
49fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
50fd4e5da5Sopenharmony_ci  EXPECT_NE(SPV_SUCCESS,
51fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
52fd4e5da5Sopenharmony_ci                            &binary, options));
53fd4e5da5Sopenharmony_ci  ASSERT_EQ(binary, nullptr);
54fd4e5da5Sopenharmony_ci
55fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
56fd4e5da5Sopenharmony_ci
57fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
58fd4e5da5Sopenharmony_ci}
59fd4e5da5Sopenharmony_ci
60fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, SpecifyConsumerWithValidationNoPassesForInvalidInput) {
61fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
62fd4e5da5Sopenharmony_ci      0xDEADFEED, // Invalid Magic
63fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
64fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
65fd4e5da5Sopenharmony_ci      0x01000000, // Bound
66fd4e5da5Sopenharmony_ci      0x00000000, // Schema
67fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
68fd4e5da5Sopenharmony_ci      0x00000001, // Shader
69fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
70fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
71fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
72fd4e5da5Sopenharmony_ci      0x00000000, // Logical
73fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
74fd4e5da5Sopenharmony_ci  };
75fd4e5da5Sopenharmony_ci
76fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
77fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
78fd4e5da5Sopenharmony_ci
79fd4e5da5Sopenharmony_ci  spvOptimizerSetMessageConsumer(
80fd4e5da5Sopenharmony_ci      optimizer,
81fd4e5da5Sopenharmony_ci      [](spv_message_level_t, const char*, const spv_position_t*,
82fd4e5da5Sopenharmony_ci         const char* message) {
83fd4e5da5Sopenharmony_ci        std::cout << message << std::endl;
84fd4e5da5Sopenharmony_ci      });
85fd4e5da5Sopenharmony_ci
86fd4e5da5Sopenharmony_ci  // Do not register any passes
87fd4e5da5Sopenharmony_ci
88fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
89fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
90fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, true);
91fd4e5da5Sopenharmony_ci
92fd4e5da5Sopenharmony_ci  testing::internal::CaptureStdout();
93fd4e5da5Sopenharmony_ci
94fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
95fd4e5da5Sopenharmony_ci  EXPECT_NE(SPV_SUCCESS,
96fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
97fd4e5da5Sopenharmony_ci                            &binary, options));
98fd4e5da5Sopenharmony_ci  ASSERT_EQ(binary, nullptr);
99fd4e5da5Sopenharmony_ci
100fd4e5da5Sopenharmony_ci  auto output = testing::internal::GetCapturedStdout();
101fd4e5da5Sopenharmony_ci  EXPECT_STRNE(output.c_str(), "");
102fd4e5da5Sopenharmony_ci
103fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
104fd4e5da5Sopenharmony_ci
105fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
106fd4e5da5Sopenharmony_ci}
107fd4e5da5Sopenharmony_ci
108fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerWithValidationNoPassesForValidInput) {
109fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
110fd4e5da5Sopenharmony_ci      0x07230203, // Magic
111fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
112fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
113fd4e5da5Sopenharmony_ci      0x00000001, // Bound
114fd4e5da5Sopenharmony_ci      0x00000000, // Schema
115fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
116fd4e5da5Sopenharmony_ci      0x00000001, // Shader
117fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
118fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
119fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
120fd4e5da5Sopenharmony_ci      0x00000000, // Logical
121fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
122fd4e5da5Sopenharmony_ci  };
123fd4e5da5Sopenharmony_ci
124fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
125fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
126fd4e5da5Sopenharmony_ci
127fd4e5da5Sopenharmony_ci  // Do not register any passes
128fd4e5da5Sopenharmony_ci
129fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
130fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
131fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, true);
132fd4e5da5Sopenharmony_ci
133fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
134fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
135fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
136fd4e5da5Sopenharmony_ci                            &binary, options));
137fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
138fd4e5da5Sopenharmony_ci
139fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
140fd4e5da5Sopenharmony_ci
141fd4e5da5Sopenharmony_ci  // Should remain unchanged
142fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t));
143fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0);
144fd4e5da5Sopenharmony_ci
145fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
146fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
147fd4e5da5Sopenharmony_ci}
148fd4e5da5Sopenharmony_ci
149fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerNoPassesForValidInput) {
150fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
151fd4e5da5Sopenharmony_ci      0x07230203, // Magic
152fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
153fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
154fd4e5da5Sopenharmony_ci      0x00000003, // Bound
155fd4e5da5Sopenharmony_ci      0x00000000, // Schema
156fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
157fd4e5da5Sopenharmony_ci      0x00000001, // Shader
158fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
159fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
160fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
161fd4e5da5Sopenharmony_ci      0x00000000, // Logical
162fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
163fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
164fd4e5da5Sopenharmony_ci      0x00000001, // %1
165fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
166fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
167fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
168fd4e5da5Sopenharmony_ci      0x00000001, // %1
169fd4e5da5Sopenharmony_ci      0x00000002, // %2
170fd4e5da5Sopenharmony_ci      0x00000001  // 1
171fd4e5da5Sopenharmony_ci  };
172fd4e5da5Sopenharmony_ci
173fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
174fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
175fd4e5da5Sopenharmony_ci
176fd4e5da5Sopenharmony_ci  // Do not register any passes
177fd4e5da5Sopenharmony_ci
178fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
179fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
180fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, true);
181fd4e5da5Sopenharmony_ci
182fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
183fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
184fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
185fd4e5da5Sopenharmony_ci                            &binary, options));
186fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
187fd4e5da5Sopenharmony_ci
188fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
189fd4e5da5Sopenharmony_ci
190fd4e5da5Sopenharmony_ci  // Should remain unchanged
191fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(spirv) / sizeof(uint32_t));
192fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, spirv, sizeof(spirv) / sizeof(uint32_t)), 0);
193fd4e5da5Sopenharmony_ci
194fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
195fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
196fd4e5da5Sopenharmony_ci}
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerLegalizationPassesForValidInput) {
199fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
200fd4e5da5Sopenharmony_ci      0x07230203, // Magic
201fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
202fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
203fd4e5da5Sopenharmony_ci      0x00000003, // Bound
204fd4e5da5Sopenharmony_ci      0x00000000, // Schema
205fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
206fd4e5da5Sopenharmony_ci      0x00000001, // Shader
207fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
208fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
209fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
210fd4e5da5Sopenharmony_ci      0x00000000, // Logical
211fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
212fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
213fd4e5da5Sopenharmony_ci      0x00000001, // %1
214fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
215fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
216fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
217fd4e5da5Sopenharmony_ci      0x00000001, // %1
218fd4e5da5Sopenharmony_ci      0x00000002, // %2
219fd4e5da5Sopenharmony_ci      0x00000001  // 1
220fd4e5da5Sopenharmony_ci  };
221fd4e5da5Sopenharmony_ci
222fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
223fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
224fd4e5da5Sopenharmony_ci
225fd4e5da5Sopenharmony_ci  spvOptimizerRegisterLegalizationPasses(optimizer);
226fd4e5da5Sopenharmony_ci
227fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
228fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
229fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, false);
230fd4e5da5Sopenharmony_ci
231fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
232fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
233fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
234fd4e5da5Sopenharmony_ci                            &binary, options));
235fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
236fd4e5da5Sopenharmony_ci
237fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
238fd4e5da5Sopenharmony_ci
239fd4e5da5Sopenharmony_ci  // Only check that SPV_SUCCESS is returned, do not verify output
240fd4e5da5Sopenharmony_ci
241fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
242fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
243fd4e5da5Sopenharmony_ci}
244fd4e5da5Sopenharmony_ci
245fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerPerformancePassesForValidInput) {
246fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
247fd4e5da5Sopenharmony_ci      0x07230203, // Magic
248fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
249fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
250fd4e5da5Sopenharmony_ci      0x00000003, // Bound
251fd4e5da5Sopenharmony_ci      0x00000000, // Schema
252fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
253fd4e5da5Sopenharmony_ci      0x00000001, // Shader
254fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
255fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
256fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
257fd4e5da5Sopenharmony_ci      0x00000000, // Logical
258fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
259fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
260fd4e5da5Sopenharmony_ci      0x00000001, // %1
261fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
262fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
263fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
264fd4e5da5Sopenharmony_ci      0x00000001, // %1
265fd4e5da5Sopenharmony_ci      0x00000002, // %2
266fd4e5da5Sopenharmony_ci      0x00000001  // 1
267fd4e5da5Sopenharmony_ci  };
268fd4e5da5Sopenharmony_ci  const uint32_t expected_spirv[] = {
269fd4e5da5Sopenharmony_ci      0x07230203, // Magic
270fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
271fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
272fd4e5da5Sopenharmony_ci      0x00000001, // Bound
273fd4e5da5Sopenharmony_ci      0x00000000, // Schema
274fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
275fd4e5da5Sopenharmony_ci      0x00000001, // Shader
276fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
277fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
278fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
279fd4e5da5Sopenharmony_ci      0x00000000, // Logical
280fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
281fd4e5da5Sopenharmony_ci  };
282fd4e5da5Sopenharmony_ci
283fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
284fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
285fd4e5da5Sopenharmony_ci
286fd4e5da5Sopenharmony_ci  spvOptimizerRegisterPerformancePasses(optimizer);
287fd4e5da5Sopenharmony_ci
288fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
289fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
290fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, false);
291fd4e5da5Sopenharmony_ci
292fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
293fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
294fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
295fd4e5da5Sopenharmony_ci                            &binary, options));
296fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
297fd4e5da5Sopenharmony_ci
298fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
299fd4e5da5Sopenharmony_ci
300fd4e5da5Sopenharmony_ci  // Unreferenced OpTypeInt and OpConstant should be removed
301fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
302fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, expected_spirv,
303fd4e5da5Sopenharmony_ci                   sizeof(expected_spirv) / sizeof(uint32_t)), 0);
304fd4e5da5Sopenharmony_ci
305fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
306fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
307fd4e5da5Sopenharmony_ci}
308fd4e5da5Sopenharmony_ci
309fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerSizePassesForValidInput) {
310fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
311fd4e5da5Sopenharmony_ci      0x07230203, // Magic
312fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
313fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
314fd4e5da5Sopenharmony_ci      0x00000003, // Bound
315fd4e5da5Sopenharmony_ci      0x00000000, // Schema
316fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
317fd4e5da5Sopenharmony_ci      0x00000001, // Shader
318fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
319fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
320fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
321fd4e5da5Sopenharmony_ci      0x00000000, // Logical
322fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
323fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
324fd4e5da5Sopenharmony_ci      0x00000001, // %1
325fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
326fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
327fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
328fd4e5da5Sopenharmony_ci      0x00000001, // %1
329fd4e5da5Sopenharmony_ci      0x00000002, // %2
330fd4e5da5Sopenharmony_ci      0x00000001  // 1
331fd4e5da5Sopenharmony_ci  };
332fd4e5da5Sopenharmony_ci  const uint32_t expected_spirv[] = {
333fd4e5da5Sopenharmony_ci      0x07230203, // Magic
334fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
335fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
336fd4e5da5Sopenharmony_ci      0x00000001, // Bound
337fd4e5da5Sopenharmony_ci      0x00000000, // Schema
338fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
339fd4e5da5Sopenharmony_ci      0x00000001, // Shader
340fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
341fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
342fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
343fd4e5da5Sopenharmony_ci      0x00000000, // Logical
344fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
345fd4e5da5Sopenharmony_ci  };
346fd4e5da5Sopenharmony_ci
347fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
348fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
349fd4e5da5Sopenharmony_ci
350fd4e5da5Sopenharmony_ci  spvOptimizerRegisterSizePasses(optimizer);
351fd4e5da5Sopenharmony_ci
352fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
353fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
354fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, false);
355fd4e5da5Sopenharmony_ci
356fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
357fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
358fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
359fd4e5da5Sopenharmony_ci                            &binary, options));
360fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
361fd4e5da5Sopenharmony_ci
362fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
363fd4e5da5Sopenharmony_ci
364fd4e5da5Sopenharmony_ci  // Unreferenced OpTypeInt and OpConstant should be removed
365fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
366fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, expected_spirv,
367fd4e5da5Sopenharmony_ci                   sizeof(expected_spirv) / sizeof(uint32_t)), 0);
368fd4e5da5Sopenharmony_ci
369fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
370fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
371fd4e5da5Sopenharmony_ci}
372fd4e5da5Sopenharmony_ci
373fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerPassFromFlagForValidInput) {
374fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
375fd4e5da5Sopenharmony_ci      0x07230203, // Magic
376fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
377fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
378fd4e5da5Sopenharmony_ci      0x00000003, // Bound
379fd4e5da5Sopenharmony_ci      0x00000000, // Schema
380fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
381fd4e5da5Sopenharmony_ci      0x00000001, // Shader
382fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
383fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
384fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
385fd4e5da5Sopenharmony_ci      0x00000000, // Logical
386fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
387fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
388fd4e5da5Sopenharmony_ci      0x00000001, // %1
389fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
390fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
391fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
392fd4e5da5Sopenharmony_ci      0x00000001, // %1
393fd4e5da5Sopenharmony_ci      0x00000002, // %2
394fd4e5da5Sopenharmony_ci      0x00000001  // 1
395fd4e5da5Sopenharmony_ci  };
396fd4e5da5Sopenharmony_ci  const uint32_t expected_spirv[] = {
397fd4e5da5Sopenharmony_ci      0x07230203, // Magic
398fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
399fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
400fd4e5da5Sopenharmony_ci      0x00000001, // Bound
401fd4e5da5Sopenharmony_ci      0x00000000, // Schema
402fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
403fd4e5da5Sopenharmony_ci      0x00000001, // Shader
404fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
405fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
406fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
407fd4e5da5Sopenharmony_ci      0x00000000, // Logical
408fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
409fd4e5da5Sopenharmony_ci  };
410fd4e5da5Sopenharmony_ci
411fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
412fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
413fd4e5da5Sopenharmony_ci
414fd4e5da5Sopenharmony_ci  EXPECT_TRUE(spvOptimizerRegisterPassFromFlag(
415fd4e5da5Sopenharmony_ci      optimizer, "--eliminate-dead-code-aggressive"));
416fd4e5da5Sopenharmony_ci
417fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
418fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
419fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, false);
420fd4e5da5Sopenharmony_ci
421fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
422fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
423fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
424fd4e5da5Sopenharmony_ci                            &binary, options));
425fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
426fd4e5da5Sopenharmony_ci
427fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
428fd4e5da5Sopenharmony_ci
429fd4e5da5Sopenharmony_ci  // Unreferenced OpTypeInt and OpConstant should be removed
430fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
431fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, expected_spirv,
432fd4e5da5Sopenharmony_ci                   sizeof(expected_spirv) / sizeof(uint32_t)), 0);
433fd4e5da5Sopenharmony_ci
434fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
435fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
436fd4e5da5Sopenharmony_ci}
437fd4e5da5Sopenharmony_ci
438fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerPassesFromFlagsForValidInput) {
439fd4e5da5Sopenharmony_ci  const uint32_t spirv[] = {
440fd4e5da5Sopenharmony_ci      0x07230203, // Magic
441fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
442fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
443fd4e5da5Sopenharmony_ci      0x00000003, // Bound
444fd4e5da5Sopenharmony_ci      0x00000000, // Schema
445fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
446fd4e5da5Sopenharmony_ci      0x00000001, // Shader
447fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
448fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
449fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
450fd4e5da5Sopenharmony_ci      0x00000000, // Logical
451fd4e5da5Sopenharmony_ci      0x00000001, // GLSL450
452fd4e5da5Sopenharmony_ci      0x00040015, // OpTypeInt
453fd4e5da5Sopenharmony_ci      0x00000001, // %1
454fd4e5da5Sopenharmony_ci      0x00000020, // 32 Bits
455fd4e5da5Sopenharmony_ci      0x00000000, // Unsigned
456fd4e5da5Sopenharmony_ci      0x0004002B, // OpConstant
457fd4e5da5Sopenharmony_ci      0x00000001, // %1
458fd4e5da5Sopenharmony_ci      0x00000002, // %2
459fd4e5da5Sopenharmony_ci      0x00000001  // 1
460fd4e5da5Sopenharmony_ci  };
461fd4e5da5Sopenharmony_ci  const uint32_t expected_spirv[] = {
462fd4e5da5Sopenharmony_ci      0x07230203, // Magic
463fd4e5da5Sopenharmony_ci      0x00010100, // Version 1.1
464fd4e5da5Sopenharmony_ci      0x00000000, // No Generator
465fd4e5da5Sopenharmony_ci      0x00000001, // Bound
466fd4e5da5Sopenharmony_ci      0x00000000, // Schema
467fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
468fd4e5da5Sopenharmony_ci      0x00000001, // Shader
469fd4e5da5Sopenharmony_ci      0x00020011, // OpCapability
470fd4e5da5Sopenharmony_ci      0x00000005, // Linkage
471fd4e5da5Sopenharmony_ci      0x0003000E, // OpMemoryModel
472fd4e5da5Sopenharmony_ci      0x00000000, // Logical
473fd4e5da5Sopenharmony_ci      0x00000001  // GLSL450
474fd4e5da5Sopenharmony_ci  };
475fd4e5da5Sopenharmony_ci
476fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
477fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
478fd4e5da5Sopenharmony_ci
479fd4e5da5Sopenharmony_ci  const char* flags[2] = {
480fd4e5da5Sopenharmony_ci      "--eliminate-dead-const",
481fd4e5da5Sopenharmony_ci      "--eliminate-dead-code-aggressive"
482fd4e5da5Sopenharmony_ci  };
483fd4e5da5Sopenharmony_ci
484fd4e5da5Sopenharmony_ci  EXPECT_TRUE(spvOptimizerRegisterPassesFromFlags(
485fd4e5da5Sopenharmony_ci      optimizer, flags, sizeof(flags) / sizeof(const char*)));
486fd4e5da5Sopenharmony_ci
487fd4e5da5Sopenharmony_ci  auto options = spvOptimizerOptionsCreate();
488fd4e5da5Sopenharmony_ci  ASSERT_NE(options, nullptr);
489fd4e5da5Sopenharmony_ci  spvOptimizerOptionsSetRunValidator(options, false);
490fd4e5da5Sopenharmony_ci
491fd4e5da5Sopenharmony_ci  spv_binary binary = nullptr;
492fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS,
493fd4e5da5Sopenharmony_ci            spvOptimizerRun(optimizer, spirv, sizeof(spirv) / sizeof(uint32_t),
494fd4e5da5Sopenharmony_ci                            &binary, options));
495fd4e5da5Sopenharmony_ci  ASSERT_NE(binary, nullptr);
496fd4e5da5Sopenharmony_ci
497fd4e5da5Sopenharmony_ci  spvOptimizerOptionsDestroy(options);
498fd4e5da5Sopenharmony_ci
499fd4e5da5Sopenharmony_ci  // Unreferenced OpTypeInt and OpConstant should be removed
500fd4e5da5Sopenharmony_ci  EXPECT_EQ(binary->wordCount, sizeof(expected_spirv) / sizeof(uint32_t));
501fd4e5da5Sopenharmony_ci  EXPECT_EQ(memcmp(binary->code, expected_spirv,
502fd4e5da5Sopenharmony_ci                   sizeof(expected_spirv) / sizeof(uint32_t)), 0);
503fd4e5da5Sopenharmony_ci
504fd4e5da5Sopenharmony_ci  spvBinaryDestroy(binary);
505fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
506fd4e5da5Sopenharmony_ci}
507fd4e5da5Sopenharmony_ci
508fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerInvalidPassFromFlag) {
509fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
510fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
511fd4e5da5Sopenharmony_ci
512fd4e5da5Sopenharmony_ci  EXPECT_FALSE(spvOptimizerRegisterPassFromFlag(
513fd4e5da5Sopenharmony_ci      optimizer, "--this-is-not-a-valid-pass"));
514fd4e5da5Sopenharmony_ci
515fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
516fd4e5da5Sopenharmony_ci}
517fd4e5da5Sopenharmony_ci
518fd4e5da5Sopenharmony_ciTEST(OptimizerCInterface, DefaultConsumerInvalidPassesFromFlags) {
519fd4e5da5Sopenharmony_ci  auto optimizer = spvOptimizerCreate(SPV_ENV_UNIVERSAL_1_1);
520fd4e5da5Sopenharmony_ci  ASSERT_NE(optimizer, nullptr);
521fd4e5da5Sopenharmony_ci
522fd4e5da5Sopenharmony_ci  const char* flags[2] = {
523fd4e5da5Sopenharmony_ci      "--eliminate-dead-const",
524fd4e5da5Sopenharmony_ci      "--this-is-not-a-valid-pass"
525fd4e5da5Sopenharmony_ci  };
526fd4e5da5Sopenharmony_ci
527fd4e5da5Sopenharmony_ci  EXPECT_FALSE(spvOptimizerRegisterPassesFromFlags(
528fd4e5da5Sopenharmony_ci      optimizer, flags, sizeof(flags) / sizeof(const char*)));
529fd4e5da5Sopenharmony_ci
530fd4e5da5Sopenharmony_ci  spvOptimizerDestroy(optimizer);
531fd4e5da5Sopenharmony_ci}
532fd4e5da5Sopenharmony_ci
533fd4e5da5Sopenharmony_ci}  // namespace
534fd4e5da5Sopenharmony_ci}  // namespace spvtools
535