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 <iostream>
16 #include <memory>
17 #include <string>
18 #include <vector>
19
20 #include "gmock/gmock.h"
21 #include "source/opt/build_module.h"
22 #include "source/opt/decoration_manager.h"
23 #include "source/opt/ir_context.h"
24 #include "source/spirv_constant.h"
25 #include "test/unit_spirv.h"
26
27 namespace spvtools {
28 namespace opt {
29 namespace analysis {
30 namespace {
31
32 using spvtest::MakeVector;
33
34 class DecorationManagerTest : public ::testing::Test {
35 public:
DecorationManagerTest()36 DecorationManagerTest()
37 : tools_(SPV_ENV_UNIVERSAL_1_2),
38 context_(),
39 consumer_([this](spv_message_level_t level, const char*,
40 const spv_position_t& position, const char* message) {
41 if (!error_message_.empty()) error_message_ += "\n";
42 switch (level) {
43 case SPV_MSG_FATAL:
44 case SPV_MSG_INTERNAL_ERROR:
45 case SPV_MSG_ERROR:
46 error_message_ += "ERROR";
47 break;
48 case SPV_MSG_WARNING:
49 error_message_ += "WARNING";
50 break;
51 case SPV_MSG_INFO:
52 error_message_ += "INFO";
53 break;
54 case SPV_MSG_DEBUG:
55 error_message_ += "DEBUG";
56 break;
57 }
58 error_message_ +=
59 ": " + std::to_string(position.index) + ": " + message;
60 }),
61 disassemble_options_(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER),
62 error_message_() {
63 tools_.SetMessageConsumer(consumer_);
64 }
65
TearDown()66 void TearDown() override { error_message_.clear(); }
67
GetDecorationManager(const std::string & text)68 DecorationManager* GetDecorationManager(const std::string& text) {
69 context_ = BuildModule(SPV_ENV_UNIVERSAL_1_2, consumer_, text);
70 if (context_.get())
71 return context_->get_decoration_mgr();
72 else
73 return nullptr;
74 }
75
76 // Disassembles |binary| and outputs the result in |text|. If |text| is a
77 // null pointer, SPV_ERROR_INVALID_POINTER is returned.
Disassemble(const std::vector<uint32_t> & binary,std::string * text)78 spv_result_t Disassemble(const std::vector<uint32_t>& binary,
79 std::string* text) {
80 if (!text) return SPV_ERROR_INVALID_POINTER;
81 return tools_.Disassemble(binary, text, disassemble_options_)
82 ? SPV_SUCCESS
83 : SPV_ERROR_INVALID_BINARY;
84 }
85
86 // Returns the accumulated error messages for the test.
GetErrorMessage() const87 std::string GetErrorMessage() const { return error_message_; }
88
ToText(const std::vector<Instruction * > & inst)89 std::string ToText(const std::vector<Instruction*>& inst) {
90 std::vector<uint32_t> binary = {SpvMagicNumber, 0x10200, 0u, 2u, 0u};
91 for (const Instruction* i : inst)
92 i->ToBinaryWithoutAttachedDebugInsts(&binary);
93 std::string text;
94 Disassemble(binary, &text);
95 return text;
96 }
97
ModuleToText()98 std::string ModuleToText() {
99 std::vector<uint32_t> binary;
100 context_->module()->ToBinary(&binary, false);
101 std::string text;
102 Disassemble(binary, &text);
103 return text;
104 }
105
GetConsumer()106 spvtools::MessageConsumer GetConsumer() { return consumer_; }
107
108 private:
109 // An instance for calling SPIRV-Tools functionalities.
110 spvtools::SpirvTools tools_;
111 std::unique_ptr<IRContext> context_;
112 spvtools::MessageConsumer consumer_;
113 uint32_t disassemble_options_;
114 std::string error_message_;
115 };
116
TEST_F(DecorationManagerTest,ComparingDecorationsWithDiffOpcodesDecorateDecorateId)117 TEST_F(DecorationManagerTest,
118 ComparingDecorationsWithDiffOpcodesDecorateDecorateId) {
119 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
120 // This parameter can be interprated both as { SpvDecorationConstant }
121 // and also as a list of IDs: { 22 }
122 const std::vector<uint32_t> param{SpvDecorationConstant};
123 // OpDecorate %1 Constant
124 Instruction inst1(
125 &ir_context, SpvOpDecorate, 0u, 0u,
126 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}});
127 // OpDecorateId %1 %22 ; 'Constant' is decoration number 22
128 Instruction inst2(
129 &ir_context, SpvOpDecorateId, 0u, 0u,
130 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, param}});
131 DecorationManager* decoManager = ir_context.get_decoration_mgr();
132 EXPECT_THAT(GetErrorMessage(), "");
133 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
134 }
135
TEST_F(DecorationManagerTest,ComparingDecorationsWithDiffOpcodesDecorateDecorateString)136 TEST_F(DecorationManagerTest,
137 ComparingDecorationsWithDiffOpcodesDecorateDecorateString) {
138 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
139 // This parameter can be interprated both as { SpvDecorationConstant }
140 // and also as a null-terminated string with a single character with value 22.
141 const std::vector<uint32_t> param{SpvDecorationConstant};
142 // OpDecorate %1 Constant
143 Instruction inst1(
144 &ir_context, SpvOpDecorate, 0u, 0u,
145 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, param}});
146 // OpDecorateStringGOOGLE %1 !22
147 Instruction inst2(
148 &ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
149 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_LITERAL_STRING, param}});
150 DecorationManager* decoManager = ir_context.get_decoration_mgr();
151 EXPECT_THAT(GetErrorMessage(), "");
152 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
153 }
154
TEST_F(DecorationManagerTest,ComparingDecorationsWithDiffDecorateParam)155 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateParam) {
156 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
157 // OpDecorate %1 Constant
158 Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
159 {{SPV_OPERAND_TYPE_ID, {1u}},
160 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
161 // OpDecorate %1 Restrict
162 Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u,
163 {{SPV_OPERAND_TYPE_ID, {1u}},
164 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationRestrict}}});
165 DecorationManager* decoManager = ir_context.get_decoration_mgr();
166 EXPECT_THAT(GetErrorMessage(), "");
167 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
168 }
169
TEST_F(DecorationManagerTest,ComparingDecorationsWithDiffDecorateIdParam)170 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateIdParam) {
171 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
172 // OpDecorate %1 Constant
173 Instruction inst1(
174 &ir_context, SpvOpDecorateId, 0u, 0u,
175 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {555}}});
176 // OpDecorate %1 Restrict
177 Instruction inst2(
178 &ir_context, SpvOpDecorateId, 0u, 0u,
179 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_ID, {666}}});
180 DecorationManager* decoManager = ir_context.get_decoration_mgr();
181 EXPECT_THAT(GetErrorMessage(), "");
182 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
183 }
184
TEST_F(DecorationManagerTest,ComparingDecorationsWithDiffDecorateStringParam)185 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateStringParam) {
186 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
187 // OpDecorate %1 Constant
188 Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
189 {{SPV_OPERAND_TYPE_ID, {1u}},
190 {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hello!")}});
191 // OpDecorate %1 Restrict
192 Instruction inst2(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
193 {{SPV_OPERAND_TYPE_ID, {1u}},
194 {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("Hellx")}});
195 DecorationManager* decoManager = ir_context.get_decoration_mgr();
196 EXPECT_THAT(GetErrorMessage(), "");
197 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
198 }
199
TEST_F(DecorationManagerTest,ComparingSameDecorationsOnDiffTargetAllowed)200 TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) {
201 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
202 // OpDecorate %1 Constant
203 Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
204 {{SPV_OPERAND_TYPE_ID, {1u}},
205 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
206 // OpDecorate %2 Constant
207 Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u,
208 {{SPV_OPERAND_TYPE_ID, {2u}},
209 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
210 DecorationManager* decoManager = ir_context.get_decoration_mgr();
211 EXPECT_THAT(GetErrorMessage(), "");
212 EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
213 }
214
TEST_F(DecorationManagerTest,ComparingSameDecorationIdsOnDiffTargetAllowed)215 TEST_F(DecorationManagerTest, ComparingSameDecorationIdsOnDiffTargetAllowed) {
216 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
217 Instruction inst1(
218 &ir_context, SpvOpDecorateId, 0u, 0u,
219 {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}});
220 Instruction inst2(
221 &ir_context, SpvOpDecorateId, 0u, 0u,
222 {{SPV_OPERAND_TYPE_ID, {2u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}});
223 DecorationManager* decoManager = ir_context.get_decoration_mgr();
224 EXPECT_THAT(GetErrorMessage(), "");
225 EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
226 }
227
TEST_F(DecorationManagerTest,ComparingSameDecorationStringsOnDiffTargetAllowed)228 TEST_F(DecorationManagerTest,
229 ComparingSameDecorationStringsOnDiffTargetAllowed) {
230 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
231 Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
232 {{SPV_OPERAND_TYPE_ID, {1u}},
233 {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}});
234 Instruction inst2(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
235 {{SPV_OPERAND_TYPE_ID, {2u}},
236 {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}});
237 DecorationManager* decoManager = ir_context.get_decoration_mgr();
238 EXPECT_THAT(GetErrorMessage(), "");
239 EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
240 }
241
TEST_F(DecorationManagerTest,ComparingSameDecorationsOnDiffTargetDisallowed)242 TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) {
243 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
244 // OpDecorate %1 Constant
245 Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
246 {{SPV_OPERAND_TYPE_ID, {1u}},
247 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
248 // OpDecorate %2 Constant
249 Instruction inst2(&ir_context, SpvOpDecorate, 0u, 0u,
250 {{SPV_OPERAND_TYPE_ID, {2u}},
251 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
252 DecorationManager* decoManager = ir_context.get_decoration_mgr();
253 EXPECT_THAT(GetErrorMessage(), "");
254 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false));
255 }
256
TEST_F(DecorationManagerTest,ComparingMemberDecorationsOnSameTypeDiffMember)257 TEST_F(DecorationManagerTest, ComparingMemberDecorationsOnSameTypeDiffMember) {
258 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
259 // OpMemberDecorate %1 0 Constant
260 Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
261 {{SPV_OPERAND_TYPE_ID, {1u}},
262 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}},
263 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
264 // OpMemberDecorate %1 1 Constant
265 Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u,
266 {{SPV_OPERAND_TYPE_ID, {1u}},
267 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1u}},
268 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
269 DecorationManager* decoManager = ir_context.get_decoration_mgr();
270 EXPECT_THAT(GetErrorMessage(), "");
271 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
272 }
273
TEST_F(DecorationManagerTest,ComparingSameMemberDecorationsOnDiffTargetAllowed)274 TEST_F(DecorationManagerTest,
275 ComparingSameMemberDecorationsOnDiffTargetAllowed) {
276 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
277 // OpMemberDecorate %1 0 Constant
278 Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
279 {{SPV_OPERAND_TYPE_ID, {1u}},
280 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}},
281 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
282 // OpMemberDecorate %2 0 Constant
283 Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u,
284 {{SPV_OPERAND_TYPE_ID, {2u}},
285 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}},
286 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
287 DecorationManager* decoManager = ir_context.get_decoration_mgr();
288 EXPECT_THAT(GetErrorMessage(), "");
289 EXPECT_TRUE(decoManager->AreDecorationsTheSame(&inst1, &inst2, true));
290 }
291
TEST_F(DecorationManagerTest,ComparingSameMemberDecorationsOnDiffTargetDisallowed)292 TEST_F(DecorationManagerTest,
293 ComparingSameMemberDecorationsOnDiffTargetDisallowed) {
294 IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
295 // OpMemberDecorate %1 0 Constant
296 Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
297 {{SPV_OPERAND_TYPE_ID, {1u}},
298 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}},
299 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
300 // OpMemberDecorate %2 0 Constant
301 Instruction inst2(&ir_context, SpvOpMemberDecorate, 0u, 0u,
302 {{SPV_OPERAND_TYPE_ID, {2u}},
303 {SPV_OPERAND_TYPE_LITERAL_INTEGER, {0u}},
304 {SPV_OPERAND_TYPE_DECORATION, {SpvDecorationConstant}}});
305 DecorationManager* decoManager = ir_context.get_decoration_mgr();
306 EXPECT_THAT(GetErrorMessage(), "");
307 EXPECT_FALSE(decoManager->AreDecorationsTheSame(&inst1, &inst2, false));
308 }
309
TEST_F(DecorationManagerTest,RemoveDecorationFromVariable)310 TEST_F(DecorationManagerTest, RemoveDecorationFromVariable) {
311 const std::string spirv = R"(
312 OpCapability Shader
313 OpCapability Linkage
314 OpMemoryModel Logical GLSL450
315 OpDecorate %1 Constant
316 OpDecorate %2 Restrict
317 %2 = OpDecorationGroup
318 OpGroupDecorate %2 %1 %3
319 %4 = OpTypeInt 32 0
320 %1 = OpVariable %4 Uniform
321 %3 = OpVariable %4 Uniform
322 )";
323 DecorationManager* decoManager = GetDecorationManager(spirv);
324 EXPECT_THAT(GetErrorMessage(), "");
325 decoManager->RemoveDecorationsFrom(1u);
326 auto decorations = decoManager->GetDecorationsFor(1u, false);
327 EXPECT_THAT(GetErrorMessage(), "");
328 EXPECT_TRUE(decorations.empty());
329 decorations = decoManager->GetDecorationsFor(3u, false);
330 EXPECT_THAT(GetErrorMessage(), "");
331
332 const std::string expected_decorations = R"(OpDecorate %2 Restrict
333 )";
334 EXPECT_THAT(ToText(decorations), expected_decorations);
335
336 const std::string expected_binary = R"(OpCapability Shader
337 OpCapability Linkage
338 OpMemoryModel Logical GLSL450
339 OpDecorate %2 Restrict
340 %2 = OpDecorationGroup
341 OpGroupDecorate %2 %3
342 %4 = OpTypeInt 32 0
343 %1 = OpVariable %4 Uniform
344 %3 = OpVariable %4 Uniform
345 )";
346 EXPECT_THAT(ModuleToText(), expected_binary);
347 }
348
TEST_F(DecorationManagerTest,RemoveDecorationStringFromVariable)349 TEST_F(DecorationManagerTest, RemoveDecorationStringFromVariable) {
350 const std::string spirv = R"(
351 OpCapability Shader
352 OpCapability Linkage
353 OpExtension "SPV_GOOGLE_hlsl_functionality1"
354 OpExtension "SPV_GOOGLE_decorate_string"
355 OpMemoryModel Logical GLSL450
356 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello world"
357 OpDecorate %2 Restrict
358 %2 = OpDecorationGroup
359 OpGroupDecorate %2 %1 %3
360 %4 = OpTypeInt 32 0
361 %1 = OpVariable %4 Uniform
362 %3 = OpVariable %4 Uniform
363 )";
364 DecorationManager* decoManager = GetDecorationManager(spirv);
365 EXPECT_THAT(GetErrorMessage(), "");
366 decoManager->RemoveDecorationsFrom(1u);
367 auto decorations = decoManager->GetDecorationsFor(1u, false);
368 EXPECT_THAT(GetErrorMessage(), "");
369 EXPECT_TRUE(decorations.empty());
370 decorations = decoManager->GetDecorationsFor(3u, false);
371 EXPECT_THAT(GetErrorMessage(), "");
372
373 const std::string expected_decorations = R"(OpDecorate %2 Restrict
374 )";
375 EXPECT_THAT(ToText(decorations), expected_decorations);
376
377 const std::string expected_binary = R"(OpCapability Shader
378 OpCapability Linkage
379 OpExtension "SPV_GOOGLE_hlsl_functionality1"
380 OpExtension "SPV_GOOGLE_decorate_string"
381 OpMemoryModel Logical GLSL450
382 OpDecorate %2 Restrict
383 %2 = OpDecorationGroup
384 OpGroupDecorate %2 %3
385 %4 = OpTypeInt 32 0
386 %1 = OpVariable %4 Uniform
387 %3 = OpVariable %4 Uniform
388 )";
389 EXPECT_THAT(ModuleToText(), expected_binary);
390 }
391
TEST_F(DecorationManagerTest,RemoveDecorationFromDecorationGroup)392 TEST_F(DecorationManagerTest, RemoveDecorationFromDecorationGroup) {
393 const std::string spirv = R"(
394 OpCapability Shader
395 OpCapability Linkage
396 OpMemoryModel Logical GLSL450
397 OpDecorate %1 Constant
398 OpDecorate %2 Restrict
399 %2 = OpDecorationGroup
400 OpGroupDecorate %2 %1 %3
401 %4 = OpTypeInt 32 0
402 %1 = OpVariable %4 Uniform
403 %3 = OpVariable %4 Uniform
404 )";
405 DecorationManager* decoManager = GetDecorationManager(spirv);
406 EXPECT_THAT(GetErrorMessage(), "");
407 decoManager->RemoveDecorationsFrom(2u);
408 auto decorations = decoManager->GetDecorationsFor(2u, false);
409 EXPECT_THAT(GetErrorMessage(), "");
410 EXPECT_TRUE(decorations.empty());
411 decorations = decoManager->GetDecorationsFor(1u, false);
412 EXPECT_THAT(GetErrorMessage(), "");
413
414 const std::string expected_decorations = R"(OpDecorate %1 Constant
415 )";
416 EXPECT_THAT(ToText(decorations), expected_decorations);
417 decorations = decoManager->GetDecorationsFor(3u, false);
418 EXPECT_THAT(GetErrorMessage(), "");
419 EXPECT_THAT(ToText(decorations), "");
420
421 const std::string expected_binary = R"(OpCapability Shader
422 OpCapability Linkage
423 OpMemoryModel Logical GLSL450
424 OpDecorate %1 Constant
425 %2 = OpDecorationGroup
426 %4 = OpTypeInt 32 0
427 %1 = OpVariable %4 Uniform
428 %3 = OpVariable %4 Uniform
429 )";
430 EXPECT_THAT(ModuleToText(), expected_binary);
431 }
432
TEST_F(DecorationManagerTest,RemoveDecorationFromDecorationGroupKeepDeadDecorations)433 TEST_F(DecorationManagerTest,
434 RemoveDecorationFromDecorationGroupKeepDeadDecorations) {
435 const std::string spirv = R"(
436 OpCapability Shader
437 OpCapability Linkage
438 OpMemoryModel Logical GLSL450
439 OpDecorate %1 Constant
440 OpDecorate %2 Restrict
441 %2 = OpDecorationGroup
442 OpGroupDecorate %2 %1
443 %3 = OpTypeInt 32 0
444 %1 = OpVariable %3 Uniform
445 )";
446 DecorationManager* decoManager = GetDecorationManager(spirv);
447 EXPECT_THAT(GetErrorMessage(), "");
448 decoManager->RemoveDecorationsFrom(1u);
449 auto decorations = decoManager->GetDecorationsFor(1u, false);
450 EXPECT_THAT(GetErrorMessage(), "");
451 EXPECT_TRUE(decorations.empty());
452 decorations = decoManager->GetDecorationsFor(2u, false);
453 EXPECT_THAT(GetErrorMessage(), "");
454
455 const std::string expected_decorations = R"(OpDecorate %2 Restrict
456 )";
457 EXPECT_THAT(ToText(decorations), expected_decorations);
458
459 const std::string expected_binary = R"(OpCapability Shader
460 OpCapability Linkage
461 OpMemoryModel Logical GLSL450
462 OpDecorate %2 Restrict
463 %2 = OpDecorationGroup
464 %3 = OpTypeInt 32 0
465 %1 = OpVariable %3 Uniform
466 )";
467 EXPECT_THAT(ModuleToText(), expected_binary);
468 }
469
TEST_F(DecorationManagerTest,RemoveAllDecorationsAppliedByGroup)470 TEST_F(DecorationManagerTest, RemoveAllDecorationsAppliedByGroup) {
471 const std::string spirv = R"(
472 OpCapability Shader
473 OpCapability Linkage
474 OpMemoryModel Logical GLSL450
475 OpDecorate %1 Constant
476 OpDecorate %2 Restrict
477 %2 = OpDecorationGroup
478 OpGroupDecorate %2 %1
479 OpDecorate %3 BuiltIn VertexId
480 %3 = OpDecorationGroup
481 OpGroupDecorate %3 %1
482 %4 = OpTypeInt 32 0
483 %1 = OpVariable %4 Input
484 )";
485 DecorationManager* decoManager = GetDecorationManager(spirv);
486 EXPECT_THAT(GetErrorMessage(), "");
487 decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) {
488 return inst.opcode() == SpvOpDecorate &&
489 inst.GetSingleWordInOperand(0u) == 3u;
490 });
491 auto decorations = decoManager->GetDecorationsFor(1u, false);
492 EXPECT_THAT(GetErrorMessage(), "");
493
494 std::string expected_decorations = R"(OpDecorate %1 Constant
495 OpDecorate %2 Restrict
496 )";
497 EXPECT_THAT(ToText(decorations), expected_decorations);
498 decorations = decoManager->GetDecorationsFor(2u, false);
499 EXPECT_THAT(GetErrorMessage(), "");
500
501 expected_decorations = R"(OpDecorate %2 Restrict
502 )";
503 EXPECT_THAT(ToText(decorations), expected_decorations);
504
505 const std::string expected_binary = R"(OpCapability Shader
506 OpCapability Linkage
507 OpMemoryModel Logical GLSL450
508 OpDecorate %1 Constant
509 OpDecorate %2 Restrict
510 %2 = OpDecorationGroup
511 OpGroupDecorate %2 %1
512 OpDecorate %3 BuiltIn VertexId
513 %3 = OpDecorationGroup
514 %4 = OpTypeInt 32 0
515 %1 = OpVariable %4 Input
516 )";
517 EXPECT_THAT(ModuleToText(), expected_binary);
518 }
519
TEST_F(DecorationManagerTest,RemoveSomeDecorationsAppliedByGroup)520 TEST_F(DecorationManagerTest, RemoveSomeDecorationsAppliedByGroup) {
521 const std::string spirv = R"(
522 OpCapability Shader
523 OpCapability Linkage
524 OpMemoryModel Logical GLSL450
525 OpDecorate %1 Constant
526 OpDecorate %2 Restrict
527 %2 = OpDecorationGroup
528 OpGroupDecorate %2 %1
529 OpDecorate %3 BuiltIn VertexId
530 OpDecorate %3 Invariant
531 %3 = OpDecorationGroup
532 OpGroupDecorate %3 %1
533 %uint = OpTypeInt 32 0
534 %1 = OpVariable %uint Input
535 )";
536 DecorationManager* decoManager = GetDecorationManager(spirv);
537 EXPECT_THAT(GetErrorMessage(), "");
538 decoManager->RemoveDecorationsFrom(1u, [](const Instruction& inst) {
539 return inst.opcode() == SpvOpDecorate &&
540 inst.GetSingleWordInOperand(0u) == 3u &&
541 inst.GetSingleWordInOperand(1u) == SpvDecorationBuiltIn;
542 });
543 auto decorations = decoManager->GetDecorationsFor(1u, false);
544 EXPECT_THAT(GetErrorMessage(), "");
545
546 std::string expected_decorations = R"(OpDecorate %1 Constant
547 OpDecorate %1 Invariant
548 OpDecorate %2 Restrict
549 )";
550 EXPECT_THAT(ToText(decorations), expected_decorations);
551 decorations = decoManager->GetDecorationsFor(2u, false);
552 EXPECT_THAT(GetErrorMessage(), "");
553
554 expected_decorations = R"(OpDecorate %2 Restrict
555 )";
556 EXPECT_THAT(ToText(decorations), expected_decorations);
557
558 const std::string expected_binary = R"(OpCapability Shader
559 OpCapability Linkage
560 OpMemoryModel Logical GLSL450
561 OpDecorate %1 Constant
562 OpDecorate %2 Restrict
563 %2 = OpDecorationGroup
564 OpGroupDecorate %2 %1
565 OpDecorate %3 BuiltIn VertexId
566 OpDecorate %3 Invariant
567 %3 = OpDecorationGroup
568 OpDecorate %1 Invariant
569 %4 = OpTypeInt 32 0
570 %1 = OpVariable %4 Input
571 )";
572 EXPECT_THAT(ModuleToText(), expected_binary);
573 }
574
TEST_F(DecorationManagerTest,RemoveDecorationDecorate)575 TEST_F(DecorationManagerTest, RemoveDecorationDecorate) {
576 const std::string spirv = R"(
577 OpCapability Shader
578 OpCapability Linkage
579 OpMemoryModel Logical GLSL450
580 OpDecorate %1 Constant
581 OpDecorate %1 Restrict
582 %2 = OpTypeInt 32 0
583 %1 = OpVariable %2 Uniform
584 )";
585 DecorationManager* decoManager = GetDecorationManager(spirv);
586 EXPECT_THAT(GetErrorMessage(), "");
587 auto decorations = decoManager->GetDecorationsFor(1u, false);
588 decoManager->RemoveDecoration(decorations.front());
589 decorations = decoManager->GetDecorationsFor(1u, false);
590 EXPECT_THAT(GetErrorMessage(), "");
591
592 const std::string expected_decorations = R"(OpDecorate %1 Restrict
593 )";
594 EXPECT_THAT(ToText(decorations), expected_decorations);
595 }
596
TEST_F(DecorationManagerTest,RemoveDecorationStringDecorate)597 TEST_F(DecorationManagerTest, RemoveDecorationStringDecorate) {
598 const std::string spirv = R"(
599 OpCapability Shader
600 OpCapability Linkage
601 OpExtension "SPV_GOOGLE_hlsl_functionality1"
602 OpExtension "SPV_GOOGLE_decorate_string"
603 OpMemoryModel Logical GLSL450
604 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "foobar"
605 OpDecorate %1 Restrict
606 %2 = OpTypeInt 32 0
607 %1 = OpVariable %2 Uniform
608 )";
609 DecorationManager* decoManager = GetDecorationManager(spirv);
610 EXPECT_THAT(GetErrorMessage(), "");
611 auto decorations = decoManager->GetDecorationsFor(1u, false);
612 decoManager->RemoveDecoration(decorations.front());
613 decorations = decoManager->GetDecorationsFor(1u, false);
614 EXPECT_THAT(GetErrorMessage(), "");
615
616 const std::string expected_decorations = R"(OpDecorate %1 Restrict
617 )";
618 EXPECT_THAT(ToText(decorations), expected_decorations);
619 }
620
TEST_F(DecorationManagerTest,CloneDecorations)621 TEST_F(DecorationManagerTest, CloneDecorations) {
622 const std::string spirv = R"(
623 OpCapability Shader
624 OpCapability Linkage
625 OpMemoryModel Logical GLSL450
626 OpDecorate %1 Constant
627 OpDecorate %2 Restrict
628 %2 = OpDecorationGroup
629 OpGroupDecorate %2 %1
630 OpDecorate %3 BuiltIn VertexId
631 OpDecorate %3 Invariant
632 %3 = OpDecorationGroup
633 OpGroupDecorate %3 %1
634 %4 = OpTypeInt 32 0
635 %1 = OpVariable %4 Input
636 %5 = OpVariable %4 Input
637 )";
638 DecorationManager* decoManager = GetDecorationManager(spirv);
639 EXPECT_THAT(GetErrorMessage(), "");
640
641 // Check cloning OpDecorate including group decorations.
642 auto decorations = decoManager->GetDecorationsFor(5u, false);
643 EXPECT_THAT(GetErrorMessage(), "");
644 EXPECT_TRUE(decorations.empty());
645
646 decoManager->CloneDecorations(1u, 5u);
647 decorations = decoManager->GetDecorationsFor(5u, false);
648 EXPECT_THAT(GetErrorMessage(), "");
649
650 std::string expected_decorations = R"(OpDecorate %5 Constant
651 OpDecorate %2 Restrict
652 OpDecorate %3 BuiltIn VertexId
653 OpDecorate %3 Invariant
654 )";
655 EXPECT_THAT(ToText(decorations), expected_decorations);
656
657 // Check that bookkeeping for ID 2 remains the same.
658 decorations = decoManager->GetDecorationsFor(2u, false);
659 EXPECT_THAT(GetErrorMessage(), "");
660
661 expected_decorations = R"(OpDecorate %2 Restrict
662 )";
663 EXPECT_THAT(ToText(decorations), expected_decorations);
664
665 const std::string expected_binary = R"(OpCapability Shader
666 OpCapability Linkage
667 OpMemoryModel Logical GLSL450
668 OpDecorate %1 Constant
669 OpDecorate %2 Restrict
670 %2 = OpDecorationGroup
671 OpGroupDecorate %2 %1 %5
672 OpDecorate %3 BuiltIn VertexId
673 OpDecorate %3 Invariant
674 %3 = OpDecorationGroup
675 OpGroupDecorate %3 %1 %5
676 OpDecorate %5 Constant
677 %4 = OpTypeInt 32 0
678 %1 = OpVariable %4 Input
679 %5 = OpVariable %4 Input
680 )";
681 EXPECT_THAT(ModuleToText(), expected_binary);
682 }
683
TEST_F(DecorationManagerTest,CloneDecorationsStringAndId)684 TEST_F(DecorationManagerTest, CloneDecorationsStringAndId) {
685 const std::string spirv = R"(OpCapability Shader
686 OpCapability Linkage
687 OpExtension "SPV_GOOGLE_hlsl_functionality1"
688 OpExtension "SPV_GOOGLE_decorate_string"
689 OpMemoryModel Logical GLSL450
690 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "blah"
691 OpDecorateId %1 HlslCounterBufferGOOGLE %2
692 OpDecorate %1 Aliased
693 %3 = OpTypeInt 32 0
694 %4 = OpTypePointer Uniform %3
695 %1 = OpVariable %4 Uniform
696 %2 = OpVariable %4 Uniform
697 %5 = OpVariable %4 Uniform
698 )";
699 DecorationManager* decoManager = GetDecorationManager(spirv);
700 EXPECT_THAT(GetErrorMessage(), "");
701
702 // Check cloning OpDecorate including group decorations.
703 auto decorations = decoManager->GetDecorationsFor(5u, false);
704 EXPECT_THAT(GetErrorMessage(), "");
705 EXPECT_TRUE(decorations.empty());
706
707 decoManager->CloneDecorations(1u, 5u);
708 decorations = decoManager->GetDecorationsFor(5u, false);
709 EXPECT_THAT(GetErrorMessage(), "");
710
711 std::string expected_decorations =
712 R"(OpDecorateStringGOOGLE %5 HlslSemanticGOOGLE "blah"
713 OpDecorateId %5 HlslCounterBufferGOOGLE %2
714 OpDecorate %5 Aliased
715 )";
716 EXPECT_THAT(ToText(decorations), expected_decorations);
717
718 const std::string expected_binary = R"(OpCapability Shader
719 OpCapability Linkage
720 OpExtension "SPV_GOOGLE_hlsl_functionality1"
721 OpExtension "SPV_GOOGLE_decorate_string"
722 OpMemoryModel Logical GLSL450
723 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "blah"
724 OpDecorateId %1 HlslCounterBufferGOOGLE %2
725 OpDecorate %1 Aliased
726 OpDecorateStringGOOGLE %5 HlslSemanticGOOGLE "blah"
727 OpDecorateId %5 HlslCounterBufferGOOGLE %2
728 OpDecorate %5 Aliased
729 %3 = OpTypeInt 32 0
730 %4 = OpTypePointer Uniform %3
731 %1 = OpVariable %4 Uniform
732 %2 = OpVariable %4 Uniform
733 %5 = OpVariable %4 Uniform
734 )";
735 EXPECT_THAT(ModuleToText(), expected_binary);
736 }
737
TEST_F(DecorationManagerTest,CloneSomeDecorations)738 TEST_F(DecorationManagerTest, CloneSomeDecorations) {
739 const std::string spirv = R"(OpCapability Shader
740 OpCapability Linkage
741 OpExtension "SPV_GOOGLE_hlsl_functionality1"
742 OpExtension "SPV_GOOGLE_decorate_string"
743 OpMemoryModel Logical GLSL450
744 OpDecorate %1 RelaxedPrecision
745 OpDecorate %1 Restrict
746 %2 = OpTypeInt 32 0
747 %3 = OpTypePointer Function %2
748 %4 = OpTypeVoid
749 %5 = OpTypeFunction %4
750 %6 = OpFunction %4 None %5
751 %7 = OpLabel
752 %1 = OpVariable %3 Function
753 %8 = OpUndef %2
754 OpReturn
755 OpFunctionEnd
756 )";
757 DecorationManager* decoManager = GetDecorationManager(spirv);
758 EXPECT_EQ(GetErrorMessage(), "");
759
760 // Check cloning OpDecorate including group decorations.
761 auto decorations = decoManager->GetDecorationsFor(8u, false);
762 EXPECT_EQ(GetErrorMessage(), "");
763 EXPECT_TRUE(decorations.empty());
764
765 decoManager->CloneDecorations(1u, 8u, {SpvDecorationRelaxedPrecision});
766 decorations = decoManager->GetDecorationsFor(8u, false);
767 EXPECT_THAT(GetErrorMessage(), "");
768
769 std::string expected_decorations =
770 R"(OpDecorate %8 RelaxedPrecision
771 )";
772 EXPECT_EQ(ToText(decorations), expected_decorations);
773
774 const std::string expected_binary = R"(OpCapability Shader
775 OpCapability Linkage
776 OpExtension "SPV_GOOGLE_hlsl_functionality1"
777 OpExtension "SPV_GOOGLE_decorate_string"
778 OpMemoryModel Logical GLSL450
779 OpDecorate %1 RelaxedPrecision
780 OpDecorate %1 Restrict
781 OpDecorate %8 RelaxedPrecision
782 %2 = OpTypeInt 32 0
783 %3 = OpTypePointer Function %2
784 %4 = OpTypeVoid
785 %5 = OpTypeFunction %4
786 %6 = OpFunction %4 None %5
787 %7 = OpLabel
788 %1 = OpVariable %3 Function
789 %8 = OpUndef %2
790 OpReturn
791 OpFunctionEnd
792 )";
793 EXPECT_EQ(ModuleToText(), expected_binary);
794 }
795
796 // Test cloning decoration for an id that is decorated via a group decoration.
TEST_F(DecorationManagerTest,CloneSomeGroupDecorations)797 TEST_F(DecorationManagerTest, CloneSomeGroupDecorations) {
798 const std::string spirv = R"(OpCapability Shader
799 OpCapability Linkage
800 OpMemoryModel Logical GLSL450
801 OpDecorate %1 RelaxedPrecision
802 OpDecorate %1 Restrict
803 %1 = OpDecorationGroup
804 OpGroupDecorate %1 %2
805 %3 = OpTypeInt 32 0
806 %4 = OpTypePointer Function %3
807 %5 = OpTypeVoid
808 %6 = OpTypeFunction %5
809 %7 = OpFunction %5 None %6
810 %8 = OpLabel
811 %2 = OpVariable %4 Function
812 %9 = OpUndef %3
813 OpReturn
814 OpFunctionEnd
815 )";
816 DecorationManager* decoManager = GetDecorationManager(spirv);
817 EXPECT_EQ(GetErrorMessage(), "");
818
819 // Check cloning OpDecorate including group decorations.
820 auto decorations = decoManager->GetDecorationsFor(9u, false);
821 EXPECT_EQ(GetErrorMessage(), "");
822 EXPECT_TRUE(decorations.empty());
823
824 decoManager->CloneDecorations(2u, 9u, {SpvDecorationRelaxedPrecision});
825 decorations = decoManager->GetDecorationsFor(9u, false);
826 EXPECT_THAT(GetErrorMessage(), "");
827
828 std::string expected_decorations =
829 R"(OpDecorate %9 RelaxedPrecision
830 )";
831 EXPECT_EQ(ToText(decorations), expected_decorations);
832
833 const std::string expected_binary = R"(OpCapability Shader
834 OpCapability Linkage
835 OpMemoryModel Logical GLSL450
836 OpDecorate %1 RelaxedPrecision
837 OpDecorate %1 Restrict
838 %1 = OpDecorationGroup
839 OpGroupDecorate %1 %2
840 OpDecorate %9 RelaxedPrecision
841 %3 = OpTypeInt 32 0
842 %4 = OpTypePointer Function %3
843 %5 = OpTypeVoid
844 %6 = OpTypeFunction %5
845 %7 = OpFunction %5 None %6
846 %8 = OpLabel
847 %2 = OpVariable %4 Function
848 %9 = OpUndef %3
849 OpReturn
850 OpFunctionEnd
851 )";
852 EXPECT_EQ(ModuleToText(), expected_binary);
853 }
854
TEST_F(DecorationManagerTest,HaveTheSameDecorationsWithoutGroupsTrue)855 TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithoutGroupsTrue) {
856 const std::string spirv = R"(
857 OpCapability Shader
858 OpCapability Linkage
859 OpMemoryModel Logical GLSL450
860 OpDecorate %1 Restrict
861 OpDecorate %2 Constant
862 OpDecorate %2 Restrict
863 OpDecorate %1 Constant
864 %u32 = OpTypeInt 32 0
865 %1 = OpVariable %u32 Uniform
866 %2 = OpVariable %u32 Uniform
867 )";
868 DecorationManager* decoManager = GetDecorationManager(spirv);
869 EXPECT_THAT(GetErrorMessage(), "");
870 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
871 }
872
TEST_F(DecorationManagerTest,HaveTheSameDecorationsWithoutGroupsFalse)873 TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithoutGroupsFalse) {
874 const std::string spirv = R"(
875 OpCapability Shader
876 OpCapability Linkage
877 OpMemoryModel Logical GLSL450
878 OpDecorate %1 Restrict
879 OpDecorate %2 Constant
880 OpDecorate %2 Restrict
881 %u32 = OpTypeInt 32 0
882 %1 = OpVariable %u32 Uniform
883 %2 = OpVariable %u32 Uniform
884 )";
885 DecorationManager* decoManager = GetDecorationManager(spirv);
886 EXPECT_THAT(GetErrorMessage(), "");
887 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
888 }
889
TEST_F(DecorationManagerTest,HaveTheSameDecorationsIdWithoutGroupsTrue)890 TEST_F(DecorationManagerTest, HaveTheSameDecorationsIdWithoutGroupsTrue) {
891 const std::string spirv = R"(
892 OpCapability Kernel
893 OpCapability Linkage
894 OpMemoryModel Logical GLSL450
895 OpDecorateId %1 AlignmentId %nine
896 OpDecorateId %3 MaxByteOffsetId %nine
897 OpDecorateId %3 AlignmentId %nine
898 OpDecorateId %1 MaxByteOffsetId %nine
899 %u32 = OpTypeInt 32 0
900 %nine = OpConstant %u32 9
901 %1 = OpVariable %u32 Uniform
902 %3 = OpVariable %u32 Uniform
903 )";
904 DecorationManager* decoManager = GetDecorationManager(spirv);
905 EXPECT_THAT(GetErrorMessage(), "");
906 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 3u));
907 }
908
TEST_F(DecorationManagerTest,HaveTheSameDecorationsIdWithoutGroupsFalse)909 TEST_F(DecorationManagerTest, HaveTheSameDecorationsIdWithoutGroupsFalse) {
910 const std::string spirv = R"(
911 OpCapability Kernel
912 OpCapability Linkage
913 OpMemoryModel Logical GLSL450
914 OpDecorateId %1 AlignmentId %nine
915 OpDecorateId %2 MaxByteOffsetId %nine
916 OpDecorateId %2 AlignmentId %nine
917 %u32 = OpTypeInt 32 0
918 %nine = OpConstant %u32 9
919 %1 = OpVariable %u32 Uniform
920 %2 = OpVariable %u32 Uniform
921 )";
922 DecorationManager* decoManager = GetDecorationManager(spirv);
923 EXPECT_THAT(GetErrorMessage(), "");
924 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
925 }
926
TEST_F(DecorationManagerTest,HaveTheSameDecorationsStringWithoutGroupsTrue)927 TEST_F(DecorationManagerTest, HaveTheSameDecorationsStringWithoutGroupsTrue) {
928 const std::string spirv = R"(
929 OpCapability Kernel
930 OpCapability Linkage
931 OpExtension "SPV_GOOGLE_hlsl_functionality1"
932 OpExtension "SPV_GOOGLE_decorate_string"
933 OpMemoryModel Logical GLSL450
934 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
935 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world"
936 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
937 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "world"
938 %u32 = OpTypeInt 32 0
939 %1 = OpVariable %u32 Uniform
940 %2 = OpVariable %u32 Uniform
941 )";
942 DecorationManager* decoManager = GetDecorationManager(spirv);
943 EXPECT_THAT(GetErrorMessage(), "");
944 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
945 }
946
TEST_F(DecorationManagerTest,HaveTheSameDecorationsStringWithoutGroupsFalse)947 TEST_F(DecorationManagerTest, HaveTheSameDecorationsStringWithoutGroupsFalse) {
948 const std::string spirv = R"(
949 OpCapability Kernel
950 OpCapability Linkage
951 OpExtension "SPV_GOOGLE_hlsl_functionality1"
952 OpExtension "SPV_GOOGLE_decorate_string"
953 OpMemoryModel Logical GLSL450
954 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
955 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world"
956 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
957 %u32 = OpTypeInt 32 0
958 %1 = OpVariable %u32 Uniform
959 %2 = OpVariable %u32 Uniform
960 )";
961 DecorationManager* decoManager = GetDecorationManager(spirv);
962 EXPECT_THAT(GetErrorMessage(), "");
963 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
964 }
965
TEST_F(DecorationManagerTest,HaveTheSameDecorationsWithGroupsTrue)966 TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithGroupsTrue) {
967 const std::string spirv = R"(
968 OpCapability Shader
969 OpCapability Linkage
970 OpMemoryModel Logical GLSL450
971 OpDecorate %1 Restrict
972 OpDecorate %2 Constant
973 OpDecorate %1 Constant
974 OpDecorate %3 Restrict
975 %3 = OpDecorationGroup
976 OpGroupDecorate %3 %2
977 OpDecorate %4 Invariant
978 %4 = OpDecorationGroup
979 OpGroupDecorate %4 %1 %2
980 %u32 = OpTypeInt 32 0
981 %1 = OpVariable %u32 Uniform
982 %2 = OpVariable %u32 Uniform
983 )";
984 DecorationManager* decoManager = GetDecorationManager(spirv);
985 EXPECT_THAT(GetErrorMessage(), "");
986 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
987 }
988
TEST_F(DecorationManagerTest,HaveTheSameDecorationsWithGroupsFalse)989 TEST_F(DecorationManagerTest, HaveTheSameDecorationsWithGroupsFalse) {
990 const std::string spirv = R"(
991 OpCapability Shader
992 OpCapability Linkage
993 OpMemoryModel Logical GLSL450
994 OpDecorate %1 Restrict
995 OpDecorate %2 Constant
996 OpDecorate %1 Constant
997 OpDecorate %4 Invariant
998 %4 = OpDecorationGroup
999 OpGroupDecorate %4 %1 %2
1000 %u32 = OpTypeInt 32 0
1001 %1 = OpVariable %u32 Uniform
1002 %2 = OpVariable %u32 Uniform
1003 )";
1004 DecorationManager* decoManager = GetDecorationManager(spirv);
1005 EXPECT_THAT(GetErrorMessage(), "");
1006 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1007 }
1008
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDuplicateDecorations)1009 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateDecorations) {
1010 const std::string spirv = R"(
1011 OpCapability Shader
1012 OpCapability Linkage
1013 OpMemoryModel Logical GLSL450
1014 OpDecorate %1 Constant
1015 OpDecorate %2 Constant
1016 OpDecorate %2 Constant
1017 %u32 = OpTypeInt 32 0
1018 %1 = OpVariable %u32 Uniform
1019 %2 = OpVariable %u32 Uniform
1020 )";
1021 DecorationManager* decoManager = GetDecorationManager(spirv);
1022 EXPECT_THAT(GetErrorMessage(), "");
1023 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
1024 }
1025
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDifferentVariations)1026 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentVariations) {
1027 const std::string spirv = R"(
1028 OpCapability Shader
1029 OpCapability Linkage
1030 OpMemoryModel Logical GLSL450
1031 OpDecorate %1 Location 0
1032 OpDecorate %2 Location 1
1033 %u32 = OpTypeInt 32 0
1034 %1 = OpVariable %u32 Uniform
1035 %2 = OpVariable %u32 Uniform
1036 )";
1037 DecorationManager* decoManager = GetDecorationManager(spirv);
1038 EXPECT_THAT(GetErrorMessage(), "");
1039 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1040 }
1041
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDuplicateMemberDecorations)1042 TEST_F(DecorationManagerTest,
1043 HaveTheSameDecorationsDuplicateMemberDecorations) {
1044 const std::string spirv = R"(
1045 OpCapability Shader
1046 OpCapability Linkage
1047 OpMemoryModel Logical GLSL450
1048 OpMemberDecorate %1 0 Location 0
1049 OpMemberDecorate %2 0 Location 0
1050 OpMemberDecorate %2 0 Location 0
1051 %u32 = OpTypeInt 32 0
1052 %1 = OpTypeStruct %u32 %u32
1053 %2 = OpTypeStruct %u32 %u32
1054 )";
1055 DecorationManager* decoManager = GetDecorationManager(spirv);
1056 EXPECT_THAT(GetErrorMessage(), "");
1057 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
1058 }
1059
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDifferentMemberSameDecoration)1060 TEST_F(DecorationManagerTest,
1061 HaveTheSameDecorationsDifferentMemberSameDecoration) {
1062 const std::string spirv = R"(
1063 OpCapability Shader
1064 OpCapability Linkage
1065 OpMemoryModel Logical GLSL450
1066 OpMemberDecorate %1 0 Location 0
1067 OpMemberDecorate %2 1 Location 0
1068 %u32 = OpTypeInt 32 0
1069 %1 = OpTypeStruct %u32 %u32
1070 %2 = OpTypeStruct %u32 %u32
1071 )";
1072 DecorationManager* decoManager = GetDecorationManager(spirv);
1073 EXPECT_THAT(GetErrorMessage(), "");
1074 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1075 }
1076
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDifferentMemberVariations)1077 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentMemberVariations) {
1078 const std::string spirv = R"(
1079 OpCapability Shader
1080 OpCapability Linkage
1081 OpMemoryModel Logical GLSL450
1082 OpMemberDecorate %1 0 Location 0
1083 OpMemberDecorate %2 0 Location 1
1084 %u32 = OpTypeInt 32 0
1085 %1 = OpTypeStruct %u32 %u32
1086 %2 = OpTypeStruct %u32 %u32
1087 )";
1088 DecorationManager* decoManager = GetDecorationManager(spirv);
1089 EXPECT_THAT(GetErrorMessage(), "");
1090 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1091 }
1092
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDuplicateIdDecorations)1093 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDuplicateIdDecorations) {
1094 const std::string spirv = R"(
1095 OpCapability Shader
1096 OpCapability Linkage
1097 OpMemoryModel Logical GLSL450
1098 OpDecorateId %1 AlignmentId %2
1099 OpDecorateId %3 AlignmentId %2
1100 OpDecorateId %3 AlignmentId %2
1101 %u32 = OpTypeInt 32 0
1102 %1 = OpVariable %u32 Uniform
1103 %3 = OpVariable %u32 Uniform
1104 %2 = OpSpecConstant %u32 0
1105 )";
1106 DecorationManager* decoManager = GetDecorationManager(spirv);
1107 EXPECT_THAT(GetErrorMessage(), "");
1108 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 3u));
1109 }
1110
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDuplicateStringDecorations)1111 TEST_F(DecorationManagerTest,
1112 HaveTheSameDecorationsDuplicateStringDecorations) {
1113 const std::string spirv = R"(
1114 OpCapability Shader
1115 OpCapability Linkage
1116 OpExtension "SPV_GOOGLE_hlsl_functionality1"
1117 OpExtension "SPV_GOOGLE_decorate_string"
1118 OpMemoryModel Logical GLSL450
1119 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
1120 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
1121 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
1122 %u32 = OpTypeInt 32 0
1123 %1 = OpVariable %u32 Uniform
1124 %2 = OpVariable %u32 Uniform
1125 )";
1126 DecorationManager* decoManager = GetDecorationManager(spirv);
1127 EXPECT_THAT(GetErrorMessage(), "");
1128 EXPECT_TRUE(decoManager->HaveTheSameDecorations(1u, 2u));
1129 }
1130
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDifferentIdVariations)1131 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentIdVariations) {
1132 const std::string spirv = R"(
1133 OpCapability Shader
1134 OpCapability Linkage
1135 OpMemoryModel Logical GLSL450
1136 OpDecorateId %1 AlignmentId %2
1137 OpDecorateId %3 AlignmentId %4
1138 %u32 = OpTypeInt 32 0
1139 %1 = OpVariable %u32 Uniform
1140 %3 = OpVariable %u32 Uniform
1141 %2 = OpSpecConstant %u32 0
1142 %4 = OpSpecConstant %u32 0
1143 )";
1144 DecorationManager* decoManager = GetDecorationManager(spirv);
1145 EXPECT_THAT(GetErrorMessage(), "");
1146 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1147 }
1148
TEST_F(DecorationManagerTest,HaveTheSameDecorationsDifferentStringVariations)1149 TEST_F(DecorationManagerTest, HaveTheSameDecorationsDifferentStringVariations) {
1150 const std::string spirv = R"(
1151 OpCapability Shader
1152 OpCapability Linkage
1153 OpExtension "SPV_GOOGLE_hlsl_functionality1"
1154 OpExtension "SPV_GOOGLE_decorate_string"
1155 OpMemoryModel Logical GLSL450
1156 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
1157 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world"
1158 )";
1159 DecorationManager* decoManager = GetDecorationManager(spirv);
1160 EXPECT_THAT(GetErrorMessage(), "");
1161 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1162 }
1163
TEST_F(DecorationManagerTest,HaveTheSameDecorationsLeftSymmetry)1164 TEST_F(DecorationManagerTest, HaveTheSameDecorationsLeftSymmetry) {
1165 // Left being a subset of right is not enough.
1166 const std::string spirv = R"(
1167 OpCapability Shader
1168 OpCapability Linkage
1169 OpMemoryModel Logical GLSL450
1170 OpDecorate %1 Constant
1171 OpDecorate %1 Constant
1172 OpDecorate %2 Constant
1173 OpDecorate %2 Restrict
1174 %u32 = OpTypeInt 32 0
1175 %1 = OpVariable %u32 Uniform
1176 %2 = OpVariable %u32 Uniform
1177 )";
1178 DecorationManager* decoManager = GetDecorationManager(spirv);
1179 EXPECT_THAT(GetErrorMessage(), "");
1180 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1181 }
1182
TEST_F(DecorationManagerTest,HaveTheSameDecorationsRightSymmetry)1183 TEST_F(DecorationManagerTest, HaveTheSameDecorationsRightSymmetry) {
1184 // Right being a subset of left is not enough.
1185 const std::string spirv = R"(
1186 OpCapability Shader
1187 OpCapability Linkage
1188 OpMemoryModel Logical GLSL450
1189 OpDecorate %1 Constant
1190 OpDecorate %1 Restrict
1191 OpDecorate %2 Constant
1192 OpDecorate %2 Constant
1193 %u32 = OpTypeInt 32 0
1194 %1 = OpVariable %u32 Uniform
1195 %2 = OpVariable %u32 Uniform
1196 )";
1197 DecorationManager* decoManager = GetDecorationManager(spirv);
1198 EXPECT_THAT(GetErrorMessage(), "");
1199 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1200 }
1201
TEST_F(DecorationManagerTest,HaveTheSameDecorationIdsLeftSymmetry)1202 TEST_F(DecorationManagerTest, HaveTheSameDecorationIdsLeftSymmetry) {
1203 const std::string spirv = R"(
1204 OpCapability Kernel
1205 OpCapability Linkage
1206 OpMemoryModel Logical GLSL450
1207 OpDecorateId %1 AlignmentId %nine
1208 OpDecorateId %1 AlignmentId %nine
1209 OpDecorateId %2 AlignmentId %nine
1210 OpDecorateId %2 MaxByteOffsetId %nine
1211 %u32 = OpTypeInt 32 0
1212 %nine = OpConstant %u32 9
1213 %1 = OpVariable %u32 Uniform
1214 %2 = OpVariable %u32 Uniform
1215 )";
1216 DecorationManager* decoManager = GetDecorationManager(spirv);
1217 EXPECT_THAT(GetErrorMessage(), "");
1218 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1219 }
1220
TEST_F(DecorationManagerTest,HaveTheSameDecorationIdsRightSymmetry)1221 TEST_F(DecorationManagerTest, HaveTheSameDecorationIdsRightSymmetry) {
1222 const std::string spirv = R"(
1223 OpCapability Kernel
1224 OpCapability Linkage
1225 OpMemoryModel Logical GLSL450
1226 OpDecorateId %1 AlignmentId %nine
1227 OpDecorateId %1 MaxByteOffsetId %nine
1228 OpDecorateId %2 AlignmentId %nine
1229 OpDecorateId %2 AlignmentId %nine
1230 %u32 = OpTypeInt 32 0
1231 %nine = OpConstant %u32 9
1232 %1 = OpVariable %u32 Uniform
1233 %2 = OpVariable %u32 Uniform
1234 )";
1235 DecorationManager* decoManager = GetDecorationManager(spirv);
1236 EXPECT_THAT(GetErrorMessage(), "");
1237 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1238 }
1239
TEST_F(DecorationManagerTest,HaveTheSameDecorationStringsLeftSymmetry)1240 TEST_F(DecorationManagerTest, HaveTheSameDecorationStringsLeftSymmetry) {
1241 const std::string spirv = R"(
1242 OpCapability Kernel
1243 OpCapability Linkage
1244 OpExtension "SPV_GOOGLE_hlsl_functionality1"
1245 OpExtension "SPV_GOOGLE_decorate_string"
1246 OpMemoryModel Logical GLSL450
1247 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
1248 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
1249 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
1250 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "world"
1251 %u32 = OpTypeInt 32 0
1252 %1 = OpVariable %u32 Uniform
1253 %2 = OpVariable %u32 Uniform
1254 )";
1255 DecorationManager* decoManager = GetDecorationManager(spirv);
1256 EXPECT_THAT(GetErrorMessage(), "");
1257 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1258 }
1259
TEST_F(DecorationManagerTest,HaveTheSameDecorationStringsRightSymmetry)1260 TEST_F(DecorationManagerTest, HaveTheSameDecorationStringsRightSymmetry) {
1261 const std::string spirv = R"(
1262 OpCapability Kernel
1263 OpCapability Linkage
1264 OpExtension "SPV_GOOGLE_hlsl_functionality1"
1265 OpExtension "SPV_GOOGLE_decorate_string"
1266 OpMemoryModel Logical GLSL450
1267 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "hello"
1268 OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE "world"
1269 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
1270 OpDecorateStringGOOGLE %2 HlslSemanticGOOGLE "hello"
1271 %u32 = OpTypeInt 32 0
1272 %1 = OpVariable %u32 Uniform
1273 %2 = OpVariable %u32 Uniform
1274 )";
1275 DecorationManager* decoManager = GetDecorationManager(spirv);
1276 EXPECT_THAT(GetErrorMessage(), "");
1277 EXPECT_FALSE(decoManager->HaveTheSameDecorations(1u, 2u));
1278 }
1279
1280 } // namespace
1281 } // namespace analysis
1282 } // namespace opt
1283 } // namespace spvtools
1284