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