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