1 // Copyright (c) 2016 Google Inc.
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 <vector>
16
17 #include "test/opt/pass_fixture.h"
18 #include "test/opt/pass_utils.h"
19
20 namespace spvtools {
21 namespace opt {
22 namespace {
23
24 using StripLineDebugInfoTest = PassTest<::testing::Test>;
25
TEST_F(StripLineDebugInfoTest,LineNoLine)26 TEST_F(StripLineDebugInfoTest, LineNoLine) {
27 std::vector<const char*> text = {
28 // clang-format off
29 "OpCapability Shader",
30 "%1 = OpExtInstImport \"GLSL.std.450\"",
31 "OpMemoryModel Logical GLSL450",
32 "OpEntryPoint Vertex %2 \"main\"",
33 "%3 = OpString \"minimal.vert\"",
34 "OpModuleProcessed \"42\"",
35 "OpModuleProcessed \"43\"",
36 "OpModuleProcessed \"44\"",
37 "OpNoLine",
38 "OpLine %3 10 10",
39 "%void = OpTypeVoid",
40 "OpLine %3 100 100",
41 "%5 = OpTypeFunction %void",
42 "%2 = OpFunction %void None %5",
43 "OpLine %3 1 1",
44 "OpNoLine",
45 "OpLine %3 2 2",
46 "OpLine %3 3 3",
47 "%6 = OpLabel",
48 "OpLine %3 4 4",
49 "OpNoLine",
50 "OpReturn",
51 "OpLine %3 4 4",
52 "OpNoLine",
53 "OpFunctionEnd",
54 "OpNoLine",
55 "OpLine %3 4 5"
56 // clang-format on
57 };
58 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(text),
59 JoinNonDebugInsts(text),
60 /* skip_nop = */ false);
61
62 // Let's add more debug instruction before the "OpString" instruction.
63 const std::vector<const char*> more_text = {
64 "OpSourceContinued \"I'm a happy shader! Yay! ;)\"",
65 "OpSourceContinued \"wahahaha\"",
66 "OpSource ESSL 310",
67 "OpSource ESSL 310",
68 "OpSourceContinued \"wahahaha\"",
69 "OpSourceContinued \"wahahaha\"",
70 "OpSourceExtension \"save-the-world-extension\"",
71 "OpName %2 \"main\"",
72 };
73 text.insert(text.begin() + 4, more_text.cbegin(), more_text.cend());
74 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(text),
75 JoinNonDebugInsts(text),
76 /* skip_nop = */ false);
77 }
78
79 using StripDebugStringTest = PassTest<::testing::Test>;
80
TEST_F(StripDebugStringTest,OpDecorateRemoved)81 TEST_F(StripDebugStringTest, OpDecorateRemoved) {
82 std::vector<const char*> input{
83 // clang-format off
84 "OpCapability Shader",
85 "%1 = OpExtInstImport \"GLSL.std.450\"",
86 "OpMemoryModel Logical GLSL450",
87 "OpEntryPoint Vertex %2 \"main\"",
88 "%3 = OpString \"minimal.vert\"",
89 "OpDecorate %3 Location 1337",
90 "%void = OpTypeVoid",
91 "%5 = OpTypeFunction %void",
92 "%2 = OpFunction %void None %5",
93 "%6 = OpLabel",
94 "OpReturn",
95 "OpFunctionEnd",
96 // clang-format on
97 };
98 std::vector<const char*> output{
99 // clang-format off
100 "OpCapability Shader",
101 "%1 = OpExtInstImport \"GLSL.std.450\"",
102 "OpMemoryModel Logical GLSL450",
103 "OpEntryPoint Vertex %2 \"main\"",
104 "%void = OpTypeVoid",
105 "%5 = OpTypeFunction %void",
106 "%2 = OpFunction %void None %5",
107 "%6 = OpLabel",
108 "OpReturn",
109 "OpFunctionEnd",
110 // clang-format on
111 };
112 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(input),
113 JoinAllInsts(output),
114 /* skip_nop = */ false,
115 /* do_validation */ true);
116 }
117
TEST_F(StripDebugStringTest,OpNameRemoved)118 TEST_F(StripDebugStringTest, OpNameRemoved) {
119 std::vector<const char*> input{
120 // clang-format off
121 "OpCapability Shader",
122 "%1 = OpExtInstImport \"GLSL.std.450\"",
123 "OpMemoryModel Logical GLSL450",
124 "OpEntryPoint Vertex %2 \"main\"",
125 "%3 = OpString \"minimal.vert\"",
126 "OpName %3 \"bob\"",
127 "%void = OpTypeVoid",
128 "%5 = OpTypeFunction %void",
129 "%2 = OpFunction %void None %5",
130 "%6 = OpLabel",
131 "OpReturn",
132 "OpFunctionEnd",
133 // clang-format on
134 };
135 std::vector<const char*> output{
136 // clang-format off
137 "OpCapability Shader",
138 "%1 = OpExtInstImport \"GLSL.std.450\"",
139 "OpMemoryModel Logical GLSL450",
140 "OpEntryPoint Vertex %2 \"main\"",
141 "%void = OpTypeVoid",
142 "%5 = OpTypeFunction %void",
143 "%2 = OpFunction %void None %5",
144 "%6 = OpLabel",
145 "OpReturn",
146 "OpFunctionEnd",
147 // clang-format on
148 };
149 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(input),
150 JoinAllInsts(output),
151 /* skip_nop = */ false,
152 /* do_validation */ true);
153 }
154
TEST_F(StripDebugStringTest,OpStringRemovedWithNonSemantic)155 TEST_F(StripDebugStringTest, OpStringRemovedWithNonSemantic) {
156 std::vector<const char*> input{
157 // clang-format off
158 "OpCapability Shader",
159 "OpExtension \"SPV_KHR_non_semantic_info\"",
160 "%1 = OpExtInstImport \"NonSemantic.Testing.Set\"",
161 "OpMemoryModel Logical GLSL450",
162 "OpEntryPoint Vertex %2 \"main\"",
163 // this string is not referenced, should be removed fully
164 "%3 = OpString \"minimal.vert\"",
165 "OpName %3 \"bob\"",
166 // this string is referenced and cannot be removed,
167 // but the name should be
168 "%4 = OpString \"secondary.inc\"",
169 "OpName %4 \"sue\"",
170 "%void = OpTypeVoid",
171 "%6 = OpTypeFunction %void",
172 "%2 = OpFunction %void None %6",
173 "%7 = OpLabel",
174 "%8 = OpExtInst %void %1 5 %4",
175 "OpReturn",
176 "OpFunctionEnd",
177 // clang-format on
178 };
179 std::vector<const char*> output{
180 // clang-format off
181 "OpCapability Shader",
182 "OpExtension \"SPV_KHR_non_semantic_info\"",
183 "%1 = OpExtInstImport \"NonSemantic.Testing.Set\"",
184 "OpMemoryModel Logical GLSL450",
185 "OpEntryPoint Vertex %2 \"main\"",
186 "%4 = OpString \"secondary.inc\"",
187 "%void = OpTypeVoid",
188 "%6 = OpTypeFunction %void",
189 "%2 = OpFunction %void None %6",
190 "%7 = OpLabel",
191 "%8 = OpExtInst %void %1 5 %4",
192 "OpReturn",
193 "OpFunctionEnd",
194 // clang-format on
195 };
196 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(input),
197 JoinAllInsts(output),
198 /* skip_nop = */ false,
199 /* do_validation */ true);
200 }
201
202 using StripDebugInfoTest = PassTest<::testing::TestWithParam<const char*>>;
203
TEST_P(StripDebugInfoTest,Kind)204 TEST_P(StripDebugInfoTest, Kind) {
205 std::vector<const char*> text = {
206 "OpCapability Shader",
207 "OpMemoryModel Logical GLSL450",
208 GetParam(),
209 };
210 SinglePassRunAndCheck<StripDebugInfoPass>(JoinAllInsts(text),
211 JoinNonDebugInsts(text),
212 /* skip_nop = */ false);
213 }
214
215 // Test each possible non-line debug instruction.
216 // clang-format off
217 INSTANTIATE_TEST_SUITE_P(
218 SingleKindDebugInst, StripDebugInfoTest,
219 ::testing::ValuesIn(std::vector<const char*>({
220 "OpSourceContinued \"I'm a happy shader! Yay! ;)\"",
221 "OpSource ESSL 310",
222 "OpSourceExtension \"save-the-world-extension\"",
223 "OpName %main \"main\"",
224 "OpMemberName %struct 0 \"field\"",
225 "%1 = OpString \"name.vert\"",
226 "OpModuleProcessed \"42\"",
227 })));
228 // clang-format on
229
230 } // namespace
231 } // namespace opt
232 } // namespace spvtools
233