1fd4e5da5Sopenharmony_ci// Copyright (c) 2020 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/fuzzer_pass_construct_composites.h"
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h"
19fd4e5da5Sopenharmony_ci#include "source/fuzz/pseudo_random_generator.h"
20fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h"
21fd4e5da5Sopenharmony_ci
22fd4e5da5Sopenharmony_cinamespace spvtools {
23fd4e5da5Sopenharmony_cinamespace fuzz {
24fd4e5da5Sopenharmony_cinamespace {
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_ciTEST(FuzzerPassConstructCompositesTest, IsomorphicStructs) {
27fd4e5da5Sopenharmony_ci  // This test declares various isomorphic structs, and a struct that is made up
28fd4e5da5Sopenharmony_ci  // of these isomorphic structs.  The pass to construct composites is then
29fd4e5da5Sopenharmony_ci  // applied several times to check that no issues arise related to using a
30fd4e5da5Sopenharmony_ci  // value of one struct type when a value of an isomorphic struct type is
31fd4e5da5Sopenharmony_ci  // required.
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_ci  std::string shader = R"(
34fd4e5da5Sopenharmony_ci               OpCapability Shader
35fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
36fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
37fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
38fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
39fd4e5da5Sopenharmony_ci               OpSource ESSL 310
40fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
41fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
42fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
43fd4e5da5Sopenharmony_ci          %7 = OpConstant %6 0
44fd4e5da5Sopenharmony_ci          %8 = OpTypeStruct %6 %6 %6
45fd4e5da5Sopenharmony_ci          %9 = OpTypeStruct %6 %6 %6
46fd4e5da5Sopenharmony_ci         %10 = OpTypeStruct %6 %6 %6
47fd4e5da5Sopenharmony_ci         %11 = OpTypeStruct %6 %6 %6
48fd4e5da5Sopenharmony_ci         %12 = OpTypeStruct %6 %6 %6
49fd4e5da5Sopenharmony_ci         %13 = OpTypeStruct %8 %9 %10 %11 %12
50fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %8 %7 %7 %7
51fd4e5da5Sopenharmony_ci         %15 = OpConstantComposite %9 %7 %7 %7
52fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %10 %7 %7 %7
53fd4e5da5Sopenharmony_ci         %17 = OpConstantComposite %11 %7 %7 %7
54fd4e5da5Sopenharmony_ci         %18 = OpConstantComposite %12 %7 %7 %7
55fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
56fd4e5da5Sopenharmony_ci          %5 = OpLabel
57fd4e5da5Sopenharmony_ci               OpNop
58fd4e5da5Sopenharmony_ci               OpNop
59fd4e5da5Sopenharmony_ci               OpNop
60fd4e5da5Sopenharmony_ci               OpNop
61fd4e5da5Sopenharmony_ci               OpNop
62fd4e5da5Sopenharmony_ci               OpNop
63fd4e5da5Sopenharmony_ci               OpNop
64fd4e5da5Sopenharmony_ci               OpNop
65fd4e5da5Sopenharmony_ci               OpNop
66fd4e5da5Sopenharmony_ci               OpNop
67fd4e5da5Sopenharmony_ci               OpNop
68fd4e5da5Sopenharmony_ci               OpNop
69fd4e5da5Sopenharmony_ci               OpNop
70fd4e5da5Sopenharmony_ci               OpNop
71fd4e5da5Sopenharmony_ci               OpNop
72fd4e5da5Sopenharmony_ci               OpNop
73fd4e5da5Sopenharmony_ci               OpReturn
74fd4e5da5Sopenharmony_ci               OpFunctionEnd
75fd4e5da5Sopenharmony_ci  )";
76fd4e5da5Sopenharmony_ci
77fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
78fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
79fd4e5da5Sopenharmony_ci
80fd4e5da5Sopenharmony_ci  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
81fd4e5da5Sopenharmony_ci                               false);
82fd4e5da5Sopenharmony_ci
83fd4e5da5Sopenharmony_ci  for (uint32_t i = 0; i < 10; i++) {
84fd4e5da5Sopenharmony_ci    const auto context =
85fd4e5da5Sopenharmony_ci        BuildModule(env, consumer, shader, kFuzzAssembleOption);
86fd4e5da5Sopenharmony_ci    spvtools::ValidatorOptions validator_options;
87fd4e5da5Sopenharmony_ci    ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
88fd4e5da5Sopenharmony_ci        context.get(), validator_options, kConsoleMessageConsumer));
89fd4e5da5Sopenharmony_ci    TransformationContext transformation_context(
90fd4e5da5Sopenharmony_ci        MakeUnique<FactManager>(context.get()), validator_options);
91fd4e5da5Sopenharmony_ci    protobufs::TransformationSequence transformation_sequence;
92fd4e5da5Sopenharmony_ci
93fd4e5da5Sopenharmony_ci    FuzzerPassConstructComposites fuzzer_pass(
94fd4e5da5Sopenharmony_ci        context.get(), &transformation_context, &fuzzer_context,
95fd4e5da5Sopenharmony_ci        &transformation_sequence, false);
96fd4e5da5Sopenharmony_ci
97fd4e5da5Sopenharmony_ci    fuzzer_pass.Apply();
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_ci    // We just check that the result is valid.
100fd4e5da5Sopenharmony_ci    ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
101fd4e5da5Sopenharmony_ci        context.get(), validator_options, kConsoleMessageConsumer));
102fd4e5da5Sopenharmony_ci  }
103fd4e5da5Sopenharmony_ci}
104fd4e5da5Sopenharmony_ci
105fd4e5da5Sopenharmony_ciTEST(FuzzerPassConstructCompositesTest, IsomorphicArrays) {
106fd4e5da5Sopenharmony_ci  // This test declares various isomorphic arrays, and a struct that is made up
107fd4e5da5Sopenharmony_ci  // of these isomorphic arrays.  The pass to construct composites is then
108fd4e5da5Sopenharmony_ci  // applied several times to check that no issues arise related to using a
109fd4e5da5Sopenharmony_ci  // value of one array type when a value of an isomorphic array type is
110fd4e5da5Sopenharmony_ci  // required.
111fd4e5da5Sopenharmony_ci
112fd4e5da5Sopenharmony_ci  std::string shader = R"(
113fd4e5da5Sopenharmony_ci               OpCapability Shader
114fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
115fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
116fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
117fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
118fd4e5da5Sopenharmony_ci               OpSource ESSL 310
119fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
120fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
121fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
122fd4e5da5Sopenharmony_ci         %50 = OpTypeInt 32 0
123fd4e5da5Sopenharmony_ci         %51 = OpConstant %50 3
124fd4e5da5Sopenharmony_ci          %7 = OpConstant %6 0
125fd4e5da5Sopenharmony_ci          %8 = OpTypeArray %6 %51
126fd4e5da5Sopenharmony_ci          %9 = OpTypeArray %6 %51
127fd4e5da5Sopenharmony_ci         %10 = OpTypeArray %6 %51
128fd4e5da5Sopenharmony_ci         %11 = OpTypeArray %6 %51
129fd4e5da5Sopenharmony_ci         %12 = OpTypeArray %6 %51
130fd4e5da5Sopenharmony_ci         %13 = OpTypeStruct %8 %9 %10 %11 %12
131fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %8 %7 %7 %7
132fd4e5da5Sopenharmony_ci         %15 = OpConstantComposite %9 %7 %7 %7
133fd4e5da5Sopenharmony_ci         %16 = OpConstantComposite %10 %7 %7 %7
134fd4e5da5Sopenharmony_ci         %17 = OpConstantComposite %11 %7 %7 %7
135fd4e5da5Sopenharmony_ci         %18 = OpConstantComposite %12 %7 %7 %7
136fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
137fd4e5da5Sopenharmony_ci          %5 = OpLabel
138fd4e5da5Sopenharmony_ci               OpNop
139fd4e5da5Sopenharmony_ci               OpNop
140fd4e5da5Sopenharmony_ci               OpNop
141fd4e5da5Sopenharmony_ci               OpNop
142fd4e5da5Sopenharmony_ci               OpNop
143fd4e5da5Sopenharmony_ci               OpNop
144fd4e5da5Sopenharmony_ci               OpNop
145fd4e5da5Sopenharmony_ci               OpNop
146fd4e5da5Sopenharmony_ci               OpNop
147fd4e5da5Sopenharmony_ci               OpNop
148fd4e5da5Sopenharmony_ci               OpNop
149fd4e5da5Sopenharmony_ci               OpNop
150fd4e5da5Sopenharmony_ci               OpNop
151fd4e5da5Sopenharmony_ci               OpNop
152fd4e5da5Sopenharmony_ci               OpNop
153fd4e5da5Sopenharmony_ci               OpNop
154fd4e5da5Sopenharmony_ci               OpReturn
155fd4e5da5Sopenharmony_ci               OpFunctionEnd
156fd4e5da5Sopenharmony_ci  )";
157fd4e5da5Sopenharmony_ci
158fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
159fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
160fd4e5da5Sopenharmony_ci
161fd4e5da5Sopenharmony_ci  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
162fd4e5da5Sopenharmony_ci                               false);
163fd4e5da5Sopenharmony_ci
164fd4e5da5Sopenharmony_ci  for (uint32_t i = 0; i < 10; i++) {
165fd4e5da5Sopenharmony_ci    const auto context =
166fd4e5da5Sopenharmony_ci        BuildModule(env, consumer, shader, kFuzzAssembleOption);
167fd4e5da5Sopenharmony_ci    spvtools::ValidatorOptions validator_options;
168fd4e5da5Sopenharmony_ci    ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
169fd4e5da5Sopenharmony_ci        context.get(), validator_options, kConsoleMessageConsumer));
170fd4e5da5Sopenharmony_ci    TransformationContext transformation_context(
171fd4e5da5Sopenharmony_ci        MakeUnique<FactManager>(context.get()), validator_options);
172fd4e5da5Sopenharmony_ci    protobufs::TransformationSequence transformation_sequence;
173fd4e5da5Sopenharmony_ci
174fd4e5da5Sopenharmony_ci    FuzzerPassConstructComposites fuzzer_pass(
175fd4e5da5Sopenharmony_ci        context.get(), &transformation_context, &fuzzer_context,
176fd4e5da5Sopenharmony_ci        &transformation_sequence, false);
177fd4e5da5Sopenharmony_ci
178fd4e5da5Sopenharmony_ci    fuzzer_pass.Apply();
179fd4e5da5Sopenharmony_ci
180fd4e5da5Sopenharmony_ci    // We just check that the result is valid.
181fd4e5da5Sopenharmony_ci    ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
182fd4e5da5Sopenharmony_ci        context.get(), validator_options, kConsoleMessageConsumer));
183fd4e5da5Sopenharmony_ci  }
184fd4e5da5Sopenharmony_ci}
185fd4e5da5Sopenharmony_ci
186fd4e5da5Sopenharmony_ci}  // namespace
187fd4e5da5Sopenharmony_ci}  // namespace fuzz
188fd4e5da5Sopenharmony_ci}  // namespace spvtools
189