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