1 // Copyright (c) 2019 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/fact_manager/fact_manager.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(IrrelevantValueFactsTest,IdIsIrrelevant)25 TEST(IrrelevantValueFactsTest, IdIsIrrelevant) {
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 320
33 %2 = OpTypeVoid
34 %3 = OpTypeFunction %2
35 %6 = OpTypeInt 32 1
36 %12 = OpConstant %6 0
37 %13 = OpConstant %6 1
38 %4 = OpFunction %2 None %3
39 %5 = OpLabel
40 OpReturn
41 OpFunctionEnd
42 )";
43
44 const auto env = SPV_ENV_UNIVERSAL_1_3;
45 const auto consumer = nullptr;
46 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
47 spvtools::ValidatorOptions validator_options;
48 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
49 kConsoleMessageConsumer));
50
51 FactManager fact_manager(context.get());
52
53 ASSERT_FALSE(fact_manager.IdIsIrrelevant(12));
54 ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
55
56 fact_manager.AddFactIdIsIrrelevant(12);
57
58 ASSERT_TRUE(fact_manager.IdIsIrrelevant(12));
59 ASSERT_FALSE(fact_manager.IdIsIrrelevant(13));
60 }
61
TEST(IrrelevantValueFactsTest,GetIrrelevantIds)62 TEST(IrrelevantValueFactsTest, GetIrrelevantIds) {
63 std::string shader = R"(
64 OpCapability Shader
65 %1 = OpExtInstImport "GLSL.std.450"
66 OpMemoryModel Logical GLSL450
67 OpEntryPoint Fragment %4 "main"
68 OpExecutionMode %4 OriginUpperLeft
69 OpSource ESSL 320
70 %2 = OpTypeVoid
71 %3 = OpTypeFunction %2
72 %6 = OpTypeInt 32 1
73 %12 = OpConstant %6 0
74 %13 = OpConstant %6 1
75 %14 = OpConstant %6 2
76 %4 = OpFunction %2 None %3
77 %5 = OpLabel
78 OpReturn
79 OpFunctionEnd
80 )";
81
82 const auto env = SPV_ENV_UNIVERSAL_1_3;
83 const auto consumer = nullptr;
84 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
85 spvtools::ValidatorOptions validator_options;
86 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
87 kConsoleMessageConsumer));
88
89 FactManager fact_manager(context.get());
90
91 ASSERT_EQ(fact_manager.GetIrrelevantIds(), std::unordered_set<uint32_t>({}));
92
93 fact_manager.AddFactIdIsIrrelevant(12);
94
95 ASSERT_EQ(fact_manager.GetIrrelevantIds(),
96 std::unordered_set<uint32_t>({12}));
97
98 fact_manager.AddFactIdIsIrrelevant(13);
99
100 ASSERT_EQ(fact_manager.GetIrrelevantIds(),
101 std::unordered_set<uint32_t>({12, 13}));
102 }
103
TEST(IrrelevantValueFactsTest,IdsFromDeadBlocksAreIrrelevant)104 TEST(IrrelevantValueFactsTest, IdsFromDeadBlocksAreIrrelevant) {
105 std::string shader = R"(
106 OpCapability Shader
107 %1 = OpExtInstImport "GLSL.std.450"
108 OpMemoryModel Logical GLSL450
109 OpEntryPoint Fragment %2 "main"
110 OpExecutionMode %2 OriginUpperLeft
111 OpSource ESSL 310
112 %3 = OpTypeVoid
113 %4 = OpTypeFunction %3
114 %5 = OpTypeBool
115 %6 = OpConstantTrue %5
116 %7 = OpTypeInt 32 1
117 %8 = OpTypePointer Function %7
118 %9 = OpConstant %7 1
119 %2 = OpFunction %3 None %4
120 %10 = OpLabel
121 %11 = OpVariable %8 Function
122 OpSelectionMerge %12 None
123 OpBranchConditional %6 %13 %14
124 %13 = OpLabel
125 OpBranch %12
126 %14 = OpLabel
127 %15 = OpCopyObject %8 %11
128 %16 = OpCopyObject %7 %9
129 %17 = OpFunctionCall %3 %18
130 OpBranch %12
131 %12 = OpLabel
132 OpReturn
133 OpFunctionEnd
134 %18 = OpFunction %3 None %4
135 %19 = OpLabel
136 %20 = OpVariable %8 Function
137 %21 = OpCopyObject %7 %9
138 OpReturn
139 OpFunctionEnd
140 )";
141
142 const auto env = SPV_ENV_UNIVERSAL_1_5;
143 const auto consumer = nullptr;
144 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
145 spvtools::ValidatorOptions validator_options;
146 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
147 kConsoleMessageConsumer));
148
149 FactManager fact_manager(context.get());
150
151 ASSERT_FALSE(fact_manager.BlockIsDead(14));
152 ASSERT_FALSE(fact_manager.BlockIsDead(19));
153
154 // Initially no id is irrelevant.
155 ASSERT_FALSE(fact_manager.IdIsIrrelevant(16));
156 ASSERT_FALSE(fact_manager.IdIsIrrelevant(17));
157 ASSERT_EQ(fact_manager.GetIrrelevantIds(), std::unordered_set<uint32_t>({}));
158
159 fact_manager.AddFactBlockIsDead(14);
160
161 // %16 and %17 should now be considered irrelevant.
162 ASSERT_TRUE(fact_manager.IdIsIrrelevant(16));
163 ASSERT_TRUE(fact_manager.IdIsIrrelevant(17));
164 ASSERT_EQ(fact_manager.GetIrrelevantIds(),
165 std::unordered_set<uint32_t>({16, 17}));
166
167 // Similarly for %21.
168 ASSERT_FALSE(fact_manager.IdIsIrrelevant(21));
169
170 fact_manager.AddFactBlockIsDead(19);
171
172 ASSERT_TRUE(fact_manager.IdIsIrrelevant(21));
173 ASSERT_EQ(fact_manager.GetIrrelevantIds(),
174 std::unordered_set<uint32_t>({16, 17, 21}));
175 }
176
177 } // namespace
178 } // namespace fuzz
179 } // namespace spvtools
180