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