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 "test/opt/pass_fixture.h"
16 #include "test/opt/pass_utils.h"
17 
18 namespace spvtools {
19 namespace opt {
20 namespace {
21 
22 // A pass turning all none debug line instructions into Nop.
23 class NopifyPass : public Pass {
24  public:
name() const25   const char* name() const override { return "NopifyPass"; }
Process()26   Status Process() override {
27     bool modified = false;
28     context()->module()->ForEachInst(
29         [&modified](Instruction* inst) {
30           inst->ToNop();
31           modified = true;
32         },
33         /* run_on_debug_line_insts = */ false);
34     return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
35   }
36 };
37 
38 using PassTestForLineDebugInfo = PassTest<::testing::Test>;
39 
40 // This test's purpose to show our implementation choice: line debug info is
41 // preserved even if the following instruction is killed. It serves as a guard
42 // of potential behavior changes.
TEST_F(PassTestForLineDebugInfo,KeepLineDebugInfo)43 TEST_F(PassTestForLineDebugInfo, KeepLineDebugInfo) {
44   // clang-format off
45   const char* text =
46                "OpCapability Shader "
47           "%1 = OpExtInstImport \"GLSL.std.450\" "
48                "OpMemoryModel Logical GLSL450 "
49                "OpEntryPoint Vertex %2 \"main\" "
50           "%3 = OpString \"minimal.vert\" "
51                "OpNoLine "
52                "OpLine %3 10 10 "
53        "%void = OpTypeVoid "
54                "OpLine %3 100 100 "
55           "%5 = OpTypeFunction %void "
56           "%2 = OpFunction %void None %5 "
57                "OpLine %3 1 1 "
58                "OpNoLine "
59                "OpLine %3 2 2 "
60                "OpLine %3 3 3 "
61           "%6 = OpLabel "
62                "OpLine %3 4 4 "
63                "OpNoLine "
64                "OpReturn "
65                "OpLine %3 4 4 "
66                "OpNoLine "
67                "OpFunctionEnd ";
68   // clang-format on
69 
70   const char* result_keep_nop =
71       "OpNop\n"
72       "OpNop\n"
73       "OpNop\n"
74       "OpNop\n"
75       "OpNop\n"
76       "OpNoLine\n"
77       "OpLine %3 10 10\n"
78       "OpNop\n"
79       "OpLine %3 100 100\n"
80       "OpNop\n"
81       "OpNop\n"
82       "OpLine %3 1 1\n"
83       "OpNoLine\n"
84       "OpLine %3 2 2\n"
85       "OpLine %3 3 3\n"
86       "OpNop\n"
87       "OpLine %3 4 4\n"
88       "OpNoLine\n"
89       "OpNop\n"
90       "OpLine %3 4 4\n"
91       "OpNoLine\n"
92       "OpNop\n";
93   SinglePassRunAndCheck<NopifyPass>(text, result_keep_nop,
94                                     /* skip_nop = */ false);
95   const char* result_skip_nop =
96       "OpNoLine\n"
97       "OpLine %3 10 10\n"
98       "OpLine %3 100 100\n"
99       "OpLine %3 1 1\n"
100       "OpNoLine\n"
101       "OpLine %3 2 2\n"
102       "OpLine %3 3 3\n"
103       "OpLine %3 4 4\n"
104       "OpNoLine\n"
105       "OpLine %3 4 4\n"
106       "OpNoLine\n";
107   SinglePassRunAndCheck<NopifyPass>(text, result_skip_nop,
108                                     /* skip_nop = */ true);
109 }
110 
111 }  // namespace
112 }  // namespace opt
113 }  // namespace spvtools
114