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
18namespace spvtools {
19namespace opt {
20namespace {
21
22// A pass turning all none debug line instructions into Nop.
23class NopifyPass : public Pass {
24 public:
25  const char* name() const override { return "NopifyPass"; }
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
38using 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.
43TEST_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