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_replace_linear_algebra_instruction.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(TransformationReplaceLinearAlgebraInstructionTest,IsApplicable)26 TEST(TransformationReplaceLinearAlgebraInstructionTest, IsApplicable) {
27 std::string shader = R"(
28 OpCapability Shader
29 %1 = OpExtInstImport "GLSL.std.450"
30 OpMemoryModel Logical GLSL450
31 OpEntryPoint Fragment %22 "main"
32 OpExecutionMode %22 OriginUpperLeft
33 OpSource ESSL 310
34 OpName %22 "main"
35 %2 = OpTypeVoid
36 %3 = OpTypeFunction %2
37 %4 = OpTypeFloat 32
38 %5 = OpTypeVector %4 2
39 %6 = OpTypeVector %4 3
40 %7 = OpTypeVector %4 4
41 %8 = OpConstant %4 1
42 %9 = OpConstant %4 2
43 %10 = OpConstant %4 3
44 %11 = OpConstant %4 4
45 %12 = OpConstant %4 5
46 %13 = OpConstant %4 6
47 %14 = OpConstant %4 7
48 %15 = OpConstant %4 8
49 %16 = OpConstantComposite %5 %8 %9
50 %17 = OpConstantComposite %5 %10 %11
51 %18 = OpConstantComposite %6 %8 %9 %10
52 %19 = OpConstantComposite %6 %11 %12 %13
53 %20 = OpConstantComposite %7 %8 %9 %10 %11
54 %21 = OpConstantComposite %7 %12 %13 %14 %15
55 %22 = OpFunction %2 None %3
56 %23 = OpLabel
57 %24 = OpDot %4 %16 %17
58 %25 = OpDot %4 %18 %19
59 %26 = OpDot %4 %20 %21
60 %27 = OpVectorTimesScalar %5 %16 %8
61 %28 = OpVectorTimesScalar %6 %18 %9
62 %29 = OpVectorTimesScalar %7 %20 %10
63 %30 = OpCopyObject %4 %24
64 %31 = OpFAdd %4 %8 %9
65 %32 = OpFMul %4 %10 %11
66 OpReturn
67 OpFunctionEnd
68 )";
69
70 const auto env = SPV_ENV_UNIVERSAL_1_5;
71 const auto consumer = nullptr;
72 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
73 spvtools::ValidatorOptions validator_options;
74 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
75 kConsoleMessageConsumer));
76 TransformationContext transformation_context(
77 MakeUnique<FactManager>(context.get()), validator_options);
78 // Tests linear algebra instructions.
79 auto instruction_descriptor = MakeInstructionDescriptor(24, SpvOpDot, 0);
80 auto transformation = TransformationReplaceLinearAlgebraInstruction(
81 {33, 34, 35, 36, 37, 38}, instruction_descriptor);
82 ASSERT_TRUE(
83 transformation.IsApplicable(context.get(), transformation_context));
84
85 instruction_descriptor =
86 MakeInstructionDescriptor(27, SpvOpVectorTimesScalar, 0);
87 transformation = TransformationReplaceLinearAlgebraInstruction(
88 {33, 34, 35, 36}, instruction_descriptor);
89 ASSERT_TRUE(
90 transformation.IsApplicable(context.get(), transformation_context));
91
92 // Tests non-linear algebra instructions.
93 instruction_descriptor = MakeInstructionDescriptor(30, SpvOpCopyObject, 0);
94 transformation = TransformationReplaceLinearAlgebraInstruction(
95 {33, 34, 35, 36, 37, 38}, instruction_descriptor);
96 ASSERT_FALSE(
97 transformation.IsApplicable(context.get(), transformation_context));
98
99 instruction_descriptor = MakeInstructionDescriptor(31, SpvOpFAdd, 0);
100 transformation = TransformationReplaceLinearAlgebraInstruction(
101 {33, 34, 35, 36, 37}, instruction_descriptor);
102 ASSERT_FALSE(
103 transformation.IsApplicable(context.get(), transformation_context));
104
105 instruction_descriptor = MakeInstructionDescriptor(32, SpvOpFMul, 0);
106 transformation = TransformationReplaceLinearAlgebraInstruction(
107 {33, 34, 35, 36}, instruction_descriptor);
108 ASSERT_FALSE(
109 transformation.IsApplicable(context.get(), transformation_context));
110
111 // Tests number of fresh ids is different than necessary.
112 instruction_descriptor = MakeInstructionDescriptor(25, SpvOpDot, 0);
113 transformation = TransformationReplaceLinearAlgebraInstruction(
114 {33, 34, 35, 36}, instruction_descriptor);
115 ASSERT_FALSE(
116 transformation.IsApplicable(context.get(), transformation_context));
117
118 instruction_descriptor =
119 MakeInstructionDescriptor(28, SpvOpVectorTimesScalar, 0);
120 transformation = TransformationReplaceLinearAlgebraInstruction(
121 {33, 34, 35, 36, 37, 38, 39}, instruction_descriptor);
122 ASSERT_FALSE(
123 transformation.IsApplicable(context.get(), transformation_context));
124
125 // Tests non-fresh ids.
126 instruction_descriptor = MakeInstructionDescriptor(26, SpvOpDot, 0);
127 transformation = TransformationReplaceLinearAlgebraInstruction(
128 {33, 34, 5, 36, 37, 8, 39, 40, 1, 42, 3, 44, 45, 46},
129 instruction_descriptor);
130 ASSERT_FALSE(
131 transformation.IsApplicable(context.get(), transformation_context));
132
133 instruction_descriptor =
134 MakeInstructionDescriptor(29, SpvOpVectorTimesScalar, 0);
135 transformation = TransformationReplaceLinearAlgebraInstruction(
136 {33, 34, 35, 36, 7, 38, 9, 40}, instruction_descriptor);
137 ASSERT_FALSE(
138 transformation.IsApplicable(context.get(), transformation_context));
139 }
140
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpTranspose)141 TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpTranspose) {
142 std::string reference_shader = R"(
143 OpCapability Shader
144 %1 = OpExtInstImport "GLSL.std.450"
145 OpMemoryModel Logical GLSL450
146 OpEntryPoint Vertex %54 "main"
147
148 ; Types
149 %2 = OpTypeVoid
150 %3 = OpTypeFunction %2
151 %4 = OpTypeFloat 32
152 %5 = OpTypeVector %4 2
153 %6 = OpTypeVector %4 3
154 %7 = OpTypeVector %4 4
155 %8 = OpTypeMatrix %5 2
156 %9 = OpTypeMatrix %5 3
157 %10 = OpTypeMatrix %5 4
158 %11 = OpTypeMatrix %6 2
159 %12 = OpTypeMatrix %6 3
160 %13 = OpTypeMatrix %6 4
161 %14 = OpTypeMatrix %7 2
162 %15 = OpTypeMatrix %7 3
163 %16 = OpTypeMatrix %7 4
164
165 ; Constant scalars
166 %17 = OpConstant %4 1
167 %18 = OpConstant %4 2
168 %19 = OpConstant %4 3
169 %20 = OpConstant %4 4
170 %21 = OpConstant %4 5
171 %22 = OpConstant %4 6
172 %23 = OpConstant %4 7
173 %24 = OpConstant %4 8
174 %25 = OpConstant %4 9
175 %26 = OpConstant %4 10
176 %27 = OpConstant %4 11
177 %28 = OpConstant %4 12
178 %29 = OpConstant %4 13
179 %30 = OpConstant %4 14
180 %31 = OpConstant %4 15
181 %32 = OpConstant %4 16
182
183 ; Constant vectors
184 %33 = OpConstantComposite %5 %17 %18
185 %34 = OpConstantComposite %5 %19 %20
186 %35 = OpConstantComposite %5 %21 %22
187 %36 = OpConstantComposite %5 %23 %24
188 %37 = OpConstantComposite %6 %17 %18 %19
189 %38 = OpConstantComposite %6 %20 %21 %22
190 %39 = OpConstantComposite %6 %23 %24 %25
191 %40 = OpConstantComposite %6 %26 %27 %28
192 %41 = OpConstantComposite %7 %17 %18 %19 %20
193 %42 = OpConstantComposite %7 %21 %22 %23 %24
194 %43 = OpConstantComposite %7 %25 %26 %27 %28
195 %44 = OpConstantComposite %7 %29 %30 %31 %32
196
197 ; Constant matrices
198 %45 = OpConstantComposite %8 %33 %34
199 %46 = OpConstantComposite %9 %33 %34 %35
200 %47 = OpConstantComposite %10 %33 %34 %35 %36
201 %48 = OpConstantComposite %11 %37 %38
202 %49 = OpConstantComposite %12 %37 %38 %39
203 %50 = OpConstantComposite %13 %37 %38 %39 %40
204 %51 = OpConstantComposite %14 %41 %42
205 %52 = OpConstantComposite %15 %41 %42 %43
206 %53 = OpConstantComposite %16 %41 %42 %43 %44
207
208 ; main function
209 %54 = OpFunction %2 None %3
210 %55 = OpLabel
211
212 ; Transposing a 2x2 matrix
213 %56 = OpTranspose %8 %45
214
215 ; Transposing a 2x3 matrix
216 %57 = OpTranspose %11 %46
217
218 ; Transposing a 2x4 matrix
219 %58 = OpTranspose %14 %47
220
221 ; Transposing a 3x2 matrix
222 %59 = OpTranspose %9 %48
223
224 ; Transposing a 3x3 matrix
225 %60 = OpTranspose %12 %49
226
227 ; Transposing a 3x4 matrix
228 %61 = OpTranspose %15 %50
229
230 ; Transposing a 4x2 matrix
231 %62 = OpTranspose %10 %51
232
233 ; Transposing a 4x3 matrix
234 %63 = OpTranspose %13 %52
235
236 ; Transposing a 4x4 matrix
237 %64 = OpTranspose %16 %53
238 OpReturn
239 OpFunctionEnd
240 )";
241
242 const auto env = SPV_ENV_UNIVERSAL_1_5;
243 const auto consumer = nullptr;
244 const auto context =
245 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
246 spvtools::ValidatorOptions validator_options;
247 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
248 kConsoleMessageConsumer));
249 TransformationContext transformation_context(
250 MakeUnique<FactManager>(context.get()), validator_options);
251 auto instruction_descriptor =
252 MakeInstructionDescriptor(56, SpvOpTranspose, 0);
253 auto transformation = TransformationReplaceLinearAlgebraInstruction(
254 {65, 66, 67, 68, 69, 70, 71, 72, 73, 74}, instruction_descriptor);
255 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
256
257 instruction_descriptor = MakeInstructionDescriptor(57, SpvOpTranspose, 0);
258 transformation = TransformationReplaceLinearAlgebraInstruction(
259 {75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88},
260 instruction_descriptor);
261 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
262
263 instruction_descriptor = MakeInstructionDescriptor(58, SpvOpTranspose, 0);
264 transformation = TransformationReplaceLinearAlgebraInstruction(
265 {89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
266 106},
267 instruction_descriptor);
268 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
269
270 instruction_descriptor = MakeInstructionDescriptor(59, SpvOpTranspose, 0);
271 transformation = TransformationReplaceLinearAlgebraInstruction(
272 {107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
273 121},
274 instruction_descriptor);
275 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
276
277 instruction_descriptor = MakeInstructionDescriptor(60, SpvOpTranspose, 0);
278 transformation = TransformationReplaceLinearAlgebraInstruction(
279 {122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
280 133, 134, 135, 136, 137, 138, 139, 140, 141, 142},
281 instruction_descriptor);
282 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
283
284 std::string variant_shader = R"(
285 OpCapability Shader
286 %1 = OpExtInstImport "GLSL.std.450"
287 OpMemoryModel Logical GLSL450
288 OpEntryPoint Vertex %54 "main"
289
290 ; Types
291 %2 = OpTypeVoid
292 %3 = OpTypeFunction %2
293 %4 = OpTypeFloat 32
294 %5 = OpTypeVector %4 2
295 %6 = OpTypeVector %4 3
296 %7 = OpTypeVector %4 4
297 %8 = OpTypeMatrix %5 2
298 %9 = OpTypeMatrix %5 3
299 %10 = OpTypeMatrix %5 4
300 %11 = OpTypeMatrix %6 2
301 %12 = OpTypeMatrix %6 3
302 %13 = OpTypeMatrix %6 4
303 %14 = OpTypeMatrix %7 2
304 %15 = OpTypeMatrix %7 3
305 %16 = OpTypeMatrix %7 4
306
307 ; Constant scalars
308 %17 = OpConstant %4 1
309 %18 = OpConstant %4 2
310 %19 = OpConstant %4 3
311 %20 = OpConstant %4 4
312 %21 = OpConstant %4 5
313 %22 = OpConstant %4 6
314 %23 = OpConstant %4 7
315 %24 = OpConstant %4 8
316 %25 = OpConstant %4 9
317 %26 = OpConstant %4 10
318 %27 = OpConstant %4 11
319 %28 = OpConstant %4 12
320 %29 = OpConstant %4 13
321 %30 = OpConstant %4 14
322 %31 = OpConstant %4 15
323 %32 = OpConstant %4 16
324
325 ; Constant vectors
326 %33 = OpConstantComposite %5 %17 %18
327 %34 = OpConstantComposite %5 %19 %20
328 %35 = OpConstantComposite %5 %21 %22
329 %36 = OpConstantComposite %5 %23 %24
330 %37 = OpConstantComposite %6 %17 %18 %19
331 %38 = OpConstantComposite %6 %20 %21 %22
332 %39 = OpConstantComposite %6 %23 %24 %25
333 %40 = OpConstantComposite %6 %26 %27 %28
334 %41 = OpConstantComposite %7 %17 %18 %19 %20
335 %42 = OpConstantComposite %7 %21 %22 %23 %24
336 %43 = OpConstantComposite %7 %25 %26 %27 %28
337 %44 = OpConstantComposite %7 %29 %30 %31 %32
338
339 ; Constant matrices
340 %45 = OpConstantComposite %8 %33 %34
341 %46 = OpConstantComposite %9 %33 %34 %35
342 %47 = OpConstantComposite %10 %33 %34 %35 %36
343 %48 = OpConstantComposite %11 %37 %38
344 %49 = OpConstantComposite %12 %37 %38 %39
345 %50 = OpConstantComposite %13 %37 %38 %39 %40
346 %51 = OpConstantComposite %14 %41 %42
347 %52 = OpConstantComposite %15 %41 %42 %43
348 %53 = OpConstantComposite %16 %41 %42 %43 %44
349
350 ; main function
351 %54 = OpFunction %2 None %3
352 %55 = OpLabel
353
354 ; Transposing a 2x2 matrix
355 %65 = OpCompositeExtract %5 %45 0
356 %66 = OpCompositeExtract %4 %65 0
357 %67 = OpCompositeExtract %5 %45 1
358 %68 = OpCompositeExtract %4 %67 0
359 %69 = OpCompositeConstruct %5 %66 %68
360 %70 = OpCompositeExtract %5 %45 0
361 %71 = OpCompositeExtract %4 %70 1
362 %72 = OpCompositeExtract %5 %45 1
363 %73 = OpCompositeExtract %4 %72 1
364 %74 = OpCompositeConstruct %5 %71 %73
365 %56 = OpCompositeConstruct %8 %69 %74
366
367 ; Transposing a 2x3 matrix
368 %75 = OpCompositeExtract %5 %46 0
369 %76 = OpCompositeExtract %4 %75 0
370 %77 = OpCompositeExtract %5 %46 1
371 %78 = OpCompositeExtract %4 %77 0
372 %79 = OpCompositeExtract %5 %46 2
373 %80 = OpCompositeExtract %4 %79 0
374 %81 = OpCompositeConstruct %6 %76 %78 %80
375 %82 = OpCompositeExtract %5 %46 0
376 %83 = OpCompositeExtract %4 %82 1
377 %84 = OpCompositeExtract %5 %46 1
378 %85 = OpCompositeExtract %4 %84 1
379 %86 = OpCompositeExtract %5 %46 2
380 %87 = OpCompositeExtract %4 %86 1
381 %88 = OpCompositeConstruct %6 %83 %85 %87
382 %57 = OpCompositeConstruct %11 %81 %88
383
384 ; Transposing a 2x4 matrix
385 %89 = OpCompositeExtract %5 %47 0
386 %90 = OpCompositeExtract %4 %89 0
387 %91 = OpCompositeExtract %5 %47 1
388 %92 = OpCompositeExtract %4 %91 0
389 %93 = OpCompositeExtract %5 %47 2
390 %94 = OpCompositeExtract %4 %93 0
391 %95 = OpCompositeExtract %5 %47 3
392 %96 = OpCompositeExtract %4 %95 0
393 %97 = OpCompositeConstruct %7 %90 %92 %94 %96
394 %98 = OpCompositeExtract %5 %47 0
395 %99 = OpCompositeExtract %4 %98 1
396 %100 = OpCompositeExtract %5 %47 1
397 %101 = OpCompositeExtract %4 %100 1
398 %102 = OpCompositeExtract %5 %47 2
399 %103 = OpCompositeExtract %4 %102 1
400 %104 = OpCompositeExtract %5 %47 3
401 %105 = OpCompositeExtract %4 %104 1
402 %106 = OpCompositeConstruct %7 %99 %101 %103 %105
403 %58 = OpCompositeConstruct %14 %97 %106
404
405 ; Transposing a 3x2 matrix
406 %107 = OpCompositeExtract %6 %48 0
407 %108 = OpCompositeExtract %4 %107 0
408 %109 = OpCompositeExtract %6 %48 1
409 %110 = OpCompositeExtract %4 %109 0
410 %111 = OpCompositeConstruct %5 %108 %110
411 %112 = OpCompositeExtract %6 %48 0
412 %113 = OpCompositeExtract %4 %112 1
413 %114 = OpCompositeExtract %6 %48 1
414 %115 = OpCompositeExtract %4 %114 1
415 %116 = OpCompositeConstruct %5 %113 %115
416 %117 = OpCompositeExtract %6 %48 0
417 %118 = OpCompositeExtract %4 %117 2
418 %119 = OpCompositeExtract %6 %48 1
419 %120 = OpCompositeExtract %4 %119 2
420 %121 = OpCompositeConstruct %5 %118 %120
421 %59 = OpCompositeConstruct %9 %111 %116 %121
422
423 ; Transposing a 3x3 matrix
424 %122 = OpCompositeExtract %6 %49 0
425 %123 = OpCompositeExtract %4 %122 0
426 %124 = OpCompositeExtract %6 %49 1
427 %125 = OpCompositeExtract %4 %124 0
428 %126 = OpCompositeExtract %6 %49 2
429 %127 = OpCompositeExtract %4 %126 0
430 %128 = OpCompositeConstruct %6 %123 %125 %127
431 %129 = OpCompositeExtract %6 %49 0
432 %130 = OpCompositeExtract %4 %129 1
433 %131 = OpCompositeExtract %6 %49 1
434 %132 = OpCompositeExtract %4 %131 1
435 %133 = OpCompositeExtract %6 %49 2
436 %134 = OpCompositeExtract %4 %133 1
437 %135 = OpCompositeConstruct %6 %130 %132 %134
438 %136 = OpCompositeExtract %6 %49 0
439 %137 = OpCompositeExtract %4 %136 2
440 %138 = OpCompositeExtract %6 %49 1
441 %139 = OpCompositeExtract %4 %138 2
442 %140 = OpCompositeExtract %6 %49 2
443 %141 = OpCompositeExtract %4 %140 2
444 %142 = OpCompositeConstruct %6 %137 %139 %141
445 %60 = OpCompositeConstruct %12 %128 %135 %142
446
447 ; Transposing a 3x4 matrix
448 %61 = OpTranspose %15 %50
449
450 ; Transposing a 4x2 matrix
451 %62 = OpTranspose %10 %51
452
453 ; Transposing a 4x3 matrix
454 %63 = OpTranspose %13 %52
455
456 ; Transposing a 4x4 matrix
457 %64 = OpTranspose %16 %53
458 OpReturn
459 OpFunctionEnd
460 )";
461
462 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
463 kConsoleMessageConsumer));
464 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
465 }
466
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpVectorTimesScalar)467 TEST(TransformationReplaceLinearAlgebraInstructionTest,
468 ReplaceOpVectorTimesScalar) {
469 std::string reference_shader = R"(
470 OpCapability Shader
471 %1 = OpExtInstImport "GLSL.std.450"
472 OpMemoryModel Logical GLSL450
473 OpEntryPoint Fragment %15 "main"
474 OpExecutionMode %15 OriginUpperLeft
475 OpSource ESSL 310
476 OpName %15 "main"
477 %2 = OpTypeVoid
478 %3 = OpTypeFunction %2
479 %4 = OpTypeFloat 32
480 %5 = OpTypeVector %4 2
481 %6 = OpTypeVector %4 3
482 %7 = OpTypeVector %4 4
483 %8 = OpConstant %4 1
484 %9 = OpConstant %4 2
485 %10 = OpConstant %4 3
486 %11 = OpConstant %4 4
487 %12 = OpConstantComposite %5 %8 %9
488 %13 = OpConstantComposite %6 %8 %9 %10
489 %14 = OpConstantComposite %7 %8 %9 %10 %11
490 %15 = OpFunction %2 None %3
491 %16 = OpLabel
492 %17 = OpVectorTimesScalar %5 %12 %8
493 %18 = OpVectorTimesScalar %6 %13 %9
494 %19 = OpVectorTimesScalar %7 %14 %10
495 OpReturn
496 OpFunctionEnd
497 )";
498
499 const auto env = SPV_ENV_UNIVERSAL_1_5;
500 const auto consumer = nullptr;
501 const auto context =
502 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
503 spvtools::ValidatorOptions validator_options;
504 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
505 kConsoleMessageConsumer));
506 TransformationContext transformation_context(
507 MakeUnique<FactManager>(context.get()), validator_options);
508 auto instruction_descriptor =
509 MakeInstructionDescriptor(17, SpvOpVectorTimesScalar, 0);
510 auto transformation = TransformationReplaceLinearAlgebraInstruction(
511 {20, 21, 22, 23}, instruction_descriptor);
512 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
513
514 instruction_descriptor =
515 MakeInstructionDescriptor(18, SpvOpVectorTimesScalar, 0);
516 transformation = TransformationReplaceLinearAlgebraInstruction(
517 {24, 25, 26, 27, 28, 29}, instruction_descriptor);
518 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
519
520 instruction_descriptor =
521 MakeInstructionDescriptor(19, SpvOpVectorTimesScalar, 0);
522 transformation = TransformationReplaceLinearAlgebraInstruction(
523 {30, 31, 32, 33, 34, 35, 36, 37}, instruction_descriptor);
524 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
525
526 std::string variant_shader = R"(
527 OpCapability Shader
528 %1 = OpExtInstImport "GLSL.std.450"
529 OpMemoryModel Logical GLSL450
530 OpEntryPoint Fragment %15 "main"
531 OpExecutionMode %15 OriginUpperLeft
532 OpSource ESSL 310
533 OpName %15 "main"
534 %2 = OpTypeVoid
535 %3 = OpTypeFunction %2
536 %4 = OpTypeFloat 32
537 %5 = OpTypeVector %4 2
538 %6 = OpTypeVector %4 3
539 %7 = OpTypeVector %4 4
540 %8 = OpConstant %4 1
541 %9 = OpConstant %4 2
542 %10 = OpConstant %4 3
543 %11 = OpConstant %4 4
544 %12 = OpConstantComposite %5 %8 %9
545 %13 = OpConstantComposite %6 %8 %9 %10
546 %14 = OpConstantComposite %7 %8 %9 %10 %11
547 %15 = OpFunction %2 None %3
548 %16 = OpLabel
549 %20 = OpCompositeExtract %4 %12 0
550 %21 = OpFMul %4 %20 %8
551 %22 = OpCompositeExtract %4 %12 1
552 %23 = OpFMul %4 %22 %8
553 %17 = OpCompositeConstruct %5 %21 %23
554 %24 = OpCompositeExtract %4 %13 0
555 %25 = OpFMul %4 %24 %9
556 %26 = OpCompositeExtract %4 %13 1
557 %27 = OpFMul %4 %26 %9
558 %28 = OpCompositeExtract %4 %13 2
559 %29 = OpFMul %4 %28 %9
560 %18 = OpCompositeConstruct %6 %25 %27 %29
561 %30 = OpCompositeExtract %4 %14 0
562 %31 = OpFMul %4 %30 %10
563 %32 = OpCompositeExtract %4 %14 1
564 %33 = OpFMul %4 %32 %10
565 %34 = OpCompositeExtract %4 %14 2
566 %35 = OpFMul %4 %34 %10
567 %36 = OpCompositeExtract %4 %14 3
568 %37 = OpFMul %4 %36 %10
569 %19 = OpCompositeConstruct %7 %31 %33 %35 %37
570 OpReturn
571 OpFunctionEnd
572 )";
573
574 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
575 kConsoleMessageConsumer));
576 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
577 }
578
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpMatrixTimesScalar)579 TEST(TransformationReplaceLinearAlgebraInstructionTest,
580 ReplaceOpMatrixTimesScalar) {
581 std::string reference_shader = R"(
582 OpCapability Shader
583 %1 = OpExtInstImport "GLSL.std.450"
584 OpMemoryModel Logical GLSL450
585 OpEntryPoint Fragment %54 "main"
586 OpExecutionMode %54 OriginUpperLeft
587
588 ; Types
589 %2 = OpTypeVoid
590 %3 = OpTypeFunction %2
591 %4 = OpTypeFloat 32
592 %5 = OpTypeVector %4 2
593 %6 = OpTypeVector %4 3
594 %7 = OpTypeVector %4 4
595 %8 = OpTypeMatrix %5 2
596 %9 = OpTypeMatrix %5 3
597 %10 = OpTypeMatrix %5 4
598 %11 = OpTypeMatrix %6 2
599 %12 = OpTypeMatrix %6 3
600 %13 = OpTypeMatrix %6 4
601 %14 = OpTypeMatrix %7 2
602 %15 = OpTypeMatrix %7 3
603 %16 = OpTypeMatrix %7 4
604
605 ; Constant scalars
606 %17 = OpConstant %4 1
607 %18 = OpConstant %4 2
608 %19 = OpConstant %4 3
609 %20 = OpConstant %4 4
610 %21 = OpConstant %4 5
611 %22 = OpConstant %4 6
612 %23 = OpConstant %4 7
613 %24 = OpConstant %4 8
614 %25 = OpConstant %4 9
615 %26 = OpConstant %4 10
616 %27 = OpConstant %4 11
617 %28 = OpConstant %4 12
618 %29 = OpConstant %4 13
619 %30 = OpConstant %4 14
620 %31 = OpConstant %4 15
621 %32 = OpConstant %4 16
622
623 ; Constant vectors
624 %33 = OpConstantComposite %5 %17 %18
625 %34 = OpConstantComposite %5 %19 %20
626 %35 = OpConstantComposite %5 %21 %22
627 %36 = OpConstantComposite %5 %23 %24
628 %37 = OpConstantComposite %6 %17 %18 %19
629 %38 = OpConstantComposite %6 %20 %21 %22
630 %39 = OpConstantComposite %6 %23 %24 %25
631 %40 = OpConstantComposite %6 %26 %27 %28
632 %41 = OpConstantComposite %7 %17 %18 %19 %20
633 %42 = OpConstantComposite %7 %21 %22 %23 %24
634 %43 = OpConstantComposite %7 %25 %26 %27 %28
635 %44 = OpConstantComposite %7 %29 %30 %31 %32
636
637 ; Constant matrices
638 %45 = OpConstantComposite %8 %33 %34
639 %46 = OpConstantComposite %9 %33 %34 %35
640 %47 = OpConstantComposite %10 %33 %34 %35 %36
641 %48 = OpConstantComposite %11 %37 %38
642 %49 = OpConstantComposite %12 %37 %38 %39
643 %50 = OpConstantComposite %13 %37 %38 %39 %40
644 %51 = OpConstantComposite %14 %41 %42
645 %52 = OpConstantComposite %15 %41 %42 %43
646 %53 = OpConstantComposite %16 %41 %42 %43 %44
647
648 ; main function
649 %54 = OpFunction %2 None %3
650 %55 = OpLabel
651
652 ; Multiplying 2-row matrices by scalar
653 %56 = OpMatrixTimesScalar %8 %45 %17
654 %57 = OpMatrixTimesScalar %9 %46 %18
655 %58 = OpMatrixTimesScalar %10 %47 %19
656
657 ; Multiplying 3-row matrices by scalar
658 %59 = OpMatrixTimesScalar %11 %48 %21
659 %60 = OpMatrixTimesScalar %12 %49 %22
660 %61 = OpMatrixTimesScalar %13 %50 %23
661
662 ; Multiplying 4-row matrices by scalar
663 %62 = OpMatrixTimesScalar %14 %51 %24
664 %63 = OpMatrixTimesScalar %15 %52 %25
665 %64 = OpMatrixTimesScalar %16 %53 %26
666 OpReturn
667 OpFunctionEnd
668 )";
669
670 const auto env = SPV_ENV_UNIVERSAL_1_5;
671 const auto consumer = nullptr;
672 const auto context =
673 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
674 spvtools::ValidatorOptions validator_options;
675 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
676 kConsoleMessageConsumer));
677 TransformationContext transformation_context(
678 MakeUnique<FactManager>(context.get()), validator_options);
679 auto instruction_descriptor =
680 MakeInstructionDescriptor(56, SpvOpMatrixTimesScalar, 0);
681 auto transformation = TransformationReplaceLinearAlgebraInstruction(
682 {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76}, instruction_descriptor);
683 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
684
685 instruction_descriptor =
686 MakeInstructionDescriptor(57, SpvOpMatrixTimesScalar, 0);
687 transformation = TransformationReplaceLinearAlgebraInstruction(
688 {77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94},
689 instruction_descriptor);
690 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
691
692 instruction_descriptor =
693 MakeInstructionDescriptor(58, SpvOpMatrixTimesScalar, 0);
694 transformation = TransformationReplaceLinearAlgebraInstruction(
695 {95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
696 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118},
697 instruction_descriptor);
698 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
699
700 std::string variant_shader = R"(
701 OpCapability Shader
702 %1 = OpExtInstImport "GLSL.std.450"
703 OpMemoryModel Logical GLSL450
704 OpEntryPoint Fragment %54 "main"
705 OpExecutionMode %54 OriginUpperLeft
706
707 ; Types
708 %2 = OpTypeVoid
709 %3 = OpTypeFunction %2
710 %4 = OpTypeFloat 32
711 %5 = OpTypeVector %4 2
712 %6 = OpTypeVector %4 3
713 %7 = OpTypeVector %4 4
714 %8 = OpTypeMatrix %5 2
715 %9 = OpTypeMatrix %5 3
716 %10 = OpTypeMatrix %5 4
717 %11 = OpTypeMatrix %6 2
718 %12 = OpTypeMatrix %6 3
719 %13 = OpTypeMatrix %6 4
720 %14 = OpTypeMatrix %7 2
721 %15 = OpTypeMatrix %7 3
722 %16 = OpTypeMatrix %7 4
723
724 ; Constant scalars
725 %17 = OpConstant %4 1
726 %18 = OpConstant %4 2
727 %19 = OpConstant %4 3
728 %20 = OpConstant %4 4
729 %21 = OpConstant %4 5
730 %22 = OpConstant %4 6
731 %23 = OpConstant %4 7
732 %24 = OpConstant %4 8
733 %25 = OpConstant %4 9
734 %26 = OpConstant %4 10
735 %27 = OpConstant %4 11
736 %28 = OpConstant %4 12
737 %29 = OpConstant %4 13
738 %30 = OpConstant %4 14
739 %31 = OpConstant %4 15
740 %32 = OpConstant %4 16
741
742 ; Constant vectors
743 %33 = OpConstantComposite %5 %17 %18
744 %34 = OpConstantComposite %5 %19 %20
745 %35 = OpConstantComposite %5 %21 %22
746 %36 = OpConstantComposite %5 %23 %24
747 %37 = OpConstantComposite %6 %17 %18 %19
748 %38 = OpConstantComposite %6 %20 %21 %22
749 %39 = OpConstantComposite %6 %23 %24 %25
750 %40 = OpConstantComposite %6 %26 %27 %28
751 %41 = OpConstantComposite %7 %17 %18 %19 %20
752 %42 = OpConstantComposite %7 %21 %22 %23 %24
753 %43 = OpConstantComposite %7 %25 %26 %27 %28
754 %44 = OpConstantComposite %7 %29 %30 %31 %32
755
756 ; Constant matrices
757 %45 = OpConstantComposite %8 %33 %34
758 %46 = OpConstantComposite %9 %33 %34 %35
759 %47 = OpConstantComposite %10 %33 %34 %35 %36
760 %48 = OpConstantComposite %11 %37 %38
761 %49 = OpConstantComposite %12 %37 %38 %39
762 %50 = OpConstantComposite %13 %37 %38 %39 %40
763 %51 = OpConstantComposite %14 %41 %42
764 %52 = OpConstantComposite %15 %41 %42 %43
765 %53 = OpConstantComposite %16 %41 %42 %43 %44
766
767 ; main function
768 %54 = OpFunction %2 None %3
769 %55 = OpLabel
770
771 ; Multiplying 2x2 matrix by scalar
772 %65 = OpCompositeExtract %5 %45 0
773 %66 = OpCompositeExtract %4 %65 0
774 %67 = OpFMul %4 %66 %17
775 %68 = OpCompositeExtract %4 %65 1
776 %69 = OpFMul %4 %68 %17
777 %70 = OpCompositeConstruct %5 %67 %69
778 %71 = OpCompositeExtract %5 %45 1
779 %72 = OpCompositeExtract %4 %71 0
780 %73 = OpFMul %4 %72 %17
781 %74 = OpCompositeExtract %4 %71 1
782 %75 = OpFMul %4 %74 %17
783 %76 = OpCompositeConstruct %5 %73 %75
784 %56 = OpCompositeConstruct %8 %70 %76
785
786 ; Multiplying 2x3 matrix by scalar
787 %77 = OpCompositeExtract %5 %46 0
788 %78 = OpCompositeExtract %4 %77 0
789 %79 = OpFMul %4 %78 %18
790 %80 = OpCompositeExtract %4 %77 1
791 %81 = OpFMul %4 %80 %18
792 %82 = OpCompositeConstruct %5 %79 %81
793 %83 = OpCompositeExtract %5 %46 1
794 %84 = OpCompositeExtract %4 %83 0
795 %85 = OpFMul %4 %84 %18
796 %86 = OpCompositeExtract %4 %83 1
797 %87 = OpFMul %4 %86 %18
798 %88 = OpCompositeConstruct %5 %85 %87
799 %89 = OpCompositeExtract %5 %46 2
800 %90 = OpCompositeExtract %4 %89 0
801 %91 = OpFMul %4 %90 %18
802 %92 = OpCompositeExtract %4 %89 1
803 %93 = OpFMul %4 %92 %18
804 %94 = OpCompositeConstruct %5 %91 %93
805 %57 = OpCompositeConstruct %9 %82 %88 %94
806
807 ; Multiplying 2x4 matrix by scalar
808 %95 = OpCompositeExtract %5 %47 0
809 %96 = OpCompositeExtract %4 %95 0
810 %97 = OpFMul %4 %96 %19
811 %98 = OpCompositeExtract %4 %95 1
812 %99 = OpFMul %4 %98 %19
813 %100 = OpCompositeConstruct %5 %97 %99
814 %101 = OpCompositeExtract %5 %47 1
815 %102 = OpCompositeExtract %4 %101 0
816 %103 = OpFMul %4 %102 %19
817 %104 = OpCompositeExtract %4 %101 1
818 %105 = OpFMul %4 %104 %19
819 %106 = OpCompositeConstruct %5 %103 %105
820 %107 = OpCompositeExtract %5 %47 2
821 %108 = OpCompositeExtract %4 %107 0
822 %109 = OpFMul %4 %108 %19
823 %110 = OpCompositeExtract %4 %107 1
824 %111 = OpFMul %4 %110 %19
825 %112 = OpCompositeConstruct %5 %109 %111
826 %113 = OpCompositeExtract %5 %47 3
827 %114 = OpCompositeExtract %4 %113 0
828 %115 = OpFMul %4 %114 %19
829 %116 = OpCompositeExtract %4 %113 1
830 %117 = OpFMul %4 %116 %19
831 %118 = OpCompositeConstruct %5 %115 %117
832 %58 = OpCompositeConstruct %10 %100 %106 %112 %118
833
834 ; Multiplying 3-row matrices by scalar
835 %59 = OpMatrixTimesScalar %11 %48 %21
836 %60 = OpMatrixTimesScalar %12 %49 %22
837 %61 = OpMatrixTimesScalar %13 %50 %23
838
839 ; Multiplying 4-row matrices by scalar
840 %62 = OpMatrixTimesScalar %14 %51 %24
841 %63 = OpMatrixTimesScalar %15 %52 %25
842 %64 = OpMatrixTimesScalar %16 %53 %26
843 OpReturn
844 OpFunctionEnd
845 )";
846
847 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
848 kConsoleMessageConsumer));
849 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
850 }
851
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpVectorTimesMatrix)852 TEST(TransformationReplaceLinearAlgebraInstructionTest,
853 ReplaceOpVectorTimesMatrix) {
854 std::string reference_shader = R"(
855 OpCapability Shader
856 %1 = OpExtInstImport "GLSL.std.450"
857 OpMemoryModel Logical GLSL450
858 OpEntryPoint Fragment %54 "main"
859 OpExecutionMode %54 OriginUpperLeft
860 OpSource ESSL 310
861 OpName %54 "main"
862
863 ; Types
864 %2 = OpTypeVoid
865 %3 = OpTypeFunction %2
866 %4 = OpTypeFloat 32
867 %5 = OpTypeVector %4 2
868 %6 = OpTypeVector %4 3
869 %7 = OpTypeVector %4 4
870 %8 = OpTypeMatrix %5 2
871 %9 = OpTypeMatrix %5 3
872 %10 = OpTypeMatrix %5 4
873 %11 = OpTypeMatrix %6 2
874 %12 = OpTypeMatrix %6 3
875 %13 = OpTypeMatrix %6 4
876 %14 = OpTypeMatrix %7 2
877 %15 = OpTypeMatrix %7 3
878 %16 = OpTypeMatrix %7 4
879
880 ; Constant scalars
881 %17 = OpConstant %4 1
882 %18 = OpConstant %4 2
883 %19 = OpConstant %4 3
884 %20 = OpConstant %4 4
885 %21 = OpConstant %4 5
886 %22 = OpConstant %4 6
887 %23 = OpConstant %4 7
888 %24 = OpConstant %4 8
889 %25 = OpConstant %4 9
890 %26 = OpConstant %4 10
891 %27 = OpConstant %4 11
892 %28 = OpConstant %4 12
893 %29 = OpConstant %4 13
894 %30 = OpConstant %4 14
895 %31 = OpConstant %4 15
896 %32 = OpConstant %4 16
897
898 ; Constant vectors
899 %33 = OpConstantComposite %5 %17 %18
900 %34 = OpConstantComposite %5 %19 %20
901 %35 = OpConstantComposite %5 %21 %22
902 %36 = OpConstantComposite %5 %23 %24
903 %37 = OpConstantComposite %6 %17 %18 %19
904 %38 = OpConstantComposite %6 %20 %21 %22
905 %39 = OpConstantComposite %6 %23 %24 %25
906 %40 = OpConstantComposite %6 %26 %27 %28
907 %41 = OpConstantComposite %7 %17 %18 %19 %20
908 %42 = OpConstantComposite %7 %21 %22 %23 %24
909 %43 = OpConstantComposite %7 %25 %26 %27 %28
910 %44 = OpConstantComposite %7 %29 %30 %31 %32
911
912 ; Constant matrices
913 %45 = OpConstantComposite %8 %33 %34
914 %46 = OpConstantComposite %9 %33 %34 %35
915 %47 = OpConstantComposite %10 %33 %34 %35 %36
916 %48 = OpConstantComposite %11 %37 %38
917 %49 = OpConstantComposite %12 %37 %38 %39
918 %50 = OpConstantComposite %13 %37 %38 %39 %40
919 %51 = OpConstantComposite %14 %41 %42
920 %52 = OpConstantComposite %15 %41 %42 %43
921 %53 = OpConstantComposite %16 %41 %42 %43 %44
922
923 ; main function
924 %54 = OpFunction %2 None %3
925 %55 = OpLabel
926
927 ; Multiplying 2-dimensional vector by 2x2 matrix
928 %56 = OpVectorTimesMatrix %5 %33 %45
929
930 ; Multiplying 2-dimensional vector by 2x3 matrix
931 %57 = OpVectorTimesMatrix %6 %34 %46
932
933 ; Multiplying 2-dimensional vector by 2x4 matrix
934 %58 = OpVectorTimesMatrix %7 %35 %47
935
936 ; Multiplying 3-dimensional vector by 3x2 matrix
937 %59 = OpVectorTimesMatrix %5 %37 %48
938
939 ; Multiplying 3-dimensional vector by 3x3 matrix
940 %60 = OpVectorTimesMatrix %6 %38 %49
941
942 ; Multiplying 3-dimensional vector by 3x4 matrix
943 %61 = OpVectorTimesMatrix %7 %39 %50
944
945 ; Multiplying 4-dimensional vector by 4x2 matrix
946 %62 = OpVectorTimesMatrix %5 %41 %51
947
948 ; Multiplying 4-dimensional vector by 4x3 matrix
949 %63 = OpVectorTimesMatrix %6 %42 %52
950
951 ; Multiplying 4-dimensional vector by 4x4 matrix
952 %64 = OpVectorTimesMatrix %7 %43 %53
953 OpReturn
954 OpFunctionEnd
955 )";
956
957 const auto env = SPV_ENV_UNIVERSAL_1_5;
958 const auto consumer = nullptr;
959 const auto context =
960 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
961 spvtools::ValidatorOptions validator_options;
962 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
963 kConsoleMessageConsumer));
964 TransformationContext transformation_context(
965 MakeUnique<FactManager>(context.get()), validator_options);
966 auto instruction_descriptor =
967 MakeInstructionDescriptor(56, SpvOpVectorTimesMatrix, 0);
968 auto transformation = TransformationReplaceLinearAlgebraInstruction(
969 {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78},
970 instruction_descriptor);
971 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
972
973 instruction_descriptor =
974 MakeInstructionDescriptor(57, SpvOpVectorTimesMatrix, 0);
975 transformation = TransformationReplaceLinearAlgebraInstruction(
976 {79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
977 89, 90, 91, 92, 93, 94, 95, 96, 97, 98},
978 instruction_descriptor);
979 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
980
981 instruction_descriptor =
982 MakeInstructionDescriptor(58, SpvOpVectorTimesMatrix, 0);
983 transformation = TransformationReplaceLinearAlgebraInstruction(
984 {99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
985 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124},
986 instruction_descriptor);
987 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
988
989 instruction_descriptor =
990 MakeInstructionDescriptor(59, SpvOpVectorTimesMatrix, 0);
991 transformation = TransformationReplaceLinearAlgebraInstruction(
992 {125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
993 136, 137, 138, 139, 140, 141, 142, 143, 144, 145},
994 instruction_descriptor);
995 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
996
997 std::string variant_shader = R"(
998 OpCapability Shader
999 %1 = OpExtInstImport "GLSL.std.450"
1000 OpMemoryModel Logical GLSL450
1001 OpEntryPoint Fragment %54 "main"
1002 OpExecutionMode %54 OriginUpperLeft
1003 OpSource ESSL 310
1004 OpName %54 "main"
1005
1006 ; Types
1007 %2 = OpTypeVoid
1008 %3 = OpTypeFunction %2
1009 %4 = OpTypeFloat 32
1010 %5 = OpTypeVector %4 2
1011 %6 = OpTypeVector %4 3
1012 %7 = OpTypeVector %4 4
1013 %8 = OpTypeMatrix %5 2
1014 %9 = OpTypeMatrix %5 3
1015 %10 = OpTypeMatrix %5 4
1016 %11 = OpTypeMatrix %6 2
1017 %12 = OpTypeMatrix %6 3
1018 %13 = OpTypeMatrix %6 4
1019 %14 = OpTypeMatrix %7 2
1020 %15 = OpTypeMatrix %7 3
1021 %16 = OpTypeMatrix %7 4
1022
1023 ; Constant scalars
1024 %17 = OpConstant %4 1
1025 %18 = OpConstant %4 2
1026 %19 = OpConstant %4 3
1027 %20 = OpConstant %4 4
1028 %21 = OpConstant %4 5
1029 %22 = OpConstant %4 6
1030 %23 = OpConstant %4 7
1031 %24 = OpConstant %4 8
1032 %25 = OpConstant %4 9
1033 %26 = OpConstant %4 10
1034 %27 = OpConstant %4 11
1035 %28 = OpConstant %4 12
1036 %29 = OpConstant %4 13
1037 %30 = OpConstant %4 14
1038 %31 = OpConstant %4 15
1039 %32 = OpConstant %4 16
1040
1041 ; Constant vectors
1042 %33 = OpConstantComposite %5 %17 %18
1043 %34 = OpConstantComposite %5 %19 %20
1044 %35 = OpConstantComposite %5 %21 %22
1045 %36 = OpConstantComposite %5 %23 %24
1046 %37 = OpConstantComposite %6 %17 %18 %19
1047 %38 = OpConstantComposite %6 %20 %21 %22
1048 %39 = OpConstantComposite %6 %23 %24 %25
1049 %40 = OpConstantComposite %6 %26 %27 %28
1050 %41 = OpConstantComposite %7 %17 %18 %19 %20
1051 %42 = OpConstantComposite %7 %21 %22 %23 %24
1052 %43 = OpConstantComposite %7 %25 %26 %27 %28
1053 %44 = OpConstantComposite %7 %29 %30 %31 %32
1054
1055 ; Constant matrices
1056 %45 = OpConstantComposite %8 %33 %34
1057 %46 = OpConstantComposite %9 %33 %34 %35
1058 %47 = OpConstantComposite %10 %33 %34 %35 %36
1059 %48 = OpConstantComposite %11 %37 %38
1060 %49 = OpConstantComposite %12 %37 %38 %39
1061 %50 = OpConstantComposite %13 %37 %38 %39 %40
1062 %51 = OpConstantComposite %14 %41 %42
1063 %52 = OpConstantComposite %15 %41 %42 %43
1064 %53 = OpConstantComposite %16 %41 %42 %43 %44
1065
1066 ; main function
1067 %54 = OpFunction %2 None %3
1068 %55 = OpLabel
1069
1070 ; Multiplying 2-dimensional vector by 2x2 matrix
1071 %65 = OpCompositeExtract %4 %33 0
1072 %66 = OpCompositeExtract %4 %33 1
1073 %67 = OpCompositeExtract %5 %45 0
1074 %68 = OpCompositeExtract %4 %67 0
1075 %69 = OpFMul %4 %65 %68
1076 %70 = OpCompositeExtract %4 %67 1
1077 %71 = OpFMul %4 %66 %70
1078 %72 = OpFAdd %4 %69 %71
1079 %73 = OpCompositeExtract %5 %45 1
1080 %74 = OpCompositeExtract %4 %73 0
1081 %75 = OpFMul %4 %65 %74
1082 %76 = OpCompositeExtract %4 %73 1
1083 %77 = OpFMul %4 %66 %76
1084 %78 = OpFAdd %4 %75 %77
1085 %56 = OpCompositeConstruct %5 %72 %78
1086
1087 ; Multiplying 2-dimensional vector by 2x3 matrix
1088 %79 = OpCompositeExtract %4 %34 0
1089 %80 = OpCompositeExtract %4 %34 1
1090 %81 = OpCompositeExtract %5 %46 0
1091 %82 = OpCompositeExtract %4 %81 0
1092 %83 = OpFMul %4 %79 %82
1093 %84 = OpCompositeExtract %4 %81 1
1094 %85 = OpFMul %4 %80 %84
1095 %86 = OpFAdd %4 %83 %85
1096 %87 = OpCompositeExtract %5 %46 1
1097 %88 = OpCompositeExtract %4 %87 0
1098 %89 = OpFMul %4 %79 %88
1099 %90 = OpCompositeExtract %4 %87 1
1100 %91 = OpFMul %4 %80 %90
1101 %92 = OpFAdd %4 %89 %91
1102 %93 = OpCompositeExtract %5 %46 2
1103 %94 = OpCompositeExtract %4 %93 0
1104 %95 = OpFMul %4 %79 %94
1105 %96 = OpCompositeExtract %4 %93 1
1106 %97 = OpFMul %4 %80 %96
1107 %98 = OpFAdd %4 %95 %97
1108 %57 = OpCompositeConstruct %6 %86 %92 %98
1109
1110 ; Multiplying 2-dimensional vector by 2x4 matrix
1111 %99 = OpCompositeExtract %4 %35 0
1112 %100 = OpCompositeExtract %4 %35 1
1113 %101 = OpCompositeExtract %5 %47 0
1114 %102 = OpCompositeExtract %4 %101 0
1115 %103 = OpFMul %4 %99 %102
1116 %104 = OpCompositeExtract %4 %101 1
1117 %105 = OpFMul %4 %100 %104
1118 %106 = OpFAdd %4 %103 %105
1119 %107 = OpCompositeExtract %5 %47 1
1120 %108 = OpCompositeExtract %4 %107 0
1121 %109 = OpFMul %4 %99 %108
1122 %110 = OpCompositeExtract %4 %107 1
1123 %111 = OpFMul %4 %100 %110
1124 %112 = OpFAdd %4 %109 %111
1125 %113 = OpCompositeExtract %5 %47 2
1126 %114 = OpCompositeExtract %4 %113 0
1127 %115 = OpFMul %4 %99 %114
1128 %116 = OpCompositeExtract %4 %113 1
1129 %117 = OpFMul %4 %100 %116
1130 %118 = OpFAdd %4 %115 %117
1131 %119 = OpCompositeExtract %5 %47 3
1132 %120 = OpCompositeExtract %4 %119 0
1133 %121 = OpFMul %4 %99 %120
1134 %122 = OpCompositeExtract %4 %119 1
1135 %123 = OpFMul %4 %100 %122
1136 %124 = OpFAdd %4 %121 %123
1137 %58 = OpCompositeConstruct %7 %106 %112 %118 %124
1138
1139 ; Multiplying 3-dimensional vector by 3x2 matrix
1140 %125 = OpCompositeExtract %4 %37 0
1141 %126 = OpCompositeExtract %4 %37 1
1142 %127 = OpCompositeExtract %4 %37 2
1143 %128 = OpCompositeExtract %6 %48 0
1144 %129 = OpCompositeExtract %4 %128 0
1145 %130 = OpFMul %4 %125 %129
1146 %131 = OpCompositeExtract %4 %128 1
1147 %132 = OpFMul %4 %126 %131
1148 %133 = OpCompositeExtract %4 %128 2
1149 %134 = OpFMul %4 %127 %133
1150 %135 = OpFAdd %4 %130 %132
1151 %136 = OpFAdd %4 %134 %135
1152 %137 = OpCompositeExtract %6 %48 1
1153 %138 = OpCompositeExtract %4 %137 0
1154 %139 = OpFMul %4 %125 %138
1155 %140 = OpCompositeExtract %4 %137 1
1156 %141 = OpFMul %4 %126 %140
1157 %142 = OpCompositeExtract %4 %137 2
1158 %143 = OpFMul %4 %127 %142
1159 %144 = OpFAdd %4 %139 %141
1160 %145 = OpFAdd %4 %143 %144
1161 %59 = OpCompositeConstruct %5 %136 %145
1162
1163 ; Multiplying 3-dimensional vector by 3x3 matrix
1164 %60 = OpVectorTimesMatrix %6 %38 %49
1165
1166 ; Multiplying 3-dimensional vector by 3x4 matrix
1167 %61 = OpVectorTimesMatrix %7 %39 %50
1168
1169 ; Multiplying 4-dimensional vector by 4x2 matrix
1170 %62 = OpVectorTimesMatrix %5 %41 %51
1171
1172 ; Multiplying 4-dimensional vector by 4x3 matrix
1173 %63 = OpVectorTimesMatrix %6 %42 %52
1174
1175 ; Multiplying 4-dimensional vector by 4x4 matrix
1176 %64 = OpVectorTimesMatrix %7 %43 %53
1177 OpReturn
1178 OpFunctionEnd
1179 )";
1180
1181 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1182 kConsoleMessageConsumer));
1183 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
1184 }
1185
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpMatrixTimesVector)1186 TEST(TransformationReplaceLinearAlgebraInstructionTest,
1187 ReplaceOpMatrixTimesVector) {
1188 std::string reference_shader = R"(
1189 OpCapability Shader
1190 %1 = OpExtInstImport "GLSL.std.450"
1191 OpMemoryModel Logical GLSL450
1192 OpEntryPoint Fragment %54 "main"
1193 OpExecutionMode %54 OriginUpperLeft
1194 OpSource ESSL 310
1195 OpName %54 "main"
1196
1197 ; Types
1198 %2 = OpTypeVoid
1199 %3 = OpTypeFunction %2
1200 %4 = OpTypeFloat 32
1201 %5 = OpTypeVector %4 2
1202 %6 = OpTypeVector %4 3
1203 %7 = OpTypeVector %4 4
1204 %8 = OpTypeMatrix %5 2
1205 %9 = OpTypeMatrix %5 3
1206 %10 = OpTypeMatrix %5 4
1207 %11 = OpTypeMatrix %6 2
1208 %12 = OpTypeMatrix %6 3
1209 %13 = OpTypeMatrix %6 4
1210 %14 = OpTypeMatrix %7 2
1211 %15 = OpTypeMatrix %7 3
1212 %16 = OpTypeMatrix %7 4
1213
1214 ; Constant scalars
1215 %17 = OpConstant %4 1
1216 %18 = OpConstant %4 2
1217 %19 = OpConstant %4 3
1218 %20 = OpConstant %4 4
1219 %21 = OpConstant %4 5
1220 %22 = OpConstant %4 6
1221 %23 = OpConstant %4 7
1222 %24 = OpConstant %4 8
1223 %25 = OpConstant %4 9
1224 %26 = OpConstant %4 10
1225 %27 = OpConstant %4 11
1226 %28 = OpConstant %4 12
1227 %29 = OpConstant %4 13
1228 %30 = OpConstant %4 14
1229 %31 = OpConstant %4 15
1230 %32 = OpConstant %4 16
1231
1232 ; Constant vectors
1233 %33 = OpConstantComposite %5 %17 %18
1234 %34 = OpConstantComposite %5 %19 %20
1235 %35 = OpConstantComposite %5 %21 %22
1236 %36 = OpConstantComposite %5 %23 %24
1237 %37 = OpConstantComposite %6 %17 %18 %19
1238 %38 = OpConstantComposite %6 %20 %21 %22
1239 %39 = OpConstantComposite %6 %23 %24 %25
1240 %40 = OpConstantComposite %6 %26 %27 %28
1241 %41 = OpConstantComposite %7 %17 %18 %19 %20
1242 %42 = OpConstantComposite %7 %21 %22 %23 %24
1243 %43 = OpConstantComposite %7 %25 %26 %27 %28
1244 %44 = OpConstantComposite %7 %29 %30 %31 %32
1245
1246 ; Constant matrices
1247 %45 = OpConstantComposite %8 %33 %34
1248 %46 = OpConstantComposite %9 %33 %34 %35
1249 %47 = OpConstantComposite %10 %33 %34 %35 %36
1250 %48 = OpConstantComposite %11 %37 %38
1251 %49 = OpConstantComposite %12 %37 %38 %39
1252 %50 = OpConstantComposite %13 %37 %38 %39 %40
1253 %51 = OpConstantComposite %14 %41 %42
1254 %52 = OpConstantComposite %15 %41 %42 %43
1255 %53 = OpConstantComposite %16 %41 %42 %43 %44
1256
1257 ; main function
1258 %54 = OpFunction %2 None %3
1259 %55 = OpLabel
1260
1261 ; Multiplying 2x2 matrix by 2-dimensional vector
1262 %56 = OpMatrixTimesVector %5 %45 %33
1263
1264 ; Multiplying 3x2 matrix by 2-dimensional vector
1265 %57 = OpMatrixTimesVector %6 %48 %34
1266
1267 ; Multiplying 4x2 matrix by 2-dimensional vector
1268 %58 = OpMatrixTimesVector %7 %51 %35
1269
1270 ; Multiplying 2x3 matrix by 3-dimensional vector
1271 %59 = OpMatrixTimesVector %5 %46 %37
1272
1273 ; Multiplying 3x3 matrix by 3-dimensional vector
1274 %60 = OpMatrixTimesVector %6 %49 %38
1275
1276 ; Multiplying 4x3 matrix by 3-dimensional vector
1277 %61 = OpMatrixTimesVector %7 %52 %39
1278
1279 ; Multiplying 2x4 matrix by 4-dimensional vector
1280 %62 = OpMatrixTimesVector %5 %47 %41
1281
1282 ; Multiplying 3x4 matrix by 4-dimensional vector
1283 %63 = OpMatrixTimesVector %6 %50 %42
1284
1285 ; Multiplying 4x4 matrix by 4-dimensional vector
1286 %64 = OpMatrixTimesVector %7 %53 %43
1287 OpReturn
1288 OpFunctionEnd
1289 )";
1290
1291 const auto env = SPV_ENV_UNIVERSAL_1_5;
1292 const auto consumer = nullptr;
1293 const auto context =
1294 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
1295 spvtools::ValidatorOptions validator_options;
1296 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1297 kConsoleMessageConsumer));
1298 TransformationContext transformation_context(
1299 MakeUnique<FactManager>(context.get()), validator_options);
1300 auto instruction_descriptor =
1301 MakeInstructionDescriptor(56, SpvOpMatrixTimesVector, 0);
1302 auto transformation = TransformationReplaceLinearAlgebraInstruction(
1303 {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78},
1304 instruction_descriptor);
1305 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1306
1307 instruction_descriptor =
1308 MakeInstructionDescriptor(57, SpvOpMatrixTimesVector, 0);
1309 transformation = TransformationReplaceLinearAlgebraInstruction(
1310 {79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1311 97},
1312 instruction_descriptor);
1313 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1314
1315 instruction_descriptor =
1316 MakeInstructionDescriptor(58, SpvOpMatrixTimesVector, 0);
1317 transformation = TransformationReplaceLinearAlgebraInstruction(
1318 {98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
1319 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121},
1320 instruction_descriptor);
1321 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1322
1323 instruction_descriptor =
1324 MakeInstructionDescriptor(59, SpvOpMatrixTimesVector, 0);
1325 transformation = TransformationReplaceLinearAlgebraInstruction(
1326 {122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,
1327 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143},
1328 instruction_descriptor);
1329 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1330
1331 std::string variant_shader = R"(
1332 OpCapability Shader
1333 %1 = OpExtInstImport "GLSL.std.450"
1334 OpMemoryModel Logical GLSL450
1335 OpEntryPoint Fragment %54 "main"
1336 OpExecutionMode %54 OriginUpperLeft
1337 OpSource ESSL 310
1338 OpName %54 "main"
1339
1340 ; Types
1341 %2 = OpTypeVoid
1342 %3 = OpTypeFunction %2
1343 %4 = OpTypeFloat 32
1344 %5 = OpTypeVector %4 2
1345 %6 = OpTypeVector %4 3
1346 %7 = OpTypeVector %4 4
1347 %8 = OpTypeMatrix %5 2
1348 %9 = OpTypeMatrix %5 3
1349 %10 = OpTypeMatrix %5 4
1350 %11 = OpTypeMatrix %6 2
1351 %12 = OpTypeMatrix %6 3
1352 %13 = OpTypeMatrix %6 4
1353 %14 = OpTypeMatrix %7 2
1354 %15 = OpTypeMatrix %7 3
1355 %16 = OpTypeMatrix %7 4
1356
1357 ; Constant scalars
1358 %17 = OpConstant %4 1
1359 %18 = OpConstant %4 2
1360 %19 = OpConstant %4 3
1361 %20 = OpConstant %4 4
1362 %21 = OpConstant %4 5
1363 %22 = OpConstant %4 6
1364 %23 = OpConstant %4 7
1365 %24 = OpConstant %4 8
1366 %25 = OpConstant %4 9
1367 %26 = OpConstant %4 10
1368 %27 = OpConstant %4 11
1369 %28 = OpConstant %4 12
1370 %29 = OpConstant %4 13
1371 %30 = OpConstant %4 14
1372 %31 = OpConstant %4 15
1373 %32 = OpConstant %4 16
1374
1375 ; Constant vectors
1376 %33 = OpConstantComposite %5 %17 %18
1377 %34 = OpConstantComposite %5 %19 %20
1378 %35 = OpConstantComposite %5 %21 %22
1379 %36 = OpConstantComposite %5 %23 %24
1380 %37 = OpConstantComposite %6 %17 %18 %19
1381 %38 = OpConstantComposite %6 %20 %21 %22
1382 %39 = OpConstantComposite %6 %23 %24 %25
1383 %40 = OpConstantComposite %6 %26 %27 %28
1384 %41 = OpConstantComposite %7 %17 %18 %19 %20
1385 %42 = OpConstantComposite %7 %21 %22 %23 %24
1386 %43 = OpConstantComposite %7 %25 %26 %27 %28
1387 %44 = OpConstantComposite %7 %29 %30 %31 %32
1388
1389 ; Constant matrices
1390 %45 = OpConstantComposite %8 %33 %34
1391 %46 = OpConstantComposite %9 %33 %34 %35
1392 %47 = OpConstantComposite %10 %33 %34 %35 %36
1393 %48 = OpConstantComposite %11 %37 %38
1394 %49 = OpConstantComposite %12 %37 %38 %39
1395 %50 = OpConstantComposite %13 %37 %38 %39 %40
1396 %51 = OpConstantComposite %14 %41 %42
1397 %52 = OpConstantComposite %15 %41 %42 %43
1398 %53 = OpConstantComposite %16 %41 %42 %43 %44
1399
1400 ; main function
1401 %54 = OpFunction %2 None %3
1402 %55 = OpLabel
1403
1404 ; Multiplying 2x2 matrix by 2-dimensional vector
1405 %65 = OpCompositeExtract %5 %45 0
1406 %66 = OpCompositeExtract %5 %45 1
1407 %67 = OpCompositeExtract %4 %33 0
1408 %68 = OpCompositeExtract %4 %33 1
1409 %69 = OpCompositeExtract %4 %65 0
1410 %70 = OpFMul %4 %69 %67
1411 %71 = OpCompositeExtract %4 %66 0
1412 %72 = OpFMul %4 %71 %68
1413 %73 = OpFAdd %4 %70 %72
1414 %74 = OpCompositeExtract %4 %65 1
1415 %75 = OpFMul %4 %74 %67
1416 %76 = OpCompositeExtract %4 %66 1
1417 %77 = OpFMul %4 %76 %68
1418 %78 = OpFAdd %4 %75 %77
1419 %56 = OpCompositeConstruct %5 %73 %78
1420
1421 ; Multiplying 3x2 matrix by 2-dimensional vector
1422 %79 = OpCompositeExtract %6 %48 0
1423 %80 = OpCompositeExtract %6 %48 1
1424 %81 = OpCompositeExtract %4 %34 0
1425 %82 = OpCompositeExtract %4 %34 1
1426 %83 = OpCompositeExtract %4 %79 0
1427 %84 = OpFMul %4 %83 %81
1428 %85 = OpCompositeExtract %4 %80 0
1429 %86 = OpFMul %4 %85 %82
1430 %87 = OpFAdd %4 %84 %86
1431 %88 = OpCompositeExtract %4 %79 1
1432 %89 = OpFMul %4 %88 %81
1433 %90 = OpCompositeExtract %4 %80 1
1434 %91 = OpFMul %4 %90 %82
1435 %92 = OpFAdd %4 %89 %91
1436 %93 = OpCompositeExtract %4 %79 2
1437 %94 = OpFMul %4 %93 %81
1438 %95 = OpCompositeExtract %4 %80 2
1439 %96 = OpFMul %4 %95 %82
1440 %97 = OpFAdd %4 %94 %96
1441 %57 = OpCompositeConstruct %6 %87 %92 %97
1442
1443 ; Multiplying 4x2 matrix by 2-dimensional vector
1444 %98 = OpCompositeExtract %7 %51 0
1445 %99 = OpCompositeExtract %7 %51 1
1446 %100 = OpCompositeExtract %4 %35 0
1447 %101 = OpCompositeExtract %4 %35 1
1448 %102 = OpCompositeExtract %4 %98 0
1449 %103 = OpFMul %4 %102 %100
1450 %104 = OpCompositeExtract %4 %99 0
1451 %105 = OpFMul %4 %104 %101
1452 %106 = OpFAdd %4 %103 %105
1453 %107 = OpCompositeExtract %4 %98 1
1454 %108 = OpFMul %4 %107 %100
1455 %109 = OpCompositeExtract %4 %99 1
1456 %110 = OpFMul %4 %109 %101
1457 %111 = OpFAdd %4 %108 %110
1458 %112 = OpCompositeExtract %4 %98 2
1459 %113 = OpFMul %4 %112 %100
1460 %114 = OpCompositeExtract %4 %99 2
1461 %115 = OpFMul %4 %114 %101
1462 %116 = OpFAdd %4 %113 %115
1463 %117 = OpCompositeExtract %4 %98 3
1464 %118 = OpFMul %4 %117 %100
1465 %119 = OpCompositeExtract %4 %99 3
1466 %120 = OpFMul %4 %119 %101
1467 %121 = OpFAdd %4 %118 %120
1468 %58 = OpCompositeConstruct %7 %106 %111 %116 %121
1469
1470 ; Multiplying 2x3 matrix by 3-dimensional vector
1471 %122 = OpCompositeExtract %5 %46 0
1472 %123 = OpCompositeExtract %5 %46 1
1473 %124 = OpCompositeExtract %5 %46 2
1474 %125 = OpCompositeExtract %4 %37 0
1475 %126 = OpCompositeExtract %4 %37 1
1476 %127 = OpCompositeExtract %4 %37 2
1477 %128 = OpCompositeExtract %4 %122 0
1478 %129 = OpFMul %4 %128 %125
1479 %130 = OpCompositeExtract %4 %123 0
1480 %131 = OpFMul %4 %130 %126
1481 %132 = OpCompositeExtract %4 %124 0
1482 %133 = OpFMul %4 %132 %127
1483 %134 = OpFAdd %4 %129 %131
1484 %135 = OpFAdd %4 %133 %134
1485 %136 = OpCompositeExtract %4 %122 1
1486 %137 = OpFMul %4 %136 %125
1487 %138 = OpCompositeExtract %4 %123 1
1488 %139 = OpFMul %4 %138 %126
1489 %140 = OpCompositeExtract %4 %124 1
1490 %141 = OpFMul %4 %140 %127
1491 %142 = OpFAdd %4 %137 %139
1492 %143 = OpFAdd %4 %141 %142
1493 %59 = OpCompositeConstruct %5 %135 %143
1494
1495 ; Multiplying 3x3 matrix by 3-dimensional vector
1496 %60 = OpMatrixTimesVector %6 %49 %38
1497
1498 ; Multiplying 4x3 matrix by 3-dimensional vector
1499 %61 = OpMatrixTimesVector %7 %52 %39
1500
1501 ; Multiplying 2x4 matrix by 4-dimensional vector
1502 %62 = OpMatrixTimesVector %5 %47 %41
1503
1504 ; Multiplying 3x4 matrix by 4-dimensional vector
1505 %63 = OpMatrixTimesVector %6 %50 %42
1506
1507 ; Multiplying 4x4 matrix by 4-dimensional vector
1508 %64 = OpMatrixTimesVector %7 %53 %43
1509 OpReturn
1510 OpFunctionEnd
1511 )";
1512
1513 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1514 kConsoleMessageConsumer));
1515 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
1516 }
1517
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpMatrixTimesMatrix)1518 TEST(TransformationReplaceLinearAlgebraInstructionTest,
1519 ReplaceOpMatrixTimesMatrix) {
1520 std::string reference_shader = R"(
1521 OpCapability Shader
1522 %1 = OpExtInstImport "GLSL.std.450"
1523 OpMemoryModel Logical GLSL450
1524 OpEntryPoint Fragment %54 "main"
1525 OpExecutionMode %54 OriginUpperLeft
1526 OpSource ESSL 310
1527 OpName %54 "main"
1528
1529 ; Types
1530 %2 = OpTypeVoid
1531 %3 = OpTypeFunction %2
1532 %4 = OpTypeFloat 32
1533 %5 = OpTypeVector %4 2
1534 %6 = OpTypeVector %4 3
1535 %7 = OpTypeVector %4 4
1536 %8 = OpTypeMatrix %5 2
1537 %9 = OpTypeMatrix %5 3
1538 %10 = OpTypeMatrix %5 4
1539 %11 = OpTypeMatrix %6 2
1540 %12 = OpTypeMatrix %6 3
1541 %13 = OpTypeMatrix %6 4
1542 %14 = OpTypeMatrix %7 2
1543 %15 = OpTypeMatrix %7 3
1544 %16 = OpTypeMatrix %7 4
1545
1546 ; Constant scalars
1547 %17 = OpConstant %4 1
1548 %18 = OpConstant %4 2
1549 %19 = OpConstant %4 3
1550 %20 = OpConstant %4 4
1551 %21 = OpConstant %4 5
1552 %22 = OpConstant %4 6
1553 %23 = OpConstant %4 7
1554 %24 = OpConstant %4 8
1555 %25 = OpConstant %4 9
1556 %26 = OpConstant %4 10
1557 %27 = OpConstant %4 11
1558 %28 = OpConstant %4 12
1559 %29 = OpConstant %4 13
1560 %30 = OpConstant %4 14
1561 %31 = OpConstant %4 15
1562 %32 = OpConstant %4 16
1563
1564 ; Constant vectors
1565 %33 = OpConstantComposite %5 %17 %18
1566 %34 = OpConstantComposite %5 %19 %20
1567 %35 = OpConstantComposite %5 %21 %22
1568 %36 = OpConstantComposite %5 %23 %24
1569 %37 = OpConstantComposite %6 %17 %18 %19
1570 %38 = OpConstantComposite %6 %20 %21 %22
1571 %39 = OpConstantComposite %6 %23 %24 %25
1572 %40 = OpConstantComposite %6 %26 %27 %28
1573 %41 = OpConstantComposite %7 %17 %18 %19 %20
1574 %42 = OpConstantComposite %7 %21 %22 %23 %24
1575 %43 = OpConstantComposite %7 %25 %26 %27 %28
1576 %44 = OpConstantComposite %7 %29 %30 %31 %32
1577
1578 ; Constant matrices
1579 %45 = OpConstantComposite %8 %33 %34
1580 %46 = OpConstantComposite %9 %33 %34 %35
1581 %47 = OpConstantComposite %10 %33 %34 %35 %36
1582 %48 = OpConstantComposite %11 %37 %38
1583 %49 = OpConstantComposite %12 %37 %38 %39
1584 %50 = OpConstantComposite %13 %37 %38 %39 %40
1585 %51 = OpConstantComposite %14 %41 %42
1586 %52 = OpConstantComposite %15 %41 %42 %43
1587 %53 = OpConstantComposite %16 %41 %42 %43 %44
1588
1589 ; main function
1590 %54 = OpFunction %2 None %3
1591 %55 = OpLabel
1592
1593 ; Multiplying 2x2 matrix by 2x2 matrix
1594 %56 = OpMatrixTimesMatrix %8 %45 %45
1595
1596 ; Multiplying 2x2 matrix by 2x3 matrix
1597 %57 = OpMatrixTimesMatrix %9 %45 %46
1598
1599 ; Multiplying 2x2 matrix by 2x4 matrix
1600 %58 = OpMatrixTimesMatrix %10 %45 %47
1601
1602 ; Multiplying 2x3 matrix by 3x2 matrix
1603 %59 = OpMatrixTimesMatrix %8 %46 %48
1604
1605 ; Multiplying 2x3 matrix by 3x3 matrix
1606 %60 = OpMatrixTimesMatrix %9 %46 %49
1607
1608 ; Multiplying 2x3 matrix by 3x4 matrix
1609 %61 = OpMatrixTimesMatrix %10 %46 %50
1610
1611 ; Multiplying 2x4 matrix by 4x2 matrix
1612 %62 = OpMatrixTimesMatrix %8 %47 %51
1613
1614 ; Multiplying 2x4 matrix by 4x3 matrix
1615 %63 = OpMatrixTimesMatrix %9 %47 %52
1616
1617 ; Multiplying 2x4 matrix by 4x4 matrix
1618 %64 = OpMatrixTimesMatrix %10 %47 %53
1619
1620 ; Multiplying 3x2 matrix by 2x2 matrix
1621 %65 = OpMatrixTimesMatrix %11 %48 %45
1622
1623 ; Multiplying 3x2 matrix by 2x3 matrix
1624 %66 = OpMatrixTimesMatrix %12 %48 %46
1625
1626 ; Multiplying 3x2 matrix by 2x4 matrix
1627 %67 = OpMatrixTimesMatrix %13 %48 %47
1628
1629 ; Multiplying 3x3 matrix by 3x2 matrix
1630 %68 = OpMatrixTimesMatrix %11 %49 %48
1631
1632 ; Multiplying 3x3 matrix by 3x3 matrix
1633 %69 = OpMatrixTimesMatrix %12 %49 %49
1634
1635 ; Multiplying 3x3 matrix by 3x4 matrix
1636 %70 = OpMatrixTimesMatrix %13 %49 %50
1637
1638 ; Multiplying 3x4 matrix by 4x2 matrix
1639 %71 = OpMatrixTimesMatrix %11 %50 %51
1640
1641 ; Multiplying 3x4 matrix by 4x3 matrix
1642 %72 = OpMatrixTimesMatrix %12 %50 %52
1643
1644 ; Multiplying 3x4 matrix by 4x4 matrix
1645 %73 = OpMatrixTimesMatrix %13 %50 %53
1646
1647 ; Multiplying 4x2 matrix by 2x2 matrix
1648 %74 = OpMatrixTimesMatrix %14 %51 %45
1649
1650 ; Multiplying 4x2 matrix by 2x3 matrix
1651 %75 = OpMatrixTimesMatrix %15 %51 %46
1652
1653 ; Multiplying 4x2 matrix by 2x4 matrix
1654 %76 = OpMatrixTimesMatrix %16 %51 %47
1655
1656 ; Multiplying 4x3 matrix by 3x2 matrix
1657 %77 = OpMatrixTimesMatrix %14 %52 %48
1658
1659 ; Multiplying 4x3 matrix by 3x3 matrix
1660 %78 = OpMatrixTimesMatrix %15 %52 %49
1661
1662 ; Multiplying 4x3 matrix by 3x4 matrix
1663 %79 = OpMatrixTimesMatrix %16 %52 %50
1664
1665 ; Multiplying 4x4 matrix by 4x2 matrix
1666 %80 = OpMatrixTimesMatrix %14 %53 %51
1667
1668 ; Multiplying 4x4 matrix by 4x3 matrix
1669 %81 = OpMatrixTimesMatrix %15 %53 %52
1670
1671 ; Multiplying 4x4 matrix by 4x4 matrix
1672 %82 = OpMatrixTimesMatrix %16 %53 %53
1673 OpReturn
1674 OpFunctionEnd
1675 )";
1676
1677 const auto env = SPV_ENV_UNIVERSAL_1_5;
1678 const auto consumer = nullptr;
1679 const auto context =
1680 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
1681 spvtools::ValidatorOptions validator_options;
1682 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1683 kConsoleMessageConsumer));
1684 TransformationContext transformation_context(
1685 MakeUnique<FactManager>(context.get()), validator_options);
1686 auto instruction_descriptor =
1687 MakeInstructionDescriptor(56, SpvOpMatrixTimesMatrix, 0);
1688 auto transformation = TransformationReplaceLinearAlgebraInstruction(
1689 {83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
1690 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
1691 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122},
1692 instruction_descriptor);
1693 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1694
1695 instruction_descriptor =
1696 MakeInstructionDescriptor(57, SpvOpMatrixTimesMatrix, 0);
1697 transformation = TransformationReplaceLinearAlgebraInstruction(
1698 {123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
1699 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
1700 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
1701 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
1702 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182},
1703 instruction_descriptor);
1704 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1705
1706 instruction_descriptor =
1707 MakeInstructionDescriptor(58, SpvOpMatrixTimesMatrix, 0);
1708 transformation = TransformationReplaceLinearAlgebraInstruction(
1709 {183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
1710 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
1711 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
1712 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
1713 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
1714 253, 254, 255, 256, 257, 258, 259, 260, 261, 262},
1715 instruction_descriptor);
1716 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
1717
1718 std::string variant_shader = R"(
1719 OpCapability Shader
1720 %1 = OpExtInstImport "GLSL.std.450"
1721 OpMemoryModel Logical GLSL450
1722 OpEntryPoint Fragment %54 "main"
1723 OpExecutionMode %54 OriginUpperLeft
1724 OpSource ESSL 310
1725 OpName %54 "main"
1726
1727 ; Types
1728 %2 = OpTypeVoid
1729 %3 = OpTypeFunction %2
1730 %4 = OpTypeFloat 32
1731 %5 = OpTypeVector %4 2
1732 %6 = OpTypeVector %4 3
1733 %7 = OpTypeVector %4 4
1734 %8 = OpTypeMatrix %5 2
1735 %9 = OpTypeMatrix %5 3
1736 %10 = OpTypeMatrix %5 4
1737 %11 = OpTypeMatrix %6 2
1738 %12 = OpTypeMatrix %6 3
1739 %13 = OpTypeMatrix %6 4
1740 %14 = OpTypeMatrix %7 2
1741 %15 = OpTypeMatrix %7 3
1742 %16 = OpTypeMatrix %7 4
1743
1744 ; Constant scalars
1745 %17 = OpConstant %4 1
1746 %18 = OpConstant %4 2
1747 %19 = OpConstant %4 3
1748 %20 = OpConstant %4 4
1749 %21 = OpConstant %4 5
1750 %22 = OpConstant %4 6
1751 %23 = OpConstant %4 7
1752 %24 = OpConstant %4 8
1753 %25 = OpConstant %4 9
1754 %26 = OpConstant %4 10
1755 %27 = OpConstant %4 11
1756 %28 = OpConstant %4 12
1757 %29 = OpConstant %4 13
1758 %30 = OpConstant %4 14
1759 %31 = OpConstant %4 15
1760 %32 = OpConstant %4 16
1761
1762 ; Constant vectors
1763 %33 = OpConstantComposite %5 %17 %18
1764 %34 = OpConstantComposite %5 %19 %20
1765 %35 = OpConstantComposite %5 %21 %22
1766 %36 = OpConstantComposite %5 %23 %24
1767 %37 = OpConstantComposite %6 %17 %18 %19
1768 %38 = OpConstantComposite %6 %20 %21 %22
1769 %39 = OpConstantComposite %6 %23 %24 %25
1770 %40 = OpConstantComposite %6 %26 %27 %28
1771 %41 = OpConstantComposite %7 %17 %18 %19 %20
1772 %42 = OpConstantComposite %7 %21 %22 %23 %24
1773 %43 = OpConstantComposite %7 %25 %26 %27 %28
1774 %44 = OpConstantComposite %7 %29 %30 %31 %32
1775
1776 ; Constant matrices
1777 %45 = OpConstantComposite %8 %33 %34
1778 %46 = OpConstantComposite %9 %33 %34 %35
1779 %47 = OpConstantComposite %10 %33 %34 %35 %36
1780 %48 = OpConstantComposite %11 %37 %38
1781 %49 = OpConstantComposite %12 %37 %38 %39
1782 %50 = OpConstantComposite %13 %37 %38 %39 %40
1783 %51 = OpConstantComposite %14 %41 %42
1784 %52 = OpConstantComposite %15 %41 %42 %43
1785 %53 = OpConstantComposite %16 %41 %42 %43 %44
1786
1787 ; main function
1788 %54 = OpFunction %2 None %3
1789 %55 = OpLabel
1790
1791 ; Multiplying 2x2 matrix by 2x2 matrix
1792 %83 = OpCompositeExtract %5 %45 0 ; matrix 2 column 0
1793 %84 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1794 %85 = OpCompositeExtract %4 %84 0 ; matrix 1 row 0 column 0
1795 %86 = OpCompositeExtract %4 %83 0 ; matrix 2 row 0 column 0
1796 %87 = OpFMul %4 %85 %86
1797 %88 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1798 %89 = OpCompositeExtract %4 %88 0 ; matrix 1 row 0 column 1
1799 %90 = OpCompositeExtract %4 %83 1 ; matrix 2 row 1 column 0
1800 %91 = OpFMul %4 %89 %90
1801 %92 = OpFAdd %4 %87 %91
1802 %93 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1803 %94 = OpCompositeExtract %4 %93 1 ; matrix 1 row 1 column 0
1804 %95 = OpCompositeExtract %4 %83 0 ; matrix 2 row 0 column 0
1805 %96 = OpFMul %4 %94 %95
1806 %97 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1807 %98 = OpCompositeExtract %4 %97 1 ; matrix 1 row 1 column 1
1808 %99 = OpCompositeExtract %4 %83 1 ; matrix 2 row 1 column 0
1809 %100 = OpFMul %4 %98 %99
1810 %101 = OpFAdd %4 %96 %100
1811 %102 = OpCompositeConstruct %5 %92 %101 ; resulting matrix column 0
1812 %103 = OpCompositeExtract %5 %45 1 ; matrix 2 column 1
1813 %104 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1814 %105 = OpCompositeExtract %4 %104 0 ; matrix 1 row 0 column 0
1815 %106 = OpCompositeExtract %4 %103 0 ; matrix 2 row 0 column 1
1816 %107 = OpFMul %4 %105 %106
1817 %108 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1818 %109 = OpCompositeExtract %4 %108 0 ; matrix 1 row 0 column 1
1819 %110 = OpCompositeExtract %4 %103 1 ; matrix 2 row 1 column 1
1820 %111 = OpFMul %4 %109 %110
1821 %112 = OpFAdd %4 %107 %111
1822 %113 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1823 %114 = OpCompositeExtract %4 %113 1 ; matrix 1 row 1 column 0
1824 %115 = OpCompositeExtract %4 %103 0 ; matrix 2 row 0 column 1
1825 %116 = OpFMul %4 %114 %115
1826 %117 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1827 %118 = OpCompositeExtract %4 %117 1 ; matrix 1 row 1 column 1
1828 %119 = OpCompositeExtract %4 %103 1 ; matrix 2 row 1 column 1
1829 %120 = OpFMul %4 %118 %119
1830 %121 = OpFAdd %4 %116 %120
1831 %122 = OpCompositeConstruct %5 %112 %121 ; resulting matrix column 1
1832 %56 = OpCompositeConstruct %8 %102 %122 ; resulting matrix
1833
1834 ; Multiplying 2x2 matrix by 2x3 matrix
1835 %123 = OpCompositeExtract %5 %46 0 ; matrix 2 column 0
1836 %124 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1837 %125 = OpCompositeExtract %4 %124 0 ; matrix 1 row 0 column 0
1838 %126 = OpCompositeExtract %4 %123 0 ; matrix 2 row 0 column 0
1839 %127 = OpFMul %4 %125 %126
1840 %128 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1841 %129 = OpCompositeExtract %4 %128 0 ; matrix 1 row 0 column 1
1842 %130 = OpCompositeExtract %4 %123 1 ; matrix 2 row 1 column 0
1843 %131 = OpFMul %4 %129 %130
1844 %132 = OpFAdd %4 %127 %131
1845 %133 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1846 %134 = OpCompositeExtract %4 %133 1 ; matrix 1 row 1 column 0
1847 %135 = OpCompositeExtract %4 %123 0 ; matrix 2 row 0 column 0
1848 %136 = OpFMul %4 %134 %135
1849 %137 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1850 %138 = OpCompositeExtract %4 %137 1 ; matrix 1 row 1 column 1
1851 %139 = OpCompositeExtract %4 %123 1 ; matrix 2 row 1 column 0
1852 %140 = OpFMul %4 %138 %139
1853 %141 = OpFAdd %4 %136 %140
1854 %142 = OpCompositeConstruct %5 %132 %141 ; resulting matrix column 0
1855 %143 = OpCompositeExtract %5 %46 1 ; matrix 2 column 1
1856 %144 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1857 %145 = OpCompositeExtract %4 %144 0 ; matrix 1 row 0 column 0
1858 %146 = OpCompositeExtract %4 %143 0 ; matrix 2 row 0 column 1
1859 %147 = OpFMul %4 %145 %146
1860 %148 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1861 %149 = OpCompositeExtract %4 %148 0 ; matrix 1 row 0 column 1
1862 %150 = OpCompositeExtract %4 %143 1 ; matrix 2 row 1 column 1
1863 %151 = OpFMul %4 %149 %150
1864 %152 = OpFAdd %4 %147 %151
1865 %153 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1866 %154 = OpCompositeExtract %4 %153 1 ; matrix 1 row 1 column 0
1867 %155 = OpCompositeExtract %4 %143 0 ; matrix 2 row 0 column 1
1868 %156 = OpFMul %4 %154 %155
1869 %157 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1870 %158 = OpCompositeExtract %4 %157 1 ; matrix 1 row 1 column 1
1871 %159 = OpCompositeExtract %4 %143 1 ; matrix 2 row 1 column 1
1872 %160 = OpFMul %4 %158 %159
1873 %161 = OpFAdd %4 %156 %160
1874 %162 = OpCompositeConstruct %5 %152 %161 ; resulting matrix column 1
1875 %163 = OpCompositeExtract %5 %46 2 ; matrix 2 column 2
1876 %164 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1877 %165 = OpCompositeExtract %4 %164 0 ; matrix 1 row 0 column 0
1878 %166 = OpCompositeExtract %4 %163 0 ; matrix 2 row 0 column 2
1879 %167 = OpFMul %4 %165 %166
1880 %168 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1881 %169 = OpCompositeExtract %4 %168 0 ; matrix 1 row 0 column 1
1882 %170 = OpCompositeExtract %4 %163 1 ; matrix 2 row 1 column 2
1883 %171 = OpFMul %4 %169 %170
1884 %172 = OpFAdd %4 %167 %171
1885 %173 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1886 %174 = OpCompositeExtract %4 %173 1 ; matrix 1 row 1 column 0
1887 %175 = OpCompositeExtract %4 %163 0 ; matrix 2 row 0 column 2
1888 %176 = OpFMul %4 %174 %175
1889 %177 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1890 %178 = OpCompositeExtract %4 %177 1 ; matrix 1 row 1 column 1
1891 %179 = OpCompositeExtract %4 %163 1 ; matrix 2 row 1 column 2
1892 %180 = OpFMul %4 %178 %179
1893 %181 = OpFAdd %4 %176 %180
1894 %182 = OpCompositeConstruct %5 %172 %181 ; resulting matrix column 2
1895 %57 = OpCompositeConstruct %9 %142 %162 %182
1896
1897 ; Multiplying 2x2 matrix by 2x4 matrix
1898 %183 = OpCompositeExtract %5 %47 0 ; matrix 2 column 0
1899 %184 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1900 %185 = OpCompositeExtract %4 %184 0 ; matrix 1 row 0 column 0
1901 %186 = OpCompositeExtract %4 %183 0 ; matrix 2 row 0 column 0
1902 %187 = OpFMul %4 %185 %186
1903 %188 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1904 %189 = OpCompositeExtract %4 %188 0 ; matrix 1 row 0 column 1
1905 %190 = OpCompositeExtract %4 %183 1 ; matrix 2 row 1 column 0
1906 %191 = OpFMul %4 %189 %190
1907 %192 = OpFAdd %4 %187 %191
1908 %193 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1909 %194 = OpCompositeExtract %4 %193 1 ; matrix 1 row 1 column 0
1910 %195 = OpCompositeExtract %4 %183 0 ; matrix 2 row 0 column 0
1911 %196 = OpFMul %4 %194 %195
1912 %197 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1913 %198 = OpCompositeExtract %4 %197 1 ; matrix 1 row 1 column 1
1914 %199 = OpCompositeExtract %4 %183 1 ; matrix 2 row 1 column 0
1915 %200 = OpFMul %4 %198 %199
1916 %201 = OpFAdd %4 %196 %200
1917 %202 = OpCompositeConstruct %5 %192 %201 ; resulting matrix column 0
1918 %203 = OpCompositeExtract %5 %47 1 ; matrix 2 column 1
1919 %204 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1920 %205 = OpCompositeExtract %4 %204 0 ; matrix 1 row 0 column 0
1921 %206 = OpCompositeExtract %4 %203 0 ; matrix 2 row 0 column 1
1922 %207 = OpFMul %4 %205 %206
1923 %208 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1924 %209 = OpCompositeExtract %4 %208 0 ; matrix 1 row 0 column 1
1925 %210 = OpCompositeExtract %4 %203 1 ; matrix 2 row 1 column 1
1926 %211 = OpFMul %4 %209 %210
1927 %212 = OpFAdd %4 %207 %211
1928 %213 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1929 %214 = OpCompositeExtract %4 %213 1 ; matrix 1 row 1 column 0
1930 %215 = OpCompositeExtract %4 %203 0 ; matrix 2 row 0 column 1
1931 %216 = OpFMul %4 %214 %215
1932 %217 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1933 %218 = OpCompositeExtract %4 %217 1 ; matrix 1 row 1 column 1
1934 %219 = OpCompositeExtract %4 %203 1 ; matrix 2 row 1 column 1
1935 %220 = OpFMul %4 %218 %219
1936 %221 = OpFAdd %4 %216 %220
1937 %222 = OpCompositeConstruct %5 %212 %221 ; resulting matrix column 1
1938 %223 = OpCompositeExtract %5 %47 2 ; matrix 2 column 2
1939 %224 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1940 %225 = OpCompositeExtract %4 %224 0 ; matrix 1 row 0 column 0
1941 %226 = OpCompositeExtract %4 %223 0 ; matrix 2 row 0 column 2
1942 %227 = OpFMul %4 %225 %226
1943 %228 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1944 %229 = OpCompositeExtract %4 %228 0 ; matrix 1 row 0 column 1
1945 %230 = OpCompositeExtract %4 %223 1 ; matrix 2 row 1 column 2
1946 %231 = OpFMul %4 %229 %230
1947 %232 = OpFAdd %4 %227 %231
1948 %233 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1949 %234 = OpCompositeExtract %4 %233 1 ; matrix 1 row 1 column 0
1950 %235 = OpCompositeExtract %4 %223 0 ; matrix 2 row 0 column 2
1951 %236 = OpFMul %4 %234 %235
1952 %237 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1953 %238 = OpCompositeExtract %4 %237 1 ; matrix 1 row 1 column 1
1954 %239 = OpCompositeExtract %4 %223 1 ; matrix 2 row 1 column 2
1955 %240 = OpFMul %4 %238 %239
1956 %241 = OpFAdd %4 %236 %240
1957 %242 = OpCompositeConstruct %5 %232 %241 ; resulting matrix column 2
1958 %243 = OpCompositeExtract %5 %47 3 ; matrix 2 column 3
1959 %244 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1960 %245 = OpCompositeExtract %4 %244 0 ; matrix 1 row 0 column 0
1961 %246 = OpCompositeExtract %4 %243 0 ; matrix 2 row 0 column 3
1962 %247 = OpFMul %4 %245 %246
1963 %248 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1964 %249 = OpCompositeExtract %4 %248 0 ; matrix 1 row 0 column 1
1965 %250 = OpCompositeExtract %4 %243 1 ; matrix 2 row 1 column 3
1966 %251 = OpFMul %4 %249 %250
1967 %252 = OpFAdd %4 %247 %251
1968 %253 = OpCompositeExtract %5 %45 0 ; matrix 1 column 0
1969 %254 = OpCompositeExtract %4 %253 1 ; matrix 1 row 1 column 0
1970 %255 = OpCompositeExtract %4 %243 0 ; matrix 2 row 0 column 3
1971 %256 = OpFMul %4 %254 %255
1972 %257 = OpCompositeExtract %5 %45 1 ; matrix 1 column 1
1973 %258 = OpCompositeExtract %4 %257 1 ; matrix 1 row 1 column 1
1974 %259 = OpCompositeExtract %4 %243 1 ; matrix 2 row 1 column 3
1975 %260 = OpFMul %4 %258 %259
1976 %261 = OpFAdd %4 %256 %260
1977 %262 = OpCompositeConstruct %5 %252 %261 ; resulting matrix column 3
1978 %58 = OpCompositeConstruct %10 %202 %222 %242 %262
1979
1980 ; Multiplying 2x3 matrix by 3x2 matrix
1981 %59 = OpMatrixTimesMatrix %8 %46 %48
1982
1983 ; Multiplying 2x3 matrix by 3x3 matrix
1984 %60 = OpMatrixTimesMatrix %9 %46 %49
1985
1986 ; Multiplying 2x3 matrix by 3x4 matrix
1987 %61 = OpMatrixTimesMatrix %10 %46 %50
1988
1989 ; Multiplying 2x4 matrix by 4x2 matrix
1990 %62 = OpMatrixTimesMatrix %8 %47 %51
1991
1992 ; Multiplying 2x4 matrix by 4x3 matrix
1993 %63 = OpMatrixTimesMatrix %9 %47 %52
1994
1995 ; Multiplying 2x4 matrix by 4x4 matrix
1996 %64 = OpMatrixTimesMatrix %10 %47 %53
1997
1998 ; Multiplying 3x2 matrix by 2x2 matrix
1999 %65 = OpMatrixTimesMatrix %11 %48 %45
2000
2001 ; Multiplying 3x2 matrix by 2x3 matrix
2002 %66 = OpMatrixTimesMatrix %12 %48 %46
2003
2004 ; Multiplying 3x2 matrix by 2x4 matrix
2005 %67 = OpMatrixTimesMatrix %13 %48 %47
2006
2007 ; Multiplying 3x3 matrix by 3x2 matrix
2008 %68 = OpMatrixTimesMatrix %11 %49 %48
2009
2010 ; Multiplying 3x3 matrix by 3x3 matrix
2011 %69 = OpMatrixTimesMatrix %12 %49 %49
2012
2013 ; Multiplying 3x3 matrix by 3x4 matrix
2014 %70 = OpMatrixTimesMatrix %13 %49 %50
2015
2016 ; Multiplying 3x4 matrix by 4x2 matrix
2017 %71 = OpMatrixTimesMatrix %11 %50 %51
2018
2019 ; Multiplying 3x4 matrix by 4x3 matrix
2020 %72 = OpMatrixTimesMatrix %12 %50 %52
2021
2022 ; Multiplying 3x4 matrix by 4x4 matrix
2023 %73 = OpMatrixTimesMatrix %13 %50 %53
2024
2025 ; Multiplying 4x2 matrix by 2x2 matrix
2026 %74 = OpMatrixTimesMatrix %14 %51 %45
2027
2028 ; Multiplying 4x2 matrix by 2x3 matrix
2029 %75 = OpMatrixTimesMatrix %15 %51 %46
2030
2031 ; Multiplying 4x2 matrix by 2x4 matrix
2032 %76 = OpMatrixTimesMatrix %16 %51 %47
2033
2034 ; Multiplying 4x3 matrix by 3x2 matrix
2035 %77 = OpMatrixTimesMatrix %14 %52 %48
2036
2037 ; Multiplying 4x3 matrix by 3x3 matrix
2038 %78 = OpMatrixTimesMatrix %15 %52 %49
2039
2040 ; Multiplying 4x3 matrix by 3x4 matrix
2041 %79 = OpMatrixTimesMatrix %16 %52 %50
2042
2043 ; Multiplying 4x4 matrix by 4x2 matrix
2044 %80 = OpMatrixTimesMatrix %14 %53 %51
2045
2046 ; Multiplying 4x4 matrix by 4x3 matrix
2047 %81 = OpMatrixTimesMatrix %15 %53 %52
2048
2049 ; Multiplying 4x4 matrix by 4x4 matrix
2050 %82 = OpMatrixTimesMatrix %16 %53 %53
2051 OpReturn
2052 OpFunctionEnd
2053 )";
2054
2055 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
2056 kConsoleMessageConsumer));
2057 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
2058 }
2059
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpOuterProduct)2060 TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpOuterProduct) {
2061 std::string reference_shader = R"(
2062 OpCapability Shader
2063 %1 = OpExtInstImport "GLSL.std.450"
2064 OpMemoryModel Logical GLSL450
2065 OpEntryPoint Vertex %45 "main"
2066
2067 ; Types
2068 %2 = OpTypeVoid
2069 %3 = OpTypeFunction %2
2070 %4 = OpTypeFloat 32
2071 %5 = OpTypeVector %4 2
2072 %6 = OpTypeVector %4 3
2073 %7 = OpTypeVector %4 4
2074 %8 = OpTypeMatrix %5 2
2075 %9 = OpTypeMatrix %5 3
2076 %10 = OpTypeMatrix %5 4
2077 %11 = OpTypeMatrix %6 2
2078 %12 = OpTypeMatrix %6 3
2079 %13 = OpTypeMatrix %6 4
2080 %14 = OpTypeMatrix %7 2
2081 %15 = OpTypeMatrix %7 3
2082 %16 = OpTypeMatrix %7 4
2083
2084 ; Constant scalars
2085 %17 = OpConstant %4 1
2086 %18 = OpConstant %4 2
2087 %19 = OpConstant %4 3
2088 %20 = OpConstant %4 4
2089 %21 = OpConstant %4 5
2090 %22 = OpConstant %4 6
2091 %23 = OpConstant %4 7
2092 %24 = OpConstant %4 8
2093 %25 = OpConstant %4 9
2094 %26 = OpConstant %4 10
2095 %27 = OpConstant %4 11
2096 %28 = OpConstant %4 12
2097 %29 = OpConstant %4 13
2098 %30 = OpConstant %4 14
2099 %31 = OpConstant %4 15
2100 %32 = OpConstant %4 16
2101
2102 ; Constant vectors
2103 %33 = OpConstantComposite %5 %17 %18
2104 %34 = OpConstantComposite %5 %19 %20
2105 %35 = OpConstantComposite %5 %21 %22
2106 %36 = OpConstantComposite %5 %23 %24
2107 %37 = OpConstantComposite %6 %17 %18 %19
2108 %38 = OpConstantComposite %6 %20 %21 %22
2109 %39 = OpConstantComposite %6 %23 %24 %25
2110 %40 = OpConstantComposite %6 %26 %27 %28
2111 %41 = OpConstantComposite %7 %17 %18 %19 %20
2112 %42 = OpConstantComposite %7 %21 %22 %23 %24
2113 %43 = OpConstantComposite %7 %25 %26 %27 %28
2114 %44 = OpConstantComposite %7 %29 %30 %31 %32
2115
2116 ; main function
2117 %45 = OpFunction %2 None %3
2118 %46 = OpLabel
2119
2120 ; Multiplying 2-dimensional vector by 2-dimensional vector
2121 %47 = OpOuterProduct %8 %33 %34
2122
2123 ; Multiplying 2-dimensional vector by 3-dimensional vector
2124 %48 = OpOuterProduct %9 %35 %37
2125
2126 ; Multiplying 2-dimensional vector by 4-dimensional vector
2127 %49 = OpOuterProduct %10 %36 %41
2128
2129 ; Multiplying 3-dimensional vector by 2-dimensional vector
2130 %50 = OpOuterProduct %11 %37 %33
2131
2132 ; Multiplying 3-dimensional vector by 3-dimensional vector
2133 %51 = OpOuterProduct %12 %38 %39
2134
2135 ; Multiplying 3-dimensional vector by 4-dimensional vector
2136 %52 = OpOuterProduct %13 %40 %41
2137
2138 ; Multiplying 4-dimensional vector by 2-dimensional vector
2139 %53 = OpOuterProduct %14 %41 %33
2140
2141 ; Multiplying 4-dimensional vector by 3-dimensional vector
2142 %54 = OpOuterProduct %15 %42 %37
2143
2144 ; Multiplying 4-dimensional vector by 4-dimensional vector
2145 %55 = OpOuterProduct %16 %43 %44
2146 OpReturn
2147 OpFunctionEnd
2148 )";
2149
2150 const auto env = SPV_ENV_UNIVERSAL_1_5;
2151 const auto consumer = nullptr;
2152 const auto context =
2153 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
2154 spvtools::ValidatorOptions validator_options;
2155 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
2156 kConsoleMessageConsumer));
2157 TransformationContext transformation_context(
2158 MakeUnique<FactManager>(context.get()), validator_options);
2159 auto instruction_descriptor =
2160 MakeInstructionDescriptor(47, SpvOpOuterProduct, 0);
2161 auto transformation = TransformationReplaceLinearAlgebraInstruction(
2162 {56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67}, instruction_descriptor);
2163 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2164
2165 instruction_descriptor = MakeInstructionDescriptor(48, SpvOpOuterProduct, 0);
2166 transformation = TransformationReplaceLinearAlgebraInstruction(
2167 {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85},
2168 instruction_descriptor);
2169 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2170
2171 instruction_descriptor = MakeInstructionDescriptor(49, SpvOpOuterProduct, 0);
2172 transformation = TransformationReplaceLinearAlgebraInstruction(
2173 {86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
2174 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109},
2175 instruction_descriptor);
2176 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2177
2178 instruction_descriptor = MakeInstructionDescriptor(50, SpvOpOuterProduct, 0);
2179 transformation = TransformationReplaceLinearAlgebraInstruction(
2180 {110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
2181 124, 125},
2182 instruction_descriptor);
2183 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2184
2185 std::string variant_shader = R"(
2186 OpCapability Shader
2187 %1 = OpExtInstImport "GLSL.std.450"
2188 OpMemoryModel Logical GLSL450
2189 OpEntryPoint Vertex %45 "main"
2190
2191 ; Types
2192 %2 = OpTypeVoid
2193 %3 = OpTypeFunction %2
2194 %4 = OpTypeFloat 32
2195 %5 = OpTypeVector %4 2
2196 %6 = OpTypeVector %4 3
2197 %7 = OpTypeVector %4 4
2198 %8 = OpTypeMatrix %5 2
2199 %9 = OpTypeMatrix %5 3
2200 %10 = OpTypeMatrix %5 4
2201 %11 = OpTypeMatrix %6 2
2202 %12 = OpTypeMatrix %6 3
2203 %13 = OpTypeMatrix %6 4
2204 %14 = OpTypeMatrix %7 2
2205 %15 = OpTypeMatrix %7 3
2206 %16 = OpTypeMatrix %7 4
2207
2208 ; Constant scalars
2209 %17 = OpConstant %4 1
2210 %18 = OpConstant %4 2
2211 %19 = OpConstant %4 3
2212 %20 = OpConstant %4 4
2213 %21 = OpConstant %4 5
2214 %22 = OpConstant %4 6
2215 %23 = OpConstant %4 7
2216 %24 = OpConstant %4 8
2217 %25 = OpConstant %4 9
2218 %26 = OpConstant %4 10
2219 %27 = OpConstant %4 11
2220 %28 = OpConstant %4 12
2221 %29 = OpConstant %4 13
2222 %30 = OpConstant %4 14
2223 %31 = OpConstant %4 15
2224 %32 = OpConstant %4 16
2225
2226 ; Constant vectors
2227 %33 = OpConstantComposite %5 %17 %18
2228 %34 = OpConstantComposite %5 %19 %20
2229 %35 = OpConstantComposite %5 %21 %22
2230 %36 = OpConstantComposite %5 %23 %24
2231 %37 = OpConstantComposite %6 %17 %18 %19
2232 %38 = OpConstantComposite %6 %20 %21 %22
2233 %39 = OpConstantComposite %6 %23 %24 %25
2234 %40 = OpConstantComposite %6 %26 %27 %28
2235 %41 = OpConstantComposite %7 %17 %18 %19 %20
2236 %42 = OpConstantComposite %7 %21 %22 %23 %24
2237 %43 = OpConstantComposite %7 %25 %26 %27 %28
2238 %44 = OpConstantComposite %7 %29 %30 %31 %32
2239
2240 ; main function
2241 %45 = OpFunction %2 None %3
2242 %46 = OpLabel
2243
2244 ; Multiplying 2-dimensional vector by 2-dimensional vector
2245 %56 = OpCompositeExtract %4 %34 0
2246 %57 = OpCompositeExtract %4 %33 0
2247 %58 = OpFMul %4 %56 %57
2248 %59 = OpCompositeExtract %4 %33 1
2249 %60 = OpFMul %4 %56 %59
2250 %61 = OpCompositeConstruct %5 %58 %60
2251 %62 = OpCompositeExtract %4 %34 1
2252 %63 = OpCompositeExtract %4 %33 0
2253 %64 = OpFMul %4 %62 %63
2254 %65 = OpCompositeExtract %4 %33 1
2255 %66 = OpFMul %4 %62 %65
2256 %67 = OpCompositeConstruct %5 %64 %66
2257 %47 = OpCompositeConstruct %8 %61 %67
2258
2259 ; Multiplying 2-dimensional vector by 3-dimensional vector
2260 %68 = OpCompositeExtract %4 %37 0
2261 %69 = OpCompositeExtract %4 %35 0
2262 %70 = OpFMul %4 %68 %69
2263 %71 = OpCompositeExtract %4 %35 1
2264 %72 = OpFMul %4 %68 %71
2265 %73 = OpCompositeConstruct %5 %70 %72
2266 %74 = OpCompositeExtract %4 %37 1
2267 %75 = OpCompositeExtract %4 %35 0
2268 %76 = OpFMul %4 %74 %75
2269 %77 = OpCompositeExtract %4 %35 1
2270 %78 = OpFMul %4 %74 %77
2271 %79 = OpCompositeConstruct %5 %76 %78
2272 %80 = OpCompositeExtract %4 %37 2
2273 %81 = OpCompositeExtract %4 %35 0
2274 %82 = OpFMul %4 %80 %81
2275 %83 = OpCompositeExtract %4 %35 1
2276 %84 = OpFMul %4 %80 %83
2277 %85 = OpCompositeConstruct %5 %82 %84
2278 %48 = OpCompositeConstruct %9 %73 %79 %85
2279
2280 ; Multiplying 2-dimensional vector by 4-dimensional vector
2281 %86 = OpCompositeExtract %4 %41 0
2282 %87 = OpCompositeExtract %4 %36 0
2283 %88 = OpFMul %4 %86 %87
2284 %89 = OpCompositeExtract %4 %36 1
2285 %90 = OpFMul %4 %86 %89
2286 %91 = OpCompositeConstruct %5 %88 %90
2287 %92 = OpCompositeExtract %4 %41 1
2288 %93 = OpCompositeExtract %4 %36 0
2289 %94 = OpFMul %4 %92 %93
2290 %95 = OpCompositeExtract %4 %36 1
2291 %96 = OpFMul %4 %92 %95
2292 %97 = OpCompositeConstruct %5 %94 %96
2293 %98 = OpCompositeExtract %4 %41 2
2294 %99 = OpCompositeExtract %4 %36 0
2295 %100 = OpFMul %4 %98 %99
2296 %101 = OpCompositeExtract %4 %36 1
2297 %102 = OpFMul %4 %98 %101
2298 %103 = OpCompositeConstruct %5 %100 %102
2299 %104 = OpCompositeExtract %4 %41 3
2300 %105 = OpCompositeExtract %4 %36 0
2301 %106 = OpFMul %4 %104 %105
2302 %107 = OpCompositeExtract %4 %36 1
2303 %108 = OpFMul %4 %104 %107
2304 %109 = OpCompositeConstruct %5 %106 %108
2305 %49 = OpCompositeConstruct %10 %91 %97 %103 %109
2306
2307 ; Multiplying 3-dimensional vector by 2-dimensional vector
2308 %110 = OpCompositeExtract %4 %33 0
2309 %111 = OpCompositeExtract %4 %37 0
2310 %112 = OpFMul %4 %110 %111
2311 %113 = OpCompositeExtract %4 %37 1
2312 %114 = OpFMul %4 %110 %113
2313 %115 = OpCompositeExtract %4 %37 2
2314 %116 = OpFMul %4 %110 %115
2315 %117 = OpCompositeConstruct %6 %112 %114 %116
2316 %118 = OpCompositeExtract %4 %33 1
2317 %119 = OpCompositeExtract %4 %37 0
2318 %120 = OpFMul %4 %118 %119
2319 %121 = OpCompositeExtract %4 %37 1
2320 %122 = OpFMul %4 %118 %121
2321 %123 = OpCompositeExtract %4 %37 2
2322 %124 = OpFMul %4 %118 %123
2323 %125 = OpCompositeConstruct %6 %120 %122 %124
2324 %50 = OpCompositeConstruct %11 %117 %125
2325
2326 ; Multiplying 3-dimensional vector by 3-dimensional vector
2327 %51 = OpOuterProduct %12 %38 %39
2328
2329 ; Multiplying 3-dimensional vector by 4-dimensional vector
2330 %52 = OpOuterProduct %13 %40 %41
2331
2332 ; Multiplying 4-dimensional vector by 2-dimensional vector
2333 %53 = OpOuterProduct %14 %41 %33
2334
2335 ; Multiplying 4-dimensional vector by 3-dimensional vector
2336 %54 = OpOuterProduct %15 %42 %37
2337
2338 ; Multiplying 4-dimensional vector by 4-dimensional vector
2339 %55 = OpOuterProduct %16 %43 %44
2340 OpReturn
2341 OpFunctionEnd
2342 )";
2343
2344 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
2345 kConsoleMessageConsumer));
2346 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
2347 }
2348
TEST(TransformationReplaceLinearAlgebraInstructionTest,ReplaceOpDot)2349 TEST(TransformationReplaceLinearAlgebraInstructionTest, ReplaceOpDot) {
2350 std::string reference_shader = R"(
2351 OpCapability Shader
2352 %1 = OpExtInstImport "GLSL.std.450"
2353 OpMemoryModel Logical GLSL450
2354 OpEntryPoint Fragment %22 "main"
2355 OpExecutionMode %22 OriginUpperLeft
2356 OpSource ESSL 310
2357 OpName %22 "main"
2358 %2 = OpTypeVoid
2359 %3 = OpTypeFunction %2
2360 %4 = OpTypeFloat 32
2361 %5 = OpTypeVector %4 2
2362 %6 = OpTypeVector %4 3
2363 %7 = OpTypeVector %4 4
2364 %8 = OpConstant %4 1
2365 %9 = OpConstant %4 2
2366 %10 = OpConstant %4 3
2367 %11 = OpConstant %4 4
2368 %12 = OpConstant %4 5
2369 %13 = OpConstant %4 6
2370 %14 = OpConstant %4 7
2371 %15 = OpConstant %4 8
2372 %16 = OpConstantComposite %5 %8 %9
2373 %17 = OpConstantComposite %5 %10 %11
2374 %18 = OpConstantComposite %6 %8 %9 %10
2375 %19 = OpConstantComposite %6 %11 %12 %13
2376 %20 = OpConstantComposite %7 %8 %9 %10 %11
2377 %21 = OpConstantComposite %7 %12 %13 %14 %15
2378 %22 = OpFunction %2 None %3
2379 %23 = OpLabel
2380 %24 = OpDot %4 %16 %17
2381 %25 = OpDot %4 %18 %19
2382 %26 = OpDot %4 %20 %21
2383 OpReturn
2384 OpFunctionEnd
2385 )";
2386
2387 const auto env = SPV_ENV_UNIVERSAL_1_5;
2388 const auto consumer = nullptr;
2389 const auto context =
2390 BuildModule(env, consumer, reference_shader, kFuzzAssembleOption);
2391 spvtools::ValidatorOptions validator_options;
2392 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
2393 kConsoleMessageConsumer));
2394 TransformationContext transformation_context(
2395 MakeUnique<FactManager>(context.get()), validator_options);
2396 auto instruction_descriptor = MakeInstructionDescriptor(24, SpvOpDot, 0);
2397 auto transformation = TransformationReplaceLinearAlgebraInstruction(
2398 {27, 28, 29, 30, 31, 32}, instruction_descriptor);
2399 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2400
2401 instruction_descriptor = MakeInstructionDescriptor(25, SpvOpDot, 0);
2402 transformation = TransformationReplaceLinearAlgebraInstruction(
2403 {33, 34, 35, 36, 37, 38, 39, 40, 41, 42}, instruction_descriptor);
2404 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2405
2406 instruction_descriptor = MakeInstructionDescriptor(26, SpvOpDot, 0);
2407 transformation = TransformationReplaceLinearAlgebraInstruction(
2408 {43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
2409 instruction_descriptor);
2410 ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
2411
2412 std::string variant_shader = R"(
2413 OpCapability Shader
2414 %1 = OpExtInstImport "GLSL.std.450"
2415 OpMemoryModel Logical GLSL450
2416 OpEntryPoint Fragment %22 "main"
2417 OpExecutionMode %22 OriginUpperLeft
2418 OpSource ESSL 310
2419 OpName %22 "main"
2420 %2 = OpTypeVoid
2421 %3 = OpTypeFunction %2
2422 %4 = OpTypeFloat 32
2423 %5 = OpTypeVector %4 2
2424 %6 = OpTypeVector %4 3
2425 %7 = OpTypeVector %4 4
2426 %8 = OpConstant %4 1
2427 %9 = OpConstant %4 2
2428 %10 = OpConstant %4 3
2429 %11 = OpConstant %4 4
2430 %12 = OpConstant %4 5
2431 %13 = OpConstant %4 6
2432 %14 = OpConstant %4 7
2433 %15 = OpConstant %4 8
2434 %16 = OpConstantComposite %5 %8 %9
2435 %17 = OpConstantComposite %5 %10 %11
2436 %18 = OpConstantComposite %6 %8 %9 %10
2437 %19 = OpConstantComposite %6 %11 %12 %13
2438 %20 = OpConstantComposite %7 %8 %9 %10 %11
2439 %21 = OpConstantComposite %7 %12 %13 %14 %15
2440 %22 = OpFunction %2 None %3
2441 %23 = OpLabel
2442 %27 = OpCompositeExtract %4 %16 0
2443 %28 = OpCompositeExtract %4 %17 0
2444 %29 = OpFMul %4 %27 %28
2445 %30 = OpCompositeExtract %4 %16 1
2446 %31 = OpCompositeExtract %4 %17 1
2447 %32 = OpFMul %4 %30 %31
2448 %24 = OpFAdd %4 %29 %32
2449 %33 = OpCompositeExtract %4 %18 0
2450 %34 = OpCompositeExtract %4 %19 0
2451 %35 = OpFMul %4 %33 %34
2452 %36 = OpCompositeExtract %4 %18 1
2453 %37 = OpCompositeExtract %4 %19 1
2454 %38 = OpFMul %4 %36 %37
2455 %39 = OpCompositeExtract %4 %18 2
2456 %40 = OpCompositeExtract %4 %19 2
2457 %41 = OpFMul %4 %39 %40
2458 %42 = OpFAdd %4 %35 %38
2459 %25 = OpFAdd %4 %41 %42
2460 %43 = OpCompositeExtract %4 %20 0
2461 %44 = OpCompositeExtract %4 %21 0
2462 %45 = OpFMul %4 %43 %44
2463 %46 = OpCompositeExtract %4 %20 1
2464 %47 = OpCompositeExtract %4 %21 1
2465 %48 = OpFMul %4 %46 %47
2466 %49 = OpCompositeExtract %4 %20 2
2467 %50 = OpCompositeExtract %4 %21 2
2468 %51 = OpFMul %4 %49 %50
2469 %52 = OpCompositeExtract %4 %20 3
2470 %53 = OpCompositeExtract %4 %21 3
2471 %54 = OpFMul %4 %52 %53
2472 %55 = OpFAdd %4 %45 %48
2473 %56 = OpFAdd %4 %51 %55
2474 %26 = OpFAdd %4 %54 %56
2475 OpReturn
2476 OpFunctionEnd
2477 )";
2478
2479 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
2480 kConsoleMessageConsumer));
2481 ASSERT_TRUE(IsEqual(env, variant_shader, context.get()));
2482 }
2483
2484 } // namespace
2485 } // namespace fuzz
2486 } // namespace spvtools
2487