1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include "source/fuzz/data_descriptor.h"
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h"
19fd4e5da5Sopenharmony_ci#include "source/fuzz/id_use_descriptor.h"
20fd4e5da5Sopenharmony_ci#include "source/fuzz/instruction_descriptor.h"
21fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_composite_extract.h"
22fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_replace_id_with_synonym.h"
23fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_vector_shuffle.h"
24fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h"
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_cinamespace spvtools {
27fd4e5da5Sopenharmony_cinamespace fuzz {
28fd4e5da5Sopenharmony_cinamespace {
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ci// This file captures tests that check correctness of the collective use of a
31fd4e5da5Sopenharmony_ci// number of transformations that relate to data synonyms.
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_ciprotobufs::Fact MakeSynonymFact(uint32_t first_id,
34fd4e5da5Sopenharmony_ci                                const std::vector<uint32_t>& first_indices,
35fd4e5da5Sopenharmony_ci                                uint32_t second_id,
36fd4e5da5Sopenharmony_ci                                const std::vector<uint32_t>& second_indices) {
37fd4e5da5Sopenharmony_ci  protobufs::FactDataSynonym data_synonym_fact;
38fd4e5da5Sopenharmony_ci  *data_synonym_fact.mutable_data1() =
39fd4e5da5Sopenharmony_ci      MakeDataDescriptor(first_id, first_indices);
40fd4e5da5Sopenharmony_ci  *data_synonym_fact.mutable_data2() =
41fd4e5da5Sopenharmony_ci      MakeDataDescriptor(second_id, second_indices);
42fd4e5da5Sopenharmony_ci  protobufs::Fact result;
43fd4e5da5Sopenharmony_ci  *result.mutable_data_synonym_fact() = data_synonym_fact;
44fd4e5da5Sopenharmony_ci  return result;
45fd4e5da5Sopenharmony_ci}
46fd4e5da5Sopenharmony_ci
47fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) {
48fd4e5da5Sopenharmony_ci  std::string shader = R"(
49fd4e5da5Sopenharmony_ci               OpCapability Shader
50fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
51fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
52fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
53fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
54fd4e5da5Sopenharmony_ci               OpSource ESSL 310
55fd4e5da5Sopenharmony_ci               OpName %4 "main"
56fd4e5da5Sopenharmony_ci               OpName %11 "A"
57fd4e5da5Sopenharmony_ci               OpName %20 "B"
58fd4e5da5Sopenharmony_ci               OpName %31 "g"
59fd4e5da5Sopenharmony_ci               OpName %35 "h"
60fd4e5da5Sopenharmony_ci               OpDecorate %11 RelaxedPrecision
61fd4e5da5Sopenharmony_ci               OpDecorate %22 RelaxedPrecision
62fd4e5da5Sopenharmony_ci               OpDecorate %27 RelaxedPrecision
63fd4e5da5Sopenharmony_ci               OpDecorate %35 RelaxedPrecision
64fd4e5da5Sopenharmony_ci               OpDecorate %36 RelaxedPrecision
65fd4e5da5Sopenharmony_ci               OpDecorate %40 RelaxedPrecision
66fd4e5da5Sopenharmony_ci               OpDecorate %41 RelaxedPrecision
67fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
68fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
69fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
70fd4e5da5Sopenharmony_ci          %7 = OpTypeInt 32 0
71fd4e5da5Sopenharmony_ci          %8 = OpConstant %7 3
72fd4e5da5Sopenharmony_ci          %9 = OpTypeArray %6 %8
73fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Function %9
74fd4e5da5Sopenharmony_ci         %12 = OpConstant %6 0
75fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 3
76fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Function %6
77fd4e5da5Sopenharmony_ci         %16 = OpTypeFloat 32
78fd4e5da5Sopenharmony_ci         %17 = OpConstant %7 4
79fd4e5da5Sopenharmony_ci         %18 = OpTypeArray %16 %17
80fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %18
81fd4e5da5Sopenharmony_ci         %24 = OpTypePointer Function %16
82fd4e5da5Sopenharmony_ci         %28 = OpConstant %16 42
83fd4e5da5Sopenharmony_ci         %30 = OpConstant %6 2
84fd4e5da5Sopenharmony_ci         %34 = OpConstant %6 1
85fd4e5da5Sopenharmony_ci         %38 = OpConstant %6 42
86fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
87fd4e5da5Sopenharmony_ci          %5 = OpLabel
88fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Function
89fd4e5da5Sopenharmony_ci         %20 = OpVariable %19 Function
90fd4e5da5Sopenharmony_ci         %31 = OpVariable %24 Function
91fd4e5da5Sopenharmony_ci         %35 = OpVariable %14 Function
92fd4e5da5Sopenharmony_ci         %15 = OpAccessChain %14 %11 %12
93fd4e5da5Sopenharmony_ci         %21 = OpAccessChain %14 %11 %12
94fd4e5da5Sopenharmony_ci         %22 = OpLoad %6 %21
95fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %9 %12 %13 %22
96fd4e5da5Sopenharmony_ci               OpStore %15 %13
97fd4e5da5Sopenharmony_ci         %23 = OpConvertSToF %16 %22
98fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %24 %20 %12
99fd4e5da5Sopenharmony_ci               OpStore %25 %23
100fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %14 %11 %12
101fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %26
102fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %24 %20 %27
103fd4e5da5Sopenharmony_ci               OpStore %29 %28
104fd4e5da5Sopenharmony_ci         %32 = OpLoad %16 %31
105fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %18 %28 %23 %32 %23
106fd4e5da5Sopenharmony_ci         %50 = OpCopyObject %16 %23
107fd4e5da5Sopenharmony_ci         %51 = OpCopyObject %16 %23
108fd4e5da5Sopenharmony_ci         %33 = OpAccessChain %24 %20 %30
109fd4e5da5Sopenharmony_ci               OpStore %33 %28
110fd4e5da5Sopenharmony_ci               OpStore %33 %32
111fd4e5da5Sopenharmony_ci         %36 = OpLoad %6 %35
112fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %14 %11 %34
113fd4e5da5Sopenharmony_ci               OpStore %37 %36
114fd4e5da5Sopenharmony_ci         %39 = OpAccessChain %14 %11 %12
115fd4e5da5Sopenharmony_ci         %40 = OpLoad %6 %39
116fd4e5da5Sopenharmony_ci         %41 = OpIAdd %6 %38 %40
117fd4e5da5Sopenharmony_ci         %42 = OpAccessChain %14 %11 %30
118fd4e5da5Sopenharmony_ci               OpStore %42 %41
119fd4e5da5Sopenharmony_ci               OpReturn
120fd4e5da5Sopenharmony_ci               OpFunctionEnd
121fd4e5da5Sopenharmony_ci  )";
122fd4e5da5Sopenharmony_ci
123fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
124fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
125fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
126fd4e5da5Sopenharmony_ci  spvtools::ValidatorOptions validator_options;
127fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
128fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
129fd4e5da5Sopenharmony_ci  TransformationContext transformation_context(
130fd4e5da5Sopenharmony_ci      MakeUnique<FactManager>(context.get()), validator_options);
131fd4e5da5Sopenharmony_ci
132fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
133fd4e5da5Sopenharmony_ci      MakeSynonymFact(12, {}, 100, {0}));
134fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
135fd4e5da5Sopenharmony_ci      MakeSynonymFact(13, {}, 100, {1}));
136fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
137fd4e5da5Sopenharmony_ci      MakeSynonymFact(22, {}, 100, {2}));
138fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
139fd4e5da5Sopenharmony_ci      MakeSynonymFact(28, {}, 101, {0}));
140fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
141fd4e5da5Sopenharmony_ci      MakeSynonymFact(23, {}, 101, {1}));
142fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
143fd4e5da5Sopenharmony_ci      MakeSynonymFact(32, {}, 101, {2}));
144fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
145fd4e5da5Sopenharmony_ci      MakeSynonymFact(23, {}, 101, {3}));
146fd4e5da5Sopenharmony_ci
147fd4e5da5Sopenharmony_ci  // Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12'
148fd4e5da5Sopenharmony_ci  auto instruction_descriptor_1 =
149fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0);
150fd4e5da5Sopenharmony_ci  auto good_extract_1 =
151fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_1, 102, 100, {0});
152fd4e5da5Sopenharmony_ci  // Bad: id already in use
153fd4e5da5Sopenharmony_ci  auto bad_extract_1 = TransformationCompositeExtract(
154fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0), 25, 100, {0});
155fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
156fd4e5da5Sopenharmony_ci      good_extract_1.IsApplicable(context.get(), transformation_context));
157fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
158fd4e5da5Sopenharmony_ci      bad_extract_1.IsApplicable(context.get(), transformation_context));
159fd4e5da5Sopenharmony_ci  good_extract_1.Apply(context.get(), &transformation_context);
160fd4e5da5Sopenharmony_ci  auto replacement_1 = TransformationReplaceIdWithSynonym(
161fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(12, instruction_descriptor_1, 1), 102);
162fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
163fd4e5da5Sopenharmony_ci      replacement_1.IsApplicable(context.get(), transformation_context));
164fd4e5da5Sopenharmony_ci  replacement_1.Apply(context.get(), &transformation_context);
165fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
166fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
167fd4e5da5Sopenharmony_ci
168fd4e5da5Sopenharmony_ci  // Replace %13 with %100[1] in 'OpStore %15 %13'
169fd4e5da5Sopenharmony_ci  auto instruction_descriptor_2 =
170fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(100, spv::Op::OpStore, 0);
171fd4e5da5Sopenharmony_ci  auto good_extract_2 =
172fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_2, 103, 100, {1});
173fd4e5da5Sopenharmony_ci  // No bad example provided here.
174fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
175fd4e5da5Sopenharmony_ci      good_extract_2.IsApplicable(context.get(), transformation_context));
176fd4e5da5Sopenharmony_ci  good_extract_2.Apply(context.get(), &transformation_context);
177fd4e5da5Sopenharmony_ci  auto replacement_2 = TransformationReplaceIdWithSynonym(
178fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(13, instruction_descriptor_2, 1), 103);
179fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
180fd4e5da5Sopenharmony_ci      replacement_2.IsApplicable(context.get(), transformation_context));
181fd4e5da5Sopenharmony_ci  replacement_2.Apply(context.get(), &transformation_context);
182fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
183fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
184fd4e5da5Sopenharmony_ci
185fd4e5da5Sopenharmony_ci  // Replace %22 with %100[2] in '%23 = OpConvertSToF %16 %22'
186fd4e5da5Sopenharmony_ci  auto instruction_descriptor_3 =
187fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(23, spv::Op::OpConvertSToF, 0);
188fd4e5da5Sopenharmony_ci  auto good_extract_3 =
189fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_3, 104, 100, {2});
190fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
191fd4e5da5Sopenharmony_ci      good_extract_3.IsApplicable(context.get(), transformation_context));
192fd4e5da5Sopenharmony_ci  good_extract_3.Apply(context.get(), &transformation_context);
193fd4e5da5Sopenharmony_ci  auto replacement_3 = TransformationReplaceIdWithSynonym(
194fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(22, instruction_descriptor_3, 0), 104);
195fd4e5da5Sopenharmony_ci  // Bad: wrong input operand index
196fd4e5da5Sopenharmony_ci  auto bad_replacement_3 = TransformationReplaceIdWithSynonym(
197fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(22, instruction_descriptor_3, 1), 104);
198fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
199fd4e5da5Sopenharmony_ci      replacement_3.IsApplicable(context.get(), transformation_context));
200fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
201fd4e5da5Sopenharmony_ci      bad_replacement_3.IsApplicable(context.get(), transformation_context));
202fd4e5da5Sopenharmony_ci  replacement_3.Apply(context.get(), &transformation_context);
203fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
204fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
205fd4e5da5Sopenharmony_ci
206fd4e5da5Sopenharmony_ci  // Replace %28 with %101[0] in 'OpStore %33 %28'
207fd4e5da5Sopenharmony_ci  auto instruction_descriptor_4 =
208fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(33, spv::Op::OpStore, 0);
209fd4e5da5Sopenharmony_ci  auto good_extract_4 =
210fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_4, 105, 101, {0});
211fd4e5da5Sopenharmony_ci  // Bad: instruction descriptor does not identify an appropriate instruction
212fd4e5da5Sopenharmony_ci  auto bad_extract_4 = TransformationCompositeExtract(
213fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(33, spv::Op::OpCopyObject, 0), 105, 101, {0});
214fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
215fd4e5da5Sopenharmony_ci      good_extract_4.IsApplicable(context.get(), transformation_context));
216fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
217fd4e5da5Sopenharmony_ci      bad_extract_4.IsApplicable(context.get(), transformation_context));
218fd4e5da5Sopenharmony_ci  good_extract_4.Apply(context.get(), &transformation_context);
219fd4e5da5Sopenharmony_ci  auto replacement_4 = TransformationReplaceIdWithSynonym(
220fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(28, instruction_descriptor_4, 1), 105);
221fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
222fd4e5da5Sopenharmony_ci      replacement_4.IsApplicable(context.get(), transformation_context));
223fd4e5da5Sopenharmony_ci  replacement_4.Apply(context.get(), &transformation_context);
224fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
225fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
226fd4e5da5Sopenharmony_ci
227fd4e5da5Sopenharmony_ci  // Replace %23 with %101[1] in '%50 = OpCopyObject %16 %23'
228fd4e5da5Sopenharmony_ci  auto instruction_descriptor_5 =
229fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(50, spv::Op::OpCopyObject, 0);
230fd4e5da5Sopenharmony_ci  auto good_extract_5 =
231fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_5, 106, 101, {1});
232fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
233fd4e5da5Sopenharmony_ci      good_extract_5.IsApplicable(context.get(), transformation_context));
234fd4e5da5Sopenharmony_ci  good_extract_5.Apply(context.get(), &transformation_context);
235fd4e5da5Sopenharmony_ci  auto replacement_5 = TransformationReplaceIdWithSynonym(
236fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 106);
237fd4e5da5Sopenharmony_ci  // Bad: wrong synonym fact being used
238fd4e5da5Sopenharmony_ci  auto bad_replacement_5 = TransformationReplaceIdWithSynonym(
239fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 105);
240fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
241fd4e5da5Sopenharmony_ci      replacement_5.IsApplicable(context.get(), transformation_context));
242fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
243fd4e5da5Sopenharmony_ci      bad_replacement_5.IsApplicable(context.get(), transformation_context));
244fd4e5da5Sopenharmony_ci  replacement_5.Apply(context.get(), &transformation_context);
245fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
246fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
247fd4e5da5Sopenharmony_ci
248fd4e5da5Sopenharmony_ci  // Replace %32 with %101[2] in 'OpStore %33 %32'
249fd4e5da5Sopenharmony_ci  auto instruction_descriptor_6 =
250fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(33, spv::Op::OpStore, 1);
251fd4e5da5Sopenharmony_ci  auto good_extract_6 =
252fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_6, 107, 101, {2});
253fd4e5da5Sopenharmony_ci  // Bad: id 1001 does not exist
254fd4e5da5Sopenharmony_ci  auto bad_extract_6 =
255fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_6, 107, 1001, {2});
256fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
257fd4e5da5Sopenharmony_ci      good_extract_6.IsApplicable(context.get(), transformation_context));
258fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
259fd4e5da5Sopenharmony_ci      bad_extract_6.IsApplicable(context.get(), transformation_context));
260fd4e5da5Sopenharmony_ci  good_extract_6.Apply(context.get(), &transformation_context);
261fd4e5da5Sopenharmony_ci  auto replacement_6 = TransformationReplaceIdWithSynonym(
262fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(32, instruction_descriptor_6, 1), 107);
263fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
264fd4e5da5Sopenharmony_ci      replacement_6.IsApplicable(context.get(), transformation_context));
265fd4e5da5Sopenharmony_ci  replacement_6.Apply(context.get(), &transformation_context);
266fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
267fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
268fd4e5da5Sopenharmony_ci
269fd4e5da5Sopenharmony_ci  // Replace %23 with %101[3] in '%51 = OpCopyObject %16 %23'
270fd4e5da5Sopenharmony_ci  auto instruction_descriptor_7 =
271fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(51, spv::Op::OpCopyObject, 0);
272fd4e5da5Sopenharmony_ci  auto good_extract_7 =
273fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_7, 108, 101, {3});
274fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
275fd4e5da5Sopenharmony_ci      good_extract_7.IsApplicable(context.get(), transformation_context));
276fd4e5da5Sopenharmony_ci  good_extract_7.Apply(context.get(), &transformation_context);
277fd4e5da5Sopenharmony_ci  auto replacement_7 = TransformationReplaceIdWithSynonym(
278fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(23, instruction_descriptor_7, 0), 108);
279fd4e5da5Sopenharmony_ci  // Bad: use id 0 is invalid
280fd4e5da5Sopenharmony_ci  auto bad_replacement_7 = TransformationReplaceIdWithSynonym(
281fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(0, instruction_descriptor_7, 0), 108);
282fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
283fd4e5da5Sopenharmony_ci      replacement_7.IsApplicable(context.get(), transformation_context));
284fd4e5da5Sopenharmony_ci  ASSERT_FALSE(
285fd4e5da5Sopenharmony_ci      bad_replacement_7.IsApplicable(context.get(), transformation_context));
286fd4e5da5Sopenharmony_ci  replacement_7.Apply(context.get(), &transformation_context);
287fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
288fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
289fd4e5da5Sopenharmony_ci
290fd4e5da5Sopenharmony_ci  const std::string after_transformation = R"(
291fd4e5da5Sopenharmony_ci               OpCapability Shader
292fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
293fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
294fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
295fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
296fd4e5da5Sopenharmony_ci               OpSource ESSL 310
297fd4e5da5Sopenharmony_ci               OpName %4 "main"
298fd4e5da5Sopenharmony_ci               OpName %11 "A"
299fd4e5da5Sopenharmony_ci               OpName %20 "B"
300fd4e5da5Sopenharmony_ci               OpName %31 "g"
301fd4e5da5Sopenharmony_ci               OpName %35 "h"
302fd4e5da5Sopenharmony_ci               OpDecorate %11 RelaxedPrecision
303fd4e5da5Sopenharmony_ci               OpDecorate %22 RelaxedPrecision
304fd4e5da5Sopenharmony_ci               OpDecorate %27 RelaxedPrecision
305fd4e5da5Sopenharmony_ci               OpDecorate %35 RelaxedPrecision
306fd4e5da5Sopenharmony_ci               OpDecorate %36 RelaxedPrecision
307fd4e5da5Sopenharmony_ci               OpDecorate %40 RelaxedPrecision
308fd4e5da5Sopenharmony_ci               OpDecorate %41 RelaxedPrecision
309fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
310fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
311fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
312fd4e5da5Sopenharmony_ci          %7 = OpTypeInt 32 0
313fd4e5da5Sopenharmony_ci          %8 = OpConstant %7 3
314fd4e5da5Sopenharmony_ci          %9 = OpTypeArray %6 %8
315fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Function %9
316fd4e5da5Sopenharmony_ci         %12 = OpConstant %6 0
317fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 3
318fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Function %6
319fd4e5da5Sopenharmony_ci         %16 = OpTypeFloat 32
320fd4e5da5Sopenharmony_ci         %17 = OpConstant %7 4
321fd4e5da5Sopenharmony_ci         %18 = OpTypeArray %16 %17
322fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %18
323fd4e5da5Sopenharmony_ci         %24 = OpTypePointer Function %16
324fd4e5da5Sopenharmony_ci         %28 = OpConstant %16 42
325fd4e5da5Sopenharmony_ci         %30 = OpConstant %6 2
326fd4e5da5Sopenharmony_ci         %34 = OpConstant %6 1
327fd4e5da5Sopenharmony_ci         %38 = OpConstant %6 42
328fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
329fd4e5da5Sopenharmony_ci          %5 = OpLabel
330fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Function
331fd4e5da5Sopenharmony_ci         %20 = OpVariable %19 Function
332fd4e5da5Sopenharmony_ci         %31 = OpVariable %24 Function
333fd4e5da5Sopenharmony_ci         %35 = OpVariable %14 Function
334fd4e5da5Sopenharmony_ci         %15 = OpAccessChain %14 %11 %12
335fd4e5da5Sopenharmony_ci         %21 = OpAccessChain %14 %11 %12
336fd4e5da5Sopenharmony_ci         %22 = OpLoad %6 %21
337fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %9 %12 %13 %22
338fd4e5da5Sopenharmony_ci        %103 = OpCompositeExtract %6 %100 1
339fd4e5da5Sopenharmony_ci               OpStore %15 %103
340fd4e5da5Sopenharmony_ci        %104 = OpCompositeExtract %6 %100 2
341fd4e5da5Sopenharmony_ci         %23 = OpConvertSToF %16 %104
342fd4e5da5Sopenharmony_ci        %102 = OpCompositeExtract %6 %100 0
343fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %24 %20 %102
344fd4e5da5Sopenharmony_ci               OpStore %25 %23
345fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %14 %11 %12
346fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %26
347fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %24 %20 %27
348fd4e5da5Sopenharmony_ci               OpStore %29 %28
349fd4e5da5Sopenharmony_ci         %32 = OpLoad %16 %31
350fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %18 %28 %23 %32 %23
351fd4e5da5Sopenharmony_ci        %106 = OpCompositeExtract %16 %101 1
352fd4e5da5Sopenharmony_ci         %50 = OpCopyObject %16 %106
353fd4e5da5Sopenharmony_ci        %108 = OpCompositeExtract %16 %101 3
354fd4e5da5Sopenharmony_ci         %51 = OpCopyObject %16 %108
355fd4e5da5Sopenharmony_ci         %33 = OpAccessChain %24 %20 %30
356fd4e5da5Sopenharmony_ci        %105 = OpCompositeExtract %16 %101 0
357fd4e5da5Sopenharmony_ci               OpStore %33 %105
358fd4e5da5Sopenharmony_ci        %107 = OpCompositeExtract %16 %101 2
359fd4e5da5Sopenharmony_ci               OpStore %33 %107
360fd4e5da5Sopenharmony_ci         %36 = OpLoad %6 %35
361fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %14 %11 %34
362fd4e5da5Sopenharmony_ci               OpStore %37 %36
363fd4e5da5Sopenharmony_ci         %39 = OpAccessChain %14 %11 %12
364fd4e5da5Sopenharmony_ci         %40 = OpLoad %6 %39
365fd4e5da5Sopenharmony_ci         %41 = OpIAdd %6 %38 %40
366fd4e5da5Sopenharmony_ci         %42 = OpAccessChain %14 %11 %30
367fd4e5da5Sopenharmony_ci               OpStore %42 %41
368fd4e5da5Sopenharmony_ci               OpReturn
369fd4e5da5Sopenharmony_ci               OpFunctionEnd
370fd4e5da5Sopenharmony_ci  )";
371fd4e5da5Sopenharmony_ci
372fd4e5da5Sopenharmony_ci  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
373fd4e5da5Sopenharmony_ci}
374fd4e5da5Sopenharmony_ci
375fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, MatrixCompositeSynonyms) {
376fd4e5da5Sopenharmony_ci  std::string shader = R"(
377fd4e5da5Sopenharmony_ci               OpCapability Shader
378fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
379fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
380fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
381fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
382fd4e5da5Sopenharmony_ci               OpSource ESSL 310
383fd4e5da5Sopenharmony_ci               OpName %4 "main"
384fd4e5da5Sopenharmony_ci               OpName %10 "m"
385fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
386fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
387fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
388fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
389fd4e5da5Sopenharmony_ci         %50 = OpUndef %7
390fd4e5da5Sopenharmony_ci          %8 = OpTypeMatrix %7 3
391fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
392fd4e5da5Sopenharmony_ci         %11 = OpTypeInt 32 1
393fd4e5da5Sopenharmony_ci         %12 = OpConstant %11 0
394fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 1
395fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %7 %13 %13 %13 %13
396fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Function %7
397fd4e5da5Sopenharmony_ci         %17 = OpConstant %11 1
398fd4e5da5Sopenharmony_ci         %18 = OpConstant %6 2
399fd4e5da5Sopenharmony_ci         %19 = OpConstantComposite %7 %18 %18 %18 %18
400fd4e5da5Sopenharmony_ci         %21 = OpConstant %11 2
401fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
402fd4e5da5Sopenharmony_ci          %5 = OpLabel
403fd4e5da5Sopenharmony_ci         %10 = OpVariable %9 Function
404fd4e5da5Sopenharmony_ci         %16 = OpAccessChain %15 %10 %12
405fd4e5da5Sopenharmony_ci               OpStore %16 %14
406fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %15 %10 %17
407fd4e5da5Sopenharmony_ci               OpStore %20 %19
408fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %15 %10 %12
409fd4e5da5Sopenharmony_ci         %23 = OpLoad %7 %22
410fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %15 %10 %17
411fd4e5da5Sopenharmony_ci         %25 = OpLoad %7 %24
412fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %8 %23 %25 %50
413fd4e5da5Sopenharmony_ci         %26 = OpFAdd %7 %23 %25
414fd4e5da5Sopenharmony_ci         %27 = OpAccessChain %15 %10 %21
415fd4e5da5Sopenharmony_ci               OpStore %27 %26
416fd4e5da5Sopenharmony_ci               OpReturn
417fd4e5da5Sopenharmony_ci               OpFunctionEnd
418fd4e5da5Sopenharmony_ci  )";
419fd4e5da5Sopenharmony_ci
420fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
421fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
422fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
423fd4e5da5Sopenharmony_ci  spvtools::ValidatorOptions validator_options;
424fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
425fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
426fd4e5da5Sopenharmony_ci  TransformationContext transformation_context(
427fd4e5da5Sopenharmony_ci      MakeUnique<FactManager>(context.get()), validator_options);
428fd4e5da5Sopenharmony_ci
429fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
430fd4e5da5Sopenharmony_ci      MakeSynonymFact(23, {}, 100, {0}));
431fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
432fd4e5da5Sopenharmony_ci      MakeSynonymFact(25, {}, 100, {1}));
433fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
434fd4e5da5Sopenharmony_ci      MakeSynonymFact(50, {}, 100, {2}));
435fd4e5da5Sopenharmony_ci
436fd4e5da5Sopenharmony_ci  // Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25'
437fd4e5da5Sopenharmony_ci  auto instruction_descriptor_1 =
438fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0);
439fd4e5da5Sopenharmony_ci  auto extract_1 =
440fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_1, 101, 100, {0});
441fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context));
442fd4e5da5Sopenharmony_ci  extract_1.Apply(context.get(), &transformation_context);
443fd4e5da5Sopenharmony_ci  auto replacement_1 = TransformationReplaceIdWithSynonym(
444fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(23, instruction_descriptor_1, 0), 101);
445fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
446fd4e5da5Sopenharmony_ci      replacement_1.IsApplicable(context.get(), transformation_context));
447fd4e5da5Sopenharmony_ci  replacement_1.Apply(context.get(), &transformation_context);
448fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
449fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
450fd4e5da5Sopenharmony_ci
451fd4e5da5Sopenharmony_ci  // Replace %25 with %100[1] in '%26 = OpFAdd %7 %23 %25'
452fd4e5da5Sopenharmony_ci  auto instruction_descriptor_2 =
453fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0);
454fd4e5da5Sopenharmony_ci  auto extract_2 =
455fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_2, 102, 100, {1});
456fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
457fd4e5da5Sopenharmony_ci  extract_2.Apply(context.get(), &transformation_context);
458fd4e5da5Sopenharmony_ci  auto replacement_2 = TransformationReplaceIdWithSynonym(
459fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(25, instruction_descriptor_2, 1), 102);
460fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
461fd4e5da5Sopenharmony_ci      replacement_2.IsApplicable(context.get(), transformation_context));
462fd4e5da5Sopenharmony_ci  replacement_2.Apply(context.get(), &transformation_context);
463fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
464fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
465fd4e5da5Sopenharmony_ci
466fd4e5da5Sopenharmony_ci  const std::string after_transformation = R"(
467fd4e5da5Sopenharmony_ci               OpCapability Shader
468fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
469fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
470fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
471fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
472fd4e5da5Sopenharmony_ci               OpSource ESSL 310
473fd4e5da5Sopenharmony_ci               OpName %4 "main"
474fd4e5da5Sopenharmony_ci               OpName %10 "m"
475fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
476fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
477fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
478fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
479fd4e5da5Sopenharmony_ci         %50 = OpUndef %7
480fd4e5da5Sopenharmony_ci          %8 = OpTypeMatrix %7 3
481fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
482fd4e5da5Sopenharmony_ci         %11 = OpTypeInt 32 1
483fd4e5da5Sopenharmony_ci         %12 = OpConstant %11 0
484fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 1
485fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %7 %13 %13 %13 %13
486fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Function %7
487fd4e5da5Sopenharmony_ci         %17 = OpConstant %11 1
488fd4e5da5Sopenharmony_ci         %18 = OpConstant %6 2
489fd4e5da5Sopenharmony_ci         %19 = OpConstantComposite %7 %18 %18 %18 %18
490fd4e5da5Sopenharmony_ci         %21 = OpConstant %11 2
491fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
492fd4e5da5Sopenharmony_ci          %5 = OpLabel
493fd4e5da5Sopenharmony_ci         %10 = OpVariable %9 Function
494fd4e5da5Sopenharmony_ci         %16 = OpAccessChain %15 %10 %12
495fd4e5da5Sopenharmony_ci               OpStore %16 %14
496fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %15 %10 %17
497fd4e5da5Sopenharmony_ci               OpStore %20 %19
498fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %15 %10 %12
499fd4e5da5Sopenharmony_ci         %23 = OpLoad %7 %22
500fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %15 %10 %17
501fd4e5da5Sopenharmony_ci         %25 = OpLoad %7 %24
502fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %8 %23 %25 %50
503fd4e5da5Sopenharmony_ci        %101 = OpCompositeExtract %7 %100 0
504fd4e5da5Sopenharmony_ci        %102 = OpCompositeExtract %7 %100 1
505fd4e5da5Sopenharmony_ci         %26 = OpFAdd %7 %101 %102
506fd4e5da5Sopenharmony_ci         %27 = OpAccessChain %15 %10 %21
507fd4e5da5Sopenharmony_ci               OpStore %27 %26
508fd4e5da5Sopenharmony_ci               OpReturn
509fd4e5da5Sopenharmony_ci               OpFunctionEnd
510fd4e5da5Sopenharmony_ci  )";
511fd4e5da5Sopenharmony_ci
512fd4e5da5Sopenharmony_ci  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
513fd4e5da5Sopenharmony_ci}
514fd4e5da5Sopenharmony_ci
515fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, StructCompositeSynonyms) {
516fd4e5da5Sopenharmony_ci  std::string shader = R"(
517fd4e5da5Sopenharmony_ci               OpCapability Shader
518fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
519fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
520fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
521fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
522fd4e5da5Sopenharmony_ci               OpSource ESSL 310
523fd4e5da5Sopenharmony_ci               OpName %4 "main"
524fd4e5da5Sopenharmony_ci               OpName %9 "Inner"
525fd4e5da5Sopenharmony_ci               OpMemberName %9 0 "a"
526fd4e5da5Sopenharmony_ci               OpMemberName %9 1 "b"
527fd4e5da5Sopenharmony_ci               OpName %11 "i1"
528fd4e5da5Sopenharmony_ci               OpName %17 "i2"
529fd4e5da5Sopenharmony_ci               OpName %31 "Point"
530fd4e5da5Sopenharmony_ci               OpMemberName %31 0 "x"
531fd4e5da5Sopenharmony_ci               OpMemberName %31 1 "y"
532fd4e5da5Sopenharmony_ci               OpMemberName %31 2 "z"
533fd4e5da5Sopenharmony_ci               OpName %32 "Outer"
534fd4e5da5Sopenharmony_ci               OpMemberName %32 0 "c"
535fd4e5da5Sopenharmony_ci               OpMemberName %32 1 "d"
536fd4e5da5Sopenharmony_ci               OpName %34 "o1"
537fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
538fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
539fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
540fd4e5da5Sopenharmony_ci          %7 = OpTypeFloat 32
541fd4e5da5Sopenharmony_ci          %8 = OpTypeVector %7 2
542fd4e5da5Sopenharmony_ci          %9 = OpTypeStruct %6 %8
543fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Function %9
544fd4e5da5Sopenharmony_ci         %12 = OpConstant %6 1
545fd4e5da5Sopenharmony_ci         %13 = OpConstant %7 2
546fd4e5da5Sopenharmony_ci         %14 = OpConstant %7 3
547fd4e5da5Sopenharmony_ci         %15 = OpConstantComposite %8 %13 %14
548fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %9 %12 %15
549fd4e5da5Sopenharmony_ci         %18 = OpConstant %6 0
550fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %6
551fd4e5da5Sopenharmony_ci         %24 = OpTypePointer Function %8
552fd4e5da5Sopenharmony_ci         %27 = OpConstant %7 4
553fd4e5da5Sopenharmony_ci         %31 = OpTypeStruct %7 %7 %7
554fd4e5da5Sopenharmony_ci         %32 = OpTypeStruct %9 %31
555fd4e5da5Sopenharmony_ci         %33 = OpTypePointer Function %32
556fd4e5da5Sopenharmony_ci         %36 = OpConstant %7 10
557fd4e5da5Sopenharmony_ci         %37 = OpTypeInt 32 0
558fd4e5da5Sopenharmony_ci         %38 = OpConstant %37 0
559fd4e5da5Sopenharmony_ci         %39 = OpTypePointer Function %7
560fd4e5da5Sopenharmony_ci         %42 = OpConstant %37 1
561fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
562fd4e5da5Sopenharmony_ci          %5 = OpLabel
563fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Function
564fd4e5da5Sopenharmony_ci         %17 = OpVariable %10 Function
565fd4e5da5Sopenharmony_ci         %34 = OpVariable %33 Function
566fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %31 %27 %36 %27
567fd4e5da5Sopenharmony_ci               OpStore %11 %16
568fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %19 %11 %18
569fd4e5da5Sopenharmony_ci         %21 = OpLoad %6 %20
570fd4e5da5Sopenharmony_ci         %22 = OpIAdd %6 %21 %12
571fd4e5da5Sopenharmony_ci        %102 = OpCompositeConstruct %9 %22 %15
572fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %19 %17 %18
573fd4e5da5Sopenharmony_ci               OpStore %23 %22
574fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %24 %17 %12
575fd4e5da5Sopenharmony_ci         %26 = OpLoad %8 %25
576fd4e5da5Sopenharmony_ci         %28 = OpCompositeConstruct %8 %27 %27
577fd4e5da5Sopenharmony_ci         %29 = OpFAdd %8 %26 %28
578fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %24 %17 %12
579fd4e5da5Sopenharmony_ci               OpStore %30 %29
580fd4e5da5Sopenharmony_ci         %35 = OpLoad %9 %11
581fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %39 %11 %12 %38
582fd4e5da5Sopenharmony_ci         %41 = OpLoad %7 %40
583fd4e5da5Sopenharmony_ci         %43 = OpAccessChain %39 %11 %12 %42
584fd4e5da5Sopenharmony_ci         %44 = OpLoad %7 %43
585fd4e5da5Sopenharmony_ci         %45 = OpCompositeConstruct %31 %36 %41 %44
586fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %32 %16 %45
587fd4e5da5Sopenharmony_ci         %46 = OpCompositeConstruct %32 %35 %45
588fd4e5da5Sopenharmony_ci               OpStore %34 %46
589fd4e5da5Sopenharmony_ci               OpReturn
590fd4e5da5Sopenharmony_ci               OpFunctionEnd
591fd4e5da5Sopenharmony_ci  )";
592fd4e5da5Sopenharmony_ci
593fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
594fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
595fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
596fd4e5da5Sopenharmony_ci  spvtools::ValidatorOptions validator_options;
597fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
598fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
599fd4e5da5Sopenharmony_ci  TransformationContext transformation_context(
600fd4e5da5Sopenharmony_ci      MakeUnique<FactManager>(context.get()), validator_options);
601fd4e5da5Sopenharmony_ci
602fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
603fd4e5da5Sopenharmony_ci      MakeSynonymFact(16, {}, 100, {0}));
604fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
605fd4e5da5Sopenharmony_ci      MakeSynonymFact(45, {}, 100, {1}));
606fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
607fd4e5da5Sopenharmony_ci      MakeSynonymFact(27, {}, 101, {0}));
608fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
609fd4e5da5Sopenharmony_ci      MakeSynonymFact(36, {}, 101, {1}));
610fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
611fd4e5da5Sopenharmony_ci      MakeSynonymFact(27, {}, 101, {2}));
612fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
613fd4e5da5Sopenharmony_ci      MakeSynonymFact(22, {}, 102, {0}));
614fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
615fd4e5da5Sopenharmony_ci      MakeSynonymFact(15, {}, 102, {1}));
616fd4e5da5Sopenharmony_ci
617fd4e5da5Sopenharmony_ci  // Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45'
618fd4e5da5Sopenharmony_ci  auto instruction_descriptor_1 =
619fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(46, spv::Op::OpCompositeConstruct, 0);
620fd4e5da5Sopenharmony_ci  auto extract_1 =
621fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_1, 201, 100, {1});
622fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context));
623fd4e5da5Sopenharmony_ci  extract_1.Apply(context.get(), &transformation_context);
624fd4e5da5Sopenharmony_ci  auto replacement_1 = TransformationReplaceIdWithSynonym(
625fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(45, instruction_descriptor_1, 1), 201);
626fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
627fd4e5da5Sopenharmony_ci      replacement_1.IsApplicable(context.get(), transformation_context));
628fd4e5da5Sopenharmony_ci  replacement_1.Apply(context.get(), &transformation_context);
629fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
630fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
631fd4e5da5Sopenharmony_ci
632fd4e5da5Sopenharmony_ci  // Replace second occurrence of %27 with %101[0] in '%28 =
633fd4e5da5Sopenharmony_ci  // OpCompositeConstruct %8 %27 %27'
634fd4e5da5Sopenharmony_ci  auto instruction_descriptor_2 =
635fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0);
636fd4e5da5Sopenharmony_ci  auto extract_2 =
637fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_2, 202, 101, {0});
638fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
639fd4e5da5Sopenharmony_ci  extract_2.Apply(context.get(), &transformation_context);
640fd4e5da5Sopenharmony_ci  auto replacement_2 = TransformationReplaceIdWithSynonym(
641fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(27, instruction_descriptor_2, 1), 202);
642fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
643fd4e5da5Sopenharmony_ci      replacement_2.IsApplicable(context.get(), transformation_context));
644fd4e5da5Sopenharmony_ci  replacement_2.Apply(context.get(), &transformation_context);
645fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
646fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
647fd4e5da5Sopenharmony_ci
648fd4e5da5Sopenharmony_ci  // Replace %36 with %101[1] in '%45 = OpCompositeConstruct %31 %36 %41 %44'
649fd4e5da5Sopenharmony_ci  auto instruction_descriptor_3 =
650fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(45, spv::Op::OpCompositeConstruct, 0);
651fd4e5da5Sopenharmony_ci  auto extract_3 =
652fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_3, 203, 101, {1});
653fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_3.IsApplicable(context.get(), transformation_context));
654fd4e5da5Sopenharmony_ci  extract_3.Apply(context.get(), &transformation_context);
655fd4e5da5Sopenharmony_ci  auto replacement_3 = TransformationReplaceIdWithSynonym(
656fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(36, instruction_descriptor_3, 0), 203);
657fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
658fd4e5da5Sopenharmony_ci      replacement_3.IsApplicable(context.get(), transformation_context));
659fd4e5da5Sopenharmony_ci  replacement_3.Apply(context.get(), &transformation_context);
660fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
661fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
662fd4e5da5Sopenharmony_ci
663fd4e5da5Sopenharmony_ci  // Replace first occurrence of %27 with %101[2] in '%28 = OpCompositeConstruct
664fd4e5da5Sopenharmony_ci  // %8 %27 %27'
665fd4e5da5Sopenharmony_ci  auto instruction_descriptor_4 =
666fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0);
667fd4e5da5Sopenharmony_ci  auto extract_4 =
668fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_4, 204, 101, {2});
669fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_4.IsApplicable(context.get(), transformation_context));
670fd4e5da5Sopenharmony_ci  extract_4.Apply(context.get(), &transformation_context);
671fd4e5da5Sopenharmony_ci  auto replacement_4 = TransformationReplaceIdWithSynonym(
672fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(27, instruction_descriptor_4, 0), 204);
673fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
674fd4e5da5Sopenharmony_ci      replacement_4.IsApplicable(context.get(), transformation_context));
675fd4e5da5Sopenharmony_ci  replacement_4.Apply(context.get(), &transformation_context);
676fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
677fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
678fd4e5da5Sopenharmony_ci
679fd4e5da5Sopenharmony_ci  // Replace %22 with %102[0] in 'OpStore %23 %22'
680fd4e5da5Sopenharmony_ci  auto instruction_descriptor_5 =
681fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(23, spv::Op::OpStore, 0);
682fd4e5da5Sopenharmony_ci  auto extract_5 =
683fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_5, 205, 102, {0});
684fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context));
685fd4e5da5Sopenharmony_ci  extract_5.Apply(context.get(), &transformation_context);
686fd4e5da5Sopenharmony_ci  auto replacement_5 = TransformationReplaceIdWithSynonym(
687fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(22, instruction_descriptor_5, 1), 205);
688fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
689fd4e5da5Sopenharmony_ci      replacement_5.IsApplicable(context.get(), transformation_context));
690fd4e5da5Sopenharmony_ci  replacement_5.Apply(context.get(), &transformation_context);
691fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
692fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
693fd4e5da5Sopenharmony_ci
694fd4e5da5Sopenharmony_ci  const std::string after_transformation = R"(
695fd4e5da5Sopenharmony_ci               OpCapability Shader
696fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
697fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
698fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
699fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
700fd4e5da5Sopenharmony_ci               OpSource ESSL 310
701fd4e5da5Sopenharmony_ci               OpName %4 "main"
702fd4e5da5Sopenharmony_ci               OpName %9 "Inner"
703fd4e5da5Sopenharmony_ci               OpMemberName %9 0 "a"
704fd4e5da5Sopenharmony_ci               OpMemberName %9 1 "b"
705fd4e5da5Sopenharmony_ci               OpName %11 "i1"
706fd4e5da5Sopenharmony_ci               OpName %17 "i2"
707fd4e5da5Sopenharmony_ci               OpName %31 "Point"
708fd4e5da5Sopenharmony_ci               OpMemberName %31 0 "x"
709fd4e5da5Sopenharmony_ci               OpMemberName %31 1 "y"
710fd4e5da5Sopenharmony_ci               OpMemberName %31 2 "z"
711fd4e5da5Sopenharmony_ci               OpName %32 "Outer"
712fd4e5da5Sopenharmony_ci               OpMemberName %32 0 "c"
713fd4e5da5Sopenharmony_ci               OpMemberName %32 1 "d"
714fd4e5da5Sopenharmony_ci               OpName %34 "o1"
715fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
716fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
717fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
718fd4e5da5Sopenharmony_ci          %7 = OpTypeFloat 32
719fd4e5da5Sopenharmony_ci          %8 = OpTypeVector %7 2
720fd4e5da5Sopenharmony_ci          %9 = OpTypeStruct %6 %8
721fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Function %9
722fd4e5da5Sopenharmony_ci         %12 = OpConstant %6 1
723fd4e5da5Sopenharmony_ci         %13 = OpConstant %7 2
724fd4e5da5Sopenharmony_ci         %14 = OpConstant %7 3
725fd4e5da5Sopenharmony_ci         %15 = OpConstantComposite %8 %13 %14
726fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %9 %12 %15
727fd4e5da5Sopenharmony_ci         %18 = OpConstant %6 0
728fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %6
729fd4e5da5Sopenharmony_ci         %24 = OpTypePointer Function %8
730fd4e5da5Sopenharmony_ci         %27 = OpConstant %7 4
731fd4e5da5Sopenharmony_ci         %31 = OpTypeStruct %7 %7 %7
732fd4e5da5Sopenharmony_ci         %32 = OpTypeStruct %9 %31
733fd4e5da5Sopenharmony_ci         %33 = OpTypePointer Function %32
734fd4e5da5Sopenharmony_ci         %36 = OpConstant %7 10
735fd4e5da5Sopenharmony_ci         %37 = OpTypeInt 32 0
736fd4e5da5Sopenharmony_ci         %38 = OpConstant %37 0
737fd4e5da5Sopenharmony_ci         %39 = OpTypePointer Function %7
738fd4e5da5Sopenharmony_ci         %42 = OpConstant %37 1
739fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
740fd4e5da5Sopenharmony_ci          %5 = OpLabel
741fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Function
742fd4e5da5Sopenharmony_ci         %17 = OpVariable %10 Function
743fd4e5da5Sopenharmony_ci         %34 = OpVariable %33 Function
744fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %31 %27 %36 %27
745fd4e5da5Sopenharmony_ci               OpStore %11 %16
746fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %19 %11 %18
747fd4e5da5Sopenharmony_ci         %21 = OpLoad %6 %20
748fd4e5da5Sopenharmony_ci         %22 = OpIAdd %6 %21 %12
749fd4e5da5Sopenharmony_ci        %102 = OpCompositeConstruct %9 %22 %15
750fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %19 %17 %18
751fd4e5da5Sopenharmony_ci        %205 = OpCompositeExtract %6 %102 0
752fd4e5da5Sopenharmony_ci               OpStore %23 %205
753fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %24 %17 %12
754fd4e5da5Sopenharmony_ci         %26 = OpLoad %8 %25
755fd4e5da5Sopenharmony_ci        %202 = OpCompositeExtract %7 %101 0
756fd4e5da5Sopenharmony_ci        %204 = OpCompositeExtract %7 %101 2
757fd4e5da5Sopenharmony_ci         %28 = OpCompositeConstruct %8 %204 %202
758fd4e5da5Sopenharmony_ci         %29 = OpFAdd %8 %26 %28
759fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %24 %17 %12
760fd4e5da5Sopenharmony_ci               OpStore %30 %29
761fd4e5da5Sopenharmony_ci         %35 = OpLoad %9 %11
762fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %39 %11 %12 %38
763fd4e5da5Sopenharmony_ci         %41 = OpLoad %7 %40
764fd4e5da5Sopenharmony_ci         %43 = OpAccessChain %39 %11 %12 %42
765fd4e5da5Sopenharmony_ci         %44 = OpLoad %7 %43
766fd4e5da5Sopenharmony_ci        %203 = OpCompositeExtract %7 %101 1
767fd4e5da5Sopenharmony_ci         %45 = OpCompositeConstruct %31 %203 %41 %44
768fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %32 %16 %45
769fd4e5da5Sopenharmony_ci        %201 = OpCompositeExtract %31 %100 1
770fd4e5da5Sopenharmony_ci         %46 = OpCompositeConstruct %32 %35 %201
771fd4e5da5Sopenharmony_ci               OpStore %34 %46
772fd4e5da5Sopenharmony_ci               OpReturn
773fd4e5da5Sopenharmony_ci               OpFunctionEnd
774fd4e5da5Sopenharmony_ci  )";
775fd4e5da5Sopenharmony_ci
776fd4e5da5Sopenharmony_ci  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
777fd4e5da5Sopenharmony_ci}
778fd4e5da5Sopenharmony_ci
779fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, VectorCompositeSynonyms) {
780fd4e5da5Sopenharmony_ci  std::string shader = R"(
781fd4e5da5Sopenharmony_ci               OpCapability Shader
782fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
783fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
784fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
785fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
786fd4e5da5Sopenharmony_ci               OpSource ESSL 310
787fd4e5da5Sopenharmony_ci               OpName %4 "main"
788fd4e5da5Sopenharmony_ci               OpName %8 "f"
789fd4e5da5Sopenharmony_ci               OpName %12 "v2"
790fd4e5da5Sopenharmony_ci               OpName %18 "v3"
791fd4e5da5Sopenharmony_ci               OpName %23 "v4"
792fd4e5da5Sopenharmony_ci               OpName %32 "b"
793fd4e5da5Sopenharmony_ci               OpName %36 "bv2"
794fd4e5da5Sopenharmony_ci               OpName %41 "bv3"
795fd4e5da5Sopenharmony_ci               OpName %50 "bv4"
796fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
797fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
798fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
799fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
800fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 42
801fd4e5da5Sopenharmony_ci         %10 = OpTypeVector %6 2
802fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Function %10
803fd4e5da5Sopenharmony_ci         %16 = OpTypeVector %6 3
804fd4e5da5Sopenharmony_ci         %17 = OpTypePointer Function %16
805fd4e5da5Sopenharmony_ci         %21 = OpTypeVector %6 4
806fd4e5da5Sopenharmony_ci         %22 = OpTypePointer Function %21
807fd4e5da5Sopenharmony_ci         %30 = OpTypeBool
808fd4e5da5Sopenharmony_ci         %31 = OpTypePointer Function %30
809fd4e5da5Sopenharmony_ci         %33 = OpConstantFalse %30
810fd4e5da5Sopenharmony_ci         %34 = OpTypeVector %30 2
811fd4e5da5Sopenharmony_ci         %35 = OpTypePointer Function %34
812fd4e5da5Sopenharmony_ci         %37 = OpConstantTrue %30
813fd4e5da5Sopenharmony_ci         %38 = OpConstantComposite %34 %37 %37
814fd4e5da5Sopenharmony_ci         %39 = OpTypeVector %30 3
815fd4e5da5Sopenharmony_ci         %40 = OpTypePointer Function %39
816fd4e5da5Sopenharmony_ci         %48 = OpTypeVector %30 4
817fd4e5da5Sopenharmony_ci         %49 = OpTypePointer Function %48
818fd4e5da5Sopenharmony_ci         %51 = OpTypeInt 32 0
819fd4e5da5Sopenharmony_ci         %52 = OpConstant %51 2
820fd4e5da5Sopenharmony_ci         %55 = OpConstant %6 0
821fd4e5da5Sopenharmony_ci         %57 = OpConstant %51 1
822fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
823fd4e5da5Sopenharmony_ci          %5 = OpLabel
824fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
825fd4e5da5Sopenharmony_ci         %12 = OpVariable %11 Function
826fd4e5da5Sopenharmony_ci         %18 = OpVariable %17 Function
827fd4e5da5Sopenharmony_ci         %23 = OpVariable %22 Function
828fd4e5da5Sopenharmony_ci         %32 = OpVariable %31 Function
829fd4e5da5Sopenharmony_ci         %36 = OpVariable %35 Function
830fd4e5da5Sopenharmony_ci         %41 = OpVariable %40 Function
831fd4e5da5Sopenharmony_ci         %50 = OpVariable %49 Function
832fd4e5da5Sopenharmony_ci               OpStore %8 %9
833fd4e5da5Sopenharmony_ci         %13 = OpLoad %6 %8
834fd4e5da5Sopenharmony_ci         %14 = OpLoad %6 %8
835fd4e5da5Sopenharmony_ci         %15 = OpCompositeConstruct %10 %13 %14
836fd4e5da5Sopenharmony_ci               OpStore %12 %15
837fd4e5da5Sopenharmony_ci         %19 = OpLoad %10 %12
838fd4e5da5Sopenharmony_ci         %20 = OpVectorShuffle %16 %19 %19 0 0 1
839fd4e5da5Sopenharmony_ci               OpStore %18 %20
840fd4e5da5Sopenharmony_ci         %24 = OpLoad %16 %18
841fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %8
842fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %6 %24 0
843fd4e5da5Sopenharmony_ci         %27 = OpCompositeExtract %6 %24 1
844fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %6 %24 2
845fd4e5da5Sopenharmony_ci         %29 = OpCompositeConstruct %21 %26 %27 %28 %25
846fd4e5da5Sopenharmony_ci               OpStore %23 %29
847fd4e5da5Sopenharmony_ci               OpStore %32 %33
848fd4e5da5Sopenharmony_ci               OpStore %36 %38
849fd4e5da5Sopenharmony_ci         %42 = OpLoad %30 %32
850fd4e5da5Sopenharmony_ci         %43 = OpLoad %34 %36
851fd4e5da5Sopenharmony_ci         %44 = OpVectorShuffle %34 %43 %43 0 0
852fd4e5da5Sopenharmony_ci         %45 = OpCompositeExtract %30 %44 0
853fd4e5da5Sopenharmony_ci         %46 = OpCompositeExtract %30 %44 1
854fd4e5da5Sopenharmony_ci         %47 = OpCompositeConstruct %39 %42 %45 %46
855fd4e5da5Sopenharmony_ci               OpStore %41 %47
856fd4e5da5Sopenharmony_ci         %53 = OpAccessChain %7 %23 %52
857fd4e5da5Sopenharmony_ci         %54 = OpLoad %6 %53
858fd4e5da5Sopenharmony_ci
859fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %21 %20 %54
860fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %21 %15 %19
861fd4e5da5Sopenharmony_ci        %102 = OpCompositeConstruct %16 %27 %15
862fd4e5da5Sopenharmony_ci        %103 = OpCompositeConstruct %48 %33 %47
863fd4e5da5Sopenharmony_ci        %104 = OpCompositeConstruct %34 %42 %45
864fd4e5da5Sopenharmony_ci        %105 = OpCompositeConstruct %39 %38 %46
865fd4e5da5Sopenharmony_ci
866fd4e5da5Sopenharmony_ci         %86 = OpCopyObject %30 %33
867fd4e5da5Sopenharmony_ci         %56 = OpFOrdNotEqual %30 %54 %55
868fd4e5da5Sopenharmony_ci         %80 = OpCopyObject %16 %20
869fd4e5da5Sopenharmony_ci         %58 = OpAccessChain %7 %18 %57
870fd4e5da5Sopenharmony_ci         %59 = OpLoad %6 %58
871fd4e5da5Sopenharmony_ci         %60 = OpFOrdNotEqual %30 %59 %55
872fd4e5da5Sopenharmony_ci         %61 = OpLoad %34 %36
873fd4e5da5Sopenharmony_ci         %62 = OpLogicalAnd %30 %45 %46
874fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %30 %45 %46
875fd4e5da5Sopenharmony_ci         %64 = OpCompositeConstruct %48 %56 %60 %62 %63
876fd4e5da5Sopenharmony_ci               OpStore %12 %15
877fd4e5da5Sopenharmony_ci         %81 = OpVectorShuffle %16 %19 %19 0 0 1
878fd4e5da5Sopenharmony_ci         %82 = OpCompositeConstruct %21 %26 %27 %28 %25
879fd4e5da5Sopenharmony_ci         %83 = OpCopyObject %10 %15
880fd4e5da5Sopenharmony_ci         %84 = OpCopyObject %39 %47
881fd4e5da5Sopenharmony_ci               OpStore %50 %64
882fd4e5da5Sopenharmony_ci         %85 = OpCopyObject %30 %42
883fd4e5da5Sopenharmony_ci               OpStore %36 %38
884fd4e5da5Sopenharmony_ci               OpReturn
885fd4e5da5Sopenharmony_ci               OpFunctionEnd
886fd4e5da5Sopenharmony_ci  )";
887fd4e5da5Sopenharmony_ci
888fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
889fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
890fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
891fd4e5da5Sopenharmony_ci  spvtools::ValidatorOptions validator_options;
892fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
893fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
894fd4e5da5Sopenharmony_ci  TransformationContext transformation_context(
895fd4e5da5Sopenharmony_ci      MakeUnique<FactManager>(context.get()), validator_options);
896fd4e5da5Sopenharmony_ci
897fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
898fd4e5da5Sopenharmony_ci      MakeSynonymFact(20, {0}, 100, {0}));
899fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
900fd4e5da5Sopenharmony_ci      MakeSynonymFact(20, {1}, 100, {1}));
901fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
902fd4e5da5Sopenharmony_ci      MakeSynonymFact(20, {2}, 100, {2}));
903fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
904fd4e5da5Sopenharmony_ci      MakeSynonymFact(54, {}, 100, {3}));
905fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
906fd4e5da5Sopenharmony_ci      MakeSynonymFact(15, {0}, 101, {0}));
907fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
908fd4e5da5Sopenharmony_ci      MakeSynonymFact(15, {1}, 101, {1}));
909fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
910fd4e5da5Sopenharmony_ci      MakeSynonymFact(19, {0}, 101, {2}));
911fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
912fd4e5da5Sopenharmony_ci      MakeSynonymFact(19, {1}, 101, {3}));
913fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
914fd4e5da5Sopenharmony_ci      MakeSynonymFact(27, {}, 102, {0}));
915fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
916fd4e5da5Sopenharmony_ci      MakeSynonymFact(15, {0}, 102, {1}));
917fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
918fd4e5da5Sopenharmony_ci      MakeSynonymFact(15, {1}, 102, {2}));
919fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
920fd4e5da5Sopenharmony_ci      MakeSynonymFact(33, {}, 103, {0}));
921fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
922fd4e5da5Sopenharmony_ci      MakeSynonymFact(47, {0}, 103, {1}));
923fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
924fd4e5da5Sopenharmony_ci      MakeSynonymFact(47, {1}, 103, {2}));
925fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
926fd4e5da5Sopenharmony_ci      MakeSynonymFact(47, {2}, 103, {3}));
927fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
928fd4e5da5Sopenharmony_ci      MakeSynonymFact(42, {}, 104, {0}));
929fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
930fd4e5da5Sopenharmony_ci      MakeSynonymFact(45, {}, 104, {1}));
931fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
932fd4e5da5Sopenharmony_ci      MakeSynonymFact(38, {0}, 105, {0}));
933fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
934fd4e5da5Sopenharmony_ci      MakeSynonymFact(38, {1}, 105, {1}));
935fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->MaybeAddFact(
936fd4e5da5Sopenharmony_ci      MakeSynonymFact(46, {}, 105, {2}));
937fd4e5da5Sopenharmony_ci
938fd4e5da5Sopenharmony_ci  // Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20'
939fd4e5da5Sopenharmony_ci  auto instruction_descriptor_1 =
940fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(80, spv::Op::OpCopyObject, 0);
941fd4e5da5Sopenharmony_ci  auto shuffle_1 = TransformationVectorShuffle(instruction_descriptor_1, 200,
942fd4e5da5Sopenharmony_ci                                               100, 100, {0, 1, 2});
943fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context));
944fd4e5da5Sopenharmony_ci  shuffle_1.Apply(context.get(), &transformation_context);
945fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
946fd4e5da5Sopenharmony_ci
947fd4e5da5Sopenharmony_ci  auto replacement_1 = TransformationReplaceIdWithSynonym(
948fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200);
949fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
950fd4e5da5Sopenharmony_ci      replacement_1.IsApplicable(context.get(), transformation_context));
951fd4e5da5Sopenharmony_ci  replacement_1.Apply(context.get(), &transformation_context);
952fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
953fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
954fd4e5da5Sopenharmony_ci
955fd4e5da5Sopenharmony_ci  // Replace %54 with %100[3] in '%56 = OpFOrdNotEqual %30 %54 %55'
956fd4e5da5Sopenharmony_ci  auto instruction_descriptor_2 =
957fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(56, spv::Op::OpFOrdNotEqual, 0);
958fd4e5da5Sopenharmony_ci  auto extract_2 =
959fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_2, 201, 100, {3});
960fd4e5da5Sopenharmony_ci
961fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context));
962fd4e5da5Sopenharmony_ci  extract_2.Apply(context.get(), &transformation_context);
963fd4e5da5Sopenharmony_ci  auto replacement_2 = TransformationReplaceIdWithSynonym(
964fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(54, instruction_descriptor_2, 0), 201);
965fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
966fd4e5da5Sopenharmony_ci      replacement_2.IsApplicable(context.get(), transformation_context));
967fd4e5da5Sopenharmony_ci  replacement_2.Apply(context.get(), &transformation_context);
968fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
969fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
970fd4e5da5Sopenharmony_ci
971fd4e5da5Sopenharmony_ci  // Replace %15 with %101[0:1] in 'OpStore %12 %15'
972fd4e5da5Sopenharmony_ci  auto instruction_descriptor_3 =
973fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(64, spv::Op::OpStore, 0);
974fd4e5da5Sopenharmony_ci  auto shuffle_3 = TransformationVectorShuffle(instruction_descriptor_3, 202,
975fd4e5da5Sopenharmony_ci                                               101, 101, {0, 1});
976fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context));
977fd4e5da5Sopenharmony_ci  shuffle_3.Apply(context.get(), &transformation_context);
978fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
979fd4e5da5Sopenharmony_ci
980fd4e5da5Sopenharmony_ci  auto replacement_3 = TransformationReplaceIdWithSynonym(
981fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202);
982fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
983fd4e5da5Sopenharmony_ci      replacement_3.IsApplicable(context.get(), transformation_context));
984fd4e5da5Sopenharmony_ci  replacement_3.Apply(context.get(), &transformation_context);
985fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
986fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
987fd4e5da5Sopenharmony_ci
988fd4e5da5Sopenharmony_ci  // Replace %19 with %101[2:3] in '%81 = OpVectorShuffle %16 %19 %19 0 0 1'
989fd4e5da5Sopenharmony_ci  auto instruction_descriptor_4 =
990fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(81, spv::Op::OpVectorShuffle, 0);
991fd4e5da5Sopenharmony_ci  auto shuffle_4 = TransformationVectorShuffle(instruction_descriptor_4, 203,
992fd4e5da5Sopenharmony_ci                                               101, 101, {2, 3});
993fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context));
994fd4e5da5Sopenharmony_ci  shuffle_4.Apply(context.get(), &transformation_context);
995fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
996fd4e5da5Sopenharmony_ci
997fd4e5da5Sopenharmony_ci  auto replacement_4 = TransformationReplaceIdWithSynonym(
998fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203);
999fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1000fd4e5da5Sopenharmony_ci      replacement_4.IsApplicable(context.get(), transformation_context));
1001fd4e5da5Sopenharmony_ci  replacement_4.Apply(context.get(), &transformation_context);
1002fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1003fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1004fd4e5da5Sopenharmony_ci
1005fd4e5da5Sopenharmony_ci  // Replace %27 with %102[0] in '%82 = OpCompositeConstruct %21 %26 %27 %28
1006fd4e5da5Sopenharmony_ci  // %25'
1007fd4e5da5Sopenharmony_ci  auto instruction_descriptor_5 =
1008fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(82, spv::Op::OpCompositeConstruct, 0);
1009fd4e5da5Sopenharmony_ci  auto extract_5 =
1010fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_5, 204, 102, {0});
1011fd4e5da5Sopenharmony_ci
1012fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context));
1013fd4e5da5Sopenharmony_ci  extract_5.Apply(context.get(), &transformation_context);
1014fd4e5da5Sopenharmony_ci  auto replacement_5 = TransformationReplaceIdWithSynonym(
1015fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(27, instruction_descriptor_5, 1), 204);
1016fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1017fd4e5da5Sopenharmony_ci      replacement_5.IsApplicable(context.get(), transformation_context));
1018fd4e5da5Sopenharmony_ci  replacement_5.Apply(context.get(), &transformation_context);
1019fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1020fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1021fd4e5da5Sopenharmony_ci
1022fd4e5da5Sopenharmony_ci  // Replace %15 with %102[1:2] in '%83 = OpCopyObject %10 %15'
1023fd4e5da5Sopenharmony_ci  auto instruction_descriptor_6 =
1024fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(83, spv::Op::OpCopyObject, 0);
1025fd4e5da5Sopenharmony_ci  auto shuffle_6 = TransformationVectorShuffle(instruction_descriptor_6, 205,
1026fd4e5da5Sopenharmony_ci                                               102, 102, {1, 2});
1027fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context));
1028fd4e5da5Sopenharmony_ci  shuffle_6.Apply(context.get(), &transformation_context);
1029fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
1030fd4e5da5Sopenharmony_ci
1031fd4e5da5Sopenharmony_ci  auto replacement_6 = TransformationReplaceIdWithSynonym(
1032fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205);
1033fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1034fd4e5da5Sopenharmony_ci      replacement_6.IsApplicable(context.get(), transformation_context));
1035fd4e5da5Sopenharmony_ci  replacement_6.Apply(context.get(), &transformation_context);
1036fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1037fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1038fd4e5da5Sopenharmony_ci
1039fd4e5da5Sopenharmony_ci  // Replace %33 with %103[0] in '%86 = OpCopyObject %30 %33'
1040fd4e5da5Sopenharmony_ci  auto instruction_descriptor_7 =
1041fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(86, spv::Op::OpCopyObject, 0);
1042fd4e5da5Sopenharmony_ci  auto extract_7 =
1043fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_7, 206, 103, {0});
1044fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_7.IsApplicable(context.get(), transformation_context));
1045fd4e5da5Sopenharmony_ci  extract_7.Apply(context.get(), &transformation_context);
1046fd4e5da5Sopenharmony_ci  auto replacement_7 = TransformationReplaceIdWithSynonym(
1047fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(33, instruction_descriptor_7, 0), 206);
1048fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1049fd4e5da5Sopenharmony_ci      replacement_7.IsApplicable(context.get(), transformation_context));
1050fd4e5da5Sopenharmony_ci  replacement_7.Apply(context.get(), &transformation_context);
1051fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1052fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1053fd4e5da5Sopenharmony_ci
1054fd4e5da5Sopenharmony_ci  // Replace %47 with %103[1:3] in '%84 = OpCopyObject %39 %47'
1055fd4e5da5Sopenharmony_ci  auto instruction_descriptor_8 =
1056fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(84, spv::Op::OpCopyObject, 0);
1057fd4e5da5Sopenharmony_ci  auto shuffle_8 = TransformationVectorShuffle(instruction_descriptor_8, 207,
1058fd4e5da5Sopenharmony_ci                                               103, 103, {1, 2, 3});
1059fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context));
1060fd4e5da5Sopenharmony_ci  shuffle_8.Apply(context.get(), &transformation_context);
1061fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
1062fd4e5da5Sopenharmony_ci
1063fd4e5da5Sopenharmony_ci  auto replacement_8 = TransformationReplaceIdWithSynonym(
1064fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207);
1065fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1066fd4e5da5Sopenharmony_ci      replacement_8.IsApplicable(context.get(), transformation_context));
1067fd4e5da5Sopenharmony_ci  replacement_8.Apply(context.get(), &transformation_context);
1068fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1069fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1070fd4e5da5Sopenharmony_ci
1071fd4e5da5Sopenharmony_ci  // Replace %42 with %104[0] in '%85 = OpCopyObject %30 %42'
1072fd4e5da5Sopenharmony_ci  auto instruction_descriptor_9 =
1073fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(85, spv::Op::OpCopyObject, 0);
1074fd4e5da5Sopenharmony_ci  auto extract_9 =
1075fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_9, 208, 104, {0});
1076fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_9.IsApplicable(context.get(), transformation_context));
1077fd4e5da5Sopenharmony_ci  extract_9.Apply(context.get(), &transformation_context);
1078fd4e5da5Sopenharmony_ci  auto replacement_9 = TransformationReplaceIdWithSynonym(
1079fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(42, instruction_descriptor_9, 0), 208);
1080fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1081fd4e5da5Sopenharmony_ci      replacement_9.IsApplicable(context.get(), transformation_context));
1082fd4e5da5Sopenharmony_ci  replacement_9.Apply(context.get(), &transformation_context);
1083fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1084fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1085fd4e5da5Sopenharmony_ci
1086fd4e5da5Sopenharmony_ci  // Replace %45 with %104[1] in '%63 = OpLogicalOr %30 %45 %46'
1087fd4e5da5Sopenharmony_ci  auto instruction_descriptor_10 =
1088fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(63, spv::Op::OpLogicalOr, 0);
1089fd4e5da5Sopenharmony_ci  auto extract_10 =
1090fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_10, 209, 104, {1});
1091fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_10.IsApplicable(context.get(), transformation_context));
1092fd4e5da5Sopenharmony_ci  extract_10.Apply(context.get(), &transformation_context);
1093fd4e5da5Sopenharmony_ci  auto replacement_10 = TransformationReplaceIdWithSynonym(
1094fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(45, instruction_descriptor_10, 0), 209);
1095fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1096fd4e5da5Sopenharmony_ci      replacement_10.IsApplicable(context.get(), transformation_context));
1097fd4e5da5Sopenharmony_ci  replacement_10.Apply(context.get(), &transformation_context);
1098fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1099fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1100fd4e5da5Sopenharmony_ci
1101fd4e5da5Sopenharmony_ci  // Replace %38 with %105[0:1] in 'OpStore %36 %38'
1102fd4e5da5Sopenharmony_ci  auto instruction_descriptor_11 =
1103fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(85, spv::Op::OpStore, 0);
1104fd4e5da5Sopenharmony_ci  auto shuffle_11 = TransformationVectorShuffle(instruction_descriptor_11, 210,
1105fd4e5da5Sopenharmony_ci                                                105, 105, {0, 1});
1106fd4e5da5Sopenharmony_ci  ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context));
1107fd4e5da5Sopenharmony_ci  shuffle_11.Apply(context.get(), &transformation_context);
1108fd4e5da5Sopenharmony_ci  transformation_context.GetFactManager()->ComputeClosureOfFacts(100);
1109fd4e5da5Sopenharmony_ci
1110fd4e5da5Sopenharmony_ci  auto replacement_11 = TransformationReplaceIdWithSynonym(
1111fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210);
1112fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1113fd4e5da5Sopenharmony_ci      replacement_11.IsApplicable(context.get(), transformation_context));
1114fd4e5da5Sopenharmony_ci  replacement_11.Apply(context.get(), &transformation_context);
1115fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1116fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1117fd4e5da5Sopenharmony_ci
1118fd4e5da5Sopenharmony_ci  // Replace %46 with %105[2] in '%62 = OpLogicalAnd %30 %45 %46'
1119fd4e5da5Sopenharmony_ci  auto instruction_descriptor_12 =
1120fd4e5da5Sopenharmony_ci      MakeInstructionDescriptor(62, spv::Op::OpLogicalAnd, 0);
1121fd4e5da5Sopenharmony_ci  auto extract_12 =
1122fd4e5da5Sopenharmony_ci      TransformationCompositeExtract(instruction_descriptor_12, 211, 105, {2});
1123fd4e5da5Sopenharmony_ci  ASSERT_TRUE(extract_12.IsApplicable(context.get(), transformation_context));
1124fd4e5da5Sopenharmony_ci  extract_12.Apply(context.get(), &transformation_context);
1125fd4e5da5Sopenharmony_ci  auto replacement_12 = TransformationReplaceIdWithSynonym(
1126fd4e5da5Sopenharmony_ci      MakeIdUseDescriptor(46, instruction_descriptor_12, 1), 211);
1127fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
1128fd4e5da5Sopenharmony_ci      replacement_12.IsApplicable(context.get(), transformation_context));
1129fd4e5da5Sopenharmony_ci  replacement_12.Apply(context.get(), &transformation_context);
1130fd4e5da5Sopenharmony_ci  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
1131fd4e5da5Sopenharmony_ci                                               kConsoleMessageConsumer));
1132fd4e5da5Sopenharmony_ci
1133fd4e5da5Sopenharmony_ci  const std::string after_transformation = R"(
1134fd4e5da5Sopenharmony_ci               OpCapability Shader
1135fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1136fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1137fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
1138fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
1139fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1140fd4e5da5Sopenharmony_ci               OpName %4 "main"
1141fd4e5da5Sopenharmony_ci               OpName %8 "f"
1142fd4e5da5Sopenharmony_ci               OpName %12 "v2"
1143fd4e5da5Sopenharmony_ci               OpName %18 "v3"
1144fd4e5da5Sopenharmony_ci               OpName %23 "v4"
1145fd4e5da5Sopenharmony_ci               OpName %32 "b"
1146fd4e5da5Sopenharmony_ci               OpName %36 "bv2"
1147fd4e5da5Sopenharmony_ci               OpName %41 "bv3"
1148fd4e5da5Sopenharmony_ci               OpName %50 "bv4"
1149fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
1150fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
1151fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
1152fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
1153fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 42
1154fd4e5da5Sopenharmony_ci         %10 = OpTypeVector %6 2
1155fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Function %10
1156fd4e5da5Sopenharmony_ci         %16 = OpTypeVector %6 3
1157fd4e5da5Sopenharmony_ci         %17 = OpTypePointer Function %16
1158fd4e5da5Sopenharmony_ci         %21 = OpTypeVector %6 4
1159fd4e5da5Sopenharmony_ci         %22 = OpTypePointer Function %21
1160fd4e5da5Sopenharmony_ci         %30 = OpTypeBool
1161fd4e5da5Sopenharmony_ci         %31 = OpTypePointer Function %30
1162fd4e5da5Sopenharmony_ci         %33 = OpConstantFalse %30
1163fd4e5da5Sopenharmony_ci         %34 = OpTypeVector %30 2
1164fd4e5da5Sopenharmony_ci         %35 = OpTypePointer Function %34
1165fd4e5da5Sopenharmony_ci         %37 = OpConstantTrue %30
1166fd4e5da5Sopenharmony_ci         %38 = OpConstantComposite %34 %37 %37
1167fd4e5da5Sopenharmony_ci         %39 = OpTypeVector %30 3
1168fd4e5da5Sopenharmony_ci         %40 = OpTypePointer Function %39
1169fd4e5da5Sopenharmony_ci         %48 = OpTypeVector %30 4
1170fd4e5da5Sopenharmony_ci         %49 = OpTypePointer Function %48
1171fd4e5da5Sopenharmony_ci         %51 = OpTypeInt 32 0
1172fd4e5da5Sopenharmony_ci         %52 = OpConstant %51 2
1173fd4e5da5Sopenharmony_ci         %55 = OpConstant %6 0
1174fd4e5da5Sopenharmony_ci         %57 = OpConstant %51 1
1175fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
1176fd4e5da5Sopenharmony_ci          %5 = OpLabel
1177fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
1178fd4e5da5Sopenharmony_ci         %12 = OpVariable %11 Function
1179fd4e5da5Sopenharmony_ci         %18 = OpVariable %17 Function
1180fd4e5da5Sopenharmony_ci         %23 = OpVariable %22 Function
1181fd4e5da5Sopenharmony_ci         %32 = OpVariable %31 Function
1182fd4e5da5Sopenharmony_ci         %36 = OpVariable %35 Function
1183fd4e5da5Sopenharmony_ci         %41 = OpVariable %40 Function
1184fd4e5da5Sopenharmony_ci         %50 = OpVariable %49 Function
1185fd4e5da5Sopenharmony_ci               OpStore %8 %9
1186fd4e5da5Sopenharmony_ci         %13 = OpLoad %6 %8
1187fd4e5da5Sopenharmony_ci         %14 = OpLoad %6 %8
1188fd4e5da5Sopenharmony_ci         %15 = OpCompositeConstruct %10 %13 %14
1189fd4e5da5Sopenharmony_ci               OpStore %12 %15
1190fd4e5da5Sopenharmony_ci         %19 = OpLoad %10 %12
1191fd4e5da5Sopenharmony_ci         %20 = OpVectorShuffle %16 %19 %19 0 0 1
1192fd4e5da5Sopenharmony_ci               OpStore %18 %20
1193fd4e5da5Sopenharmony_ci         %24 = OpLoad %16 %18
1194fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %8
1195fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %6 %24 0
1196fd4e5da5Sopenharmony_ci         %27 = OpCompositeExtract %6 %24 1
1197fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %6 %24 2
1198fd4e5da5Sopenharmony_ci         %29 = OpCompositeConstruct %21 %26 %27 %28 %25
1199fd4e5da5Sopenharmony_ci               OpStore %23 %29
1200fd4e5da5Sopenharmony_ci               OpStore %32 %33
1201fd4e5da5Sopenharmony_ci               OpStore %36 %38
1202fd4e5da5Sopenharmony_ci         %42 = OpLoad %30 %32
1203fd4e5da5Sopenharmony_ci         %43 = OpLoad %34 %36
1204fd4e5da5Sopenharmony_ci         %44 = OpVectorShuffle %34 %43 %43 0 0
1205fd4e5da5Sopenharmony_ci         %45 = OpCompositeExtract %30 %44 0
1206fd4e5da5Sopenharmony_ci         %46 = OpCompositeExtract %30 %44 1
1207fd4e5da5Sopenharmony_ci         %47 = OpCompositeConstruct %39 %42 %45 %46
1208fd4e5da5Sopenharmony_ci               OpStore %41 %47
1209fd4e5da5Sopenharmony_ci         %53 = OpAccessChain %7 %23 %52
1210fd4e5da5Sopenharmony_ci         %54 = OpLoad %6 %53
1211fd4e5da5Sopenharmony_ci
1212fd4e5da5Sopenharmony_ci        %100 = OpCompositeConstruct %21 %20 %54
1213fd4e5da5Sopenharmony_ci        %101 = OpCompositeConstruct %21 %15 %19
1214fd4e5da5Sopenharmony_ci        %102 = OpCompositeConstruct %16 %27 %15
1215fd4e5da5Sopenharmony_ci        %103 = OpCompositeConstruct %48 %33 %47
1216fd4e5da5Sopenharmony_ci        %104 = OpCompositeConstruct %34 %42 %45
1217fd4e5da5Sopenharmony_ci        %105 = OpCompositeConstruct %39 %38 %46
1218fd4e5da5Sopenharmony_ci
1219fd4e5da5Sopenharmony_ci        %206 = OpCompositeExtract %30 %103 0
1220fd4e5da5Sopenharmony_ci         %86 = OpCopyObject %30 %206
1221fd4e5da5Sopenharmony_ci        %201 = OpCompositeExtract %6 %100 3
1222fd4e5da5Sopenharmony_ci         %56 = OpFOrdNotEqual %30 %201 %55
1223fd4e5da5Sopenharmony_ci        %200 = OpVectorShuffle %16 %100 %100 0 1 2
1224fd4e5da5Sopenharmony_ci         %80 = OpCopyObject %16 %200
1225fd4e5da5Sopenharmony_ci         %58 = OpAccessChain %7 %18 %57
1226fd4e5da5Sopenharmony_ci         %59 = OpLoad %6 %58
1227fd4e5da5Sopenharmony_ci         %60 = OpFOrdNotEqual %30 %59 %55
1228fd4e5da5Sopenharmony_ci         %61 = OpLoad %34 %36
1229fd4e5da5Sopenharmony_ci        %211 = OpCompositeExtract %30 %105 2
1230fd4e5da5Sopenharmony_ci         %62 = OpLogicalAnd %30 %45 %211
1231fd4e5da5Sopenharmony_ci        %209 = OpCompositeExtract %30 %104 1
1232fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %30 %209 %46
1233fd4e5da5Sopenharmony_ci         %64 = OpCompositeConstruct %48 %56 %60 %62 %63
1234fd4e5da5Sopenharmony_ci        %202 = OpVectorShuffle %10 %101 %101 0 1
1235fd4e5da5Sopenharmony_ci               OpStore %12 %202
1236fd4e5da5Sopenharmony_ci        %203 = OpVectorShuffle %10 %101 %101 2 3
1237fd4e5da5Sopenharmony_ci         %81 = OpVectorShuffle %16 %203 %19 0 0 1
1238fd4e5da5Sopenharmony_ci        %204 = OpCompositeExtract %6 %102 0
1239fd4e5da5Sopenharmony_ci         %82 = OpCompositeConstruct %21 %26 %204 %28 %25
1240fd4e5da5Sopenharmony_ci        %205 = OpVectorShuffle %10 %102 %102 1 2
1241fd4e5da5Sopenharmony_ci         %83 = OpCopyObject %10 %205
1242fd4e5da5Sopenharmony_ci        %207 = OpVectorShuffle %39 %103 %103 1 2 3
1243fd4e5da5Sopenharmony_ci         %84 = OpCopyObject %39 %207
1244fd4e5da5Sopenharmony_ci               OpStore %50 %64
1245fd4e5da5Sopenharmony_ci        %208 = OpCompositeExtract %30 %104 0
1246fd4e5da5Sopenharmony_ci         %85 = OpCopyObject %30 %208
1247fd4e5da5Sopenharmony_ci        %210 = OpVectorShuffle %34 %105 %105 0 1
1248fd4e5da5Sopenharmony_ci               OpStore %36 %210
1249fd4e5da5Sopenharmony_ci               OpReturn
1250fd4e5da5Sopenharmony_ci               OpFunctionEnd
1251fd4e5da5Sopenharmony_ci  )";
1252fd4e5da5Sopenharmony_ci
1253fd4e5da5Sopenharmony_ci  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
1254fd4e5da5Sopenharmony_ci}
1255fd4e5da5Sopenharmony_ci
1256fd4e5da5Sopenharmony_ci}  // namespace
1257fd4e5da5Sopenharmony_ci}  // namespace fuzz
1258fd4e5da5Sopenharmony_ci}  // namespace spvtools
1259