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 <algorithm>
16fd4e5da5Sopenharmony_ci#include <memory>
17fd4e5da5Sopenharmony_ci#include <unordered_set>
18fd4e5da5Sopenharmony_ci#include <utility>
19fd4e5da5Sopenharmony_ci#include <vector>
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
22fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h"
23fd4e5da5Sopenharmony_ci#include "source/opt/def_use_manager.h"
24fd4e5da5Sopenharmony_ci#include "source/opt/ir_context.h"
25fd4e5da5Sopenharmony_ci#include "spirv-tools/libspirv.hpp"
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_cinamespace spvtools {
28fd4e5da5Sopenharmony_cinamespace opt {
29fd4e5da5Sopenharmony_cinamespace {
30fd4e5da5Sopenharmony_ci
31fd4e5da5Sopenharmony_ciusing ::testing::ContainerEq;
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_ciconstexpr uint32_t kOpLineOperandLineIndex = 1;
34fd4e5da5Sopenharmony_ci
35fd4e5da5Sopenharmony_civoid DoRoundTripCheck(const std::string& text) {
36fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
37fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
38fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
39fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context) << "Failed to assemble\n" << text;
40fd4e5da5Sopenharmony_ci
41fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
42fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, /* skip_nop = */ false);
43fd4e5da5Sopenharmony_ci
44fd4e5da5Sopenharmony_ci  std::string disassembled_text;
45fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
46fd4e5da5Sopenharmony_ci  EXPECT_EQ(text, disassembled_text);
47fd4e5da5Sopenharmony_ci}
48fd4e5da5Sopenharmony_ci
49fd4e5da5Sopenharmony_ciTEST(IrBuilder, RoundTrip) {
50fd4e5da5Sopenharmony_ci  // #version 310 es
51fd4e5da5Sopenharmony_ci  // int add(int a, int b) { return a + b; }
52fd4e5da5Sopenharmony_ci  // void main() { add(1, 2); }
53fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
54fd4e5da5Sopenharmony_ci      // clang-format off
55fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
56fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"\n"
57fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
58fd4e5da5Sopenharmony_ci               "OpEntryPoint Vertex %main \"main\"\n"
59fd4e5da5Sopenharmony_ci               "OpSource ESSL 310\n"
60fd4e5da5Sopenharmony_ci               "OpSourceExtension \"GL_GOOGLE_cpp_style_line_directive\"\n"
61fd4e5da5Sopenharmony_ci               "OpSourceExtension \"GL_GOOGLE_include_directive\"\n"
62fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
63fd4e5da5Sopenharmony_ci               "OpName %add_i1_i1_ \"add(i1;i1;\"\n"
64fd4e5da5Sopenharmony_ci               "OpName %a \"a\"\n"
65fd4e5da5Sopenharmony_ci               "OpName %b \"b\"\n"
66fd4e5da5Sopenharmony_ci               "OpName %param \"param\"\n"
67fd4e5da5Sopenharmony_ci               "OpName %param_0 \"param\"\n"
68fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
69fd4e5da5Sopenharmony_ci          "%9 = OpTypeFunction %void\n"
70fd4e5da5Sopenharmony_ci        "%int = OpTypeInt 32 1\n"
71fd4e5da5Sopenharmony_ci "%_ptr_Function_int = OpTypePointer Function %int\n"
72fd4e5da5Sopenharmony_ci         "%12 = OpTypeFunction %int %_ptr_Function_int %_ptr_Function_int\n"
73fd4e5da5Sopenharmony_ci      "%int_1 = OpConstant %int 1\n"
74fd4e5da5Sopenharmony_ci      "%int_2 = OpConstant %int 2\n"
75fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %9\n"
76fd4e5da5Sopenharmony_ci         "%15 = OpLabel\n"
77fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_int Function\n"
78fd4e5da5Sopenharmony_ci    "%param_0 = OpVariable %_ptr_Function_int Function\n"
79fd4e5da5Sopenharmony_ci               "OpStore %param %int_1\n"
80fd4e5da5Sopenharmony_ci               "OpStore %param_0 %int_2\n"
81fd4e5da5Sopenharmony_ci         "%16 = OpFunctionCall %int %add_i1_i1_ %param %param_0\n"
82fd4e5da5Sopenharmony_ci               "OpReturn\n"
83fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n"
84fd4e5da5Sopenharmony_ci "%add_i1_i1_ = OpFunction %int None %12\n"
85fd4e5da5Sopenharmony_ci          "%a = OpFunctionParameter %_ptr_Function_int\n"
86fd4e5da5Sopenharmony_ci          "%b = OpFunctionParameter %_ptr_Function_int\n"
87fd4e5da5Sopenharmony_ci         "%17 = OpLabel\n"
88fd4e5da5Sopenharmony_ci         "%18 = OpLoad %int %a\n"
89fd4e5da5Sopenharmony_ci         "%19 = OpLoad %int %b\n"
90fd4e5da5Sopenharmony_ci         "%20 = OpIAdd %int %18 %19\n"
91fd4e5da5Sopenharmony_ci               "OpReturnValue %20\n"
92fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
93fd4e5da5Sopenharmony_ci  // clang-format on
94fd4e5da5Sopenharmony_ci}
95fd4e5da5Sopenharmony_ci
96fd4e5da5Sopenharmony_ciTEST(IrBuilder, RoundTripIncompleteBasicBlock) {
97fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
98fd4e5da5Sopenharmony_ci      "%2 = OpFunction %1 None %3\n"
99fd4e5da5Sopenharmony_ci      "%4 = OpLabel\n"
100fd4e5da5Sopenharmony_ci      "OpNop\n");
101fd4e5da5Sopenharmony_ci}
102fd4e5da5Sopenharmony_ci
103fd4e5da5Sopenharmony_ciTEST(IrBuilder, RoundTripIncompleteFunction) {
104fd4e5da5Sopenharmony_ci  DoRoundTripCheck("%2 = OpFunction %1 None %3\n");
105fd4e5da5Sopenharmony_ci}
106fd4e5da5Sopenharmony_ci
107fd4e5da5Sopenharmony_ciTEST(IrBuilder, RoundTripFunctionPointer) {
108fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
109fd4e5da5Sopenharmony_ci      "OpCapability Linkage\n"
110fd4e5da5Sopenharmony_ci      "OpCapability FunctionPointersINTEL\n"
111fd4e5da5Sopenharmony_ci      "OpName %some_function \"some_function\"\n"
112fd4e5da5Sopenharmony_ci      "OpName %ptr_to_function \"ptr_to_function\"\n"
113fd4e5da5Sopenharmony_ci      "OpDecorate %some_function LinkageAttributes \"some_function\" Import\n"
114fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32\n"
115fd4e5da5Sopenharmony_ci      "%4 = OpTypeFunction %float %float\n"
116fd4e5da5Sopenharmony_ci      "%_ptr_Function_4 = OpTypePointer Function %4\n"
117fd4e5da5Sopenharmony_ci      "%ptr_to_function = OpConstantFunctionPointerINTEL %_ptr_Function_4 "
118fd4e5da5Sopenharmony_ci      "%some_function\n"
119fd4e5da5Sopenharmony_ci      "%some_function = OpFunction %float Const %4\n"
120fd4e5da5Sopenharmony_ci      "%6 = OpFunctionParameter %float\n"
121fd4e5da5Sopenharmony_ci      "OpFunctionEnd\n");
122fd4e5da5Sopenharmony_ci}
123fd4e5da5Sopenharmony_ciTEST(IrBuilder, KeepLineDebugInfo) {
124fd4e5da5Sopenharmony_ci  // #version 310 es
125fd4e5da5Sopenharmony_ci  // void main() {}
126fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
127fd4e5da5Sopenharmony_ci      // clang-format off
128fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
129fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"\n"
130fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
131fd4e5da5Sopenharmony_ci               "OpEntryPoint Vertex %main \"main\"\n"
132fd4e5da5Sopenharmony_ci          "%3 = OpString \"minimal.vert\"\n"
133fd4e5da5Sopenharmony_ci               "OpSource ESSL 310\n"
134fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
135fd4e5da5Sopenharmony_ci               "OpLine %3 10 10\n"
136fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
137fd4e5da5Sopenharmony_ci               "OpLine %3 100 100\n"
138fd4e5da5Sopenharmony_ci          "%5 = OpTypeFunction %void\n"
139fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %5\n"
140fd4e5da5Sopenharmony_ci               "OpLine %3 1 1\n"
141fd4e5da5Sopenharmony_ci               "OpNoLine\n"
142fd4e5da5Sopenharmony_ci               "OpLine %3 2 2\n"
143fd4e5da5Sopenharmony_ci               "OpLine %3 3 3\n"
144fd4e5da5Sopenharmony_ci          "%6 = OpLabel\n"
145fd4e5da5Sopenharmony_ci               "OpLine %3 4 4\n"
146fd4e5da5Sopenharmony_ci               "OpNoLine\n"
147fd4e5da5Sopenharmony_ci               "OpReturn\n"
148fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
149fd4e5da5Sopenharmony_ci  // clang-format on
150fd4e5da5Sopenharmony_ci}
151fd4e5da5Sopenharmony_ci
152fd4e5da5Sopenharmony_ciTEST(IrBuilder, DistributeLineDebugInfo) {
153fd4e5da5Sopenharmony_ci  const std::string text =
154fd4e5da5Sopenharmony_ci      // clang-format off
155fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
156fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"\n"
157fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
158fd4e5da5Sopenharmony_ci               "OpEntryPoint Vertex %main \"main\"\n"
159fd4e5da5Sopenharmony_ci               "OpSource ESSL 310\n"
160fd4e5da5Sopenharmony_ci       "%file = OpString \"test\"\n"
161fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
162fd4e5da5Sopenharmony_ci               "OpName %f_ \"f(\"\n"
163fd4e5da5Sopenharmony_ci               "OpName %gv1 \"gv1\"\n"
164fd4e5da5Sopenharmony_ci               "OpName %gv2 \"gv2\"\n"
165fd4e5da5Sopenharmony_ci               "OpName %lv1 \"lv1\"\n"
166fd4e5da5Sopenharmony_ci               "OpName %lv2 \"lv2\"\n"
167fd4e5da5Sopenharmony_ci               "OpName %lv1_0 \"lv1\"\n"
168fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
169fd4e5da5Sopenharmony_ci         "%10 = OpTypeFunction %void\n"
170fd4e5da5Sopenharmony_ci               "OpLine %file 10 0\n"
171fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32\n"
172fd4e5da5Sopenharmony_ci         "%12 = OpTypeFunction %float\n"
173fd4e5da5Sopenharmony_ci "%_ptr_Private_float = OpTypePointer Private %float\n"
174fd4e5da5Sopenharmony_ci        "%gv1 = OpVariable %_ptr_Private_float Private\n"
175fd4e5da5Sopenharmony_ci   "%float_10 = OpConstant %float 10\n"
176fd4e5da5Sopenharmony_ci        "%gv2 = OpVariable %_ptr_Private_float Private\n"
177fd4e5da5Sopenharmony_ci  "%float_100 = OpConstant %float 100\n"
178fd4e5da5Sopenharmony_ci "%_ptr_Function_float = OpTypePointer Function %float\n"
179fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %10\n"
180fd4e5da5Sopenharmony_ci         "%17 = OpLabel\n"
181fd4e5da5Sopenharmony_ci      "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
182fd4e5da5Sopenharmony_ci               "OpStore %gv1 %float_10\n"
183fd4e5da5Sopenharmony_ci               "OpStore %gv2 %float_100\n"
184fd4e5da5Sopenharmony_ci               "OpLine %file 1 0\n"
185fd4e5da5Sopenharmony_ci               "OpNoLine\n"
186fd4e5da5Sopenharmony_ci               "OpLine %file 2 0\n"
187fd4e5da5Sopenharmony_ci         "%18 = OpLoad %float %gv1\n"
188fd4e5da5Sopenharmony_ci         "%19 = OpLoad %float %gv2\n"
189fd4e5da5Sopenharmony_ci         "%20 = OpFSub %float %18 %19\n"
190fd4e5da5Sopenharmony_ci               "OpStore %lv1_0 %20\n"
191fd4e5da5Sopenharmony_ci               "OpReturn\n"
192fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n"
193fd4e5da5Sopenharmony_ci         "%f_ = OpFunction %float None %12\n"
194fd4e5da5Sopenharmony_ci         "%21 = OpLabel\n"
195fd4e5da5Sopenharmony_ci        "%lv1 = OpVariable %_ptr_Function_float Function\n"
196fd4e5da5Sopenharmony_ci        "%lv2 = OpVariable %_ptr_Function_float Function\n"
197fd4e5da5Sopenharmony_ci               "OpLine %file 3 0\n"
198fd4e5da5Sopenharmony_ci               "OpLine %file 4 0\n"
199fd4e5da5Sopenharmony_ci         "%22 = OpLoad %float %gv1\n"
200fd4e5da5Sopenharmony_ci         "%23 = OpLoad %float %gv2\n"
201fd4e5da5Sopenharmony_ci         "%24 = OpFAdd %float %22 %23\n"
202fd4e5da5Sopenharmony_ci               "OpStore %lv1 %24\n"
203fd4e5da5Sopenharmony_ci               "OpLine %file 5 0\n"
204fd4e5da5Sopenharmony_ci               "OpLine %file 6 0\n"
205fd4e5da5Sopenharmony_ci               "OpNoLine\n"
206fd4e5da5Sopenharmony_ci         "%25 = OpLoad %float %gv1\n"
207fd4e5da5Sopenharmony_ci         "%26 = OpLoad %float %gv2\n"
208fd4e5da5Sopenharmony_ci         "%27 = OpFMul %float %25 %26\n"
209fd4e5da5Sopenharmony_ci               "OpBranch %28\n"
210fd4e5da5Sopenharmony_ci         "%28 = OpLabel\n"
211fd4e5da5Sopenharmony_ci               "OpStore %lv2 %27\n"
212fd4e5da5Sopenharmony_ci         "%29 = OpLoad %float %lv1\n"
213fd4e5da5Sopenharmony_ci               "OpLine %file 7 0\n"
214fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %lv2\n"
215fd4e5da5Sopenharmony_ci         "%31 = OpFDiv %float %28 %29\n"
216fd4e5da5Sopenharmony_ci               "OpReturnValue %30\n"
217fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n";
218fd4e5da5Sopenharmony_ci  // clang-format on
219fd4e5da5Sopenharmony_ci
220fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
221fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
222fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
223fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
224fd4e5da5Sopenharmony_ci
225fd4e5da5Sopenharmony_ci  struct LineInstrCheck {
226fd4e5da5Sopenharmony_ci    uint32_t id;
227fd4e5da5Sopenharmony_ci    std::vector<uint32_t> line_numbers;
228fd4e5da5Sopenharmony_ci  };
229fd4e5da5Sopenharmony_ci  const uint32_t kNoLine = 0;
230fd4e5da5Sopenharmony_ci  const LineInstrCheck line_checks[] = {
231fd4e5da5Sopenharmony_ci      {12, {10}},   {18, {1, kNoLine, 2}},
232fd4e5da5Sopenharmony_ci      {19, {2}},    {20, {2}},
233fd4e5da5Sopenharmony_ci      {22, {3, 4}}, {23, {4}},
234fd4e5da5Sopenharmony_ci      {24, {4}},    {25, {5, 6, kNoLine}},
235fd4e5da5Sopenharmony_ci      {26, {}},     {27, {}},
236fd4e5da5Sopenharmony_ci      {28, {}},     {29, {}},
237fd4e5da5Sopenharmony_ci      {30, {7}},    {31, {7}},
238fd4e5da5Sopenharmony_ci  };
239fd4e5da5Sopenharmony_ci
240fd4e5da5Sopenharmony_ci  spvtools::opt::analysis::DefUseManager* def_use_mgr =
241fd4e5da5Sopenharmony_ci      context->get_def_use_mgr();
242fd4e5da5Sopenharmony_ci  for (const LineInstrCheck& check : line_checks) {
243fd4e5da5Sopenharmony_ci    auto& lines = def_use_mgr->GetDef(check.id)->dbg_line_insts();
244fd4e5da5Sopenharmony_ci    for (uint32_t i = 0; i < check.line_numbers.size(); ++i) {
245fd4e5da5Sopenharmony_ci      if (check.line_numbers[i] == kNoLine) {
246fd4e5da5Sopenharmony_ci        EXPECT_EQ(lines[i].opcode(), spv::Op::OpNoLine);
247fd4e5da5Sopenharmony_ci        continue;
248fd4e5da5Sopenharmony_ci      }
249fd4e5da5Sopenharmony_ci      EXPECT_EQ(lines[i].opcode(), spv::Op::OpLine);
250fd4e5da5Sopenharmony_ci      EXPECT_EQ(lines[i].GetSingleWordOperand(kOpLineOperandLineIndex),
251fd4e5da5Sopenharmony_ci                check.line_numbers[i]);
252fd4e5da5Sopenharmony_ci    }
253fd4e5da5Sopenharmony_ci  }
254fd4e5da5Sopenharmony_ci}
255fd4e5da5Sopenharmony_ci
256fd4e5da5Sopenharmony_ciTEST(IrBuilder, BuildModule_WithoutExtraLines) {
257fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
258fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
259fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
260fd4e5da5Sopenharmony_ci%file = OpString "my file"
261fd4e5da5Sopenharmony_ci%void = OpTypeVoid
262fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
263fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
264fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
265fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
266fd4e5da5Sopenharmony_ci%100 = OpLabel
267fd4e5da5Sopenharmony_ci%1 = OpFAdd %float %float_1 %float_1
268fd4e5da5Sopenharmony_ciOpLine %file 1 0
269fd4e5da5Sopenharmony_ci%2 = OpFMul %float %1 %1
270fd4e5da5Sopenharmony_ci%3 = OpFSub %float %2 %2
271fd4e5da5Sopenharmony_ciOpReturn
272fd4e5da5Sopenharmony_ciOpFunctionEnd
273fd4e5da5Sopenharmony_ci)";
274fd4e5da5Sopenharmony_ci
275fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
276fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
277fd4e5da5Sopenharmony_ci  ASSERT_TRUE(t.Assemble(text, &binary,
278fd4e5da5Sopenharmony_ci                         SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS));
279fd4e5da5Sopenharmony_ci
280fd4e5da5Sopenharmony_ci  // This is the function we're testing.
281fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context = BuildModule(
282fd4e5da5Sopenharmony_ci      SPV_ENV_UNIVERSAL_1_5, nullptr, binary.data(), binary.size(), false);
283fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
284fd4e5da5Sopenharmony_ci
285fd4e5da5Sopenharmony_ci  spvtools::opt::analysis::DefUseManager* def_use_mgr =
286fd4e5da5Sopenharmony_ci      context->get_def_use_mgr();
287fd4e5da5Sopenharmony_ci
288fd4e5da5Sopenharmony_ci  std::vector<spv::Op> opcodes;
289fd4e5da5Sopenharmony_ci  for (auto* inst = def_use_mgr->GetDef(1);
290fd4e5da5Sopenharmony_ci       inst && (inst->opcode() != spv::Op::OpFunctionEnd);
291fd4e5da5Sopenharmony_ci       inst = inst->NextNode()) {
292fd4e5da5Sopenharmony_ci    inst->ForEachInst(
293fd4e5da5Sopenharmony_ci        [&opcodes](spvtools::opt::Instruction* sub_inst) {
294fd4e5da5Sopenharmony_ci          opcodes.push_back(sub_inst->opcode());
295fd4e5da5Sopenharmony_ci        },
296fd4e5da5Sopenharmony_ci        true);
297fd4e5da5Sopenharmony_ci  }
298fd4e5da5Sopenharmony_ci
299fd4e5da5Sopenharmony_ci  EXPECT_THAT(opcodes, ContainerEq(std::vector<spv::Op>{
300fd4e5da5Sopenharmony_ci                           spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul,
301fd4e5da5Sopenharmony_ci                           spv::Op::OpFSub, spv::Op::OpReturn}));
302fd4e5da5Sopenharmony_ci}
303fd4e5da5Sopenharmony_ci
304fd4e5da5Sopenharmony_ciTEST(IrBuilder, BuildModule_WithExtraLines_IsDefault) {
305fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
306fd4e5da5Sopenharmony_ciOpMemoryModel Logical Simple
307fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
308fd4e5da5Sopenharmony_ci%file = OpString "my file"
309fd4e5da5Sopenharmony_ci%void = OpTypeVoid
310fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
311fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
312fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
313fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
314fd4e5da5Sopenharmony_ci%100 = OpLabel
315fd4e5da5Sopenharmony_ci%1 = OpFAdd %float %float_1 %float_1
316fd4e5da5Sopenharmony_ciOpLine %file 1 0
317fd4e5da5Sopenharmony_ci%2 = OpFMul %float %1 %1
318fd4e5da5Sopenharmony_ci%3 = OpFSub %float %2 %2
319fd4e5da5Sopenharmony_ciOpReturn
320fd4e5da5Sopenharmony_ciOpFunctionEnd
321fd4e5da5Sopenharmony_ci)";
322fd4e5da5Sopenharmony_ci
323fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
324fd4e5da5Sopenharmony_ci
325fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
326fd4e5da5Sopenharmony_ci  ASSERT_TRUE(t.Assemble(text, &binary,
327fd4e5da5Sopenharmony_ci                         SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS));
328fd4e5da5Sopenharmony_ci
329fd4e5da5Sopenharmony_ci  // This is the function we're testing.
330fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
331fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_5, nullptr, binary.data(), binary.size());
332fd4e5da5Sopenharmony_ci
333fd4e5da5Sopenharmony_ci  spvtools::opt::analysis::DefUseManager* def_use_mgr =
334fd4e5da5Sopenharmony_ci      context->get_def_use_mgr();
335fd4e5da5Sopenharmony_ci
336fd4e5da5Sopenharmony_ci  std::vector<spv::Op> opcodes;
337fd4e5da5Sopenharmony_ci  for (auto* inst = def_use_mgr->GetDef(1);
338fd4e5da5Sopenharmony_ci       inst && (inst->opcode() != spv::Op::OpFunctionEnd);
339fd4e5da5Sopenharmony_ci       inst = inst->NextNode()) {
340fd4e5da5Sopenharmony_ci    inst->ForEachInst(
341fd4e5da5Sopenharmony_ci        [&opcodes](spvtools::opt::Instruction* sub_inst) {
342fd4e5da5Sopenharmony_ci          opcodes.push_back(sub_inst->opcode());
343fd4e5da5Sopenharmony_ci        },
344fd4e5da5Sopenharmony_ci        true);
345fd4e5da5Sopenharmony_ci  }
346fd4e5da5Sopenharmony_ci
347fd4e5da5Sopenharmony_ci  EXPECT_THAT(opcodes, ContainerEq(std::vector<spv::Op>{
348fd4e5da5Sopenharmony_ci                           spv::Op::OpFAdd, spv::Op::OpLine, spv::Op::OpFMul,
349fd4e5da5Sopenharmony_ci                           spv::Op::OpLine, spv::Op::OpFSub, spv::Op::OpLine,
350fd4e5da5Sopenharmony_ci                           spv::Op::OpReturn}));
351fd4e5da5Sopenharmony_ci}
352fd4e5da5Sopenharmony_ci
353fd4e5da5Sopenharmony_ciTEST(IrBuilder, ConsumeDebugInfoInst) {
354fd4e5da5Sopenharmony_ci  // /* HLSL */
355fd4e5da5Sopenharmony_ci  //
356fd4e5da5Sopenharmony_ci  // struct VS_OUTPUT {
357fd4e5da5Sopenharmony_ci  //   float4 pos : SV_POSITION;
358fd4e5da5Sopenharmony_ci  //   float4 color : COLOR;
359fd4e5da5Sopenharmony_ci  // };
360fd4e5da5Sopenharmony_ci  //
361fd4e5da5Sopenharmony_ci  // VS_OUTPUT main(float4 pos : POSITION,
362fd4e5da5Sopenharmony_ci  //                float4 color : COLOR) {
363fd4e5da5Sopenharmony_ci  //   VS_OUTPUT vout;
364fd4e5da5Sopenharmony_ci  //   vout.pos = pos;
365fd4e5da5Sopenharmony_ci  //   vout.color = color;
366fd4e5da5Sopenharmony_ci  //   return vout;
367fd4e5da5Sopenharmony_ci  // }
368fd4e5da5Sopenharmony_ci  DoRoundTripCheck(R"(OpCapability Shader
369fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
370fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
371fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %pos %color %gl_Position %out_var_COLOR
372fd4e5da5Sopenharmony_ci%7 = OpString "simple_vs.hlsl"
373fd4e5da5Sopenharmony_ci%8 = OpString "#line 1 \"simple_vs.hlsl\"
374fd4e5da5Sopenharmony_cistruct VS_OUTPUT {
375fd4e5da5Sopenharmony_ci  float4 pos : SV_POSITION;
376fd4e5da5Sopenharmony_ci  float4 color : COLOR;
377fd4e5da5Sopenharmony_ci};
378fd4e5da5Sopenharmony_ci
379fd4e5da5Sopenharmony_ciVS_OUTPUT main(float4 pos : POSITION,
380fd4e5da5Sopenharmony_ci               float4 color : COLOR) {
381fd4e5da5Sopenharmony_ci  VS_OUTPUT vout;
382fd4e5da5Sopenharmony_ci  vout.pos = pos;
383fd4e5da5Sopenharmony_ci  vout.color = color;
384fd4e5da5Sopenharmony_ci  return vout;
385fd4e5da5Sopenharmony_ci}
386fd4e5da5Sopenharmony_ci"
387fd4e5da5Sopenharmony_ciOpSource HLSL 600 %7 "#line 1 \"simple_vs.hlsl\"
388fd4e5da5Sopenharmony_cistruct VS_OUTPUT {
389fd4e5da5Sopenharmony_ci  float4 pos : SV_POSITION;
390fd4e5da5Sopenharmony_ci  float4 color : COLOR;
391fd4e5da5Sopenharmony_ci};
392fd4e5da5Sopenharmony_ci
393fd4e5da5Sopenharmony_ciVS_OUTPUT main(float4 pos : POSITION,
394fd4e5da5Sopenharmony_ci               float4 color : COLOR) {
395fd4e5da5Sopenharmony_ci  VS_OUTPUT vout;
396fd4e5da5Sopenharmony_ci  vout.pos = pos;
397fd4e5da5Sopenharmony_ci  vout.color = color;
398fd4e5da5Sopenharmony_ci  return vout;
399fd4e5da5Sopenharmony_ci}
400fd4e5da5Sopenharmony_ci"
401fd4e5da5Sopenharmony_ci%9 = OpString "struct VS_OUTPUT"
402fd4e5da5Sopenharmony_ci%10 = OpString "float"
403fd4e5da5Sopenharmony_ci%11 = OpString "pos : SV_POSITION"
404fd4e5da5Sopenharmony_ci%12 = OpString "color : COLOR"
405fd4e5da5Sopenharmony_ci%13 = OpString "VS_OUTPUT"
406fd4e5da5Sopenharmony_ci%14 = OpString "main"
407fd4e5da5Sopenharmony_ci%15 = OpString "VS_OUTPUT_main_v4f_v4f"
408fd4e5da5Sopenharmony_ci%16 = OpString "pos : POSITION"
409fd4e5da5Sopenharmony_ci%17 = OpString "color : COLOR"
410fd4e5da5Sopenharmony_ci%18 = OpString "vout"
411fd4e5da5Sopenharmony_ciOpName %out_var_COLOR "out.var.COLOR"
412fd4e5da5Sopenharmony_ciOpName %main "main"
413fd4e5da5Sopenharmony_ciOpName %VS_OUTPUT "VS_OUTPUT"
414fd4e5da5Sopenharmony_ciOpMemberName %VS_OUTPUT 0 "pos"
415fd4e5da5Sopenharmony_ciOpMemberName %VS_OUTPUT 1 "color"
416fd4e5da5Sopenharmony_ciOpName %pos "pos"
417fd4e5da5Sopenharmony_ciOpName %color "color"
418fd4e5da5Sopenharmony_ciOpName %vout "vout"
419fd4e5da5Sopenharmony_ciOpDecorate %gl_Position BuiltIn Position
420fd4e5da5Sopenharmony_ciOpDecorate %pos Location 0
421fd4e5da5Sopenharmony_ciOpDecorate %color Location 1
422fd4e5da5Sopenharmony_ciOpDecorate %out_var_COLOR Location 0
423fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
424fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
425fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
426fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32
427fd4e5da5Sopenharmony_ci%int_128 = OpConstant %int 128
428fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
429fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
430fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
431fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
432fd4e5da5Sopenharmony_ci%void = OpTypeVoid
433fd4e5da5Sopenharmony_ci%31 = OpTypeFunction %void
434fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
435fd4e5da5Sopenharmony_ci%VS_OUTPUT = OpTypeStruct %v4float %v4float
436fd4e5da5Sopenharmony_ci%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
437fd4e5da5Sopenharmony_ciOpLine %7 6 23
438fd4e5da5Sopenharmony_ci%pos = OpVariable %_ptr_Input_v4float Input
439fd4e5da5Sopenharmony_ciOpLine %7 7 23
440fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Input_v4float Input
441fd4e5da5Sopenharmony_ciOpLine %7 2 16
442fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
443fd4e5da5Sopenharmony_ciOpLine %7 3 18
444fd4e5da5Sopenharmony_ci%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
445fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %1 DebugSource %7 %8
446fd4e5da5Sopenharmony_ci%35 = OpExtInst %void %1 DebugCompilationUnit 2 4 %34 HLSL
447fd4e5da5Sopenharmony_ci%36 = OpExtInst %void %1 DebugTypeComposite %9 Structure %34 1 1 %35 %13 %int_128 FlagIsProtected|FlagIsPrivate %37 %38
448fd4e5da5Sopenharmony_ci%39 = OpExtInst %void %1 DebugTypeBasic %10 %int_32 Float
449fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugTypeVector %39 4
450fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugTypeMember %11 %40 %34 2 3 %36 %int_0 %int_128 FlagIsProtected|FlagIsPrivate
451fd4e5da5Sopenharmony_ci%38 = OpExtInst %void %1 DebugTypeMember %12 %40 %34 3 3 %36 %int_128 %int_128 FlagIsProtected|FlagIsPrivate
452fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %40 %40
453fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugExpression
454fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugFunction %14 %41 %34 6 1 %35 %15 FlagIsProtected|FlagIsPrivate 7 %main
455fd4e5da5Sopenharmony_ci%44 = OpExtInst %void %1 DebugLocalVariable %16 %40 %34 6 16 %43 FlagIsLocal 0
456fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugLocalVariable %17 %40 %34 7 16 %43 FlagIsLocal 1
457fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugLocalVariable %18 %36 %34 8 3 %43 FlagIsLocal
458fd4e5da5Sopenharmony_ciOpLine %7 6 1
459fd4e5da5Sopenharmony_ci%main = OpFunction %void None %31
460fd4e5da5Sopenharmony_ci%47 = OpLabel
461fd4e5da5Sopenharmony_ci%60 = OpExtInst %void %1 DebugScope %43
462fd4e5da5Sopenharmony_ciOpLine %7 8 13
463fd4e5da5Sopenharmony_ci%vout = OpVariable %_ptr_Function_VS_OUTPUT Function
464fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugDeclare %46 %vout %42
465fd4e5da5Sopenharmony_ciOpLine %7 9 14
466fd4e5da5Sopenharmony_ci%50 = OpLoad %v4float %pos
467fd4e5da5Sopenharmony_ciOpLine %7 9 3
468fd4e5da5Sopenharmony_ci%51 = OpAccessChain %_ptr_Function_v4float %vout %int_0
469fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugValue %46 %51 %42 %int_0
470fd4e5da5Sopenharmony_ciOpStore %51 %50
471fd4e5da5Sopenharmony_ciOpLine %7 10 16
472fd4e5da5Sopenharmony_ci%53 = OpLoad %v4float %color
473fd4e5da5Sopenharmony_ciOpLine %7 10 3
474fd4e5da5Sopenharmony_ci%54 = OpAccessChain %_ptr_Function_v4float %vout %int_1
475fd4e5da5Sopenharmony_ci%55 = OpExtInst %void %1 DebugValue %46 %54 %42 %int_1
476fd4e5da5Sopenharmony_ciOpStore %54 %53
477fd4e5da5Sopenharmony_ciOpLine %7 11 10
478fd4e5da5Sopenharmony_ci%56 = OpLoad %VS_OUTPUT %vout
479fd4e5da5Sopenharmony_ciOpLine %7 11 3
480fd4e5da5Sopenharmony_ci%57 = OpCompositeExtract %v4float %56 0
481fd4e5da5Sopenharmony_ciOpStore %gl_Position %57
482fd4e5da5Sopenharmony_ci%58 = OpCompositeExtract %v4float %56 1
483fd4e5da5Sopenharmony_ciOpStore %out_var_COLOR %58
484fd4e5da5Sopenharmony_ci%61 = OpExtInst %void %1 DebugNoScope
485fd4e5da5Sopenharmony_ciOpReturn
486fd4e5da5Sopenharmony_ciOpFunctionEnd
487fd4e5da5Sopenharmony_ci)");
488fd4e5da5Sopenharmony_ci}
489fd4e5da5Sopenharmony_ci
490fd4e5da5Sopenharmony_ciTEST(IrBuilder, ConsumeDebugInfoLexicalScopeInst) {
491fd4e5da5Sopenharmony_ci  // /* HLSL */
492fd4e5da5Sopenharmony_ci  //
493fd4e5da5Sopenharmony_ci  // float4 func2(float arg2) {   // func2_block
494fd4e5da5Sopenharmony_ci  //   return float4(arg2, 0, 0, 0);
495fd4e5da5Sopenharmony_ci  // }
496fd4e5da5Sopenharmony_ci  //
497fd4e5da5Sopenharmony_ci  // float4 func1(float arg1) {   // func1_block
498fd4e5da5Sopenharmony_ci  //   if (arg1 > 1) {       // if_true_block
499fd4e5da5Sopenharmony_ci  //     return float4(0, 0, 0, 0);
500fd4e5da5Sopenharmony_ci  //   }
501fd4e5da5Sopenharmony_ci  //   return func2(arg1);   // if_merge_block
502fd4e5da5Sopenharmony_ci  // }
503fd4e5da5Sopenharmony_ci  //
504fd4e5da5Sopenharmony_ci  // float4 main(float pos : POSITION) : SV_POSITION {  // main
505fd4e5da5Sopenharmony_ci  //   return func1(pos);
506fd4e5da5Sopenharmony_ci  // }
507fd4e5da5Sopenharmony_ci  DoRoundTripCheck(R"(OpCapability Shader
508fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
509fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
510fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %pos %gl_Position
511fd4e5da5Sopenharmony_ci%5 = OpString "block/block.hlsl"
512fd4e5da5Sopenharmony_ci%6 = OpString "#line 1 \"block/block.hlsl\"
513fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
514fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
515fd4e5da5Sopenharmony_ci}
516fd4e5da5Sopenharmony_ci
517fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
518fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
519fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
520fd4e5da5Sopenharmony_ci  }
521fd4e5da5Sopenharmony_ci  return func2(arg1);
522fd4e5da5Sopenharmony_ci}
523fd4e5da5Sopenharmony_ci
524fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
525fd4e5da5Sopenharmony_ci  return func1(pos);
526fd4e5da5Sopenharmony_ci}
527fd4e5da5Sopenharmony_ci"
528fd4e5da5Sopenharmony_ciOpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
529fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
530fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
531fd4e5da5Sopenharmony_ci}
532fd4e5da5Sopenharmony_ci
533fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
534fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
535fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
536fd4e5da5Sopenharmony_ci  }
537fd4e5da5Sopenharmony_ci  return func2(arg1);
538fd4e5da5Sopenharmony_ci}
539fd4e5da5Sopenharmony_ci
540fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
541fd4e5da5Sopenharmony_ci  return func1(pos);
542fd4e5da5Sopenharmony_ci}
543fd4e5da5Sopenharmony_ci"
544fd4e5da5Sopenharmony_ci%7 = OpString "float"
545fd4e5da5Sopenharmony_ci%8 = OpString "main"
546fd4e5da5Sopenharmony_ci%9 = OpString "v4f_main_f"
547fd4e5da5Sopenharmony_ci%10 = OpString "v4f_func1_f"
548fd4e5da5Sopenharmony_ci%11 = OpString "v4f_func2_f"
549fd4e5da5Sopenharmony_ci%12 = OpString "pos : POSITION"
550fd4e5da5Sopenharmony_ci%13 = OpString "func1"
551fd4e5da5Sopenharmony_ci%14 = OpString "func2"
552fd4e5da5Sopenharmony_ciOpName %main "main"
553fd4e5da5Sopenharmony_ciOpName %pos "pos"
554fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
555fd4e5da5Sopenharmony_ciOpName %param_var_arg1 "param.var.arg1"
556fd4e5da5Sopenharmony_ciOpName %func1 "func1"
557fd4e5da5Sopenharmony_ciOpName %arg1 "arg1"
558fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
559fd4e5da5Sopenharmony_ciOpName %param_var_arg2 "param.var.arg2"
560fd4e5da5Sopenharmony_ciOpName %if_true "if.true"
561fd4e5da5Sopenharmony_ciOpName %if_merge "if.merge"
562fd4e5da5Sopenharmony_ciOpName %func2 "func2"
563fd4e5da5Sopenharmony_ciOpName %arg2 "arg2"
564fd4e5da5Sopenharmony_ciOpName %bb_entry_1 "bb.entry"
565fd4e5da5Sopenharmony_ciOpDecorate %gl_Position BuiltIn Position
566fd4e5da5Sopenharmony_ciOpDecorate %pos Location 0
567fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
568fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
569fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
570fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
571fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32
572fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
573fd4e5da5Sopenharmony_ci%32 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
574fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
575fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
576fd4e5da5Sopenharmony_ci%void = OpTypeVoid
577fd4e5da5Sopenharmony_ci%36 = OpTypeFunction %void
578fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
579fd4e5da5Sopenharmony_ci%38 = OpTypeFunction %v4float %_ptr_Function_float
580fd4e5da5Sopenharmony_ci%bool = OpTypeBool
581fd4e5da5Sopenharmony_ciOpLine %5 12 25
582fd4e5da5Sopenharmony_ci%pos = OpVariable %_ptr_Input_float Input
583fd4e5da5Sopenharmony_ciOpLine %5 12 37
584fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
585fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugSource %5 %6
586fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugCompilationUnit 2 4 %40 HLSL
587fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
588fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugTypeVector %42 4
589fd4e5da5Sopenharmony_ci%44 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
590fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
591fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
592fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugFunction %8 %44 %40 12 1 %41 %9 FlagIsProtected|FlagIsPrivate 13 %main
593fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugFunction %13 %45 %40 5 1 %41 %10 FlagIsProtected|FlagIsPrivate 13 %func1
594fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugFunction %14 %46 %40 1 1 %41 %11 FlagIsProtected|FlagIsPrivate 13 %func2
595fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugLexicalBlock %40 6 17 %48
596fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugLexicalBlock %40 9 3 %48
597fd4e5da5Sopenharmony_ciOpLine %5 12 1
598fd4e5da5Sopenharmony_ci%main = OpFunction %void None %36
599fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
600fd4e5da5Sopenharmony_ci%70 = OpExtInst %void %1 DebugScope %47
601fd4e5da5Sopenharmony_ciOpLine %5 13 16
602fd4e5da5Sopenharmony_ci%param_var_arg1 = OpVariable %_ptr_Function_float Function
603fd4e5da5Sopenharmony_ci%53 = OpLoad %float %pos
604fd4e5da5Sopenharmony_ciOpStore %param_var_arg1 %53
605fd4e5da5Sopenharmony_ciOpLine %5 13 10
606fd4e5da5Sopenharmony_ci%54 = OpFunctionCall %v4float %func1 %param_var_arg1
607fd4e5da5Sopenharmony_ciOpLine %5 13 3
608fd4e5da5Sopenharmony_ciOpStore %gl_Position %54
609fd4e5da5Sopenharmony_ci%71 = OpExtInst %void %1 DebugNoScope
610fd4e5da5Sopenharmony_ciOpReturn
611fd4e5da5Sopenharmony_ciOpFunctionEnd
612fd4e5da5Sopenharmony_ciOpLine %5 5 1
613fd4e5da5Sopenharmony_ci%func1 = OpFunction %v4float None %38
614fd4e5da5Sopenharmony_ciOpLine %5 5 20
615fd4e5da5Sopenharmony_ci%arg1 = OpFunctionParameter %_ptr_Function_float
616fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
617fd4e5da5Sopenharmony_ci%72 = OpExtInst %void %1 DebugScope %48
618fd4e5da5Sopenharmony_ciOpLine %5 9 16
619fd4e5da5Sopenharmony_ci%param_var_arg2 = OpVariable %_ptr_Function_float Function
620fd4e5da5Sopenharmony_ciOpLine %5 6 7
621fd4e5da5Sopenharmony_ci%57 = OpLoad %float %arg1
622fd4e5da5Sopenharmony_ciOpLine %5 6 12
623fd4e5da5Sopenharmony_ci%58 = OpFOrdGreaterThan %bool %57 %float_1
624fd4e5da5Sopenharmony_ciOpLine %5 6 17
625fd4e5da5Sopenharmony_ci%73 = OpExtInst %void %1 DebugNoScope
626fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None
627fd4e5da5Sopenharmony_ciOpBranchConditional %58 %if_true %if_merge
628fd4e5da5Sopenharmony_ci%if_true = OpLabel
629fd4e5da5Sopenharmony_ci%74 = OpExtInst %void %1 DebugScope %50
630fd4e5da5Sopenharmony_ciOpLine %5 7 5
631fd4e5da5Sopenharmony_ci%75 = OpExtInst %void %1 DebugNoScope
632fd4e5da5Sopenharmony_ciOpReturnValue %32
633fd4e5da5Sopenharmony_ci%if_merge = OpLabel
634fd4e5da5Sopenharmony_ci%76 = OpExtInst %void %1 DebugScope %51
635fd4e5da5Sopenharmony_ciOpLine %5 9 16
636fd4e5da5Sopenharmony_ci%63 = OpLoad %float %arg1
637fd4e5da5Sopenharmony_ciOpStore %param_var_arg2 %63
638fd4e5da5Sopenharmony_ciOpLine %5 9 10
639fd4e5da5Sopenharmony_ci%64 = OpFunctionCall %v4float %func2 %param_var_arg2
640fd4e5da5Sopenharmony_ciOpLine %5 9 3
641fd4e5da5Sopenharmony_ci%77 = OpExtInst %void %1 DebugNoScope
642fd4e5da5Sopenharmony_ciOpReturnValue %64
643fd4e5da5Sopenharmony_ciOpFunctionEnd
644fd4e5da5Sopenharmony_ciOpLine %5 1 1
645fd4e5da5Sopenharmony_ci%func2 = OpFunction %v4float None %38
646fd4e5da5Sopenharmony_ciOpLine %5 1 20
647fd4e5da5Sopenharmony_ci%arg2 = OpFunctionParameter %_ptr_Function_float
648fd4e5da5Sopenharmony_ci%bb_entry_1 = OpLabel
649fd4e5da5Sopenharmony_ci%78 = OpExtInst %void %1 DebugScope %49
650fd4e5da5Sopenharmony_ciOpLine %5 2 17
651fd4e5da5Sopenharmony_ci%67 = OpLoad %float %arg2
652fd4e5da5Sopenharmony_ci%68 = OpCompositeConstruct %v4float %67 %float_0 %float_0 %float_0
653fd4e5da5Sopenharmony_ciOpLine %5 2 3
654fd4e5da5Sopenharmony_ci%79 = OpExtInst %void %1 DebugNoScope
655fd4e5da5Sopenharmony_ciOpReturnValue %68
656fd4e5da5Sopenharmony_ciOpFunctionEnd
657fd4e5da5Sopenharmony_ci)");
658fd4e5da5Sopenharmony_ci}
659fd4e5da5Sopenharmony_ci
660fd4e5da5Sopenharmony_ciTEST(IrBuilder, ConsumeDebugInlinedAt) {
661fd4e5da5Sopenharmony_ci  // /* HLSL */
662fd4e5da5Sopenharmony_ci  //
663fd4e5da5Sopenharmony_ci  // float4 func2(float arg2) {   // func2_block
664fd4e5da5Sopenharmony_ci  //   return float4(arg2, 0, 0, 0);
665fd4e5da5Sopenharmony_ci  // }
666fd4e5da5Sopenharmony_ci  //
667fd4e5da5Sopenharmony_ci  // float4 func1(float arg1) {   // func1_block
668fd4e5da5Sopenharmony_ci  //   if (arg1 > 1) {       // if_true_block
669fd4e5da5Sopenharmony_ci  //     return float4(0, 0, 0, 0);
670fd4e5da5Sopenharmony_ci  //   }
671fd4e5da5Sopenharmony_ci  //   return func2(arg1);   // if_merge_block
672fd4e5da5Sopenharmony_ci  // }
673fd4e5da5Sopenharmony_ci  //
674fd4e5da5Sopenharmony_ci  // float4 main(float pos : POSITION) : SV_POSITION {  // main
675fd4e5da5Sopenharmony_ci  //   return func1(pos);
676fd4e5da5Sopenharmony_ci  // }
677fd4e5da5Sopenharmony_ci  //
678fd4e5da5Sopenharmony_ci  // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): In the following
679fd4e5da5Sopenharmony_ci  // SPIRV code, we use DebugInfoNone to reference opted-out function from
680fd4e5da5Sopenharmony_ci  // DebugFunction similar to opted-out global variable for DebugGlobalVariable,
681fd4e5da5Sopenharmony_ci  // but this is not a part of the spec yet. We are still in discussion and we
682fd4e5da5Sopenharmony_ci  // must correct it if our decision is different.
683fd4e5da5Sopenharmony_ci  DoRoundTripCheck(R"(OpCapability Shader
684fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
685fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
686fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %pos %gl_Position
687fd4e5da5Sopenharmony_ci%5 = OpString "block/block.hlsl"
688fd4e5da5Sopenharmony_ci%6 = OpString "#line 1 \"block/block.hlsl\"
689fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
690fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
691fd4e5da5Sopenharmony_ci}
692fd4e5da5Sopenharmony_ci
693fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
694fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
695fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
696fd4e5da5Sopenharmony_ci  }
697fd4e5da5Sopenharmony_ci  return func2(arg1);
698fd4e5da5Sopenharmony_ci}
699fd4e5da5Sopenharmony_ci
700fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
701fd4e5da5Sopenharmony_ci  return func1(pos);
702fd4e5da5Sopenharmony_ci}
703fd4e5da5Sopenharmony_ci"
704fd4e5da5Sopenharmony_ciOpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
705fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
706fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
707fd4e5da5Sopenharmony_ci}
708fd4e5da5Sopenharmony_ci
709fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
710fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
711fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
712fd4e5da5Sopenharmony_ci  }
713fd4e5da5Sopenharmony_ci  return func2(arg1);
714fd4e5da5Sopenharmony_ci}
715fd4e5da5Sopenharmony_ci
716fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
717fd4e5da5Sopenharmony_ci  return func1(pos);
718fd4e5da5Sopenharmony_ci}
719fd4e5da5Sopenharmony_ci"
720fd4e5da5Sopenharmony_ci%7 = OpString "float"
721fd4e5da5Sopenharmony_ci%8 = OpString "main"
722fd4e5da5Sopenharmony_ci%9 = OpString "v4f_main_f"
723fd4e5da5Sopenharmony_ci%10 = OpString "v4f_func1_f"
724fd4e5da5Sopenharmony_ci%11 = OpString "v4f_func2_f"
725fd4e5da5Sopenharmony_ci%12 = OpString "pos : POSITION"
726fd4e5da5Sopenharmony_ci%13 = OpString "func1"
727fd4e5da5Sopenharmony_ci%14 = OpString "func2"
728fd4e5da5Sopenharmony_ciOpName %main "main"
729fd4e5da5Sopenharmony_ciOpName %pos "pos"
730fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
731fd4e5da5Sopenharmony_ciOpName %if_true "if.true"
732fd4e5da5Sopenharmony_ciOpName %if_merge "if.merge"
733fd4e5da5Sopenharmony_ciOpDecorate %gl_Position BuiltIn Position
734fd4e5da5Sopenharmony_ciOpDecorate %pos Location 0
735fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
736fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
737fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
738fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
739fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32
740fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
741fd4e5da5Sopenharmony_ci%24 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
742fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
743fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
744fd4e5da5Sopenharmony_ci%void = OpTypeVoid
745fd4e5da5Sopenharmony_ci%28 = OpTypeFunction %void
746fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
747fd4e5da5Sopenharmony_ci%30 = OpTypeFunction %v4float %_ptr_Function_float
748fd4e5da5Sopenharmony_ci%bool = OpTypeBool
749fd4e5da5Sopenharmony_ciOpLine %5 12 25
750fd4e5da5Sopenharmony_ci%pos = OpVariable %_ptr_Input_float Input
751fd4e5da5Sopenharmony_ciOpLine %5 12 37
752fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
753fd4e5da5Sopenharmony_ci%32 = OpExtInst %void %1 DebugInfoNone
754fd4e5da5Sopenharmony_ci%33 = OpExtInst %void %1 DebugSource %5 %6
755fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %1 DebugCompilationUnit 2 4 %33 HLSL
756fd4e5da5Sopenharmony_ci%35 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
757fd4e5da5Sopenharmony_ci%36 = OpExtInst %void %1 DebugTypeVector %35 4
758fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
759fd4e5da5Sopenharmony_ci%38 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
760fd4e5da5Sopenharmony_ci%39 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %36 %35
761fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugFunction %8 %37 %33 12 1 %34 %9 FlagIsProtected|FlagIsPrivate 13 %main
762fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugFunction %13 %38 %33 5 1 %34 %10 FlagIsProtected|FlagIsPrivate 13 %32
763fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugFunction %14 %39 %33 1 1 %34 %11 FlagIsProtected|FlagIsPrivate 13 %32
764fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugLexicalBlock %33 12 49 %40
765fd4e5da5Sopenharmony_ci%44 = OpExtInst %void %1 DebugLexicalBlock %33 5 26 %41
766fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugLexicalBlock %33 1 26 %42
767fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugLexicalBlock %33 6 17 %44
768fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugLexicalBlock %33 9 3 %44
769fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugInlinedAt 9 %47
770fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugInlinedAt 13 %43
771fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugInlinedAt 13 %43 %48
772fd4e5da5Sopenharmony_ciOpLine %5 12 1
773fd4e5da5Sopenharmony_ci%main = OpFunction %void None %28
774fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
775fd4e5da5Sopenharmony_ci%62 = OpExtInst %void %1 DebugScope %44 %49
776fd4e5da5Sopenharmony_ciOpLine %5 6 7
777fd4e5da5Sopenharmony_ci%52 = OpLoad %float %pos
778fd4e5da5Sopenharmony_ciOpLine %5 6 12
779fd4e5da5Sopenharmony_ci%53 = OpFOrdGreaterThan %bool %52 %float_1
780fd4e5da5Sopenharmony_ciOpLine %5 6 17
781fd4e5da5Sopenharmony_ci%63 = OpExtInst %void %1 DebugNoScope
782fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None
783fd4e5da5Sopenharmony_ciOpBranchConditional %53 %if_true %if_merge
784fd4e5da5Sopenharmony_ci%if_true = OpLabel
785fd4e5da5Sopenharmony_ci%64 = OpExtInst %void %1 DebugScope %46 %49
786fd4e5da5Sopenharmony_ciOpLine %5 7 5
787fd4e5da5Sopenharmony_ciOpStore %gl_Position %24
788fd4e5da5Sopenharmony_ci%65 = OpExtInst %void %1 DebugNoScope
789fd4e5da5Sopenharmony_ciOpReturn
790fd4e5da5Sopenharmony_ci%if_merge = OpLabel
791fd4e5da5Sopenharmony_ci%66 = OpExtInst %void %1 DebugScope %45 %50
792fd4e5da5Sopenharmony_ciOpLine %5 2 17
793fd4e5da5Sopenharmony_ci%58 = OpLoad %float %pos
794fd4e5da5Sopenharmony_ciOpLine %5 2 10
795fd4e5da5Sopenharmony_ci%59 = OpCompositeConstruct %v4float %58 %float_0 %float_0 %float_0
796fd4e5da5Sopenharmony_ci%67 = OpExtInst %void %1 DebugScope %43
797fd4e5da5Sopenharmony_ciOpLine %5 13 3
798fd4e5da5Sopenharmony_ciOpStore %gl_Position %59
799fd4e5da5Sopenharmony_ci%68 = OpExtInst %void %1 DebugNoScope
800fd4e5da5Sopenharmony_ciOpReturn
801fd4e5da5Sopenharmony_ciOpFunctionEnd
802fd4e5da5Sopenharmony_ci)");
803fd4e5da5Sopenharmony_ci}
804fd4e5da5Sopenharmony_ci
805fd4e5da5Sopenharmony_ciTEST(IrBuilder, DebugInfoInstInFunctionOutOfBlock) {
806fd4e5da5Sopenharmony_ci  // /* HLSL */
807fd4e5da5Sopenharmony_ci  //
808fd4e5da5Sopenharmony_ci  // float4 func2(float arg2) {   // func2_block
809fd4e5da5Sopenharmony_ci  //   return float4(arg2, 0, 0, 0);
810fd4e5da5Sopenharmony_ci  // }
811fd4e5da5Sopenharmony_ci  //
812fd4e5da5Sopenharmony_ci  // float4 func1(float arg1) {   // func1_block
813fd4e5da5Sopenharmony_ci  //   if (arg1 > 1) {       // if_true_block
814fd4e5da5Sopenharmony_ci  //     return float4(0, 0, 0, 0);
815fd4e5da5Sopenharmony_ci  //   }
816fd4e5da5Sopenharmony_ci  //   return func2(arg1);   // if_merge_block
817fd4e5da5Sopenharmony_ci  // }
818fd4e5da5Sopenharmony_ci  //
819fd4e5da5Sopenharmony_ci  // float4 main(float pos : POSITION) : SV_POSITION {  // main
820fd4e5da5Sopenharmony_ci  //   return func1(pos);
821fd4e5da5Sopenharmony_ci  // }
822fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
823fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
824fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
825fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %pos %gl_Position
826fd4e5da5Sopenharmony_ci%5 = OpString "block/block.hlsl"
827fd4e5da5Sopenharmony_ci%6 = OpString "#line 1 \"block/block.hlsl\"
828fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
829fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
830fd4e5da5Sopenharmony_ci}
831fd4e5da5Sopenharmony_ci
832fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
833fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
834fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
835fd4e5da5Sopenharmony_ci  }
836fd4e5da5Sopenharmony_ci  return func2(arg1);
837fd4e5da5Sopenharmony_ci}
838fd4e5da5Sopenharmony_ci
839fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
840fd4e5da5Sopenharmony_ci  return func1(pos);
841fd4e5da5Sopenharmony_ci}
842fd4e5da5Sopenharmony_ci"
843fd4e5da5Sopenharmony_ciOpSource HLSL 600 %5 "#line 1 \"block/block.hlsl\"
844fd4e5da5Sopenharmony_cifloat4 func2(float arg2) {
845fd4e5da5Sopenharmony_ci  return float4(arg2, 0, 0, 0);
846fd4e5da5Sopenharmony_ci}
847fd4e5da5Sopenharmony_ci
848fd4e5da5Sopenharmony_cifloat4 func1(float arg1) {
849fd4e5da5Sopenharmony_ci  if (arg1 > 1) {
850fd4e5da5Sopenharmony_ci    return float4(0, 0, 0, 0);
851fd4e5da5Sopenharmony_ci  }
852fd4e5da5Sopenharmony_ci  return func2(arg1);
853fd4e5da5Sopenharmony_ci}
854fd4e5da5Sopenharmony_ci
855fd4e5da5Sopenharmony_cifloat4 main(float pos : POSITION) : SV_POSITION {
856fd4e5da5Sopenharmony_ci  return func1(pos);
857fd4e5da5Sopenharmony_ci}
858fd4e5da5Sopenharmony_ci"
859fd4e5da5Sopenharmony_ci%7 = OpString "float"
860fd4e5da5Sopenharmony_ci%8 = OpString "main"
861fd4e5da5Sopenharmony_ci%9 = OpString "v4f_main_f"
862fd4e5da5Sopenharmony_ci%10 = OpString "v4f_func1_f"
863fd4e5da5Sopenharmony_ci%11 = OpString "v4f_func2_f"
864fd4e5da5Sopenharmony_ci%12 = OpString "pos : POSITION"
865fd4e5da5Sopenharmony_ci%13 = OpString "func1"
866fd4e5da5Sopenharmony_ci%14 = OpString "func2"
867fd4e5da5Sopenharmony_ciOpName %main "main"
868fd4e5da5Sopenharmony_ciOpName %pos "pos"
869fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
870fd4e5da5Sopenharmony_ciOpName %param_var_arg1 "param.var.arg1"
871fd4e5da5Sopenharmony_ciOpName %func1 "func1"
872fd4e5da5Sopenharmony_ciOpName %arg1 "arg1"
873fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
874fd4e5da5Sopenharmony_ciOpName %param_var_arg2 "param.var.arg2"
875fd4e5da5Sopenharmony_ciOpName %if_true "if.true"
876fd4e5da5Sopenharmony_ciOpName %if_merge "if.merge"
877fd4e5da5Sopenharmony_ciOpName %func2 "func2"
878fd4e5da5Sopenharmony_ciOpName %arg2 "arg2"
879fd4e5da5Sopenharmony_ciOpName %bb_entry_1 "bb.entry"
880fd4e5da5Sopenharmony_ciOpDecorate %gl_Position BuiltIn Position
881fd4e5da5Sopenharmony_ciOpDecorate %pos Location 0
882fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
883fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
884fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
885fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
886fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32
887fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
888fd4e5da5Sopenharmony_ci%32 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
889fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
890fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
891fd4e5da5Sopenharmony_ci%void = OpTypeVoid
892fd4e5da5Sopenharmony_ci%36 = OpTypeFunction %void
893fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
894fd4e5da5Sopenharmony_ci%38 = OpTypeFunction %v4float %_ptr_Function_float
895fd4e5da5Sopenharmony_ci%bool = OpTypeBool
896fd4e5da5Sopenharmony_ciOpLine %5 12 25
897fd4e5da5Sopenharmony_ci%pos = OpVariable %_ptr_Input_float Input
898fd4e5da5Sopenharmony_ciOpLine %5 12 37
899fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
900fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugSource %5 %6
901fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugCompilationUnit 2 4 %40 HLSL
902fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugTypeBasic %7 %int_32 Float
903fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugTypeVector %42 4
904fd4e5da5Sopenharmony_ci%44 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
905fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
906fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %42
907fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugFunction %8 %44 %40 12 1 %41 %9 FlagIsProtected|FlagIsPrivate 13 %main
908fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugFunction %13 %45 %40 5 1 %41 %10 FlagIsProtected|FlagIsPrivate 13 %func1
909fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugFunction %14 %46 %40 1 1 %41 %11 FlagIsProtected|FlagIsPrivate 13 %func2
910fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugLexicalBlock %40 6 17 %48
911fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugLexicalBlock %40 9 3 %48
912fd4e5da5Sopenharmony_ciOpLine %5 12 1
913fd4e5da5Sopenharmony_ci%main = OpFunction %void None %36
914fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
915fd4e5da5Sopenharmony_ci%70 = OpExtInst %void %1 DebugScope %47
916fd4e5da5Sopenharmony_ciOpLine %5 13 16
917fd4e5da5Sopenharmony_ci%param_var_arg1 = OpVariable %_ptr_Function_float Function
918fd4e5da5Sopenharmony_ci%53 = OpLoad %float %pos
919fd4e5da5Sopenharmony_ciOpStore %param_var_arg1 %53
920fd4e5da5Sopenharmony_ciOpLine %5 13 10
921fd4e5da5Sopenharmony_ci%54 = OpFunctionCall %v4float %func1 %param_var_arg1
922fd4e5da5Sopenharmony_ciOpLine %5 13 3
923fd4e5da5Sopenharmony_ciOpStore %gl_Position %54
924fd4e5da5Sopenharmony_ci%71 = OpExtInst %void %1 DebugNoScope
925fd4e5da5Sopenharmony_ciOpReturn
926fd4e5da5Sopenharmony_ciOpFunctionEnd
927fd4e5da5Sopenharmony_ciOpLine %5 5 1
928fd4e5da5Sopenharmony_ci%func1 = OpFunction %v4float None %38
929fd4e5da5Sopenharmony_ciOpLine %5 5 20
930fd4e5da5Sopenharmony_ci%arg1 = OpFunctionParameter %_ptr_Function_float
931fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
932fd4e5da5Sopenharmony_ci%72 = OpExtInst %void %1 DebugScope %48
933fd4e5da5Sopenharmony_ciOpLine %5 9 16
934fd4e5da5Sopenharmony_ci%param_var_arg2 = OpVariable %_ptr_Function_float Function
935fd4e5da5Sopenharmony_ciOpLine %5 6 7
936fd4e5da5Sopenharmony_ci%57 = OpLoad %float %arg1
937fd4e5da5Sopenharmony_ciOpLine %5 6 12
938fd4e5da5Sopenharmony_ci%58 = OpFOrdGreaterThan %bool %57 %float_1
939fd4e5da5Sopenharmony_ciOpLine %5 6 17
940fd4e5da5Sopenharmony_ci%73 = OpExtInst %void %1 DebugNoScope
941fd4e5da5Sopenharmony_ciOpSelectionMerge %if_merge None
942fd4e5da5Sopenharmony_ciOpBranchConditional %58 %if_true %if_merge
943fd4e5da5Sopenharmony_ci%if_true = OpLabel
944fd4e5da5Sopenharmony_ci%74 = OpExtInst %void %1 DebugScope %50
945fd4e5da5Sopenharmony_ciOpLine %5 7 5
946fd4e5da5Sopenharmony_ci%75 = OpExtInst %void %1 DebugNoScope
947fd4e5da5Sopenharmony_ciOpReturnValue %32
948fd4e5da5Sopenharmony_ci%if_merge = OpLabel
949fd4e5da5Sopenharmony_ci%76 = OpExtInst %void %1 DebugScope %51
950fd4e5da5Sopenharmony_ciOpLine %5 9 16
951fd4e5da5Sopenharmony_ci%63 = OpLoad %float %arg1
952fd4e5da5Sopenharmony_ciOpStore %param_var_arg2 %63
953fd4e5da5Sopenharmony_ciOpLine %5 9 10
954fd4e5da5Sopenharmony_ci%64 = OpFunctionCall %v4float %func2 %param_var_arg2
955fd4e5da5Sopenharmony_ciOpLine %5 9 3
956fd4e5da5Sopenharmony_ci%77 = OpExtInst %void %1 DebugNoScope
957fd4e5da5Sopenharmony_ciOpReturnValue %64
958fd4e5da5Sopenharmony_ciOpFunctionEnd
959fd4e5da5Sopenharmony_ciOpLine %5 1 1
960fd4e5da5Sopenharmony_ci%func2 = OpFunction %v4float None %38
961fd4e5da5Sopenharmony_ciOpLine %5 1 20
962fd4e5da5Sopenharmony_ci%arg2 = OpFunctionParameter %_ptr_Function_float
963fd4e5da5Sopenharmony_ci%bb_entry_1 = OpLabel
964fd4e5da5Sopenharmony_ci%78 = OpExtInst %void %1 DebugScope %49
965fd4e5da5Sopenharmony_ciOpLine %5 2 17
966fd4e5da5Sopenharmony_ci%67 = OpLoad %float %arg2
967fd4e5da5Sopenharmony_ci%68 = OpCompositeConstruct %v4float %67 %float_0 %float_0 %float_0
968fd4e5da5Sopenharmony_ciOpLine %5 2 3
969fd4e5da5Sopenharmony_ci%79 = OpExtInst %void %1 DebugNoScope
970fd4e5da5Sopenharmony_ciOpReturnValue %68
971fd4e5da5Sopenharmony_ciOpFunctionEnd
972fd4e5da5Sopenharmony_ci)";
973fd4e5da5Sopenharmony_ci
974fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
975fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
976fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
977fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
978fd4e5da5Sopenharmony_ci
979fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
980fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, /* skip_nop = */ false);
981fd4e5da5Sopenharmony_ci
982fd4e5da5Sopenharmony_ci  std::string disassembled_text;
983fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
984fd4e5da5Sopenharmony_ci  EXPECT_EQ(text, disassembled_text);
985fd4e5da5Sopenharmony_ci}
986fd4e5da5Sopenharmony_ci
987fd4e5da5Sopenharmony_ciTEST(IrBuilder, DebugInfoInstInFunctionOutOfBlock2) {
988fd4e5da5Sopenharmony_ci  // /* HLSL */
989fd4e5da5Sopenharmony_ci  //
990fd4e5da5Sopenharmony_ci  // struct VS_OUTPUT {
991fd4e5da5Sopenharmony_ci  //   float4 pos : SV_POSITION;
992fd4e5da5Sopenharmony_ci  //   float4 color : COLOR;
993fd4e5da5Sopenharmony_ci  // };
994fd4e5da5Sopenharmony_ci  //
995fd4e5da5Sopenharmony_ci  // VS_OUTPUT main(float4 pos : POSITION,
996fd4e5da5Sopenharmony_ci  //                float4 color : COLOR) {
997fd4e5da5Sopenharmony_ci  //   VS_OUTPUT vout;
998fd4e5da5Sopenharmony_ci  //   vout.pos = pos;
999fd4e5da5Sopenharmony_ci  //   vout.color = color;
1000fd4e5da5Sopenharmony_ci  //   return vout;
1001fd4e5da5Sopenharmony_ci  // }
1002fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
1003fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
1004fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1005fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
1006fd4e5da5Sopenharmony_ci%7 = OpString "vs.hlsl"
1007fd4e5da5Sopenharmony_ciOpSource HLSL 600 %7 "#line 1 \"vs.hlsl\"
1008fd4e5da5Sopenharmony_cistruct VS_OUTPUT {
1009fd4e5da5Sopenharmony_ci  float4 pos : SV_POSITION;
1010fd4e5da5Sopenharmony_ci  float4 color : COLOR;
1011fd4e5da5Sopenharmony_ci};
1012fd4e5da5Sopenharmony_ci
1013fd4e5da5Sopenharmony_ciVS_OUTPUT main(float4 pos : POSITION,
1014fd4e5da5Sopenharmony_ci               float4 color : COLOR) {
1015fd4e5da5Sopenharmony_ci  VS_OUTPUT vout;
1016fd4e5da5Sopenharmony_ci  vout.pos = pos;
1017fd4e5da5Sopenharmony_ci  vout.color = color;
1018fd4e5da5Sopenharmony_ci  return vout;
1019fd4e5da5Sopenharmony_ci}
1020fd4e5da5Sopenharmony_ci"
1021fd4e5da5Sopenharmony_ci%8 = OpString "#line 1 \"vs.hlsl\"
1022fd4e5da5Sopenharmony_cistruct VS_OUTPUT {
1023fd4e5da5Sopenharmony_ci  float4 pos : SV_POSITION;
1024fd4e5da5Sopenharmony_ci  float4 color : COLOR;
1025fd4e5da5Sopenharmony_ci};
1026fd4e5da5Sopenharmony_ci
1027fd4e5da5Sopenharmony_ciVS_OUTPUT main(float4 pos : POSITION,
1028fd4e5da5Sopenharmony_ci               float4 color : COLOR) {
1029fd4e5da5Sopenharmony_ci  VS_OUTPUT vout;
1030fd4e5da5Sopenharmony_ci  vout.pos = pos;
1031fd4e5da5Sopenharmony_ci  vout.color = color;
1032fd4e5da5Sopenharmony_ci  return vout;
1033fd4e5da5Sopenharmony_ci}
1034fd4e5da5Sopenharmony_ci"
1035fd4e5da5Sopenharmony_ci%9 = OpString "VS_OUTPUT"
1036fd4e5da5Sopenharmony_ci%10 = OpString "float"
1037fd4e5da5Sopenharmony_ci%11 = OpString "src.main"
1038fd4e5da5Sopenharmony_ci%12 = OpString "pos"
1039fd4e5da5Sopenharmony_ci%13 = OpString "color"
1040fd4e5da5Sopenharmony_ci%14 = OpString "vout"
1041fd4e5da5Sopenharmony_ciOpName %in_var_POSITION "in.var.POSITION"
1042fd4e5da5Sopenharmony_ciOpName %in_var_COLOR "in.var.COLOR"
1043fd4e5da5Sopenharmony_ciOpName %out_var_COLOR "out.var.COLOR"
1044fd4e5da5Sopenharmony_ciOpName %main "main"
1045fd4e5da5Sopenharmony_ciOpName %param_var_pos "param.var.pos"
1046fd4e5da5Sopenharmony_ciOpName %param_var_color "param.var.color"
1047fd4e5da5Sopenharmony_ciOpName %VS_OUTPUT "VS_OUTPUT"
1048fd4e5da5Sopenharmony_ciOpMemberName %VS_OUTPUT 0 "pos"
1049fd4e5da5Sopenharmony_ciOpMemberName %VS_OUTPUT 1 "color"
1050fd4e5da5Sopenharmony_ciOpName %src_main "src.main"
1051fd4e5da5Sopenharmony_ciOpName %pos "pos"
1052fd4e5da5Sopenharmony_ciOpName %color "color"
1053fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
1054fd4e5da5Sopenharmony_ciOpName %vout "vout"
1055fd4e5da5Sopenharmony_ciOpDecorate %gl_Position BuiltIn Position
1056fd4e5da5Sopenharmony_ciOpDecorate %in_var_POSITION Location 0
1057fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 1
1058fd4e5da5Sopenharmony_ciOpDecorate %out_var_COLOR Location 0
1059fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1060fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1061fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
1062fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1063fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
1064fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1065fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1066fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1067fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1068fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1069fd4e5da5Sopenharmony_ci%uint_256 = OpConstant %uint 256
1070fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1071fd4e5da5Sopenharmony_ci%uint_128 = OpConstant %uint 128
1072fd4e5da5Sopenharmony_ci%36 = OpTypeFunction %void
1073fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1074fd4e5da5Sopenharmony_ci%VS_OUTPUT = OpTypeStruct %v4float %v4float
1075fd4e5da5Sopenharmony_ci%38 = OpTypeFunction %VS_OUTPUT %_ptr_Function_v4float %_ptr_Function_v4float
1076fd4e5da5Sopenharmony_ci%_ptr_Function_VS_OUTPUT = OpTypePointer Function %VS_OUTPUT
1077fd4e5da5Sopenharmony_ciOpLine %7 6 29
1078fd4e5da5Sopenharmony_ci%in_var_POSITION = OpVariable %_ptr_Input_v4float Input
1079fd4e5da5Sopenharmony_ciOpLine %7 7 31
1080fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
1081fd4e5da5Sopenharmony_ciOpLine %7 2 16
1082fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
1083fd4e5da5Sopenharmony_ciOpLine %7 3 18
1084fd4e5da5Sopenharmony_ci%out_var_COLOR = OpVariable %_ptr_Output_v4float Output
1085fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugExpression
1086fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugSource %7 %8
1087fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugCompilationUnit 1 4 %41 HLSL
1088fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugTypeComposite %9 Structure %41 1 1 %42 %9 %uint_256 FlagIsProtected|FlagIsPrivate %44 %45
1089fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugTypeBasic %10 %uint_32 Float
1090fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugTypeVector %46 4
1091fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %43 %47 %47
1092fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugFunction %11 %48 %41 6 1 %42 %11 FlagIsProtected|FlagIsPrivate 7 %src_main
1093fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugLocalVariable %12 %47 %41 6 23 %49 FlagIsLocal 0
1094fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugLocalVariable %13 %47 %41 7 23 %49 FlagIsLocal 1
1095fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugLexicalBlock %41 7 38 %49
1096fd4e5da5Sopenharmony_ci%53 = OpExtInst %void %1 DebugLocalVariable %14 %43 %41 8 13 %52 FlagIsLocal
1097fd4e5da5Sopenharmony_ci%44 = OpExtInst %void %1 DebugTypeMember %12 %47 %41 2 3 %43 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
1098fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugTypeMember %13 %47 %41 3 3 %43 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
1099fd4e5da5Sopenharmony_ciOpLine %7 6 1
1100fd4e5da5Sopenharmony_ci%main = OpFunction %void None %36
1101fd4e5da5Sopenharmony_ci%54 = OpLabel
1102fd4e5da5Sopenharmony_ci%74 = OpExtInst %void %1 DebugScope %42
1103fd4e5da5Sopenharmony_ciOpLine %7 6 23
1104fd4e5da5Sopenharmony_ci%param_var_pos = OpVariable %_ptr_Function_v4float Function
1105fd4e5da5Sopenharmony_ciOpLine %7 7 23
1106fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function
1107fd4e5da5Sopenharmony_ciOpLine %7 6 23
1108fd4e5da5Sopenharmony_ci%56 = OpLoad %v4float %in_var_POSITION
1109fd4e5da5Sopenharmony_ciOpStore %param_var_pos %56
1110fd4e5da5Sopenharmony_ciOpLine %7 7 23
1111fd4e5da5Sopenharmony_ci%57 = OpLoad %v4float %in_var_COLOR
1112fd4e5da5Sopenharmony_ciOpStore %param_var_color %57
1113fd4e5da5Sopenharmony_ciOpLine %7 6 1
1114fd4e5da5Sopenharmony_ci%58 = OpFunctionCall %VS_OUTPUT %src_main %param_var_pos %param_var_color
1115fd4e5da5Sopenharmony_ciOpLine %7 6 11
1116fd4e5da5Sopenharmony_ci%59 = OpCompositeExtract %v4float %58 0
1117fd4e5da5Sopenharmony_ciOpLine %7 2 16
1118fd4e5da5Sopenharmony_ciOpStore %gl_Position %59
1119fd4e5da5Sopenharmony_ciOpLine %7 6 11
1120fd4e5da5Sopenharmony_ci%60 = OpCompositeExtract %v4float %58 1
1121fd4e5da5Sopenharmony_ciOpLine %7 3 18
1122fd4e5da5Sopenharmony_ciOpStore %out_var_COLOR %60
1123fd4e5da5Sopenharmony_ci%75 = OpExtInst %void %1 DebugNoScope
1124fd4e5da5Sopenharmony_ciOpReturn
1125fd4e5da5Sopenharmony_ciOpFunctionEnd
1126fd4e5da5Sopenharmony_ciOpLine %7 6 1
1127fd4e5da5Sopenharmony_ci%src_main = OpFunction %VS_OUTPUT None %38
1128fd4e5da5Sopenharmony_ci%76 = OpExtInst %void %1 DebugScope %49
1129fd4e5da5Sopenharmony_ciOpLine %7 6 23
1130fd4e5da5Sopenharmony_ci%pos = OpFunctionParameter %_ptr_Function_v4float
1131fd4e5da5Sopenharmony_ciOpLine %7 7 23
1132fd4e5da5Sopenharmony_ci%color = OpFunctionParameter %_ptr_Function_v4float
1133fd4e5da5Sopenharmony_ci%63 = OpExtInst %void %1 DebugDeclare %50 %pos %40
1134fd4e5da5Sopenharmony_ci%64 = OpExtInst %void %1 DebugDeclare %51 %color %40
1135fd4e5da5Sopenharmony_ci%77 = OpExtInst %void %1 DebugNoScope
1136fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
1137fd4e5da5Sopenharmony_ci%78 = OpExtInst %void %1 DebugScope %52
1138fd4e5da5Sopenharmony_ciOpLine %7 8 13
1139fd4e5da5Sopenharmony_ci%vout = OpVariable %_ptr_Function_VS_OUTPUT Function
1140fd4e5da5Sopenharmony_ci%67 = OpExtInst %void %1 DebugDeclare %53 %vout %40
1141fd4e5da5Sopenharmony_ciOpLine %7 9 14
1142fd4e5da5Sopenharmony_ci%68 = OpLoad %v4float %pos
1143fd4e5da5Sopenharmony_ciOpLine %7 9 3
1144fd4e5da5Sopenharmony_ci%69 = OpAccessChain %_ptr_Function_v4float %vout %int_0
1145fd4e5da5Sopenharmony_ciOpStore %69 %68
1146fd4e5da5Sopenharmony_ciOpLine %7 10 16
1147fd4e5da5Sopenharmony_ci%70 = OpLoad %v4float %color
1148fd4e5da5Sopenharmony_ciOpLine %7 10 3
1149fd4e5da5Sopenharmony_ci%71 = OpAccessChain %_ptr_Function_v4float %vout %int_1
1150fd4e5da5Sopenharmony_ciOpStore %71 %70
1151fd4e5da5Sopenharmony_ciOpLine %7 11 10
1152fd4e5da5Sopenharmony_ci%72 = OpLoad %VS_OUTPUT %vout
1153fd4e5da5Sopenharmony_ciOpLine %7 11 3
1154fd4e5da5Sopenharmony_ci%79 = OpExtInst %void %1 DebugNoScope
1155fd4e5da5Sopenharmony_ciOpReturnValue %72
1156fd4e5da5Sopenharmony_ciOpFunctionEnd
1157fd4e5da5Sopenharmony_ci)";
1158fd4e5da5Sopenharmony_ci
1159fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
1160fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1161fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
1162fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
1163fd4e5da5Sopenharmony_ci
1164fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
1165fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, /* skip_nop = */ false);
1166fd4e5da5Sopenharmony_ci
1167fd4e5da5Sopenharmony_ci  std::string disassembled_text;
1168fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
1169fd4e5da5Sopenharmony_ci  EXPECT_EQ(text, disassembled_text);
1170fd4e5da5Sopenharmony_ci}
1171fd4e5da5Sopenharmony_ci
1172fd4e5da5Sopenharmony_ciTEST(IrBuilder, DebugInfoForTerminationInsts) {
1173fd4e5da5Sopenharmony_ci  // Check that DebugScope instructions for termination instructions are
1174fd4e5da5Sopenharmony_ci  // preserved.
1175fd4e5da5Sopenharmony_ci  DoRoundTripCheck(R"(OpCapability Shader
1176fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100"
1177fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1178fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1179fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1180fd4e5da5Sopenharmony_ci%3 = OpString "simple_vs.hlsl"
1181fd4e5da5Sopenharmony_ciOpSource HLSL 600 %3
1182fd4e5da5Sopenharmony_ciOpName %main "main"
1183fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1184fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void
1185fd4e5da5Sopenharmony_ci%6 = OpExtInst %void %1 DebugSource %3
1186fd4e5da5Sopenharmony_ci%7 = OpExtInst %void %1 DebugCompilationUnit 2 4 %6 HLSL
1187fd4e5da5Sopenharmony_ci%main = OpFunction %void None %5
1188fd4e5da5Sopenharmony_ci%8 = OpLabel
1189fd4e5da5Sopenharmony_ci%20 = OpExtInst %void %1 DebugScope %7
1190fd4e5da5Sopenharmony_ciOpBranch %10
1191fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %1 DebugNoScope
1192fd4e5da5Sopenharmony_ci%10 = OpLabel
1193fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugScope %7
1194fd4e5da5Sopenharmony_ciOpKill
1195fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugNoScope
1196fd4e5da5Sopenharmony_ci%14 = OpLabel
1197fd4e5da5Sopenharmony_ci%24 = OpExtInst %void %1 DebugScope %7
1198fd4e5da5Sopenharmony_ciOpUnreachable
1199fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugNoScope
1200fd4e5da5Sopenharmony_ci%17 = OpLabel
1201fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %1 DebugScope %7
1202fd4e5da5Sopenharmony_ciOpReturn
1203fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugNoScope
1204fd4e5da5Sopenharmony_ciOpFunctionEnd
1205fd4e5da5Sopenharmony_ci)");
1206fd4e5da5Sopenharmony_ci}
1207fd4e5da5Sopenharmony_ci
1208fd4e5da5Sopenharmony_ciTEST(IrBuilder, LocalGlobalVariables) {
1209fd4e5da5Sopenharmony_ci  // #version 310 es
1210fd4e5da5Sopenharmony_ci  //
1211fd4e5da5Sopenharmony_ci  // float gv1 = 10.;
1212fd4e5da5Sopenharmony_ci  // float gv2 = 100.;
1213fd4e5da5Sopenharmony_ci  //
1214fd4e5da5Sopenharmony_ci  // float f() {
1215fd4e5da5Sopenharmony_ci  //   float lv1 = gv1 + gv2;
1216fd4e5da5Sopenharmony_ci  //   float lv2 = gv1 * gv2;
1217fd4e5da5Sopenharmony_ci  //   return lv1 / lv2;
1218fd4e5da5Sopenharmony_ci  // }
1219fd4e5da5Sopenharmony_ci  //
1220fd4e5da5Sopenharmony_ci  // void main() {
1221fd4e5da5Sopenharmony_ci  //   float lv1 = gv1 - gv2;
1222fd4e5da5Sopenharmony_ci  // }
1223fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1224fd4e5da5Sopenharmony_ci      // clang-format off
1225fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1226fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1227fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1228fd4e5da5Sopenharmony_ci               "OpEntryPoint Vertex %main \"main\"\n"
1229fd4e5da5Sopenharmony_ci               "OpSource ESSL 310\n"
1230fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
1231fd4e5da5Sopenharmony_ci               "OpName %f_ \"f(\"\n"
1232fd4e5da5Sopenharmony_ci               "OpName %gv1 \"gv1\"\n"
1233fd4e5da5Sopenharmony_ci               "OpName %gv2 \"gv2\"\n"
1234fd4e5da5Sopenharmony_ci               "OpName %lv1 \"lv1\"\n"
1235fd4e5da5Sopenharmony_ci               "OpName %lv2 \"lv2\"\n"
1236fd4e5da5Sopenharmony_ci               "OpName %lv1_0 \"lv1\"\n"
1237fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1238fd4e5da5Sopenharmony_ci         "%10 = OpTypeFunction %void\n"
1239fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32\n"
1240fd4e5da5Sopenharmony_ci         "%12 = OpTypeFunction %float\n"
1241fd4e5da5Sopenharmony_ci "%_ptr_Private_float = OpTypePointer Private %float\n"
1242fd4e5da5Sopenharmony_ci        "%gv1 = OpVariable %_ptr_Private_float Private\n"
1243fd4e5da5Sopenharmony_ci   "%float_10 = OpConstant %float 10\n"
1244fd4e5da5Sopenharmony_ci        "%gv2 = OpVariable %_ptr_Private_float Private\n"
1245fd4e5da5Sopenharmony_ci  "%float_100 = OpConstant %float 100\n"
1246fd4e5da5Sopenharmony_ci "%_ptr_Function_float = OpTypePointer Function %float\n"
1247fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %10\n"
1248fd4e5da5Sopenharmony_ci         "%17 = OpLabel\n"
1249fd4e5da5Sopenharmony_ci      "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
1250fd4e5da5Sopenharmony_ci               "OpStore %gv1 %float_10\n"
1251fd4e5da5Sopenharmony_ci               "OpStore %gv2 %float_100\n"
1252fd4e5da5Sopenharmony_ci         "%18 = OpLoad %float %gv1\n"
1253fd4e5da5Sopenharmony_ci         "%19 = OpLoad %float %gv2\n"
1254fd4e5da5Sopenharmony_ci         "%20 = OpFSub %float %18 %19\n"
1255fd4e5da5Sopenharmony_ci               "OpStore %lv1_0 %20\n"
1256fd4e5da5Sopenharmony_ci               "OpReturn\n"
1257fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n"
1258fd4e5da5Sopenharmony_ci         "%f_ = OpFunction %float None %12\n"
1259fd4e5da5Sopenharmony_ci         "%21 = OpLabel\n"
1260fd4e5da5Sopenharmony_ci        "%lv1 = OpVariable %_ptr_Function_float Function\n"
1261fd4e5da5Sopenharmony_ci        "%lv2 = OpVariable %_ptr_Function_float Function\n"
1262fd4e5da5Sopenharmony_ci         "%22 = OpLoad %float %gv1\n"
1263fd4e5da5Sopenharmony_ci         "%23 = OpLoad %float %gv2\n"
1264fd4e5da5Sopenharmony_ci         "%24 = OpFAdd %float %22 %23\n"
1265fd4e5da5Sopenharmony_ci               "OpStore %lv1 %24\n"
1266fd4e5da5Sopenharmony_ci         "%25 = OpLoad %float %gv1\n"
1267fd4e5da5Sopenharmony_ci         "%26 = OpLoad %float %gv2\n"
1268fd4e5da5Sopenharmony_ci         "%27 = OpFMul %float %25 %26\n"
1269fd4e5da5Sopenharmony_ci               "OpStore %lv2 %27\n"
1270fd4e5da5Sopenharmony_ci         "%28 = OpLoad %float %lv1\n"
1271fd4e5da5Sopenharmony_ci         "%29 = OpLoad %float %lv2\n"
1272fd4e5da5Sopenharmony_ci         "%30 = OpFDiv %float %28 %29\n"
1273fd4e5da5Sopenharmony_ci               "OpReturnValue %30\n"
1274fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
1275fd4e5da5Sopenharmony_ci  // clang-format on
1276fd4e5da5Sopenharmony_ci}
1277fd4e5da5Sopenharmony_ci
1278fd4e5da5Sopenharmony_ciTEST(IrBuilder, OpUndefOutsideFunction) {
1279fd4e5da5Sopenharmony_ci  // #version 310 es
1280fd4e5da5Sopenharmony_ci  // void main() {}
1281fd4e5da5Sopenharmony_ci  const std::string text =
1282fd4e5da5Sopenharmony_ci      // clang-format off
1283fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1284fd4e5da5Sopenharmony_ci        "%int = OpTypeInt 32 1\n"
1285fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0\n"
1286fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32\n"
1287fd4e5da5Sopenharmony_ci          "%4 = OpUndef %int\n"
1288fd4e5da5Sopenharmony_ci     "%int_10 = OpConstant %int 10\n"
1289fd4e5da5Sopenharmony_ci          "%6 = OpUndef %uint\n"
1290fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool\n"
1291fd4e5da5Sopenharmony_ci          "%8 = OpUndef %float\n"
1292fd4e5da5Sopenharmony_ci     "%double = OpTypeFloat 64\n";
1293fd4e5da5Sopenharmony_ci  // clang-format on
1294fd4e5da5Sopenharmony_ci
1295fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
1296fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1297fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
1298fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
1299fd4e5da5Sopenharmony_ci
1300fd4e5da5Sopenharmony_ci  const auto opundef_count = std::count_if(
1301fd4e5da5Sopenharmony_ci      context->module()->types_values_begin(),
1302fd4e5da5Sopenharmony_ci      context->module()->types_values_end(), [](const Instruction& inst) {
1303fd4e5da5Sopenharmony_ci        return inst.opcode() == spv::Op::OpUndef;
1304fd4e5da5Sopenharmony_ci      });
1305fd4e5da5Sopenharmony_ci  EXPECT_EQ(3, opundef_count);
1306fd4e5da5Sopenharmony_ci
1307fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
1308fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, /* skip_nop = */ false);
1309fd4e5da5Sopenharmony_ci
1310fd4e5da5Sopenharmony_ci  std::string disassembled_text;
1311fd4e5da5Sopenharmony_ci  EXPECT_TRUE(t.Disassemble(binary, &disassembled_text));
1312fd4e5da5Sopenharmony_ci  EXPECT_EQ(text, disassembled_text);
1313fd4e5da5Sopenharmony_ci}
1314fd4e5da5Sopenharmony_ci
1315fd4e5da5Sopenharmony_ciTEST(IrBuilder, OpUndefInBasicBlock) {
1316fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1317fd4e5da5Sopenharmony_ci      // clang-format off
1318fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1319fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
1320fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1321fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0\n"
1322fd4e5da5Sopenharmony_ci     "%double = OpTypeFloat 64\n"
1323fd4e5da5Sopenharmony_ci          "%5 = OpTypeFunction %void\n"
1324fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %5\n"
1325fd4e5da5Sopenharmony_ci          "%6 = OpLabel\n"
1326fd4e5da5Sopenharmony_ci          "%7 = OpUndef %uint\n"
1327fd4e5da5Sopenharmony_ci          "%8 = OpUndef %double\n"
1328fd4e5da5Sopenharmony_ci               "OpReturn\n"
1329fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
1330fd4e5da5Sopenharmony_ci  // clang-format on
1331fd4e5da5Sopenharmony_ci}
1332fd4e5da5Sopenharmony_ci
1333fd4e5da5Sopenharmony_ciTEST(IrBuilder, KeepLineDebugInfoBeforeType) {
1334fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1335fd4e5da5Sopenharmony_ci      // clang-format off
1336fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1337fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1338fd4e5da5Sopenharmony_ci          "%1 = OpString \"minimal.vert\"\n"
1339fd4e5da5Sopenharmony_ci               "OpLine %1 1 1\n"
1340fd4e5da5Sopenharmony_ci               "OpNoLine\n"
1341fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1342fd4e5da5Sopenharmony_ci               "OpLine %1 2 2\n"
1343fd4e5da5Sopenharmony_ci          "%3 = OpTypeFunction %void\n");
1344fd4e5da5Sopenharmony_ci  // clang-format on
1345fd4e5da5Sopenharmony_ci}
1346fd4e5da5Sopenharmony_ci
1347fd4e5da5Sopenharmony_ciTEST(IrBuilder, KeepLineDebugInfoBeforeLabel) {
1348fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1349fd4e5da5Sopenharmony_ci      // clang-format off
1350fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1351fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1352fd4e5da5Sopenharmony_ci          "%1 = OpString \"minimal.vert\"\n"
1353fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1354fd4e5da5Sopenharmony_ci          "%3 = OpTypeFunction %void\n"
1355fd4e5da5Sopenharmony_ci       "%4 = OpFunction %void None %3\n"
1356fd4e5da5Sopenharmony_ci          "%5 = OpLabel\n"
1357fd4e5da5Sopenharmony_ci   "OpBranch %6\n"
1358fd4e5da5Sopenharmony_ci               "OpLine %1 1 1\n"
1359fd4e5da5Sopenharmony_ci               "OpLine %1 2 2\n"
1360fd4e5da5Sopenharmony_ci          "%6 = OpLabel\n"
1361fd4e5da5Sopenharmony_ci               "OpBranch %7\n"
1362fd4e5da5Sopenharmony_ci               "OpLine %1 100 100\n"
1363fd4e5da5Sopenharmony_ci          "%7 = OpLabel\n"
1364fd4e5da5Sopenharmony_ci               "OpReturn\n"
1365fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
1366fd4e5da5Sopenharmony_ci  // clang-format on
1367fd4e5da5Sopenharmony_ci}
1368fd4e5da5Sopenharmony_ci
1369fd4e5da5Sopenharmony_ciTEST(IrBuilder, KeepLineDebugInfoBeforeFunctionEnd) {
1370fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1371fd4e5da5Sopenharmony_ci      // clang-format off
1372fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1373fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1374fd4e5da5Sopenharmony_ci          "%1 = OpString \"minimal.vert\"\n"
1375fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1376fd4e5da5Sopenharmony_ci          "%3 = OpTypeFunction %void\n"
1377fd4e5da5Sopenharmony_ci       "%4 = OpFunction %void None %3\n"
1378fd4e5da5Sopenharmony_ci               "OpLine %1 1 1\n"
1379fd4e5da5Sopenharmony_ci               "OpLine %1 2 2\n"
1380fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n");
1381fd4e5da5Sopenharmony_ci  // clang-format on
1382fd4e5da5Sopenharmony_ci}
1383fd4e5da5Sopenharmony_ci
1384fd4e5da5Sopenharmony_ciTEST(IrBuilder, KeepModuleProcessedInRightPlace) {
1385fd4e5da5Sopenharmony_ci  DoRoundTripCheck(
1386fd4e5da5Sopenharmony_ci      // clang-format off
1387fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1388fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1389fd4e5da5Sopenharmony_ci          "%1 = OpString \"minimal.vert\"\n"
1390fd4e5da5Sopenharmony_ci               "OpName %void \"void\"\n"
1391fd4e5da5Sopenharmony_ci               "OpModuleProcessed \"Made it faster\"\n"
1392fd4e5da5Sopenharmony_ci               "OpModuleProcessed \".. and smaller\"\n"
1393fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n");
1394fd4e5da5Sopenharmony_ci  // clang-format on
1395fd4e5da5Sopenharmony_ci}
1396fd4e5da5Sopenharmony_ci
1397fd4e5da5Sopenharmony_ci// Checks the given |error_message| is reported when trying to build a module
1398fd4e5da5Sopenharmony_ci// from the given |assembly|.
1399fd4e5da5Sopenharmony_civoid DoErrorMessageCheck(const std::string& assembly,
1400fd4e5da5Sopenharmony_ci                         const std::string& error_message, uint32_t line_num) {
1401fd4e5da5Sopenharmony_ci  auto consumer = [error_message, line_num](spv_message_level_t, const char*,
1402fd4e5da5Sopenharmony_ci                                            const spv_position_t& position,
1403fd4e5da5Sopenharmony_ci                                            const char* m) {
1404fd4e5da5Sopenharmony_ci    EXPECT_EQ(error_message, m);
1405fd4e5da5Sopenharmony_ci    EXPECT_EQ(line_num, position.line);
1406fd4e5da5Sopenharmony_ci  };
1407fd4e5da5Sopenharmony_ci
1408fd4e5da5Sopenharmony_ci  SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
1409fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1410fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, std::move(consumer), assembly);
1411fd4e5da5Sopenharmony_ci  EXPECT_EQ(nullptr, context);
1412fd4e5da5Sopenharmony_ci}
1413fd4e5da5Sopenharmony_ci
1414fd4e5da5Sopenharmony_ciTEST(IrBuilder, FunctionInsideFunction) {
1415fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("%2 = OpFunction %1 None %3\n%5 = OpFunction %4 None %6",
1416fd4e5da5Sopenharmony_ci                      "function inside function", 2);
1417fd4e5da5Sopenharmony_ci}
1418fd4e5da5Sopenharmony_ci
1419fd4e5da5Sopenharmony_ciTEST(IrBuilder, MismatchOpFunctionEnd) {
1420fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("OpFunctionEnd",
1421fd4e5da5Sopenharmony_ci                      "OpFunctionEnd without corresponding OpFunction", 1);
1422fd4e5da5Sopenharmony_ci}
1423fd4e5da5Sopenharmony_ci
1424fd4e5da5Sopenharmony_ciTEST(IrBuilder, OpFunctionEndInsideBasicBlock) {
1425fd4e5da5Sopenharmony_ci  DoErrorMessageCheck(
1426fd4e5da5Sopenharmony_ci      "%2 = OpFunction %1 None %3\n"
1427fd4e5da5Sopenharmony_ci      "%4 = OpLabel\n"
1428fd4e5da5Sopenharmony_ci      "OpFunctionEnd",
1429fd4e5da5Sopenharmony_ci      "OpFunctionEnd inside basic block", 3);
1430fd4e5da5Sopenharmony_ci}
1431fd4e5da5Sopenharmony_ci
1432fd4e5da5Sopenharmony_ciTEST(IrBuilder, BasicBlockOutsideFunction) {
1433fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("OpCapability Shader\n%1 = OpLabel",
1434fd4e5da5Sopenharmony_ci                      "OpLabel outside function", 2);
1435fd4e5da5Sopenharmony_ci}
1436fd4e5da5Sopenharmony_ci
1437fd4e5da5Sopenharmony_ciTEST(IrBuilder, OpLabelInsideBasicBlock) {
1438fd4e5da5Sopenharmony_ci  DoErrorMessageCheck(
1439fd4e5da5Sopenharmony_ci      "%2 = OpFunction %1 None %3\n"
1440fd4e5da5Sopenharmony_ci      "%4 = OpLabel\n"
1441fd4e5da5Sopenharmony_ci      "%5 = OpLabel",
1442fd4e5da5Sopenharmony_ci      "OpLabel inside basic block", 3);
1443fd4e5da5Sopenharmony_ci}
1444fd4e5da5Sopenharmony_ci
1445fd4e5da5Sopenharmony_ciTEST(IrBuilder, TerminatorOutsideFunction) {
1446fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("OpReturn", "terminator instruction outside function", 1);
1447fd4e5da5Sopenharmony_ci}
1448fd4e5da5Sopenharmony_ci
1449fd4e5da5Sopenharmony_ciTEST(IrBuilder, TerminatorOutsideBasicBlock) {
1450fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("%2 = OpFunction %1 None %3\nOpReturn",
1451fd4e5da5Sopenharmony_ci                      "terminator instruction outside basic block", 2);
1452fd4e5da5Sopenharmony_ci}
1453fd4e5da5Sopenharmony_ci
1454fd4e5da5Sopenharmony_ciTEST(IrBuilder, NotAllowedInstAppearingInFunction) {
1455fd4e5da5Sopenharmony_ci  DoErrorMessageCheck("%2 = OpFunction %1 None %3\n%5 = OpVariable %4 Function",
1456fd4e5da5Sopenharmony_ci                      "Non-OpFunctionParameter (opcode: 59) found inside "
1457fd4e5da5Sopenharmony_ci                      "function but outside basic block",
1458fd4e5da5Sopenharmony_ci                      2);
1459fd4e5da5Sopenharmony_ci}
1460fd4e5da5Sopenharmony_ci
1461fd4e5da5Sopenharmony_ciTEST(IrBuilder, UniqueIds) {
1462fd4e5da5Sopenharmony_ci  const std::string text =
1463fd4e5da5Sopenharmony_ci      // clang-format off
1464fd4e5da5Sopenharmony_ci               "OpCapability Shader\n"
1465fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1466fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450\n"
1467fd4e5da5Sopenharmony_ci               "OpEntryPoint Vertex %main \"main\"\n"
1468fd4e5da5Sopenharmony_ci               "OpSource ESSL 310\n"
1469fd4e5da5Sopenharmony_ci               "OpName %main \"main\"\n"
1470fd4e5da5Sopenharmony_ci               "OpName %f_ \"f(\"\n"
1471fd4e5da5Sopenharmony_ci               "OpName %gv1 \"gv1\"\n"
1472fd4e5da5Sopenharmony_ci               "OpName %gv2 \"gv2\"\n"
1473fd4e5da5Sopenharmony_ci               "OpName %lv1 \"lv1\"\n"
1474fd4e5da5Sopenharmony_ci               "OpName %lv2 \"lv2\"\n"
1475fd4e5da5Sopenharmony_ci               "OpName %lv1_0 \"lv1\"\n"
1476fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid\n"
1477fd4e5da5Sopenharmony_ci         "%10 = OpTypeFunction %void\n"
1478fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32\n"
1479fd4e5da5Sopenharmony_ci         "%12 = OpTypeFunction %float\n"
1480fd4e5da5Sopenharmony_ci "%_ptr_Private_float = OpTypePointer Private %float\n"
1481fd4e5da5Sopenharmony_ci        "%gv1 = OpVariable %_ptr_Private_float Private\n"
1482fd4e5da5Sopenharmony_ci   "%float_10 = OpConstant %float 10\n"
1483fd4e5da5Sopenharmony_ci        "%gv2 = OpVariable %_ptr_Private_float Private\n"
1484fd4e5da5Sopenharmony_ci  "%float_100 = OpConstant %float 100\n"
1485fd4e5da5Sopenharmony_ci "%_ptr_Function_float = OpTypePointer Function %float\n"
1486fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %10\n"
1487fd4e5da5Sopenharmony_ci         "%17 = OpLabel\n"
1488fd4e5da5Sopenharmony_ci      "%lv1_0 = OpVariable %_ptr_Function_float Function\n"
1489fd4e5da5Sopenharmony_ci               "OpStore %gv1 %float_10\n"
1490fd4e5da5Sopenharmony_ci               "OpStore %gv2 %float_100\n"
1491fd4e5da5Sopenharmony_ci         "%18 = OpLoad %float %gv1\n"
1492fd4e5da5Sopenharmony_ci         "%19 = OpLoad %float %gv2\n"
1493fd4e5da5Sopenharmony_ci         "%20 = OpFSub %float %18 %19\n"
1494fd4e5da5Sopenharmony_ci               "OpStore %lv1_0 %20\n"
1495fd4e5da5Sopenharmony_ci               "OpReturn\n"
1496fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n"
1497fd4e5da5Sopenharmony_ci         "%f_ = OpFunction %float None %12\n"
1498fd4e5da5Sopenharmony_ci         "%21 = OpLabel\n"
1499fd4e5da5Sopenharmony_ci        "%lv1 = OpVariable %_ptr_Function_float Function\n"
1500fd4e5da5Sopenharmony_ci        "%lv2 = OpVariable %_ptr_Function_float Function\n"
1501fd4e5da5Sopenharmony_ci         "%22 = OpLoad %float %gv1\n"
1502fd4e5da5Sopenharmony_ci         "%23 = OpLoad %float %gv2\n"
1503fd4e5da5Sopenharmony_ci         "%24 = OpFAdd %float %22 %23\n"
1504fd4e5da5Sopenharmony_ci               "OpStore %lv1 %24\n"
1505fd4e5da5Sopenharmony_ci         "%25 = OpLoad %float %gv1\n"
1506fd4e5da5Sopenharmony_ci         "%26 = OpLoad %float %gv2\n"
1507fd4e5da5Sopenharmony_ci         "%27 = OpFMul %float %25 %26\n"
1508fd4e5da5Sopenharmony_ci               "OpStore %lv2 %27\n"
1509fd4e5da5Sopenharmony_ci         "%28 = OpLoad %float %lv1\n"
1510fd4e5da5Sopenharmony_ci         "%29 = OpLoad %float %lv2\n"
1511fd4e5da5Sopenharmony_ci         "%30 = OpFDiv %float %28 %29\n"
1512fd4e5da5Sopenharmony_ci               "OpReturnValue %30\n"
1513fd4e5da5Sopenharmony_ci               "OpFunctionEnd\n";
1514fd4e5da5Sopenharmony_ci  // clang-format on
1515fd4e5da5Sopenharmony_ci
1516fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1517fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
1518fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
1519fd4e5da5Sopenharmony_ci
1520fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> ids;
1521fd4e5da5Sopenharmony_ci  context->module()->ForEachInst([&ids](const Instruction* inst) {
1522fd4e5da5Sopenharmony_ci    EXPECT_TRUE(ids.insert(inst->unique_id()).second);
1523fd4e5da5Sopenharmony_ci  });
1524fd4e5da5Sopenharmony_ci}
1525fd4e5da5Sopenharmony_ci
1526fd4e5da5Sopenharmony_ci}  // namespace
1527fd4e5da5Sopenharmony_ci}  // namespace opt
1528fd4e5da5Sopenharmony_ci}  // namespace spvtools
1529