• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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