1 // Copyright (c) 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "source/fuzz/transformation_add_constant_null.h"
16
17 #include "gtest/gtest.h"
18 #include "source/fuzz/fuzzer_util.h"
19 #include "test/fuzz/fuzz_test_util.h"
20
21 namespace spvtools {
22 namespace fuzz {
23 namespace {
24
TEST(TransformationAddConstantNullTest, BasicTest)25 TEST(TransformationAddConstantNullTest, BasicTest) {
26 std::string shader = R"(
27 OpCapability Shader
28 %1 = OpExtInstImport "GLSL.std.450"
29 OpMemoryModel Logical GLSL450
30 OpEntryPoint Fragment %4 "main"
31 OpExecutionMode %4 OriginUpperLeft
32 OpSource ESSL 310
33 %2 = OpTypeVoid
34 %3 = OpTypeFunction %2
35 %6 = OpTypeFloat 32
36 %7 = OpTypeInt 32 1
37 %8 = OpTypeVector %6 2
38 %9 = OpTypeVector %6 3
39 %10 = OpTypeVector %6 4
40 %11 = OpTypeVector %7 2
41 %20 = OpTypeSampler
42 %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
43 %22 = OpTypeSampledImage %21
44 %4 = OpFunction %2 None %3
45 %5 = OpLabel
46 OpReturn
47 OpFunctionEnd
48 )";
49
50 const auto env = SPV_ENV_UNIVERSAL_1_4;
51 const auto consumer = nullptr;
52 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
53 spvtools::ValidatorOptions validator_options;
54 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
55 kConsoleMessageConsumer));
56 TransformationContext transformation_context(
57 MakeUnique<FactManager>(context.get()), validator_options);
58 // Id already in use
59 ASSERT_FALSE(TransformationAddConstantNull(4, 11).IsApplicable(
60 context.get(), transformation_context));
61 // %1 is not a type
62 ASSERT_FALSE(TransformationAddConstantNull(100, 1).IsApplicable(
63 context.get(), transformation_context));
64
65 // %3 is a function type
66 ASSERT_FALSE(TransformationAddConstantNull(100, 3).IsApplicable(
67 context.get(), transformation_context));
68
69 // %20 is a sampler type
70 ASSERT_FALSE(TransformationAddConstantNull(100, 20).IsApplicable(
71 context.get(), transformation_context));
72
73 // %21 is an image type
74 ASSERT_FALSE(TransformationAddConstantNull(100, 21).IsApplicable(
75 context.get(), transformation_context));
76
77 // %22 is a sampled image type
78 ASSERT_FALSE(TransformationAddConstantNull(100, 22).IsApplicable(
79 context.get(), transformation_context));
80
81 {
82 // %100 = OpConstantNull %6
83 TransformationAddConstantNull transformation(100, 6);
84 ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
85 ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
86 ASSERT_TRUE(
87 transformation.IsApplicable(context.get(), transformation_context));
88 ApplyAndCheckFreshIds(transformation, context.get(),
89 &transformation_context);
90 ASSERT_EQ(spv::Op::OpConstantNull,
91 context->get_def_use_mgr()->GetDef(100)->opcode());
92 ASSERT_EQ(
93 0.0F,
94 context->get_constant_mgr()->FindDeclaredConstant(100)->GetFloat());
95 }
96
97 TransformationAddConstantNull transformations[] = {
98
99 // %101 = OpConstantNull %7
100 TransformationAddConstantNull(101, 7),
101
102 // %102 = OpConstantNull %8
103 TransformationAddConstantNull(102, 8),
104
105 // %103 = OpConstantNull %9
106 TransformationAddConstantNull(103, 9),
107
108 // %104 = OpConstantNull %10
109 TransformationAddConstantNull(104, 10),
110
111 // %105 = OpConstantNull %11
112 TransformationAddConstantNull(105, 11)};
113
114 for (auto& transformation : transformations) {
115 ASSERT_TRUE(
116 transformation.IsApplicable(context.get(), transformation_context));
117 ApplyAndCheckFreshIds(transformation, context.get(),
118 &transformation_context);
119 }
120 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
121 kConsoleMessageConsumer));
122
123 std::string after_transformation = R"(
124 OpCapability Shader
125 %1 = OpExtInstImport "GLSL.std.450"
126 OpMemoryModel Logical GLSL450
127 OpEntryPoint Fragment %4 "main"
128 OpExecutionMode %4 OriginUpperLeft
129 OpSource ESSL 310
130 %2 = OpTypeVoid
131 %3 = OpTypeFunction %2
132 %6 = OpTypeFloat 32
133 %7 = OpTypeInt 32 1
134 %8 = OpTypeVector %6 2
135 %9 = OpTypeVector %6 3
136 %10 = OpTypeVector %6 4
137 %11 = OpTypeVector %7 2
138 %20 = OpTypeSampler
139 %21 = OpTypeImage %6 2D 0 0 0 0 Rgba32f
140 %22 = OpTypeSampledImage %21
141 %100 = OpConstantNull %6
142 %101 = OpConstantNull %7
143 %102 = OpConstantNull %8
144 %103 = OpConstantNull %9
145 %104 = OpConstantNull %10
146 %105 = OpConstantNull %11
147 %4 = OpFunction %2 None %3
148 %5 = OpLabel
149 OpReturn
150 OpFunctionEnd
151 )";
152 ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
153 }
154
155 } // namespace
156 } // namespace fuzz
157 } // namespace spvtools
158