1 // Copyright (c) 2020 André Perez Maselco
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 "source/fuzz/transformation_add_bit_instruction_synonym.h"
16 
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "source/fuzz/instruction_descriptor.h"
20 #include "test/fuzz/fuzz_test_util.h"
21 
22 namespace spvtools {
23 namespace fuzz {
24 namespace {
25 
TEST(TransformationAddBitInstructionSynonymTest, IsApplicable)26 TEST(TransformationAddBitInstructionSynonymTest, IsApplicable) {
27   std::string reference_shader = R"(
28                OpCapability Shader
29           %1 = OpExtInstImport "GLSL.std.450"
30                OpMemoryModel Logical GLSL450
31                OpEntryPoint Vertex %37 "main"
32 
33           ; Types
34           %2 = OpTypeInt 32 0
35           %3 = OpTypeVoid
36           %4 = OpTypeFunction %3
37 
38           ; Constants
39           %5 = OpConstant %2 0
40           %6 = OpConstant %2 1
41           %7 = OpConstant %2 2
42           %8 = OpConstant %2 3
43           %9 = OpConstant %2 4
44          %10 = OpConstant %2 5
45          %11 = OpConstant %2 6
46          %12 = OpConstant %2 7
47          %13 = OpConstant %2 8
48          %14 = OpConstant %2 9
49          %15 = OpConstant %2 10
50          %16 = OpConstant %2 11
51          %17 = OpConstant %2 12
52          %18 = OpConstant %2 13
53          %19 = OpConstant %2 14
54          %20 = OpConstant %2 15
55          %21 = OpConstant %2 16
56          %22 = OpConstant %2 17
57          %23 = OpConstant %2 18
58          %24 = OpConstant %2 19
59          %25 = OpConstant %2 20
60          %26 = OpConstant %2 21
61          %27 = OpConstant %2 22
62          %28 = OpConstant %2 23
63          %29 = OpConstant %2 24
64          %30 = OpConstant %2 25
65          %31 = OpConstant %2 26
66          %32 = OpConstant %2 27
67          %33 = OpConstant %2 28
68          %34 = OpConstant %2 29
69          %35 = OpConstant %2 30
70          %36 = OpConstant %2 31
71 
72          ; main function
73          %37 = OpFunction %3 None %4
74          %38 = OpLabel
75 
76          ; Supported bit instructions
77          %39 = OpBitwiseOr %2 %5 %6
78          %40 = OpBitwiseXor %2 %7 %8
79          %41 = OpBitwiseAnd %2 %9 %10
80          %42 = OpNot %2 %11
81 
82          ; Not yet supported bit instructions
83          %43 = OpShiftRightLogical %2 %12 %13
84          %44 = OpShiftRightArithmetic %2 %14 %15
85          %45 = OpShiftLeftLogical %2 %16 %17
86          %46 = OpBitReverse %2 %18
87          %47 = OpBitCount %2 %19
88                OpReturn
89                OpFunctionEnd
90   )";
91 
92   const auto env = SPV_ENV_UNIVERSAL_1_5;
93   const auto consumer = nullptr;
94   const auto context =
95       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
96   spvtools::ValidatorOptions validator_options;
97   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
98                                                kConsoleMessageConsumer));
99   TransformationContext transformation_context(
100       MakeUnique<FactManager>(context.get()), validator_options);
101 
102   // Tests undefined bit instruction.
103   auto transformation = TransformationAddBitInstructionSynonym(
104       48, {49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
105            62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
106            75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
107            88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100,
108            101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
109            114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
110            127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
111            140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
112            153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
113            166, 167, 168, 169, 170, 171, 172, 173, 174, 175});
114   ASSERT_FALSE(
115       transformation.IsApplicable(context.get(), transformation_context));
116 
117   // Tests false bit instruction.
118   transformation = TransformationAddBitInstructionSynonym(
119       38, {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
120            61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,
121            74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,
122            87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
123            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
124            113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
125            126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
126            139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
127            152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
128            165, 166, 167, 168, 169, 170, 171, 172, 173, 174});
129   ASSERT_FALSE(
130       transformation.IsApplicable(context.get(), transformation_context));
131 
132   // Tests the number of fresh ids being different than the necessary.
133   transformation = TransformationAddBitInstructionSynonym(
134       39,
135       {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
136        62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,
137        76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
138        90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103,
139        104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
140        118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
141        132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
142        146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
143        160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173});
144   ASSERT_FALSE(
145       transformation.IsApplicable(context.get(), transformation_context));
146 
147   // Tests non-fresh ids.
148   transformation = TransformationAddBitInstructionSynonym(
149       40, {47,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
150            61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,
151            74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,
152            87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
153            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
154            113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
155            126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
156            139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
157            152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
158            165, 166, 167, 168, 169, 170, 171, 172, 173, 174});
159   ASSERT_FALSE(
160       transformation.IsApplicable(context.get(), transformation_context));
161 
162   // Tests unsupported transformation.
163   transformation = TransformationAddBitInstructionSynonym(
164       43, {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
165            61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,
166            74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,
167            87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
168            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
169            113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
170            126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
171            139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
172            152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
173            165, 166, 167, 168, 169, 170, 171, 172, 173, 174});
174   ASSERT_FALSE(
175       transformation.IsApplicable(context.get(), transformation_context));
176 
177   // Tests supported transformation.
178   transformation = TransformationAddBitInstructionSynonym(
179       41, {48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,
180            61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,
181            74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,
182            87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
183            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
184            113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
185            126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
186            139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
187            152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
188            165, 166, 167, 168, 169, 170, 171, 172, 173, 174});
189   ASSERT_TRUE(
190       transformation.IsApplicable(context.get(), transformation_context));
191 }
192 
TEST(TransformationAddBitInstructionSynonymTest, AddOpBitwiseOrSynonym)193 TEST(TransformationAddBitInstructionSynonymTest, AddOpBitwiseOrSynonym) {
194   std::string reference_shader = R"(
195                OpCapability Shader
196           %1 = OpExtInstImport "GLSL.std.450"
197                OpMemoryModel Logical GLSL450
198                OpEntryPoint Vertex %37 "main"
199 
200 ; Types
201           %2 = OpTypeInt 32 0
202           %3 = OpTypeVoid
203           %4 = OpTypeFunction %3
204 
205 ; Constants
206           %5 = OpConstant %2 0
207           %6 = OpConstant %2 1
208           %7 = OpConstant %2 2
209           %8 = OpConstant %2 3
210           %9 = OpConstant %2 4
211          %10 = OpConstant %2 5
212          %11 = OpConstant %2 6
213          %12 = OpConstant %2 7
214          %13 = OpConstant %2 8
215          %14 = OpConstant %2 9
216          %15 = OpConstant %2 10
217          %16 = OpConstant %2 11
218          %17 = OpConstant %2 12
219          %18 = OpConstant %2 13
220          %19 = OpConstant %2 14
221          %20 = OpConstant %2 15
222          %21 = OpConstant %2 16
223          %22 = OpConstant %2 17
224          %23 = OpConstant %2 18
225          %24 = OpConstant %2 19
226          %25 = OpConstant %2 20
227          %26 = OpConstant %2 21
228          %27 = OpConstant %2 22
229          %28 = OpConstant %2 23
230          %29 = OpConstant %2 24
231          %30 = OpConstant %2 25
232          %31 = OpConstant %2 26
233          %32 = OpConstant %2 27
234          %33 = OpConstant %2 28
235          %34 = OpConstant %2 29
236          %35 = OpConstant %2 30
237          %36 = OpConstant %2 31
238 
239 ; main function
240          %37 = OpFunction %3 None %4
241          %38 = OpLabel
242          %39 = OpBitwiseOr %2 %5 %6 ; bit instruction
243                OpReturn
244                OpFunctionEnd
245   )";
246 
247   const auto env = SPV_ENV_UNIVERSAL_1_5;
248   const auto consumer = nullptr;
249   const auto context =
250       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
251   spvtools::ValidatorOptions validator_options;
252   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
253                                                kConsoleMessageConsumer));
254   TransformationContext transformation_context(
255       MakeUnique<FactManager>(context.get()), validator_options);
256 
257   // Adds OpBitwiseOr synonym.
258   auto transformation = TransformationAddBitInstructionSynonym(
259       39, {40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,
260            53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
261            66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
262            79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,
263            92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
264            105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
265            118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
266            131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
267            144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
268            157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
269   ASSERT_TRUE(
270       transformation.IsApplicable(context.get(), transformation_context));
271   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
272   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
273       MakeDataDescriptor(166, {}), MakeDataDescriptor(39, {})));
274 
275   std::string variant_shader = R"(
276                OpCapability Shader
277           %1 = OpExtInstImport "GLSL.std.450"
278                OpMemoryModel Logical GLSL450
279                OpEntryPoint Vertex %37 "main"
280 
281 ; Types
282           %2 = OpTypeInt 32 0
283           %3 = OpTypeVoid
284           %4 = OpTypeFunction %3
285 
286 ; Constants
287           %5 = OpConstant %2 0
288           %6 = OpConstant %2 1
289           %7 = OpConstant %2 2
290           %8 = OpConstant %2 3
291           %9 = OpConstant %2 4
292          %10 = OpConstant %2 5
293          %11 = OpConstant %2 6
294          %12 = OpConstant %2 7
295          %13 = OpConstant %2 8
296          %14 = OpConstant %2 9
297          %15 = OpConstant %2 10
298          %16 = OpConstant %2 11
299          %17 = OpConstant %2 12
300          %18 = OpConstant %2 13
301          %19 = OpConstant %2 14
302          %20 = OpConstant %2 15
303          %21 = OpConstant %2 16
304          %22 = OpConstant %2 17
305          %23 = OpConstant %2 18
306          %24 = OpConstant %2 19
307          %25 = OpConstant %2 20
308          %26 = OpConstant %2 21
309          %27 = OpConstant %2 22
310          %28 = OpConstant %2 23
311          %29 = OpConstant %2 24
312          %30 = OpConstant %2 25
313          %31 = OpConstant %2 26
314          %32 = OpConstant %2 27
315          %33 = OpConstant %2 28
316          %34 = OpConstant %2 29
317          %35 = OpConstant %2 30
318          %36 = OpConstant %2 31
319 
320 ; main function
321          %37 = OpFunction %3 None %4
322          %38 = OpLabel
323 
324 ; Add OpBitwiseOr synonym
325          %40 = OpBitFieldUExtract %2 %5 %5 %6 ; extracts bit 0 from %5
326          %41 = OpBitFieldUExtract %2 %6 %5 %6 ; extracts bit 0 from %6
327          %42 = OpBitwiseOr %2 %40 %41
328 
329          %43 = OpBitFieldUExtract %2 %5 %6 %6 ; extracts bit 1 from %5
330          %44 = OpBitFieldUExtract %2 %6 %6 %6 ; extracts bit 1 from %6
331          %45 = OpBitwiseOr %2 %43 %44
332 
333          %46 = OpBitFieldUExtract %2 %5 %7 %6 ; extracts bit 2 from %5
334          %47 = OpBitFieldUExtract %2 %6 %7 %6 ; extracts bit 2 from %6
335          %48 = OpBitwiseOr %2 %46 %47
336 
337          %49 = OpBitFieldUExtract %2 %5 %8 %6 ; extracts bit 3 from %5
338          %50 = OpBitFieldUExtract %2 %6 %8 %6 ; extracts bit 3 from %6
339          %51 = OpBitwiseOr %2 %49 %50
340 
341          %52 = OpBitFieldUExtract %2 %5 %9 %6 ; extracts bit 4 from %5
342          %53 = OpBitFieldUExtract %2 %6 %9 %6 ; extracts bit 4 from %6
343          %54 = OpBitwiseOr %2 %52 %53
344 
345          %55 = OpBitFieldUExtract %2 %5 %10 %6 ; extracts bit 5 from %5
346          %56 = OpBitFieldUExtract %2 %6 %10 %6 ; extracts bit 5 from %6
347          %57 = OpBitwiseOr %2 %55 %56
348 
349          %58 = OpBitFieldUExtract %2 %5 %11 %6 ; extracts bit 6 from %5
350          %59 = OpBitFieldUExtract %2 %6 %11 %6 ; extracts bit 6 from %6
351          %60 = OpBitwiseOr %2 %58 %59
352 
353          %61 = OpBitFieldUExtract %2 %5 %12 %6 ; extracts bit 7 from %5
354          %62 = OpBitFieldUExtract %2 %6 %12 %6 ; extracts bit 7 from %6
355          %63 = OpBitwiseOr %2 %61 %62
356 
357          %64 = OpBitFieldUExtract %2 %5 %13 %6 ; extracts bit 8 from %5
358          %65 = OpBitFieldUExtract %2 %6 %13 %6 ; extracts bit 8 from %6
359          %66 = OpBitwiseOr %2 %64 %65
360 
361          %67 = OpBitFieldUExtract %2 %5 %14 %6 ; extracts bit 9 from %5
362          %68 = OpBitFieldUExtract %2 %6 %14 %6 ; extracts bit 9 from %6
363          %69 = OpBitwiseOr %2 %67 %68
364 
365          %70 = OpBitFieldUExtract %2 %5 %15 %6 ; extracts bit 10 from %5
366          %71 = OpBitFieldUExtract %2 %6 %15 %6 ; extracts bit 10 from %6
367          %72 = OpBitwiseOr %2 %70 %71
368 
369          %73 = OpBitFieldUExtract %2 %5 %16 %6 ; extracts bit 11 from %5
370          %74 = OpBitFieldUExtract %2 %6 %16 %6 ; extracts bit 11 from %6
371          %75 = OpBitwiseOr %2 %73 %74
372 
373          %76 = OpBitFieldUExtract %2 %5 %17 %6 ; extracts bit 12 from %5
374          %77 = OpBitFieldUExtract %2 %6 %17 %6 ; extracts bit 12 from %6
375          %78 = OpBitwiseOr %2 %76 %77
376 
377          %79 = OpBitFieldUExtract %2 %5 %18 %6 ; extracts bit 13 from %5
378          %80 = OpBitFieldUExtract %2 %6 %18 %6 ; extracts bit 13 from %6
379          %81 = OpBitwiseOr %2 %79 %80
380 
381          %82 = OpBitFieldUExtract %2 %5 %19 %6 ; extracts bit 14 from %5
382          %83 = OpBitFieldUExtract %2 %6 %19 %6 ; extracts bit 14 from %6
383          %84 = OpBitwiseOr %2 %82 %83
384 
385          %85 = OpBitFieldUExtract %2 %5 %20 %6 ; extracts bit 15 from %5
386          %86 = OpBitFieldUExtract %2 %6 %20 %6 ; extracts bit 15 from %6
387          %87 = OpBitwiseOr %2 %85 %86
388 
389          %88 = OpBitFieldUExtract %2 %5 %21 %6 ; extracts bit 16 from %5
390          %89 = OpBitFieldUExtract %2 %6 %21 %6 ; extracts bit 16 from %6
391          %90 = OpBitwiseOr %2 %88 %89
392 
393          %91 = OpBitFieldUExtract %2 %5 %22 %6 ; extracts bit 17 from %5
394          %92 = OpBitFieldUExtract %2 %6 %22 %6 ; extracts bit 17 from %6
395          %93 = OpBitwiseOr %2 %91 %92
396 
397          %94 = OpBitFieldUExtract %2 %5 %23 %6 ; extracts bit 18 from %5
398          %95 = OpBitFieldUExtract %2 %6 %23 %6 ; extracts bit 18 from %6
399          %96 = OpBitwiseOr %2 %94 %95
400 
401          %97 = OpBitFieldUExtract %2 %5 %24 %6 ; extracts bit 19 from %5
402          %98 = OpBitFieldUExtract %2 %6 %24 %6 ; extracts bit 19 from %6
403          %99 = OpBitwiseOr %2 %97 %98
404 
405         %100 = OpBitFieldUExtract %2 %5 %25 %6 ; extracts bit 20 from %5
406         %101 = OpBitFieldUExtract %2 %6 %25 %6 ; extracts bit 20 from %6
407         %102 = OpBitwiseOr %2 %100 %101
408 
409         %103 = OpBitFieldUExtract %2 %5 %26 %6 ; extracts bit 21 from %5
410         %104 = OpBitFieldUExtract %2 %6 %26 %6 ; extracts bit 21 from %6
411         %105 = OpBitwiseOr %2 %103 %104
412 
413         %106 = OpBitFieldUExtract %2 %5 %27 %6 ; extracts bit 22 from %5
414         %107 = OpBitFieldUExtract %2 %6 %27 %6 ; extracts bit 22 from %6
415         %108 = OpBitwiseOr %2 %106 %107
416 
417         %109 = OpBitFieldUExtract %2 %5 %28 %6 ; extracts bit 23 from %5
418         %110 = OpBitFieldUExtract %2 %6 %28 %6 ; extracts bit 23 from %6
419         %111 = OpBitwiseOr %2 %109 %110
420 
421         %112 = OpBitFieldUExtract %2 %5 %29 %6 ; extracts bit 24 from %5
422         %113 = OpBitFieldUExtract %2 %6 %29 %6 ; extracts bit 24 from %6
423         %114 = OpBitwiseOr %2 %112 %113
424 
425         %115 = OpBitFieldUExtract %2 %5 %30 %6 ; extracts bit 25 from %5
426         %116 = OpBitFieldUExtract %2 %6 %30 %6 ; extracts bit 25 from %6
427         %117 = OpBitwiseOr %2 %115 %116
428 
429         %118 = OpBitFieldUExtract %2 %5 %31 %6 ; extracts bit 26 from %5
430         %119 = OpBitFieldUExtract %2 %6 %31 %6 ; extracts bit 26 from %6
431         %120 = OpBitwiseOr %2 %118 %119
432 
433         %121 = OpBitFieldUExtract %2 %5 %32 %6 ; extracts bit 27 from %5
434         %122 = OpBitFieldUExtract %2 %6 %32 %6 ; extracts bit 27 from %6
435         %123 = OpBitwiseOr %2 %121 %122
436 
437         %124 = OpBitFieldUExtract %2 %5 %33 %6 ; extracts bit 28 from %5
438         %125 = OpBitFieldUExtract %2 %6 %33 %6 ; extracts bit 28 from %6
439         %126 = OpBitwiseOr %2 %124 %125
440 
441         %127 = OpBitFieldUExtract %2 %5 %34 %6 ; extracts bit 29 from %5
442         %128 = OpBitFieldUExtract %2 %6 %34 %6 ; extracts bit 29 from %6
443         %129 = OpBitwiseOr %2 %127 %128
444 
445         %130 = OpBitFieldUExtract %2 %5 %35 %6 ; extracts bit 30 from %5
446         %131 = OpBitFieldUExtract %2 %6 %35 %6 ; extracts bit 30 from %6
447         %132 = OpBitwiseOr %2 %130 %131
448 
449         %133 = OpBitFieldUExtract %2 %5 %36 %6 ; extracts bit 31 from %5
450         %134 = OpBitFieldUExtract %2 %6 %36 %6 ; extracts bit 31 from %6
451         %135 = OpBitwiseOr %2 %133 %134
452 
453         %136 = OpBitFieldInsert %2 %42 %45 %6 %6 ; inserts bit 1
454         %137 = OpBitFieldInsert %2 %136 %48 %7 %6 ; inserts bit 2
455         %138 = OpBitFieldInsert %2 %137 %51 %8 %6 ; inserts bit 3
456         %139 = OpBitFieldInsert %2 %138 %54 %9 %6 ; inserts bit 4
457         %140 = OpBitFieldInsert %2 %139 %57 %10 %6 ; inserts bit 5
458         %141 = OpBitFieldInsert %2 %140 %60 %11 %6 ; inserts bit 6
459         %142 = OpBitFieldInsert %2 %141 %63 %12 %6 ; inserts bit 7
460         %143 = OpBitFieldInsert %2 %142 %66 %13 %6 ; inserts bit 8
461         %144 = OpBitFieldInsert %2 %143 %69 %14 %6 ; inserts bit 9
462         %145 = OpBitFieldInsert %2 %144 %72 %15 %6 ; inserts bit 10
463         %146 = OpBitFieldInsert %2 %145 %75 %16 %6 ; inserts bit 11
464         %147 = OpBitFieldInsert %2 %146 %78 %17 %6 ; inserts bit 12
465         %148 = OpBitFieldInsert %2 %147 %81 %18 %6 ; inserts bit 13
466         %149 = OpBitFieldInsert %2 %148 %84 %19 %6 ; inserts bit 14
467         %150 = OpBitFieldInsert %2 %149 %87 %20 %6 ; inserts bit 15
468         %151 = OpBitFieldInsert %2 %150 %90 %21 %6 ; inserts bit 16
469         %152 = OpBitFieldInsert %2 %151 %93 %22 %6 ; inserts bit 17
470         %153 = OpBitFieldInsert %2 %152 %96 %23 %6 ; inserts bit 18
471         %154 = OpBitFieldInsert %2 %153 %99 %24 %6 ; inserts bit 19
472         %155 = OpBitFieldInsert %2 %154 %102 %25 %6 ; inserts bit 20
473         %156 = OpBitFieldInsert %2 %155 %105 %26 %6 ; inserts bit 21
474         %157 = OpBitFieldInsert %2 %156 %108 %27 %6 ; inserts bit 22
475         %158 = OpBitFieldInsert %2 %157 %111 %28 %6 ; inserts bit 23
476         %159 = OpBitFieldInsert %2 %158 %114 %29 %6 ; inserts bit 24
477         %160 = OpBitFieldInsert %2 %159 %117 %30 %6 ; inserts bit 25
478         %161 = OpBitFieldInsert %2 %160 %120 %31 %6 ; inserts bit 26
479         %162 = OpBitFieldInsert %2 %161 %123 %32 %6 ; inserts bit 27
480         %163 = OpBitFieldInsert %2 %162 %126 %33 %6 ; inserts bit 28
481         %164 = OpBitFieldInsert %2 %163 %129 %34 %6 ; inserts bit 29
482         %165 = OpBitFieldInsert %2 %164 %132 %35 %6 ; inserts bit 30
483         %166 = OpBitFieldInsert %2 %165 %135 %36 %6 ; inserts bit 31
484          %39 = OpBitwiseOr %2 %5 %6
485                OpReturn
486                OpFunctionEnd
487   )";
488 
489   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
490                                                kConsoleMessageConsumer));
491   ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
492 }
493 
TEST(TransformationAddBitInstructionSynonymTest, AddOpNotSynonym)494 TEST(TransformationAddBitInstructionSynonymTest, AddOpNotSynonym) {
495   std::string reference_shader = R"(
496                OpCapability Shader
497           %1 = OpExtInstImport "GLSL.std.450"
498                OpMemoryModel Logical GLSL450
499                OpEntryPoint Vertex %37 "main"
500 
501 ; Types
502           %2 = OpTypeInt 32 0
503           %3 = OpTypeVoid
504           %4 = OpTypeFunction %3
505 
506 ; Constants
507           %5 = OpConstant %2 0
508           %6 = OpConstant %2 1
509           %7 = OpConstant %2 2
510           %8 = OpConstant %2 3
511           %9 = OpConstant %2 4
512          %10 = OpConstant %2 5
513          %11 = OpConstant %2 6
514          %12 = OpConstant %2 7
515          %13 = OpConstant %2 8
516          %14 = OpConstant %2 9
517          %15 = OpConstant %2 10
518          %16 = OpConstant %2 11
519          %17 = OpConstant %2 12
520          %18 = OpConstant %2 13
521          %19 = OpConstant %2 14
522          %20 = OpConstant %2 15
523          %21 = OpConstant %2 16
524          %22 = OpConstant %2 17
525          %23 = OpConstant %2 18
526          %24 = OpConstant %2 19
527          %25 = OpConstant %2 20
528          %26 = OpConstant %2 21
529          %27 = OpConstant %2 22
530          %28 = OpConstant %2 23
531          %29 = OpConstant %2 24
532          %30 = OpConstant %2 25
533          %31 = OpConstant %2 26
534          %32 = OpConstant %2 27
535          %33 = OpConstant %2 28
536          %34 = OpConstant %2 29
537          %35 = OpConstant %2 30
538          %36 = OpConstant %2 31
539 
540 ; main function
541          %37 = OpFunction %3 None %4
542          %38 = OpLabel
543          %39 = OpNot %2 %5 ; bit instruction
544                OpReturn
545                OpFunctionEnd
546   )";
547 
548   const auto env = SPV_ENV_UNIVERSAL_1_5;
549   const auto consumer = nullptr;
550   const auto context =
551       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
552   spvtools::ValidatorOptions validator_options;
553   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
554                                                kConsoleMessageConsumer));
555   TransformationContext transformation_context(
556       MakeUnique<FactManager>(context.get()), validator_options);
557 
558   // Adds OpNot synonym.
559   auto transformation = TransformationAddBitInstructionSynonym(
560       39, {40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,
561            54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
562            68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,
563            82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
564            96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
565            110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
566            124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134});
567   ASSERT_TRUE(
568       transformation.IsApplicable(context.get(), transformation_context));
569   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
570   ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
571       MakeDataDescriptor(134, {}), MakeDataDescriptor(39, {})));
572 
573   std::string variant_shader = R"(
574                OpCapability Shader
575           %1 = OpExtInstImport "GLSL.std.450"
576                OpMemoryModel Logical GLSL450
577                OpEntryPoint Vertex %37 "main"
578 
579 ; Types
580           %2 = OpTypeInt 32 0
581           %3 = OpTypeVoid
582           %4 = OpTypeFunction %3
583 
584 ; Constants
585           %5 = OpConstant %2 0
586           %6 = OpConstant %2 1
587           %7 = OpConstant %2 2
588           %8 = OpConstant %2 3
589           %9 = OpConstant %2 4
590          %10 = OpConstant %2 5
591          %11 = OpConstant %2 6
592          %12 = OpConstant %2 7
593          %13 = OpConstant %2 8
594          %14 = OpConstant %2 9
595          %15 = OpConstant %2 10
596          %16 = OpConstant %2 11
597          %17 = OpConstant %2 12
598          %18 = OpConstant %2 13
599          %19 = OpConstant %2 14
600          %20 = OpConstant %2 15
601          %21 = OpConstant %2 16
602          %22 = OpConstant %2 17
603          %23 = OpConstant %2 18
604          %24 = OpConstant %2 19
605          %25 = OpConstant %2 20
606          %26 = OpConstant %2 21
607          %27 = OpConstant %2 22
608          %28 = OpConstant %2 23
609          %29 = OpConstant %2 24
610          %30 = OpConstant %2 25
611          %31 = OpConstant %2 26
612          %32 = OpConstant %2 27
613          %33 = OpConstant %2 28
614          %34 = OpConstant %2 29
615          %35 = OpConstant %2 30
616          %36 = OpConstant %2 31
617 
618 ; main function
619          %37 = OpFunction %3 None %4
620          %38 = OpLabel
621 
622 ; Add OpNot synonym
623          %40 = OpBitFieldUExtract %2 %5 %5 %6 ; extracts bit 0 from %5
624          %41 = OpNot %2 %40
625 
626          %42 = OpBitFieldUExtract %2 %5 %6 %6 ; extracts bit 1 from %5
627          %43 = OpNot %2 %42
628 
629          %44 = OpBitFieldUExtract %2 %5 %7 %6 ; extracts bit 2 from %5
630          %45 = OpNot %2 %44
631 
632          %46 = OpBitFieldUExtract %2 %5 %8 %6 ; extracts bit 3 from %5
633          %47 = OpNot %2 %46
634 
635          %48 = OpBitFieldUExtract %2 %5 %9 %6 ; extracts bit 4 from %5
636          %49 = OpNot %2 %48
637 
638          %50 = OpBitFieldUExtract %2 %5 %10 %6 ; extracts bit 5 from %5
639          %51 = OpNot %2 %50
640 
641          %52 = OpBitFieldUExtract %2 %5 %11 %6 ; extracts bit 6 from %5
642          %53 = OpNot %2 %52
643 
644          %54 = OpBitFieldUExtract %2 %5 %12 %6 ; extracts bit 7 from %5
645          %55 = OpNot %2 %54
646 
647          %56 = OpBitFieldUExtract %2 %5 %13 %6 ; extracts bit 8 from %5
648          %57 = OpNot %2 %56
649 
650          %58 = OpBitFieldUExtract %2 %5 %14 %6 ; extracts bit 9 from %5
651          %59 = OpNot %2 %58
652 
653          %60 = OpBitFieldUExtract %2 %5 %15 %6 ; extracts bit 10 from %5
654          %61 = OpNot %2 %60
655 
656          %62 = OpBitFieldUExtract %2 %5 %16 %6 ; extracts bit 11 from %5
657          %63 = OpNot %2 %62
658 
659          %64 = OpBitFieldUExtract %2 %5 %17 %6 ; extracts bit 12 from %5
660          %65 = OpNot %2 %64
661 
662          %66 = OpBitFieldUExtract %2 %5 %18 %6 ; extracts bit 13 from %5
663          %67 = OpNot %2 %66
664 
665          %68 = OpBitFieldUExtract %2 %5 %19 %6 ; extracts bit 14 from %5
666          %69 = OpNot %2 %68
667 
668          %70 = OpBitFieldUExtract %2 %5 %20 %6 ; extracts bit 15 from %5
669          %71 = OpNot %2 %70
670 
671          %72 = OpBitFieldUExtract %2 %5 %21 %6 ; extracts bit 16 from %5
672          %73 = OpNot %2 %72
673 
674          %74 = OpBitFieldUExtract %2 %5 %22 %6 ; extracts bit 17 from %5
675          %75 = OpNot %2 %74
676 
677          %76 = OpBitFieldUExtract %2 %5 %23 %6 ; extracts bit 18 from %5
678          %77 = OpNot %2 %76
679 
680          %78 = OpBitFieldUExtract %2 %5 %24 %6 ; extracts bit 19 from %5
681          %79 = OpNot %2 %78
682 
683          %80 = OpBitFieldUExtract %2 %5 %25 %6 ; extracts bit 20 from %5
684          %81 = OpNot %2 %80
685 
686          %82 = OpBitFieldUExtract %2 %5 %26 %6 ; extracts bit 21 from %5
687          %83 = OpNot %2 %82
688 
689          %84 = OpBitFieldUExtract %2 %5 %27 %6 ; extracts bit 22 from %5
690          %85 = OpNot %2 %84
691 
692          %86 = OpBitFieldUExtract %2 %5 %28 %6 ; extracts bit 23 from %5
693          %87 = OpNot %2 %86
694 
695          %88 = OpBitFieldUExtract %2 %5 %29 %6 ; extracts bit 24 from %5
696          %89 = OpNot %2 %88
697 
698          %90 = OpBitFieldUExtract %2 %5 %30 %6 ; extracts bit 25 from %5
699          %91 = OpNot %2 %90
700 
701          %92 = OpBitFieldUExtract %2 %5 %31 %6 ; extracts bit 26 from %5
702          %93 = OpNot %2 %92
703 
704          %94 = OpBitFieldUExtract %2 %5 %32 %6 ; extracts bit 27 from %5
705          %95 = OpNot %2 %94
706 
707          %96 = OpBitFieldUExtract %2 %5 %33 %6 ; extracts bit 28 from %5
708          %97 = OpNot %2 %96
709 
710          %98 = OpBitFieldUExtract %2 %5 %34 %6 ; extracts bit 29 from %5
711          %99 = OpNot %2 %98
712 
713         %100 = OpBitFieldUExtract %2 %5 %35 %6 ; extracts bit 30 from %5
714         %101 = OpNot %2 %100
715 
716         %102 = OpBitFieldUExtract %2 %5 %36 %6 ; extracts bit 31 from %5
717         %103 = OpNot %2 %102
718 
719         %104 = OpBitFieldInsert %2 %41 %43 %6 %6 ; inserts bit 1
720         %105 = OpBitFieldInsert %2 %104 %45 %7 %6 ; inserts bit 2
721         %106 = OpBitFieldInsert %2 %105 %47 %8 %6 ; inserts bit 3
722         %107 = OpBitFieldInsert %2 %106 %49 %9 %6 ; inserts bit 4
723         %108 = OpBitFieldInsert %2 %107 %51 %10 %6 ; inserts bit 5
724         %109 = OpBitFieldInsert %2 %108 %53 %11 %6 ; inserts bit 6
725         %110 = OpBitFieldInsert %2 %109 %55 %12 %6 ; inserts bit 7
726         %111 = OpBitFieldInsert %2 %110 %57 %13 %6 ; inserts bit 8
727         %112 = OpBitFieldInsert %2 %111 %59 %14 %6 ; inserts bit 9
728         %113 = OpBitFieldInsert %2 %112 %61 %15 %6 ; inserts bit 10
729         %114 = OpBitFieldInsert %2 %113 %63 %16 %6 ; inserts bit 11
730         %115 = OpBitFieldInsert %2 %114 %65 %17 %6 ; inserts bit 12
731         %116 = OpBitFieldInsert %2 %115 %67 %18 %6 ; inserts bit 13
732         %117 = OpBitFieldInsert %2 %116 %69 %19 %6 ; inserts bit 14
733         %118 = OpBitFieldInsert %2 %117 %71 %20 %6 ; inserts bit 15
734         %119 = OpBitFieldInsert %2 %118 %73 %21 %6 ; inserts bit 16
735         %120 = OpBitFieldInsert %2 %119 %75 %22 %6 ; inserts bit 17
736         %121 = OpBitFieldInsert %2 %120 %77 %23 %6 ; inserts bit 18
737         %122 = OpBitFieldInsert %2 %121 %79 %24 %6 ; inserts bit 19
738         %123 = OpBitFieldInsert %2 %122 %81 %25 %6 ; inserts bit 20
739         %124 = OpBitFieldInsert %2 %123 %83 %26 %6 ; inserts bit 21
740         %125 = OpBitFieldInsert %2 %124 %85 %27 %6 ; inserts bit 22
741         %126 = OpBitFieldInsert %2 %125 %87 %28 %6 ; inserts bit 23
742         %127 = OpBitFieldInsert %2 %126 %89 %29 %6 ; inserts bit 24
743         %128 = OpBitFieldInsert %2 %127 %91 %30 %6 ; inserts bit 25
744         %129 = OpBitFieldInsert %2 %128 %93 %31 %6 ; inserts bit 26
745         %130 = OpBitFieldInsert %2 %129 %95 %32 %6 ; inserts bit 27
746         %131 = OpBitFieldInsert %2 %130 %97 %33 %6 ; inserts bit 28
747         %132 = OpBitFieldInsert %2 %131 %99 %34 %6 ; inserts bit 29
748         %133 = OpBitFieldInsert %2 %132 %101 %35 %6 ; inserts bit 30
749         %134 = OpBitFieldInsert %2 %133 %103 %36 %6 ; inserts bit 31
750          %39 = OpNot %2 %5
751                OpReturn
752                OpFunctionEnd
753   )";
754 
755   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
756                                                kConsoleMessageConsumer));
757   ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
758 }
759 
TEST(TransformationAddBitInstructionSynonymTest, NoSynonymWhenIdIsIrrelevant)760 TEST(TransformationAddBitInstructionSynonymTest, NoSynonymWhenIdIsIrrelevant) {
761   std::string reference_shader = R"(
762                OpCapability Shader
763           %1 = OpExtInstImport "GLSL.std.450"
764                OpMemoryModel Logical GLSL450
765                OpEntryPoint Vertex %37 "main"
766 
767 ; Types
768           %2 = OpTypeInt 32 0
769           %3 = OpTypeVoid
770           %4 = OpTypeFunction %3
771 
772 ; Constants
773           %5 = OpConstant %2 0
774           %6 = OpConstant %2 1
775           %7 = OpConstant %2 2
776           %8 = OpConstant %2 3
777           %9 = OpConstant %2 4
778          %10 = OpConstant %2 5
779          %11 = OpConstant %2 6
780          %12 = OpConstant %2 7
781          %13 = OpConstant %2 8
782          %14 = OpConstant %2 9
783          %15 = OpConstant %2 10
784          %16 = OpConstant %2 11
785          %17 = OpConstant %2 12
786          %18 = OpConstant %2 13
787          %19 = OpConstant %2 14
788          %20 = OpConstant %2 15
789          %21 = OpConstant %2 16
790          %22 = OpConstant %2 17
791          %23 = OpConstant %2 18
792          %24 = OpConstant %2 19
793          %25 = OpConstant %2 20
794          %26 = OpConstant %2 21
795          %27 = OpConstant %2 22
796          %28 = OpConstant %2 23
797          %29 = OpConstant %2 24
798          %30 = OpConstant %2 25
799          %31 = OpConstant %2 26
800          %32 = OpConstant %2 27
801          %33 = OpConstant %2 28
802          %34 = OpConstant %2 29
803          %35 = OpConstant %2 30
804          %36 = OpConstant %2 31
805 
806 ; main function
807          %37 = OpFunction %3 None %4
808          %38 = OpLabel
809          %39 = OpBitwiseOr %2 %5 %6 ; bit instruction
810                OpReturn
811                OpFunctionEnd
812   )";
813 
814   const auto env = SPV_ENV_UNIVERSAL_1_5;
815   const auto consumer = nullptr;
816   const auto context =
817       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
818   spvtools::ValidatorOptions validator_options;
819   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
820                                                kConsoleMessageConsumer));
821   TransformationContext transformation_context(
822       MakeUnique<FactManager>(context.get()), validator_options);
823 
824   // Mark the result id of the bit instruction as irrelevant.
825   transformation_context.GetFactManager()->AddFactIdIsIrrelevant(39);
826 
827   // Adds OpBitwiseOr synonym.
828   auto transformation = TransformationAddBitInstructionSynonym(
829       39, {40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,
830            53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
831            66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
832            79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,
833            92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
834            105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
835            118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
836            131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
837            144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
838            157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
839   ASSERT_TRUE(
840       transformation.IsApplicable(context.get(), transformation_context));
841   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
842   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
843                                                kConsoleMessageConsumer));
844   // No synonym should have been created, since the bit instruction is
845   // irrelevant.
846   ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous(
847       MakeDataDescriptor(166, {}), MakeDataDescriptor(39, {})));
848 }
849 
TEST(TransformationAddBitInstructionSynonymTest, NoSynonymWhenBlockIsDead)850 TEST(TransformationAddBitInstructionSynonymTest, NoSynonymWhenBlockIsDead) {
851   std::string reference_shader = R"(
852                OpCapability Shader
853           %1 = OpExtInstImport "GLSL.std.450"
854                OpMemoryModel Logical GLSL450
855                OpEntryPoint Vertex %37 "main"
856 
857 ; Types
858           %2 = OpTypeInt 32 0
859           %3 = OpTypeVoid
860           %4 = OpTypeFunction %3
861 
862 ; Constants
863           %5 = OpConstant %2 0
864           %6 = OpConstant %2 1
865           %7 = OpConstant %2 2
866           %8 = OpConstant %2 3
867           %9 = OpConstant %2 4
868          %10 = OpConstant %2 5
869          %11 = OpConstant %2 6
870          %12 = OpConstant %2 7
871          %13 = OpConstant %2 8
872          %14 = OpConstant %2 9
873          %15 = OpConstant %2 10
874          %16 = OpConstant %2 11
875          %17 = OpConstant %2 12
876          %18 = OpConstant %2 13
877          %19 = OpConstant %2 14
878          %20 = OpConstant %2 15
879          %21 = OpConstant %2 16
880          %22 = OpConstant %2 17
881          %23 = OpConstant %2 18
882          %24 = OpConstant %2 19
883          %25 = OpConstant %2 20
884          %26 = OpConstant %2 21
885          %27 = OpConstant %2 22
886          %28 = OpConstant %2 23
887          %29 = OpConstant %2 24
888          %30 = OpConstant %2 25
889          %31 = OpConstant %2 26
890          %32 = OpConstant %2 27
891          %33 = OpConstant %2 28
892          %34 = OpConstant %2 29
893          %35 = OpConstant %2 30
894          %36 = OpConstant %2 31
895 
896 ; main function
897          %37 = OpFunction %3 None %4
898          %38 = OpLabel
899          %39 = OpBitwiseOr %2 %5 %6 ; bit instruction
900                OpReturn
901                OpFunctionEnd
902   )";
903 
904   const auto env = SPV_ENV_UNIVERSAL_1_5;
905   const auto consumer = nullptr;
906   const auto context =
907       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
908   spvtools::ValidatorOptions validator_options;
909   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
910                                                kConsoleMessageConsumer));
911   TransformationContext transformation_context(
912       MakeUnique<FactManager>(context.get()), validator_options);
913 
914   // Mark the block where we will try to create the synonym as dead.
915   transformation_context.GetFactManager()->AddFactBlockIsDead(38);
916 
917   // Adds OpBitwiseOr synonym.
918   auto transformation = TransformationAddBitInstructionSynonym(
919       39, {40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,
920            53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
921            66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
922            79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,
923            92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
924            105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
925            118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
926            131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
927            144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
928            157, 158, 159, 160, 161, 162, 163, 164, 165, 166});
929   ASSERT_TRUE(
930       transformation.IsApplicable(context.get(), transformation_context));
931   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
932   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
933                                                kConsoleMessageConsumer));
934   // No synonym should have been created, since the bit instruction is
935   // irrelevant.
936   ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous(
937       MakeDataDescriptor(166, {}), MakeDataDescriptor(39, {})));
938 }
939 
TEST(TransformationAddBitInstructionSynonymTest, DifferentSingedness)940 TEST(TransformationAddBitInstructionSynonymTest, DifferentSingedness) {
941   std::string reference_shader = R"(
942                OpCapability Shader
943           %1 = OpExtInstImport "GLSL.std.450"
944                OpMemoryModel Logical GLSL450
945                OpEntryPoint Vertex %37 "main"
946 
947 ; Types
948           %2 = OpTypeInt 32 0
949         %200 = OpTypeInt 32 1
950           %3 = OpTypeVoid
951           %4 = OpTypeFunction %3
952 
953 ; Constants
954           %5 = OpConstant %2 0
955           %6 = OpConstant %2 1
956           %7 = OpConstant %2 2
957           %8 = OpConstant %2 3
958           %9 = OpConstant %2 4
959          %10 = OpConstant %2 5
960          %11 = OpConstant %2 6
961          %12 = OpConstant %2 7
962          %13 = OpConstant %2 8
963          %14 = OpConstant %2 9
964          %15 = OpConstant %2 10
965          %16 = OpConstant %2 11
966          %17 = OpConstant %2 12
967          %18 = OpConstant %2 13
968          %19 = OpConstant %2 14
969          %20 = OpConstant %2 15
970          %21 = OpConstant %2 16
971          %22 = OpConstant %2 17
972          %23 = OpConstant %2 18
973          %24 = OpConstant %2 19
974          %25 = OpConstant %2 20
975          %26 = OpConstant %2 21
976          %27 = OpConstant %2 22
977          %28 = OpConstant %2 23
978          %29 = OpConstant %2 24
979          %30 = OpConstant %2 25
980          %31 = OpConstant %2 26
981          %32 = OpConstant %2 27
982          %33 = OpConstant %2 28
983          %34 = OpConstant %2 29
984          %35 = OpConstant %2 30
985          %36 = OpConstant %2 31
986          %45 = OpConstant %200 32
987 
988 ; main function
989          %37 = OpFunction %3 None %4
990          %38 = OpLabel
991          %39 = OpNot %200 %5 ; bit instruction
992          %40 = OpBitwiseOr %200 %6 %45  ; bit instruction
993          %41 = OpBitwiseAnd %2 %5 %6 ; bit instruction
994                OpReturn
995                OpFunctionEnd
996   )";
997 
998   const auto env = SPV_ENV_UNIVERSAL_1_5;
999   const auto consumer = nullptr;
1000   const auto context =
1001       BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
1002   spvtools::ValidatorOptions validator_options;
1003   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1004                                                kConsoleMessageConsumer));
1005   TransformationContext transformation_context(
1006       MakeUnique<FactManager>(context.get()), validator_options);
1007 
1008   // Invalid because the sign of id 200 result is not equal to the sign of id 5
1009   // operand in OpNot.
1010   auto transformation = TransformationAddBitInstructionSynonym(
1011       39, {300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312,
1012            313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325,
1013            326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
1014            339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351,
1015            352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
1016            365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377,
1017            378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390,
1018            391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
1019            404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416,
1020            417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427});
1021   ASSERT_FALSE(
1022       transformation.IsApplicable(context.get(), transformation_context));
1023 
1024   // Invalid because the sign of two operands not the same and the first operand
1025   // sign not equal the result sign in OpBitwiseOr.
1026   transformation = TransformationAddBitInstructionSynonym(
1027       40, {300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312,
1028            313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325,
1029            326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
1030            339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351,
1031            352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
1032            365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377,
1033            378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390,
1034            391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
1035            404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416,
1036            417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427});
1037   ASSERT_FALSE(
1038       transformation.IsApplicable(context.get(), transformation_context));
1039 
1040   // Successful transformation
1041   {
1042     // Instruction operands are the same and it's equal with the result sign in
1043     // OpBitwiseAnd bitwise operation.
1044     transformation = TransformationAddBitInstructionSynonym(
1045         41, {46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
1046              59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,
1047              72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
1048              85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
1049              98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
1050              111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
1051              124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
1052              137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
1053              150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
1054              163, 164, 165, 166, 167, 168, 169, 170, 171, 172});
1055     ASSERT_TRUE(
1056         transformation.IsApplicable(context.get(), transformation_context));
1057 
1058     ApplyAndCheckFreshIds(transformation, context.get(),
1059                           &transformation_context);
1060     ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
1061         context.get(), validator_options, kConsoleMessageConsumer));
1062   }
1063 }
1064 
1065 }  // namespace
1066 }  // namespace fuzz
1067 }  // namespace spvtools
1068