1fd4e5da5Sopenharmony_ci// Copyright (c) 2017-2022 Valve Corporation
2fd4e5da5Sopenharmony_ci// Copyright (c) 2017-2022 LunarG Inc.
3fd4e5da5Sopenharmony_ci//
4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
7fd4e5da5Sopenharmony_ci//
8fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
9fd4e5da5Sopenharmony_ci//
10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
14fd4e5da5Sopenharmony_ci// limitations under the License.
15fd4e5da5Sopenharmony_ci
16fd4e5da5Sopenharmony_ci#include <memory>
17fd4e5da5Sopenharmony_ci#include <string>
18fd4e5da5Sopenharmony_ci#include <vector>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_cinamespace spvtools {
24fd4e5da5Sopenharmony_cinamespace opt {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing InlineTest = PassTest<::testing::Test>;
28fd4e5da5Sopenharmony_ci
29fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Simple) {
30fd4e5da5Sopenharmony_ci  // #version 140
31fd4e5da5Sopenharmony_ci  //
32fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
33fd4e5da5Sopenharmony_ci  //
34fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
35fd4e5da5Sopenharmony_ci  // {
36fd4e5da5Sopenharmony_ci  //     return bar.x + bar.y;
37fd4e5da5Sopenharmony_ci  // }
38fd4e5da5Sopenharmony_ci  //
39fd4e5da5Sopenharmony_ci  // void main()
40fd4e5da5Sopenharmony_ci  // {
41fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
42fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
43fd4e5da5Sopenharmony_ci  // }
44fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
45fd4e5da5Sopenharmony_ci      // clang-format off
46fd4e5da5Sopenharmony_ci               "OpCapability Shader",
47fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
48fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
49fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor",
50fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
51fd4e5da5Sopenharmony_ci               "OpSource GLSL 140",
52fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
53fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
54fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
55fd4e5da5Sopenharmony_ci               "OpName %color \"color\"",
56fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
57fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
58fd4e5da5Sopenharmony_ci               "OpName %gl_FragColor \"gl_FragColor\"",
59fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
60fd4e5da5Sopenharmony_ci         "%10 = OpTypeFunction %void",
61fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
62fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
63fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
64fd4e5da5Sopenharmony_ci         "%14 = OpTypeFunction %float %_ptr_Function_v4float",
65fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
66fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
67fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
68fd4e5da5Sopenharmony_ci     "%uint_1 = OpConstant %uint 1",
69fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
70fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
71fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
72fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output",
73fd4e5da5Sopenharmony_ci      // clang-format on
74fd4e5da5Sopenharmony_ci  };
75fd4e5da5Sopenharmony_ci
76fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
77fd4e5da5Sopenharmony_ci      // clang-format off
78fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %14",
79fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
80fd4e5da5Sopenharmony_ci         "%26 = OpLabel",
81fd4e5da5Sopenharmony_ci         "%27 = OpAccessChain %_ptr_Function_float %bar %uint_0",
82fd4e5da5Sopenharmony_ci         "%28 = OpLoad %float %27",
83fd4e5da5Sopenharmony_ci         "%29 = OpAccessChain %_ptr_Function_float %bar %uint_1",
84fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %29",
85fd4e5da5Sopenharmony_ci         "%31 = OpFAdd %float %28 %30",
86fd4e5da5Sopenharmony_ci               "OpReturnValue %31",
87fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
88fd4e5da5Sopenharmony_ci      // clang-format on
89fd4e5da5Sopenharmony_ci  };
90fd4e5da5Sopenharmony_ci
91fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
92fd4e5da5Sopenharmony_ci      // clang-format off
93fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %10",
94fd4e5da5Sopenharmony_ci         "%21 = OpLabel",
95fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
96fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
97fd4e5da5Sopenharmony_ci         "%22 = OpLoad %v4float %BaseColor",
98fd4e5da5Sopenharmony_ci               "OpStore %param %22",
99fd4e5da5Sopenharmony_ci         "%23 = OpFunctionCall %float %foo_vf4_ %param",
100fd4e5da5Sopenharmony_ci         "%24 = OpCompositeConstruct %v4float %23 %23 %23 %23",
101fd4e5da5Sopenharmony_ci               "OpStore %color %24",
102fd4e5da5Sopenharmony_ci         "%25 = OpLoad %v4float %color",
103fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %25",
104fd4e5da5Sopenharmony_ci               "OpReturn",
105fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
106fd4e5da5Sopenharmony_ci      // clang-format on
107fd4e5da5Sopenharmony_ci  };
108fd4e5da5Sopenharmony_ci
109fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
110fd4e5da5Sopenharmony_ci      // clang-format off
111fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %10",
112fd4e5da5Sopenharmony_ci         "%21 = OpLabel",
113fd4e5da5Sopenharmony_ci         "%32 = OpVariable %_ptr_Function_float Function",
114fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
115fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
116fd4e5da5Sopenharmony_ci         "%22 = OpLoad %v4float %BaseColor",
117fd4e5da5Sopenharmony_ci               "OpStore %param %22",
118fd4e5da5Sopenharmony_ci         "%34 = OpAccessChain %_ptr_Function_float %param %uint_0",
119fd4e5da5Sopenharmony_ci         "%35 = OpLoad %float %34",
120fd4e5da5Sopenharmony_ci         "%36 = OpAccessChain %_ptr_Function_float %param %uint_1",
121fd4e5da5Sopenharmony_ci         "%37 = OpLoad %float %36",
122fd4e5da5Sopenharmony_ci         "%38 = OpFAdd %float %35 %37",
123fd4e5da5Sopenharmony_ci               "OpStore %32 %38",
124fd4e5da5Sopenharmony_ci         "%23 = OpLoad %float %32",
125fd4e5da5Sopenharmony_ci         "%24 = OpCompositeConstruct %v4float %23 %23 %23 %23",
126fd4e5da5Sopenharmony_ci               "OpStore %color %24",
127fd4e5da5Sopenharmony_ci         "%25 = OpLoad %v4float %color",
128fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %25",
129fd4e5da5Sopenharmony_ci               "OpReturn",
130fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
131fd4e5da5Sopenharmony_ci      // clang-format on
132fd4e5da5Sopenharmony_ci  };
133fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
134fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
135fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
136fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
137fd4e5da5Sopenharmony_ci}
138fd4e5da5Sopenharmony_ci
139fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Nested) {
140fd4e5da5Sopenharmony_ci  // #version 140
141fd4e5da5Sopenharmony_ci  //
142fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
143fd4e5da5Sopenharmony_ci  //
144fd4e5da5Sopenharmony_ci  // float foo2(float f, float f2)
145fd4e5da5Sopenharmony_ci  // {
146fd4e5da5Sopenharmony_ci  //     return f * f2;
147fd4e5da5Sopenharmony_ci  // }
148fd4e5da5Sopenharmony_ci  //
149fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
150fd4e5da5Sopenharmony_ci  // {
151fd4e5da5Sopenharmony_ci  //     return foo2(bar.x + bar.y, bar.z);
152fd4e5da5Sopenharmony_ci  // }
153fd4e5da5Sopenharmony_ci  //
154fd4e5da5Sopenharmony_ci  // void main()
155fd4e5da5Sopenharmony_ci  // {
156fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
157fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
158fd4e5da5Sopenharmony_ci  // }
159fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
160fd4e5da5Sopenharmony_ci      // clang-format off
161fd4e5da5Sopenharmony_ci               "OpCapability Shader",
162fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
163fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
164fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor",
165fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
166fd4e5da5Sopenharmony_ci               "OpSource GLSL 140",
167fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
168fd4e5da5Sopenharmony_ci               "OpName %foo2_f1_f1_ \"foo2(f1;f1;\"",
169fd4e5da5Sopenharmony_ci               "OpName %f \"f\"",
170fd4e5da5Sopenharmony_ci               "OpName %f2 \"f2\"",
171fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
172fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
173fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
174fd4e5da5Sopenharmony_ci               "OpName %param_0 \"param\"",
175fd4e5da5Sopenharmony_ci               "OpName %color \"color\"",
176fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
177fd4e5da5Sopenharmony_ci               "OpName %param_1 \"param\"",
178fd4e5da5Sopenharmony_ci               "OpName %gl_FragColor \"gl_FragColor\"",
179fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
180fd4e5da5Sopenharmony_ci         "%15 = OpTypeFunction %void",
181fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
182fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
183fd4e5da5Sopenharmony_ci         "%18 = OpTypeFunction %float %_ptr_Function_float %_ptr_Function_float",
184fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
185fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
186fd4e5da5Sopenharmony_ci         "%21 = OpTypeFunction %float %_ptr_Function_v4float",
187fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
188fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
189fd4e5da5Sopenharmony_ci     "%uint_1 = OpConstant %uint 1",
190fd4e5da5Sopenharmony_ci     "%uint_2 = OpConstant %uint 2",
191fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
192fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
193fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
194fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output",
195fd4e5da5Sopenharmony_ci      // clang-format on
196fd4e5da5Sopenharmony_ci  };
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
199fd4e5da5Sopenharmony_ci      // clang-format off
200fd4e5da5Sopenharmony_ci"%foo2_f1_f1_ = OpFunction %float None %18",
201fd4e5da5Sopenharmony_ci          "%f = OpFunctionParameter %_ptr_Function_float",
202fd4e5da5Sopenharmony_ci         "%f2 = OpFunctionParameter %_ptr_Function_float",
203fd4e5da5Sopenharmony_ci         "%33 = OpLabel",
204fd4e5da5Sopenharmony_ci         "%34 = OpLoad %float %f",
205fd4e5da5Sopenharmony_ci         "%35 = OpLoad %float %f2",
206fd4e5da5Sopenharmony_ci         "%36 = OpFMul %float %34 %35",
207fd4e5da5Sopenharmony_ci               "OpReturnValue %36",
208fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
209fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %21",
210fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
211fd4e5da5Sopenharmony_ci         "%37 = OpLabel",
212fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_float Function",
213fd4e5da5Sopenharmony_ci    "%param_0 = OpVariable %_ptr_Function_float Function",
214fd4e5da5Sopenharmony_ci         "%38 = OpAccessChain %_ptr_Function_float %bar %uint_0",
215fd4e5da5Sopenharmony_ci         "%39 = OpLoad %float %38",
216fd4e5da5Sopenharmony_ci         "%40 = OpAccessChain %_ptr_Function_float %bar %uint_1",
217fd4e5da5Sopenharmony_ci         "%41 = OpLoad %float %40",
218fd4e5da5Sopenharmony_ci         "%42 = OpFAdd %float %39 %41",
219fd4e5da5Sopenharmony_ci               "OpStore %param %42",
220fd4e5da5Sopenharmony_ci         "%43 = OpAccessChain %_ptr_Function_float %bar %uint_2",
221fd4e5da5Sopenharmony_ci         "%44 = OpLoad %float %43",
222fd4e5da5Sopenharmony_ci               "OpStore %param_0 %44",
223fd4e5da5Sopenharmony_ci         "%45 = OpFunctionCall %float %foo2_f1_f1_ %param %param_0",
224fd4e5da5Sopenharmony_ci               "OpReturnValue %45",
225fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
226fd4e5da5Sopenharmony_ci      // clang-format on
227fd4e5da5Sopenharmony_ci  };
228fd4e5da5Sopenharmony_ci
229fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
230fd4e5da5Sopenharmony_ci      // clang-format off
231fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %15",
232fd4e5da5Sopenharmony_ci         "%28 = OpLabel",
233fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
234fd4e5da5Sopenharmony_ci    "%param_1 = OpVariable %_ptr_Function_v4float Function",
235fd4e5da5Sopenharmony_ci         "%29 = OpLoad %v4float %BaseColor",
236fd4e5da5Sopenharmony_ci               "OpStore %param_1 %29",
237fd4e5da5Sopenharmony_ci         "%30 = OpFunctionCall %float %foo_vf4_ %param_1",
238fd4e5da5Sopenharmony_ci         "%31 = OpCompositeConstruct %v4float %30 %30 %30 %30",
239fd4e5da5Sopenharmony_ci               "OpStore %color %31",
240fd4e5da5Sopenharmony_ci         "%32 = OpLoad %v4float %color",
241fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %32",
242fd4e5da5Sopenharmony_ci               "OpReturn",
243fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
244fd4e5da5Sopenharmony_ci      // clang-format on
245fd4e5da5Sopenharmony_ci  };
246fd4e5da5Sopenharmony_ci
247fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
248fd4e5da5Sopenharmony_ci      // clang-format off
249fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %15",
250fd4e5da5Sopenharmony_ci         "%28 = OpLabel",
251fd4e5da5Sopenharmony_ci         "%58 = OpVariable %_ptr_Function_float Function",
252fd4e5da5Sopenharmony_ci         "%46 = OpVariable %_ptr_Function_float Function",
253fd4e5da5Sopenharmony_ci         "%47 = OpVariable %_ptr_Function_float Function",
254fd4e5da5Sopenharmony_ci         "%48 = OpVariable %_ptr_Function_float Function",
255fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
256fd4e5da5Sopenharmony_ci    "%param_1 = OpVariable %_ptr_Function_v4float Function",
257fd4e5da5Sopenharmony_ci         "%29 = OpLoad %v4float %BaseColor",
258fd4e5da5Sopenharmony_ci               "OpStore %param_1 %29",
259fd4e5da5Sopenharmony_ci         "%50 = OpAccessChain %_ptr_Function_float %param_1 %uint_0",
260fd4e5da5Sopenharmony_ci         "%51 = OpLoad %float %50",
261fd4e5da5Sopenharmony_ci         "%52 = OpAccessChain %_ptr_Function_float %param_1 %uint_1",
262fd4e5da5Sopenharmony_ci         "%53 = OpLoad %float %52",
263fd4e5da5Sopenharmony_ci         "%54 = OpFAdd %float %51 %53",
264fd4e5da5Sopenharmony_ci               "OpStore %46 %54",
265fd4e5da5Sopenharmony_ci         "%55 = OpAccessChain %_ptr_Function_float %param_1 %uint_2",
266fd4e5da5Sopenharmony_ci         "%56 = OpLoad %float %55",
267fd4e5da5Sopenharmony_ci               "OpStore %47 %56",
268fd4e5da5Sopenharmony_ci         "%60 = OpLoad %float %46",
269fd4e5da5Sopenharmony_ci         "%61 = OpLoad %float %47",
270fd4e5da5Sopenharmony_ci         "%62 = OpFMul %float %60 %61",
271fd4e5da5Sopenharmony_ci               "OpStore %58 %62",
272fd4e5da5Sopenharmony_ci         "%57 = OpLoad %float %58",
273fd4e5da5Sopenharmony_ci               "OpStore %48 %57",
274fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %48",
275fd4e5da5Sopenharmony_ci         "%31 = OpCompositeConstruct %v4float %30 %30 %30 %30",
276fd4e5da5Sopenharmony_ci               "OpStore %color %31",
277fd4e5da5Sopenharmony_ci         "%32 = OpLoad %v4float %color",
278fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %32",
279fd4e5da5Sopenharmony_ci               "OpReturn",
280fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
281fd4e5da5Sopenharmony_ci      // clang-format on
282fd4e5da5Sopenharmony_ci  };
283fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
284fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
285fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
286fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
287fd4e5da5Sopenharmony_ci}
288fd4e5da5Sopenharmony_ci
289fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InOutParameter) {
290fd4e5da5Sopenharmony_ci  // #version 400
291fd4e5da5Sopenharmony_ci  //
292fd4e5da5Sopenharmony_ci  // in vec4 Basecolor;
293fd4e5da5Sopenharmony_ci  //
294fd4e5da5Sopenharmony_ci  // void foo(inout vec4 bar)
295fd4e5da5Sopenharmony_ci  // {
296fd4e5da5Sopenharmony_ci  //     bar.z = bar.x + bar.y;
297fd4e5da5Sopenharmony_ci  // }
298fd4e5da5Sopenharmony_ci  //
299fd4e5da5Sopenharmony_ci  // void main()
300fd4e5da5Sopenharmony_ci  // {
301fd4e5da5Sopenharmony_ci  //     vec4 b = Basecolor;
302fd4e5da5Sopenharmony_ci  //     foo(b);
303fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(b.z);
304fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
305fd4e5da5Sopenharmony_ci  // }
306fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
307fd4e5da5Sopenharmony_ci      // clang-format off
308fd4e5da5Sopenharmony_ci               "OpCapability Shader",
309fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
310fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
311fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %Basecolor %gl_FragColor",
312fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
313fd4e5da5Sopenharmony_ci               "OpSource GLSL 400",
314fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
315fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
316fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
317fd4e5da5Sopenharmony_ci               "OpName %b \"b\"",
318fd4e5da5Sopenharmony_ci               "OpName %Basecolor \"Basecolor\"",
319fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
320fd4e5da5Sopenharmony_ci               "OpName %color \"color\"",
321fd4e5da5Sopenharmony_ci               "OpName %gl_FragColor \"gl_FragColor\"",
322fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
323fd4e5da5Sopenharmony_ci         "%11 = OpTypeFunction %void",
324fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
325fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
326fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
327fd4e5da5Sopenharmony_ci         "%15 = OpTypeFunction %void %_ptr_Function_v4float",
328fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
329fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
330fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
331fd4e5da5Sopenharmony_ci     "%uint_1 = OpConstant %uint 1",
332fd4e5da5Sopenharmony_ci     "%uint_2 = OpConstant %uint 2",
333fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
334fd4e5da5Sopenharmony_ci  "%Basecolor = OpVariable %_ptr_Input_v4float Input",
335fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
336fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output",
337fd4e5da5Sopenharmony_ci      // clang-format on
338fd4e5da5Sopenharmony_ci  };
339fd4e5da5Sopenharmony_ci
340fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
341fd4e5da5Sopenharmony_ci      // clang-format off
342fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %void None %15",
343fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
344fd4e5da5Sopenharmony_ci         "%32 = OpLabel",
345fd4e5da5Sopenharmony_ci         "%33 = OpAccessChain %_ptr_Function_float %bar %uint_0",
346fd4e5da5Sopenharmony_ci         "%34 = OpLoad %float %33",
347fd4e5da5Sopenharmony_ci         "%35 = OpAccessChain %_ptr_Function_float %bar %uint_1",
348fd4e5da5Sopenharmony_ci         "%36 = OpLoad %float %35",
349fd4e5da5Sopenharmony_ci         "%37 = OpFAdd %float %34 %36",
350fd4e5da5Sopenharmony_ci         "%38 = OpAccessChain %_ptr_Function_float %bar %uint_2",
351fd4e5da5Sopenharmony_ci               "OpStore %38 %37",
352fd4e5da5Sopenharmony_ci               "OpReturn",
353fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
354fd4e5da5Sopenharmony_ci      // clang-format on
355fd4e5da5Sopenharmony_ci  };
356fd4e5da5Sopenharmony_ci
357fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
358fd4e5da5Sopenharmony_ci      // clang-format off
359fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %11",
360fd4e5da5Sopenharmony_ci         "%23 = OpLabel",
361fd4e5da5Sopenharmony_ci          "%b = OpVariable %_ptr_Function_v4float Function",
362fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
363fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
364fd4e5da5Sopenharmony_ci         "%24 = OpLoad %v4float %Basecolor",
365fd4e5da5Sopenharmony_ci               "OpStore %b %24",
366fd4e5da5Sopenharmony_ci         "%25 = OpLoad %v4float %b",
367fd4e5da5Sopenharmony_ci               "OpStore %param %25",
368fd4e5da5Sopenharmony_ci         "%26 = OpFunctionCall %void %foo_vf4_ %param",
369fd4e5da5Sopenharmony_ci         "%27 = OpLoad %v4float %param",
370fd4e5da5Sopenharmony_ci               "OpStore %b %27",
371fd4e5da5Sopenharmony_ci         "%28 = OpAccessChain %_ptr_Function_float %b %uint_2",
372fd4e5da5Sopenharmony_ci         "%29 = OpLoad %float %28",
373fd4e5da5Sopenharmony_ci         "%30 = OpCompositeConstruct %v4float %29 %29 %29 %29",
374fd4e5da5Sopenharmony_ci               "OpStore %color %30",
375fd4e5da5Sopenharmony_ci         "%31 = OpLoad %v4float %color",
376fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %31",
377fd4e5da5Sopenharmony_ci               "OpReturn",
378fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
379fd4e5da5Sopenharmony_ci      // clang-format on
380fd4e5da5Sopenharmony_ci  };
381fd4e5da5Sopenharmony_ci
382fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
383fd4e5da5Sopenharmony_ci      // clang-format off
384fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %11",
385fd4e5da5Sopenharmony_ci         "%23 = OpLabel",
386fd4e5da5Sopenharmony_ci          "%b = OpVariable %_ptr_Function_v4float Function",
387fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
388fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
389fd4e5da5Sopenharmony_ci         "%24 = OpLoad %v4float %Basecolor",
390fd4e5da5Sopenharmony_ci               "OpStore %b %24",
391fd4e5da5Sopenharmony_ci         "%25 = OpLoad %v4float %b",
392fd4e5da5Sopenharmony_ci               "OpStore %param %25",
393fd4e5da5Sopenharmony_ci         "%40 = OpAccessChain %_ptr_Function_float %param %uint_0",
394fd4e5da5Sopenharmony_ci         "%41 = OpLoad %float %40",
395fd4e5da5Sopenharmony_ci         "%42 = OpAccessChain %_ptr_Function_float %param %uint_1",
396fd4e5da5Sopenharmony_ci         "%43 = OpLoad %float %42",
397fd4e5da5Sopenharmony_ci         "%44 = OpFAdd %float %41 %43",
398fd4e5da5Sopenharmony_ci         "%45 = OpAccessChain %_ptr_Function_float %param %uint_2",
399fd4e5da5Sopenharmony_ci               "OpStore %45 %44",
400fd4e5da5Sopenharmony_ci         "%27 = OpLoad %v4float %param",
401fd4e5da5Sopenharmony_ci               "OpStore %b %27",
402fd4e5da5Sopenharmony_ci         "%28 = OpAccessChain %_ptr_Function_float %b %uint_2",
403fd4e5da5Sopenharmony_ci         "%29 = OpLoad %float %28",
404fd4e5da5Sopenharmony_ci         "%30 = OpCompositeConstruct %v4float %29 %29 %29 %29",
405fd4e5da5Sopenharmony_ci               "OpStore %color %30",
406fd4e5da5Sopenharmony_ci         "%31 = OpLoad %v4float %color",
407fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %31",
408fd4e5da5Sopenharmony_ci               "OpReturn",
409fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
410fd4e5da5Sopenharmony_ci      // clang-format on
411fd4e5da5Sopenharmony_ci  };
412fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
413fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
414fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
415fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
416fd4e5da5Sopenharmony_ci}
417fd4e5da5Sopenharmony_ci
418fd4e5da5Sopenharmony_ciTEST_F(InlineTest, BranchInCallee) {
419fd4e5da5Sopenharmony_ci  // #version 140
420fd4e5da5Sopenharmony_ci  //
421fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
422fd4e5da5Sopenharmony_ci  //
423fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
424fd4e5da5Sopenharmony_ci  // {
425fd4e5da5Sopenharmony_ci  //     float r = bar.x;
426fd4e5da5Sopenharmony_ci  //     if (r < 0.0)
427fd4e5da5Sopenharmony_ci  //         r = -r;
428fd4e5da5Sopenharmony_ci  //     return r;
429fd4e5da5Sopenharmony_ci  // }
430fd4e5da5Sopenharmony_ci  //
431fd4e5da5Sopenharmony_ci  // void main()
432fd4e5da5Sopenharmony_ci  // {
433fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
434fd4e5da5Sopenharmony_ci  //
435fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
436fd4e5da5Sopenharmony_ci  // }
437fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
438fd4e5da5Sopenharmony_ci      // clang-format off
439fd4e5da5Sopenharmony_ci               "OpCapability Shader",
440fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
441fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
442fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor",
443fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
444fd4e5da5Sopenharmony_ci               "OpSource GLSL 140",
445fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
446fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
447fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
448fd4e5da5Sopenharmony_ci               "OpName %r \"r\"",
449fd4e5da5Sopenharmony_ci               "OpName %color \"color\"",
450fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
451fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
452fd4e5da5Sopenharmony_ci               "OpName %gl_FragColor \"gl_FragColor\"",
453fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
454fd4e5da5Sopenharmony_ci         "%11 = OpTypeFunction %void",
455fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
456fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
457fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
458fd4e5da5Sopenharmony_ci         "%15 = OpTypeFunction %float %_ptr_Function_v4float",
459fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
460fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
461fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
462fd4e5da5Sopenharmony_ci    "%float_0 = OpConstant %float 0",
463fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool",
464fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
465fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
466fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
467fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output",
468fd4e5da5Sopenharmony_ci      // clang-format on
469fd4e5da5Sopenharmony_ci  };
470fd4e5da5Sopenharmony_ci
471fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
472fd4e5da5Sopenharmony_ci      // clang-format off
473fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %15",
474fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
475fd4e5da5Sopenharmony_ci         "%28 = OpLabel",
476fd4e5da5Sopenharmony_ci          "%r = OpVariable %_ptr_Function_float Function",
477fd4e5da5Sopenharmony_ci         "%29 = OpAccessChain %_ptr_Function_float %bar %uint_0",
478fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %29",
479fd4e5da5Sopenharmony_ci               "OpStore %r %30",
480fd4e5da5Sopenharmony_ci         "%31 = OpLoad %float %r",
481fd4e5da5Sopenharmony_ci         "%32 = OpFOrdLessThan %bool %31 %float_0",
482fd4e5da5Sopenharmony_ci               "OpSelectionMerge %33 None",
483fd4e5da5Sopenharmony_ci               "OpBranchConditional %32 %34 %33",
484fd4e5da5Sopenharmony_ci         "%34 = OpLabel",
485fd4e5da5Sopenharmony_ci         "%35 = OpLoad %float %r",
486fd4e5da5Sopenharmony_ci         "%36 = OpFNegate %float %35",
487fd4e5da5Sopenharmony_ci               "OpStore %r %36",
488fd4e5da5Sopenharmony_ci               "OpBranch %33",
489fd4e5da5Sopenharmony_ci         "%33 = OpLabel",
490fd4e5da5Sopenharmony_ci         "%37 = OpLoad %float %r",
491fd4e5da5Sopenharmony_ci               "OpReturnValue %37",
492fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
493fd4e5da5Sopenharmony_ci      // clang-format on
494fd4e5da5Sopenharmony_ci  };
495fd4e5da5Sopenharmony_ci
496fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
497fd4e5da5Sopenharmony_ci      // clang-format off
498fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %11",
499fd4e5da5Sopenharmony_ci         "%23 = OpLabel",
500fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
501fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
502fd4e5da5Sopenharmony_ci         "%24 = OpLoad %v4float %BaseColor",
503fd4e5da5Sopenharmony_ci               "OpStore %param %24",
504fd4e5da5Sopenharmony_ci         "%25 = OpFunctionCall %float %foo_vf4_ %param",
505fd4e5da5Sopenharmony_ci         "%26 = OpCompositeConstruct %v4float %25 %25 %25 %25",
506fd4e5da5Sopenharmony_ci               "OpStore %color %26",
507fd4e5da5Sopenharmony_ci         "%27 = OpLoad %v4float %color",
508fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %27",
509fd4e5da5Sopenharmony_ci               "OpReturn",
510fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
511fd4e5da5Sopenharmony_ci      // clang-format on
512fd4e5da5Sopenharmony_ci  };
513fd4e5da5Sopenharmony_ci
514fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
515fd4e5da5Sopenharmony_ci      // clang-format off
516fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %11",
517fd4e5da5Sopenharmony_ci         "%23 = OpLabel",
518fd4e5da5Sopenharmony_ci         "%38 = OpVariable %_ptr_Function_float Function",
519fd4e5da5Sopenharmony_ci         "%39 = OpVariable %_ptr_Function_float Function",
520fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
521fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
522fd4e5da5Sopenharmony_ci         "%24 = OpLoad %v4float %BaseColor",
523fd4e5da5Sopenharmony_ci               "OpStore %param %24",
524fd4e5da5Sopenharmony_ci         "%41 = OpAccessChain %_ptr_Function_float %param %uint_0",
525fd4e5da5Sopenharmony_ci         "%42 = OpLoad %float %41",
526fd4e5da5Sopenharmony_ci               "OpStore %38 %42",
527fd4e5da5Sopenharmony_ci         "%43 = OpLoad %float %38",
528fd4e5da5Sopenharmony_ci         "%44 = OpFOrdLessThan %bool %43 %float_0",
529fd4e5da5Sopenharmony_ci               "OpSelectionMerge %48 None",
530fd4e5da5Sopenharmony_ci               "OpBranchConditional %44 %45 %48",
531fd4e5da5Sopenharmony_ci         "%45 = OpLabel",
532fd4e5da5Sopenharmony_ci         "%46 = OpLoad %float %38",
533fd4e5da5Sopenharmony_ci         "%47 = OpFNegate %float %46",
534fd4e5da5Sopenharmony_ci               "OpStore %38 %47",
535fd4e5da5Sopenharmony_ci               "OpBranch %48",
536fd4e5da5Sopenharmony_ci         "%48 = OpLabel",
537fd4e5da5Sopenharmony_ci         "%49 = OpLoad %float %38",
538fd4e5da5Sopenharmony_ci               "OpStore %39 %49",
539fd4e5da5Sopenharmony_ci         "%25 = OpLoad %float %39",
540fd4e5da5Sopenharmony_ci         "%26 = OpCompositeConstruct %v4float %25 %25 %25 %25",
541fd4e5da5Sopenharmony_ci               "OpStore %color %26",
542fd4e5da5Sopenharmony_ci         "%27 = OpLoad %v4float %color",
543fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %27",
544fd4e5da5Sopenharmony_ci               "OpReturn",
545fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
546fd4e5da5Sopenharmony_ci      // clang-format on
547fd4e5da5Sopenharmony_ci  };
548fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
549fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
550fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
551fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
552fd4e5da5Sopenharmony_ci}
553fd4e5da5Sopenharmony_ci
554fd4e5da5Sopenharmony_ciTEST_F(InlineTest, PhiAfterCall) {
555fd4e5da5Sopenharmony_ci  // #version 140
556fd4e5da5Sopenharmony_ci  //
557fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
558fd4e5da5Sopenharmony_ci  //
559fd4e5da5Sopenharmony_ci  // float foo(float bar)
560fd4e5da5Sopenharmony_ci  // {
561fd4e5da5Sopenharmony_ci  //     float r = bar;
562fd4e5da5Sopenharmony_ci  //     if (r < 0.0)
563fd4e5da5Sopenharmony_ci  //         r = -r;
564fd4e5da5Sopenharmony_ci  //     return r;
565fd4e5da5Sopenharmony_ci  // }
566fd4e5da5Sopenharmony_ci  //
567fd4e5da5Sopenharmony_ci  // void main()
568fd4e5da5Sopenharmony_ci  // {
569fd4e5da5Sopenharmony_ci  //     vec4 color = BaseColor;
570fd4e5da5Sopenharmony_ci  //     if (foo(color.x) > 2.0 && foo(color.y) > 2.0)
571fd4e5da5Sopenharmony_ci  //         color = vec4(0.0);
572fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
573fd4e5da5Sopenharmony_ci  // }
574fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
575fd4e5da5Sopenharmony_ci      // clang-format off
576fd4e5da5Sopenharmony_ci               "OpCapability Shader",
577fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
578fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
579fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %gl_FragColor",
580fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
581fd4e5da5Sopenharmony_ci               "OpSource GLSL 140",
582fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
583fd4e5da5Sopenharmony_ci               "OpName %foo_f1_ \"foo(f1;\"",
584fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
585fd4e5da5Sopenharmony_ci               "OpName %r \"r\"",
586fd4e5da5Sopenharmony_ci               "OpName %color \"color\"",
587fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
588fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
589fd4e5da5Sopenharmony_ci               "OpName %param_0 \"param\"",
590fd4e5da5Sopenharmony_ci               "OpName %gl_FragColor \"gl_FragColor\"",
591fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
592fd4e5da5Sopenharmony_ci         "%12 = OpTypeFunction %void",
593fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
594fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
595fd4e5da5Sopenharmony_ci         "%15 = OpTypeFunction %float %_ptr_Function_float",
596fd4e5da5Sopenharmony_ci    "%float_0 = OpConstant %float 0",
597fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool",
598fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
599fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
600fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
601fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
602fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
603fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
604fd4e5da5Sopenharmony_ci    "%float_2 = OpConstant %float 2",
605fd4e5da5Sopenharmony_ci     "%uint_1 = OpConstant %uint 1",
606fd4e5da5Sopenharmony_ci         "%25 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0",
607fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
608fd4e5da5Sopenharmony_ci"%gl_FragColor = OpVariable %_ptr_Output_v4float Output",
609fd4e5da5Sopenharmony_ci      // clang-format on
610fd4e5da5Sopenharmony_ci  };
611fd4e5da5Sopenharmony_ci
612fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
613fd4e5da5Sopenharmony_ci      // clang-format off
614fd4e5da5Sopenharmony_ci    "%foo_f1_ = OpFunction %float None %15",
615fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_float",
616fd4e5da5Sopenharmony_ci         "%43 = OpLabel",
617fd4e5da5Sopenharmony_ci          "%r = OpVariable %_ptr_Function_float Function",
618fd4e5da5Sopenharmony_ci         "%44 = OpLoad %float %bar",
619fd4e5da5Sopenharmony_ci               "OpStore %r %44",
620fd4e5da5Sopenharmony_ci         "%45 = OpLoad %float %r",
621fd4e5da5Sopenharmony_ci         "%46 = OpFOrdLessThan %bool %45 %float_0",
622fd4e5da5Sopenharmony_ci               "OpSelectionMerge %47 None",
623fd4e5da5Sopenharmony_ci               "OpBranchConditional %46 %48 %47",
624fd4e5da5Sopenharmony_ci         "%48 = OpLabel",
625fd4e5da5Sopenharmony_ci         "%49 = OpLoad %float %r",
626fd4e5da5Sopenharmony_ci         "%50 = OpFNegate %float %49",
627fd4e5da5Sopenharmony_ci               "OpStore %r %50",
628fd4e5da5Sopenharmony_ci               "OpBranch %47",
629fd4e5da5Sopenharmony_ci         "%47 = OpLabel",
630fd4e5da5Sopenharmony_ci         "%51 = OpLoad %float %r",
631fd4e5da5Sopenharmony_ci               "OpReturnValue %51",
632fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
633fd4e5da5Sopenharmony_ci      // clang-format on
634fd4e5da5Sopenharmony_ci  };
635fd4e5da5Sopenharmony_ci
636fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
637fd4e5da5Sopenharmony_ci      // clang-format off
638fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %12",
639fd4e5da5Sopenharmony_ci         "%27 = OpLabel",
640fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
641fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_float Function",
642fd4e5da5Sopenharmony_ci    "%param_0 = OpVariable %_ptr_Function_float Function",
643fd4e5da5Sopenharmony_ci         "%28 = OpLoad %v4float %BaseColor",
644fd4e5da5Sopenharmony_ci               "OpStore %color %28",
645fd4e5da5Sopenharmony_ci         "%29 = OpAccessChain %_ptr_Function_float %color %uint_0",
646fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %29",
647fd4e5da5Sopenharmony_ci               "OpStore %param %30",
648fd4e5da5Sopenharmony_ci         "%31 = OpFunctionCall %float %foo_f1_ %param",
649fd4e5da5Sopenharmony_ci         "%32 = OpFOrdGreaterThan %bool %31 %float_2",
650fd4e5da5Sopenharmony_ci               "OpSelectionMerge %33 None",
651fd4e5da5Sopenharmony_ci               "OpBranchConditional %32 %34 %33",
652fd4e5da5Sopenharmony_ci         "%34 = OpLabel",
653fd4e5da5Sopenharmony_ci         "%35 = OpAccessChain %_ptr_Function_float %color %uint_1",
654fd4e5da5Sopenharmony_ci         "%36 = OpLoad %float %35",
655fd4e5da5Sopenharmony_ci               "OpStore %param_0 %36",
656fd4e5da5Sopenharmony_ci         "%37 = OpFunctionCall %float %foo_f1_ %param_0",
657fd4e5da5Sopenharmony_ci         "%38 = OpFOrdGreaterThan %bool %37 %float_2",
658fd4e5da5Sopenharmony_ci               "OpBranch %33",
659fd4e5da5Sopenharmony_ci         "%33 = OpLabel",
660fd4e5da5Sopenharmony_ci         "%39 = OpPhi %bool %32 %27 %38 %34",
661fd4e5da5Sopenharmony_ci               "OpSelectionMerge %40 None",
662fd4e5da5Sopenharmony_ci               "OpBranchConditional %39 %41 %40",
663fd4e5da5Sopenharmony_ci         "%41 = OpLabel",
664fd4e5da5Sopenharmony_ci               "OpStore %color %25",
665fd4e5da5Sopenharmony_ci               "OpBranch %40",
666fd4e5da5Sopenharmony_ci         "%40 = OpLabel",
667fd4e5da5Sopenharmony_ci         "%42 = OpLoad %v4float %color",
668fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %42",
669fd4e5da5Sopenharmony_ci               "OpReturn",
670fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
671fd4e5da5Sopenharmony_ci      // clang-format on
672fd4e5da5Sopenharmony_ci  };
673fd4e5da5Sopenharmony_ci
674fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
675fd4e5da5Sopenharmony_ci      // clang-format off
676fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %12",
677fd4e5da5Sopenharmony_ci         "%27 = OpLabel",
678fd4e5da5Sopenharmony_ci         "%63 = OpVariable %_ptr_Function_float Function",
679fd4e5da5Sopenharmony_ci         "%64 = OpVariable %_ptr_Function_float Function",
680fd4e5da5Sopenharmony_ci         "%52 = OpVariable %_ptr_Function_float Function",
681fd4e5da5Sopenharmony_ci         "%53 = OpVariable %_ptr_Function_float Function",
682fd4e5da5Sopenharmony_ci      "%color = OpVariable %_ptr_Function_v4float Function",
683fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_float Function",
684fd4e5da5Sopenharmony_ci    "%param_0 = OpVariable %_ptr_Function_float Function",
685fd4e5da5Sopenharmony_ci         "%28 = OpLoad %v4float %BaseColor",
686fd4e5da5Sopenharmony_ci               "OpStore %color %28",
687fd4e5da5Sopenharmony_ci         "%29 = OpAccessChain %_ptr_Function_float %color %uint_0",
688fd4e5da5Sopenharmony_ci         "%30 = OpLoad %float %29",
689fd4e5da5Sopenharmony_ci               "OpStore %param %30",
690fd4e5da5Sopenharmony_ci         "%55 = OpLoad %float %param",
691fd4e5da5Sopenharmony_ci               "OpStore %52 %55",
692fd4e5da5Sopenharmony_ci         "%56 = OpLoad %float %52",
693fd4e5da5Sopenharmony_ci         "%57 = OpFOrdLessThan %bool %56 %float_0",
694fd4e5da5Sopenharmony_ci               "OpSelectionMerge %61 None",
695fd4e5da5Sopenharmony_ci               "OpBranchConditional %57 %58 %61",
696fd4e5da5Sopenharmony_ci         "%58 = OpLabel",
697fd4e5da5Sopenharmony_ci         "%59 = OpLoad %float %52",
698fd4e5da5Sopenharmony_ci         "%60 = OpFNegate %float %59",
699fd4e5da5Sopenharmony_ci               "OpStore %52 %60",
700fd4e5da5Sopenharmony_ci               "OpBranch %61",
701fd4e5da5Sopenharmony_ci         "%61 = OpLabel",
702fd4e5da5Sopenharmony_ci         "%62 = OpLoad %float %52",
703fd4e5da5Sopenharmony_ci               "OpStore %53 %62",
704fd4e5da5Sopenharmony_ci         "%31 = OpLoad %float %53",
705fd4e5da5Sopenharmony_ci         "%32 = OpFOrdGreaterThan %bool %31 %float_2",
706fd4e5da5Sopenharmony_ci               "OpSelectionMerge %33 None",
707fd4e5da5Sopenharmony_ci               "OpBranchConditional %32 %34 %33",
708fd4e5da5Sopenharmony_ci         "%34 = OpLabel",
709fd4e5da5Sopenharmony_ci         "%35 = OpAccessChain %_ptr_Function_float %color %uint_1",
710fd4e5da5Sopenharmony_ci         "%36 = OpLoad %float %35",
711fd4e5da5Sopenharmony_ci               "OpStore %param_0 %36",
712fd4e5da5Sopenharmony_ci         "%66 = OpLoad %float %param_0",
713fd4e5da5Sopenharmony_ci               "OpStore %63 %66",
714fd4e5da5Sopenharmony_ci         "%67 = OpLoad %float %63",
715fd4e5da5Sopenharmony_ci         "%68 = OpFOrdLessThan %bool %67 %float_0",
716fd4e5da5Sopenharmony_ci               "OpSelectionMerge %72 None",
717fd4e5da5Sopenharmony_ci               "OpBranchConditional %68 %69 %72",
718fd4e5da5Sopenharmony_ci         "%69 = OpLabel",
719fd4e5da5Sopenharmony_ci         "%70 = OpLoad %float %63",
720fd4e5da5Sopenharmony_ci         "%71 = OpFNegate %float %70",
721fd4e5da5Sopenharmony_ci               "OpStore %63 %71",
722fd4e5da5Sopenharmony_ci               "OpBranch %72",
723fd4e5da5Sopenharmony_ci         "%72 = OpLabel",
724fd4e5da5Sopenharmony_ci         "%73 = OpLoad %float %63",
725fd4e5da5Sopenharmony_ci               "OpStore %64 %73",
726fd4e5da5Sopenharmony_ci         "%37 = OpLoad %float %64",
727fd4e5da5Sopenharmony_ci         "%38 = OpFOrdGreaterThan %bool %37 %float_2",
728fd4e5da5Sopenharmony_ci               "OpBranch %33",
729fd4e5da5Sopenharmony_ci         "%33 = OpLabel",
730fd4e5da5Sopenharmony_ci         "%39 = OpPhi %bool %32 %61 %38 %72",
731fd4e5da5Sopenharmony_ci               "OpSelectionMerge %40 None",
732fd4e5da5Sopenharmony_ci               "OpBranchConditional %39 %41 %40",
733fd4e5da5Sopenharmony_ci         "%41 = OpLabel",
734fd4e5da5Sopenharmony_ci               "OpStore %color %25",
735fd4e5da5Sopenharmony_ci               "OpBranch %40",
736fd4e5da5Sopenharmony_ci         "%40 = OpLabel",
737fd4e5da5Sopenharmony_ci         "%42 = OpLoad %v4float %color",
738fd4e5da5Sopenharmony_ci               "OpStore %gl_FragColor %42",
739fd4e5da5Sopenharmony_ci               "OpReturn",
740fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
741fd4e5da5Sopenharmony_ci      // clang-format on
742fd4e5da5Sopenharmony_ci  };
743fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
744fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
745fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
746fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
747fd4e5da5Sopenharmony_ci}
748fd4e5da5Sopenharmony_ci
749fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpSampledImageOutOfBlock) {
750fd4e5da5Sopenharmony_ci  // #version 450
751fd4e5da5Sopenharmony_ci  //
752fd4e5da5Sopenharmony_ci  // uniform texture2D t2D;
753fd4e5da5Sopenharmony_ci  // uniform sampler samp;
754fd4e5da5Sopenharmony_ci  // out vec4 FragColor;
755fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
756fd4e5da5Sopenharmony_ci  //
757fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
758fd4e5da5Sopenharmony_ci  // {
759fd4e5da5Sopenharmony_ci  //     float r = bar.x;
760fd4e5da5Sopenharmony_ci  //     if (r < 0.0)
761fd4e5da5Sopenharmony_ci  //         r = -r;
762fd4e5da5Sopenharmony_ci  //     return r;
763fd4e5da5Sopenharmony_ci  // }
764fd4e5da5Sopenharmony_ci  //
765fd4e5da5Sopenharmony_ci  // void main()
766fd4e5da5Sopenharmony_ci  // {
767fd4e5da5Sopenharmony_ci  //     vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0));
768fd4e5da5Sopenharmony_ci  //     vec4 color2 = vec4(foo(BaseColor));
769fd4e5da5Sopenharmony_ci  //     vec4 color3 = texture(sampler2D(t2D, samp), vec2(0.5));
770fd4e5da5Sopenharmony_ci  //     FragColor = (color1 + color2 + color3)/3;
771fd4e5da5Sopenharmony_ci  // }
772fd4e5da5Sopenharmony_ci  //
773fd4e5da5Sopenharmony_ci  // Note: the before SPIR-V will need to be edited to create a use of
774fd4e5da5Sopenharmony_ci  // the OpSampledImage across the function call.
775fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
776fd4e5da5Sopenharmony_ci      // clang-format off
777fd4e5da5Sopenharmony_ci               "OpCapability Shader",
778fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
779fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
780fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor",
781fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
782fd4e5da5Sopenharmony_ci               "OpSource GLSL 450",
783fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
784fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
785fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
786fd4e5da5Sopenharmony_ci               "OpName %r \"r\"",
787fd4e5da5Sopenharmony_ci               "OpName %color1 \"color1\"",
788fd4e5da5Sopenharmony_ci               "OpName %t2D \"t2D\"",
789fd4e5da5Sopenharmony_ci               "OpName %samp \"samp\"",
790fd4e5da5Sopenharmony_ci               "OpName %color2 \"color2\"",
791fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
792fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
793fd4e5da5Sopenharmony_ci               "OpName %color3 \"color3\"",
794fd4e5da5Sopenharmony_ci               "OpName %FragColor \"FragColor\"",
795fd4e5da5Sopenharmony_ci               "OpDecorate %t2D DescriptorSet 0",
796fd4e5da5Sopenharmony_ci               "OpDecorate %samp DescriptorSet 0",
797fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
798fd4e5da5Sopenharmony_ci         "%15 = OpTypeFunction %void",
799fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
800fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
801fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
802fd4e5da5Sopenharmony_ci         "%19 = OpTypeFunction %float %_ptr_Function_v4float",
803fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
804fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
805fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
806fd4e5da5Sopenharmony_ci    "%float_0 = OpConstant %float 0",
807fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool",
808fd4e5da5Sopenharmony_ci         "%25 = OpTypeImage %float 2D 0 0 0 1 Unknown",
809fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25",
810fd4e5da5Sopenharmony_ci        "%t2D = OpVariable %_ptr_UniformConstant_25 UniformConstant",
811fd4e5da5Sopenharmony_ci         "%27 = OpTypeSampler",
812fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_27 = OpTypePointer UniformConstant %27",
813fd4e5da5Sopenharmony_ci       "%samp = OpVariable %_ptr_UniformConstant_27 UniformConstant",
814fd4e5da5Sopenharmony_ci         "%29 = OpTypeSampledImage %25",
815fd4e5da5Sopenharmony_ci    "%v2float = OpTypeVector %float 2",
816fd4e5da5Sopenharmony_ci    "%float_1 = OpConstant %float 1",
817fd4e5da5Sopenharmony_ci         "%32 = OpConstantComposite %v2float %float_1 %float_1",
818fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
819fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
820fd4e5da5Sopenharmony_ci  "%float_0_5 = OpConstant %float 0.5",
821fd4e5da5Sopenharmony_ci         "%35 = OpConstantComposite %v2float %float_0_5 %float_0_5",
822fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
823fd4e5da5Sopenharmony_ci  "%FragColor = OpVariable %_ptr_Output_v4float Output",
824fd4e5da5Sopenharmony_ci    "%float_3 = OpConstant %float 3",
825fd4e5da5Sopenharmony_ci      // clang-format on
826fd4e5da5Sopenharmony_ci  };
827fd4e5da5Sopenharmony_ci
828fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
829fd4e5da5Sopenharmony_ci      // clang-format off
830fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %19",
831fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
832fd4e5da5Sopenharmony_ci         "%56 = OpLabel",
833fd4e5da5Sopenharmony_ci          "%r = OpVariable %_ptr_Function_float Function",
834fd4e5da5Sopenharmony_ci         "%57 = OpAccessChain %_ptr_Function_float %bar %uint_0",
835fd4e5da5Sopenharmony_ci         "%58 = OpLoad %float %57",
836fd4e5da5Sopenharmony_ci               "OpStore %r %58",
837fd4e5da5Sopenharmony_ci         "%59 = OpLoad %float %r",
838fd4e5da5Sopenharmony_ci         "%60 = OpFOrdLessThan %bool %59 %float_0",
839fd4e5da5Sopenharmony_ci               "OpSelectionMerge %61 None",
840fd4e5da5Sopenharmony_ci               "OpBranchConditional %60 %62 %61",
841fd4e5da5Sopenharmony_ci         "%62 = OpLabel",
842fd4e5da5Sopenharmony_ci         "%63 = OpLoad %float %r",
843fd4e5da5Sopenharmony_ci         "%64 = OpFNegate %float %63",
844fd4e5da5Sopenharmony_ci               "OpStore %r %64",
845fd4e5da5Sopenharmony_ci               "OpBranch %61",
846fd4e5da5Sopenharmony_ci         "%61 = OpLabel",
847fd4e5da5Sopenharmony_ci         "%65 = OpLoad %float %r",
848fd4e5da5Sopenharmony_ci               "OpReturnValue %65",
849fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
850fd4e5da5Sopenharmony_ci      // clang-format on
851fd4e5da5Sopenharmony_ci  };
852fd4e5da5Sopenharmony_ci
853fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
854fd4e5da5Sopenharmony_ci      // clang-format off
855fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %15",
856fd4e5da5Sopenharmony_ci         "%38 = OpLabel",
857fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
858fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
859fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
860fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
861fd4e5da5Sopenharmony_ci         "%39 = OpLoad %25 %t2D",
862fd4e5da5Sopenharmony_ci         "%40 = OpLoad %27 %samp",
863fd4e5da5Sopenharmony_ci         "%41 = OpSampledImage %29 %39 %40",
864fd4e5da5Sopenharmony_ci         "%42 = OpImageSampleImplicitLod %v4float %41 %32",
865fd4e5da5Sopenharmony_ci               "OpStore %color1 %42",
866fd4e5da5Sopenharmony_ci         "%43 = OpLoad %v4float %BaseColor",
867fd4e5da5Sopenharmony_ci               "OpStore %param %43",
868fd4e5da5Sopenharmony_ci         "%44 = OpFunctionCall %float %foo_vf4_ %param",
869fd4e5da5Sopenharmony_ci         "%45 = OpCompositeConstruct %v4float %44 %44 %44 %44",
870fd4e5da5Sopenharmony_ci               "OpStore %color2 %45",
871fd4e5da5Sopenharmony_ci         "%46 = OpLoad %25 %t2D",
872fd4e5da5Sopenharmony_ci         "%47 = OpLoad %27 %samp",
873fd4e5da5Sopenharmony_ci         "%48 = OpImageSampleImplicitLod %v4float %41 %35",
874fd4e5da5Sopenharmony_ci               "OpStore %color3 %48",
875fd4e5da5Sopenharmony_ci         "%49 = OpLoad %v4float %color1",
876fd4e5da5Sopenharmony_ci         "%50 = OpLoad %v4float %color2",
877fd4e5da5Sopenharmony_ci         "%51 = OpFAdd %v4float %49 %50",
878fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color3",
879fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
880fd4e5da5Sopenharmony_ci         "%54 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
881fd4e5da5Sopenharmony_ci         "%55 = OpFDiv %v4float %53 %54",
882fd4e5da5Sopenharmony_ci               "OpStore %FragColor %55",
883fd4e5da5Sopenharmony_ci               "OpReturn",
884fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
885fd4e5da5Sopenharmony_ci      // clang-format on
886fd4e5da5Sopenharmony_ci  };
887fd4e5da5Sopenharmony_ci
888fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
889fd4e5da5Sopenharmony_ci      // clang-format off
890fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %15",
891fd4e5da5Sopenharmony_ci         "%38 = OpLabel",
892fd4e5da5Sopenharmony_ci         "%66 = OpVariable %_ptr_Function_float Function",
893fd4e5da5Sopenharmony_ci         "%67 = OpVariable %_ptr_Function_float Function",
894fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
895fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
896fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
897fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
898fd4e5da5Sopenharmony_ci         "%39 = OpLoad %25 %t2D",
899fd4e5da5Sopenharmony_ci         "%40 = OpLoad %27 %samp",
900fd4e5da5Sopenharmony_ci         "%41 = OpSampledImage %29 %39 %40",
901fd4e5da5Sopenharmony_ci         "%42 = OpImageSampleImplicitLod %v4float %41 %32",
902fd4e5da5Sopenharmony_ci               "OpStore %color1 %42",
903fd4e5da5Sopenharmony_ci         "%43 = OpLoad %v4float %BaseColor",
904fd4e5da5Sopenharmony_ci               "OpStore %param %43",
905fd4e5da5Sopenharmony_ci         "%69 = OpAccessChain %_ptr_Function_float %param %uint_0",
906fd4e5da5Sopenharmony_ci         "%70 = OpLoad %float %69",
907fd4e5da5Sopenharmony_ci               "OpStore %66 %70",
908fd4e5da5Sopenharmony_ci         "%71 = OpLoad %float %66",
909fd4e5da5Sopenharmony_ci         "%72 = OpFOrdLessThan %bool %71 %float_0",
910fd4e5da5Sopenharmony_ci               "OpSelectionMerge %76 None",
911fd4e5da5Sopenharmony_ci               "OpBranchConditional %72 %73 %76",
912fd4e5da5Sopenharmony_ci         "%73 = OpLabel",
913fd4e5da5Sopenharmony_ci         "%74 = OpLoad %float %66",
914fd4e5da5Sopenharmony_ci         "%75 = OpFNegate %float %74",
915fd4e5da5Sopenharmony_ci               "OpStore %66 %75",
916fd4e5da5Sopenharmony_ci               "OpBranch %76",
917fd4e5da5Sopenharmony_ci         "%76 = OpLabel",
918fd4e5da5Sopenharmony_ci         "%77 = OpLoad %float %66",
919fd4e5da5Sopenharmony_ci               "OpStore %67 %77",
920fd4e5da5Sopenharmony_ci         "%44 = OpLoad %float %67",
921fd4e5da5Sopenharmony_ci         "%45 = OpCompositeConstruct %v4float %44 %44 %44 %44",
922fd4e5da5Sopenharmony_ci               "OpStore %color2 %45",
923fd4e5da5Sopenharmony_ci         "%46 = OpLoad %25 %t2D",
924fd4e5da5Sopenharmony_ci         "%47 = OpLoad %27 %samp",
925fd4e5da5Sopenharmony_ci         "%78 = OpSampledImage %29 %39 %40",
926fd4e5da5Sopenharmony_ci         "%48 = OpImageSampleImplicitLod %v4float %78 %35",
927fd4e5da5Sopenharmony_ci               "OpStore %color3 %48",
928fd4e5da5Sopenharmony_ci         "%49 = OpLoad %v4float %color1",
929fd4e5da5Sopenharmony_ci         "%50 = OpLoad %v4float %color2",
930fd4e5da5Sopenharmony_ci         "%51 = OpFAdd %v4float %49 %50",
931fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color3",
932fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
933fd4e5da5Sopenharmony_ci         "%54 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
934fd4e5da5Sopenharmony_ci         "%55 = OpFDiv %v4float %53 %54",
935fd4e5da5Sopenharmony_ci               "OpStore %FragColor %55",
936fd4e5da5Sopenharmony_ci               "OpReturn",
937fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
938fd4e5da5Sopenharmony_ci      // clang-format on
939fd4e5da5Sopenharmony_ci  };
940fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
941fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
942fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
943fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
944fd4e5da5Sopenharmony_ci}
945fd4e5da5Sopenharmony_ci
946fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpImageOutOfBlock) {
947fd4e5da5Sopenharmony_ci  // #version 450
948fd4e5da5Sopenharmony_ci  //
949fd4e5da5Sopenharmony_ci  // uniform texture2D t2D;
950fd4e5da5Sopenharmony_ci  // uniform sampler samp;
951fd4e5da5Sopenharmony_ci  // uniform sampler samp2;
952fd4e5da5Sopenharmony_ci  //
953fd4e5da5Sopenharmony_ci  // out vec4 FragColor;
954fd4e5da5Sopenharmony_ci  //
955fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
956fd4e5da5Sopenharmony_ci  //
957fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
958fd4e5da5Sopenharmony_ci  // {
959fd4e5da5Sopenharmony_ci  //     float r = bar.x;
960fd4e5da5Sopenharmony_ci  //     if (r < 0.0)
961fd4e5da5Sopenharmony_ci  //         r = -r;
962fd4e5da5Sopenharmony_ci  //     return r;
963fd4e5da5Sopenharmony_ci  // }
964fd4e5da5Sopenharmony_ci  //
965fd4e5da5Sopenharmony_ci  // void main()
966fd4e5da5Sopenharmony_ci  // {
967fd4e5da5Sopenharmony_ci  //     vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0));
968fd4e5da5Sopenharmony_ci  //     vec4 color2 = vec4(foo(BaseColor));
969fd4e5da5Sopenharmony_ci  //     vec4 color3 = texture(sampler2D(t2D, samp2), vec2(0.5));
970fd4e5da5Sopenharmony_ci  //     FragColor = (color1 + color2 + color3)/3;
971fd4e5da5Sopenharmony_ci  // }
972fd4e5da5Sopenharmony_ci  // Note: the before SPIR-V will need to be edited to create an OpImage
973fd4e5da5Sopenharmony_ci  // from the first OpSampledImage, place it before the call and use it
974fd4e5da5Sopenharmony_ci  // in the second OpSampledImage following the call.
975fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
976fd4e5da5Sopenharmony_ci      // clang-format off
977fd4e5da5Sopenharmony_ci               "OpCapability Shader",
978fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
979fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
980fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor",
981fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
982fd4e5da5Sopenharmony_ci               "OpSource GLSL 450",
983fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
984fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
985fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
986fd4e5da5Sopenharmony_ci               "OpName %r \"r\"",
987fd4e5da5Sopenharmony_ci               "OpName %color1 \"color1\"",
988fd4e5da5Sopenharmony_ci               "OpName %t2D \"t2D\"",
989fd4e5da5Sopenharmony_ci               "OpName %samp \"samp\"",
990fd4e5da5Sopenharmony_ci               "OpName %color2 \"color2\"",
991fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
992fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
993fd4e5da5Sopenharmony_ci               "OpName %color3 \"color3\"",
994fd4e5da5Sopenharmony_ci               "OpName %samp2 \"samp2\"",
995fd4e5da5Sopenharmony_ci               "OpName %FragColor \"FragColor\"",
996fd4e5da5Sopenharmony_ci               "OpDecorate %t2D DescriptorSet 0",
997fd4e5da5Sopenharmony_ci               "OpDecorate %samp DescriptorSet 0",
998fd4e5da5Sopenharmony_ci               "OpDecorate %samp2 DescriptorSet 0",
999fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
1000fd4e5da5Sopenharmony_ci         "%16 = OpTypeFunction %void",
1001fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
1002fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
1003fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
1004fd4e5da5Sopenharmony_ci         "%20 = OpTypeFunction %float %_ptr_Function_v4float",
1005fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
1006fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
1007fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
1008fd4e5da5Sopenharmony_ci    "%float_0 = OpConstant %float 0",
1009fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool",
1010fd4e5da5Sopenharmony_ci         "%26 = OpTypeImage %float 2D 0 0 0 1 Unknown",
1011fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_26 = OpTypePointer UniformConstant %26",
1012fd4e5da5Sopenharmony_ci        "%t2D = OpVariable %_ptr_UniformConstant_26 UniformConstant",
1013fd4e5da5Sopenharmony_ci         "%28 = OpTypeSampler",
1014fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_28 = OpTypePointer UniformConstant %28",
1015fd4e5da5Sopenharmony_ci       "%samp = OpVariable %_ptr_UniformConstant_28 UniformConstant",
1016fd4e5da5Sopenharmony_ci         "%30 = OpTypeSampledImage %26",
1017fd4e5da5Sopenharmony_ci    "%v2float = OpTypeVector %float 2",
1018fd4e5da5Sopenharmony_ci    "%float_1 = OpConstant %float 1",
1019fd4e5da5Sopenharmony_ci         "%33 = OpConstantComposite %v2float %float_1 %float_1",
1020fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
1021fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
1022fd4e5da5Sopenharmony_ci      "%samp2 = OpVariable %_ptr_UniformConstant_28 UniformConstant",
1023fd4e5da5Sopenharmony_ci  "%float_0_5 = OpConstant %float 0.5",
1024fd4e5da5Sopenharmony_ci         "%36 = OpConstantComposite %v2float %float_0_5 %float_0_5",
1025fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
1026fd4e5da5Sopenharmony_ci  "%FragColor = OpVariable %_ptr_Output_v4float Output",
1027fd4e5da5Sopenharmony_ci    "%float_3 = OpConstant %float 3",
1028fd4e5da5Sopenharmony_ci      // clang-format on
1029fd4e5da5Sopenharmony_ci  };
1030fd4e5da5Sopenharmony_ci
1031fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
1032fd4e5da5Sopenharmony_ci      // clang-format off
1033fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %20",
1034fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
1035fd4e5da5Sopenharmony_ci         "%58 = OpLabel",
1036fd4e5da5Sopenharmony_ci          "%r = OpVariable %_ptr_Function_float Function",
1037fd4e5da5Sopenharmony_ci         "%59 = OpAccessChain %_ptr_Function_float %bar %uint_0",
1038fd4e5da5Sopenharmony_ci         "%60 = OpLoad %float %59",
1039fd4e5da5Sopenharmony_ci               "OpStore %r %60",
1040fd4e5da5Sopenharmony_ci         "%61 = OpLoad %float %r",
1041fd4e5da5Sopenharmony_ci         "%62 = OpFOrdLessThan %bool %61 %float_0",
1042fd4e5da5Sopenharmony_ci               "OpSelectionMerge %63 None",
1043fd4e5da5Sopenharmony_ci               "OpBranchConditional %62 %64 %63",
1044fd4e5da5Sopenharmony_ci         "%64 = OpLabel",
1045fd4e5da5Sopenharmony_ci         "%65 = OpLoad %float %r",
1046fd4e5da5Sopenharmony_ci         "%66 = OpFNegate %float %65",
1047fd4e5da5Sopenharmony_ci               "OpStore %r %66",
1048fd4e5da5Sopenharmony_ci               "OpBranch %63",
1049fd4e5da5Sopenharmony_ci         "%63 = OpLabel",
1050fd4e5da5Sopenharmony_ci         "%67 = OpLoad %float %r",
1051fd4e5da5Sopenharmony_ci               "OpReturnValue %67",
1052fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1053fd4e5da5Sopenharmony_ci      // clang-format on
1054fd4e5da5Sopenharmony_ci  };
1055fd4e5da5Sopenharmony_ci
1056fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
1057fd4e5da5Sopenharmony_ci      // clang-format off
1058fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %16",
1059fd4e5da5Sopenharmony_ci         "%39 = OpLabel",
1060fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
1061fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
1062fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
1063fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
1064fd4e5da5Sopenharmony_ci         "%40 = OpLoad %26 %t2D",
1065fd4e5da5Sopenharmony_ci         "%41 = OpLoad %28 %samp",
1066fd4e5da5Sopenharmony_ci         "%42 = OpSampledImage %30 %40 %41",
1067fd4e5da5Sopenharmony_ci         "%43 = OpImageSampleImplicitLod %v4float %42 %33",
1068fd4e5da5Sopenharmony_ci         "%44 = OpImage %26 %42",
1069fd4e5da5Sopenharmony_ci         "%45 = OpLoad %28 %samp2",
1070fd4e5da5Sopenharmony_ci               "OpStore %color1 %43",
1071fd4e5da5Sopenharmony_ci         "%46 = OpLoad %v4float %BaseColor",
1072fd4e5da5Sopenharmony_ci               "OpStore %param %46",
1073fd4e5da5Sopenharmony_ci         "%47 = OpFunctionCall %float %foo_vf4_ %param",
1074fd4e5da5Sopenharmony_ci         "%48 = OpCompositeConstruct %v4float %47 %47 %47 %47",
1075fd4e5da5Sopenharmony_ci               "OpStore %color2 %48",
1076fd4e5da5Sopenharmony_ci         "%49 = OpSampledImage %30 %44 %45",
1077fd4e5da5Sopenharmony_ci         "%50 = OpImageSampleImplicitLod %v4float %49 %36",
1078fd4e5da5Sopenharmony_ci               "OpStore %color3 %50",
1079fd4e5da5Sopenharmony_ci         "%51 = OpLoad %v4float %color1",
1080fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color2",
1081fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
1082fd4e5da5Sopenharmony_ci         "%54 = OpLoad %v4float %color3",
1083fd4e5da5Sopenharmony_ci         "%55 = OpFAdd %v4float %53 %54",
1084fd4e5da5Sopenharmony_ci         "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
1085fd4e5da5Sopenharmony_ci         "%57 = OpFDiv %v4float %55 %56",
1086fd4e5da5Sopenharmony_ci               "OpStore %FragColor %57",
1087fd4e5da5Sopenharmony_ci               "OpReturn",
1088fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1089fd4e5da5Sopenharmony_ci      // clang-format on
1090fd4e5da5Sopenharmony_ci  };
1091fd4e5da5Sopenharmony_ci
1092fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
1093fd4e5da5Sopenharmony_ci      // clang-format off
1094fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %16",
1095fd4e5da5Sopenharmony_ci         "%39 = OpLabel",
1096fd4e5da5Sopenharmony_ci         "%68 = OpVariable %_ptr_Function_float Function",
1097fd4e5da5Sopenharmony_ci         "%69 = OpVariable %_ptr_Function_float Function",
1098fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
1099fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
1100fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
1101fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
1102fd4e5da5Sopenharmony_ci         "%40 = OpLoad %26 %t2D",
1103fd4e5da5Sopenharmony_ci         "%41 = OpLoad %28 %samp",
1104fd4e5da5Sopenharmony_ci         "%42 = OpSampledImage %30 %40 %41",
1105fd4e5da5Sopenharmony_ci         "%43 = OpImageSampleImplicitLod %v4float %42 %33",
1106fd4e5da5Sopenharmony_ci         "%44 = OpImage %26 %42",
1107fd4e5da5Sopenharmony_ci         "%45 = OpLoad %28 %samp2",
1108fd4e5da5Sopenharmony_ci               "OpStore %color1 %43",
1109fd4e5da5Sopenharmony_ci         "%46 = OpLoad %v4float %BaseColor",
1110fd4e5da5Sopenharmony_ci               "OpStore %param %46",
1111fd4e5da5Sopenharmony_ci         "%71 = OpAccessChain %_ptr_Function_float %param %uint_0",
1112fd4e5da5Sopenharmony_ci         "%72 = OpLoad %float %71",
1113fd4e5da5Sopenharmony_ci               "OpStore %68 %72",
1114fd4e5da5Sopenharmony_ci         "%73 = OpLoad %float %68",
1115fd4e5da5Sopenharmony_ci         "%74 = OpFOrdLessThan %bool %73 %float_0",
1116fd4e5da5Sopenharmony_ci               "OpSelectionMerge %78 None",
1117fd4e5da5Sopenharmony_ci               "OpBranchConditional %74 %75 %78",
1118fd4e5da5Sopenharmony_ci         "%75 = OpLabel",
1119fd4e5da5Sopenharmony_ci         "%76 = OpLoad %float %68",
1120fd4e5da5Sopenharmony_ci         "%77 = OpFNegate %float %76",
1121fd4e5da5Sopenharmony_ci               "OpStore %68 %77",
1122fd4e5da5Sopenharmony_ci               "OpBranch %78",
1123fd4e5da5Sopenharmony_ci         "%78 = OpLabel",
1124fd4e5da5Sopenharmony_ci         "%79 = OpLoad %float %68",
1125fd4e5da5Sopenharmony_ci               "OpStore %69 %79",
1126fd4e5da5Sopenharmony_ci         "%47 = OpLoad %float %69",
1127fd4e5da5Sopenharmony_ci         "%48 = OpCompositeConstruct %v4float %47 %47 %47 %47",
1128fd4e5da5Sopenharmony_ci               "OpStore %color2 %48",
1129fd4e5da5Sopenharmony_ci         "%80 = OpSampledImage %30 %40 %41",
1130fd4e5da5Sopenharmony_ci         "%81 = OpImage %26 %80",
1131fd4e5da5Sopenharmony_ci         "%49 = OpSampledImage %30 %81 %45",
1132fd4e5da5Sopenharmony_ci         "%50 = OpImageSampleImplicitLod %v4float %49 %36",
1133fd4e5da5Sopenharmony_ci               "OpStore %color3 %50",
1134fd4e5da5Sopenharmony_ci         "%51 = OpLoad %v4float %color1",
1135fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color2",
1136fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
1137fd4e5da5Sopenharmony_ci         "%54 = OpLoad %v4float %color3",
1138fd4e5da5Sopenharmony_ci         "%55 = OpFAdd %v4float %53 %54",
1139fd4e5da5Sopenharmony_ci         "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
1140fd4e5da5Sopenharmony_ci         "%57 = OpFDiv %v4float %55 %56",
1141fd4e5da5Sopenharmony_ci               "OpStore %FragColor %57",
1142fd4e5da5Sopenharmony_ci               "OpReturn",
1143fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1144fd4e5da5Sopenharmony_ci      // clang-format on
1145fd4e5da5Sopenharmony_ci  };
1146fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
1147fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
1148fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
1149fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
1150fd4e5da5Sopenharmony_ci}
1151fd4e5da5Sopenharmony_ci
1152fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpImageAndOpSampledImageOutOfBlock) {
1153fd4e5da5Sopenharmony_ci  // #version 450
1154fd4e5da5Sopenharmony_ci  //
1155fd4e5da5Sopenharmony_ci  // uniform texture2D t2D;
1156fd4e5da5Sopenharmony_ci  // uniform sampler samp;
1157fd4e5da5Sopenharmony_ci  // uniform sampler samp2;
1158fd4e5da5Sopenharmony_ci  //
1159fd4e5da5Sopenharmony_ci  // out vec4 FragColor;
1160fd4e5da5Sopenharmony_ci  //
1161fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
1162fd4e5da5Sopenharmony_ci  //
1163fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
1164fd4e5da5Sopenharmony_ci  // {
1165fd4e5da5Sopenharmony_ci  //     float r = bar.x;
1166fd4e5da5Sopenharmony_ci  //     if (r < 0.0)
1167fd4e5da5Sopenharmony_ci  //         r = -r;
1168fd4e5da5Sopenharmony_ci  //     return r;
1169fd4e5da5Sopenharmony_ci  // }
1170fd4e5da5Sopenharmony_ci  //
1171fd4e5da5Sopenharmony_ci  // void main()
1172fd4e5da5Sopenharmony_ci  // {
1173fd4e5da5Sopenharmony_ci  //     vec4 color1 = texture(sampler2D(t2D, samp), vec2(1.0));
1174fd4e5da5Sopenharmony_ci  //     vec4 color2 = vec4(foo(BaseColor));
1175fd4e5da5Sopenharmony_ci  //     vec4 color3 = texture(sampler2D(t2D, samp2), vec2(0.5));
1176fd4e5da5Sopenharmony_ci  //     FragColor = (color1 + color2 + color3)/3;
1177fd4e5da5Sopenharmony_ci  // }
1178fd4e5da5Sopenharmony_ci  // Note: the before SPIR-V will need to be edited to create an OpImage
1179fd4e5da5Sopenharmony_ci  // and subsequent OpSampledImage that is used across the function call.
1180fd4e5da5Sopenharmony_ci  const std::vector<const char*> predefs = {
1181fd4e5da5Sopenharmony_ci      // clang-format off
1182fd4e5da5Sopenharmony_ci               "OpCapability Shader",
1183fd4e5da5Sopenharmony_ci          "%1 = OpExtInstImport \"GLSL.std.450\"",
1184fd4e5da5Sopenharmony_ci               "OpMemoryModel Logical GLSL450",
1185fd4e5da5Sopenharmony_ci               "OpEntryPoint Fragment %main \"main\" %BaseColor %FragColor",
1186fd4e5da5Sopenharmony_ci               "OpExecutionMode %main OriginUpperLeft",
1187fd4e5da5Sopenharmony_ci               "OpSource GLSL 450",
1188fd4e5da5Sopenharmony_ci               "OpName %main \"main\"",
1189fd4e5da5Sopenharmony_ci               "OpName %foo_vf4_ \"foo(vf4;\"",
1190fd4e5da5Sopenharmony_ci               "OpName %bar \"bar\"",
1191fd4e5da5Sopenharmony_ci               "OpName %r \"r\"",
1192fd4e5da5Sopenharmony_ci               "OpName %color1 \"color1\"",
1193fd4e5da5Sopenharmony_ci               "OpName %t2D \"t2D\"",
1194fd4e5da5Sopenharmony_ci               "OpName %samp \"samp\"",
1195fd4e5da5Sopenharmony_ci               "OpName %color2 \"color2\"",
1196fd4e5da5Sopenharmony_ci               "OpName %BaseColor \"BaseColor\"",
1197fd4e5da5Sopenharmony_ci               "OpName %param \"param\"",
1198fd4e5da5Sopenharmony_ci               "OpName %color3 \"color3\"",
1199fd4e5da5Sopenharmony_ci               "OpName %samp2 \"samp2\"",
1200fd4e5da5Sopenharmony_ci               "OpName %FragColor \"FragColor\"",
1201fd4e5da5Sopenharmony_ci               "OpDecorate %t2D DescriptorSet 0",
1202fd4e5da5Sopenharmony_ci               "OpDecorate %samp DescriptorSet 0",
1203fd4e5da5Sopenharmony_ci               "OpDecorate %samp2 DescriptorSet 0",
1204fd4e5da5Sopenharmony_ci       "%void = OpTypeVoid",
1205fd4e5da5Sopenharmony_ci         "%16 = OpTypeFunction %void",
1206fd4e5da5Sopenharmony_ci      "%float = OpTypeFloat 32",
1207fd4e5da5Sopenharmony_ci    "%v4float = OpTypeVector %float 4",
1208fd4e5da5Sopenharmony_ci"%_ptr_Function_v4float = OpTypePointer Function %v4float",
1209fd4e5da5Sopenharmony_ci         "%20 = OpTypeFunction %float %_ptr_Function_v4float",
1210fd4e5da5Sopenharmony_ci"%_ptr_Function_float = OpTypePointer Function %float",
1211fd4e5da5Sopenharmony_ci       "%uint = OpTypeInt 32 0",
1212fd4e5da5Sopenharmony_ci     "%uint_0 = OpConstant %uint 0",
1213fd4e5da5Sopenharmony_ci    "%float_0 = OpConstant %float 0",
1214fd4e5da5Sopenharmony_ci       "%bool = OpTypeBool",
1215fd4e5da5Sopenharmony_ci         "%26 = OpTypeImage %float 2D 0 0 0 1 Unknown",
1216fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_26 = OpTypePointer UniformConstant %26",
1217fd4e5da5Sopenharmony_ci        "%t2D = OpVariable %_ptr_UniformConstant_26 UniformConstant",
1218fd4e5da5Sopenharmony_ci         "%28 = OpTypeSampler",
1219fd4e5da5Sopenharmony_ci"%_ptr_UniformConstant_28 = OpTypePointer UniformConstant %28",
1220fd4e5da5Sopenharmony_ci       "%samp = OpVariable %_ptr_UniformConstant_28 UniformConstant",
1221fd4e5da5Sopenharmony_ci         "%30 = OpTypeSampledImage %26",
1222fd4e5da5Sopenharmony_ci    "%v2float = OpTypeVector %float 2",
1223fd4e5da5Sopenharmony_ci    "%float_1 = OpConstant %float 1",
1224fd4e5da5Sopenharmony_ci         "%33 = OpConstantComposite %v2float %float_1 %float_1",
1225fd4e5da5Sopenharmony_ci"%_ptr_Input_v4float = OpTypePointer Input %v4float",
1226fd4e5da5Sopenharmony_ci  "%BaseColor = OpVariable %_ptr_Input_v4float Input",
1227fd4e5da5Sopenharmony_ci      "%samp2 = OpVariable %_ptr_UniformConstant_28 UniformConstant",
1228fd4e5da5Sopenharmony_ci  "%float_0_5 = OpConstant %float 0.5",
1229fd4e5da5Sopenharmony_ci         "%36 = OpConstantComposite %v2float %float_0_5 %float_0_5",
1230fd4e5da5Sopenharmony_ci"%_ptr_Output_v4float = OpTypePointer Output %v4float",
1231fd4e5da5Sopenharmony_ci  "%FragColor = OpVariable %_ptr_Output_v4float Output",
1232fd4e5da5Sopenharmony_ci    "%float_3 = OpConstant %float 3",
1233fd4e5da5Sopenharmony_ci      // clang-format on
1234fd4e5da5Sopenharmony_ci  };
1235fd4e5da5Sopenharmony_ci
1236fd4e5da5Sopenharmony_ci  const std::vector<const char*> nonEntryFuncs = {
1237fd4e5da5Sopenharmony_ci      // clang-format off
1238fd4e5da5Sopenharmony_ci   "%foo_vf4_ = OpFunction %float None %20",
1239fd4e5da5Sopenharmony_ci        "%bar = OpFunctionParameter %_ptr_Function_v4float",
1240fd4e5da5Sopenharmony_ci         "%58 = OpLabel",
1241fd4e5da5Sopenharmony_ci          "%r = OpVariable %_ptr_Function_float Function",
1242fd4e5da5Sopenharmony_ci         "%59 = OpAccessChain %_ptr_Function_float %bar %uint_0",
1243fd4e5da5Sopenharmony_ci         "%60 = OpLoad %float %59",
1244fd4e5da5Sopenharmony_ci               "OpStore %r %60",
1245fd4e5da5Sopenharmony_ci         "%61 = OpLoad %float %r",
1246fd4e5da5Sopenharmony_ci         "%62 = OpFOrdLessThan %bool %61 %float_0",
1247fd4e5da5Sopenharmony_ci               "OpSelectionMerge %63 None",
1248fd4e5da5Sopenharmony_ci               "OpBranchConditional %62 %64 %63",
1249fd4e5da5Sopenharmony_ci         "%64 = OpLabel",
1250fd4e5da5Sopenharmony_ci         "%65 = OpLoad %float %r",
1251fd4e5da5Sopenharmony_ci         "%66 = OpFNegate %float %65",
1252fd4e5da5Sopenharmony_ci               "OpStore %r %66",
1253fd4e5da5Sopenharmony_ci               "OpBranch %63",
1254fd4e5da5Sopenharmony_ci         "%63 = OpLabel",
1255fd4e5da5Sopenharmony_ci         "%67 = OpLoad %float %r",
1256fd4e5da5Sopenharmony_ci               "OpReturnValue %67",
1257fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1258fd4e5da5Sopenharmony_ci      // clang-format on
1259fd4e5da5Sopenharmony_ci  };
1260fd4e5da5Sopenharmony_ci
1261fd4e5da5Sopenharmony_ci  const std::vector<const char*> before = {
1262fd4e5da5Sopenharmony_ci      // clang-format off
1263fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %16",
1264fd4e5da5Sopenharmony_ci         "%39 = OpLabel",
1265fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
1266fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
1267fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
1268fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
1269fd4e5da5Sopenharmony_ci         "%40 = OpLoad %26 %t2D",
1270fd4e5da5Sopenharmony_ci         "%41 = OpLoad %28 %samp",
1271fd4e5da5Sopenharmony_ci         "%42 = OpSampledImage %30 %40 %41",
1272fd4e5da5Sopenharmony_ci         "%43 = OpImageSampleImplicitLod %v4float %42 %33",
1273fd4e5da5Sopenharmony_ci         "%44 = OpImage %26 %42",
1274fd4e5da5Sopenharmony_ci         "%45 = OpLoad %28 %samp2",
1275fd4e5da5Sopenharmony_ci         "%46 = OpSampledImage %30 %44 %45",
1276fd4e5da5Sopenharmony_ci               "OpStore %color1 %43",
1277fd4e5da5Sopenharmony_ci         "%47 = OpLoad %v4float %BaseColor",
1278fd4e5da5Sopenharmony_ci               "OpStore %param %47",
1279fd4e5da5Sopenharmony_ci         "%48 = OpFunctionCall %float %foo_vf4_ %param",
1280fd4e5da5Sopenharmony_ci         "%49 = OpCompositeConstruct %v4float %48 %48 %48 %48",
1281fd4e5da5Sopenharmony_ci               "OpStore %color2 %49",
1282fd4e5da5Sopenharmony_ci         "%50 = OpImageSampleImplicitLod %v4float %46 %36",
1283fd4e5da5Sopenharmony_ci               "OpStore %color3 %50",
1284fd4e5da5Sopenharmony_ci         "%51 = OpLoad %v4float %color1",
1285fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color2",
1286fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
1287fd4e5da5Sopenharmony_ci         "%54 = OpLoad %v4float %color3",
1288fd4e5da5Sopenharmony_ci         "%55 = OpFAdd %v4float %53 %54",
1289fd4e5da5Sopenharmony_ci         "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
1290fd4e5da5Sopenharmony_ci         "%57 = OpFDiv %v4float %55 %56",
1291fd4e5da5Sopenharmony_ci               "OpStore %FragColor %57",
1292fd4e5da5Sopenharmony_ci               "OpReturn",
1293fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1294fd4e5da5Sopenharmony_ci      // clang-format on
1295fd4e5da5Sopenharmony_ci  };
1296fd4e5da5Sopenharmony_ci
1297fd4e5da5Sopenharmony_ci  const std::vector<const char*> after = {
1298fd4e5da5Sopenharmony_ci      // clang-format off
1299fd4e5da5Sopenharmony_ci       "%main = OpFunction %void None %16",
1300fd4e5da5Sopenharmony_ci         "%39 = OpLabel",
1301fd4e5da5Sopenharmony_ci         "%68 = OpVariable %_ptr_Function_float Function",
1302fd4e5da5Sopenharmony_ci         "%69 = OpVariable %_ptr_Function_float Function",
1303fd4e5da5Sopenharmony_ci     "%color1 = OpVariable %_ptr_Function_v4float Function",
1304fd4e5da5Sopenharmony_ci     "%color2 = OpVariable %_ptr_Function_v4float Function",
1305fd4e5da5Sopenharmony_ci      "%param = OpVariable %_ptr_Function_v4float Function",
1306fd4e5da5Sopenharmony_ci     "%color3 = OpVariable %_ptr_Function_v4float Function",
1307fd4e5da5Sopenharmony_ci         "%40 = OpLoad %26 %t2D",
1308fd4e5da5Sopenharmony_ci         "%41 = OpLoad %28 %samp",
1309fd4e5da5Sopenharmony_ci         "%42 = OpSampledImage %30 %40 %41",
1310fd4e5da5Sopenharmony_ci         "%43 = OpImageSampleImplicitLod %v4float %42 %33",
1311fd4e5da5Sopenharmony_ci         "%44 = OpImage %26 %42",
1312fd4e5da5Sopenharmony_ci         "%45 = OpLoad %28 %samp2",
1313fd4e5da5Sopenharmony_ci         "%46 = OpSampledImage %30 %44 %45",
1314fd4e5da5Sopenharmony_ci               "OpStore %color1 %43",
1315fd4e5da5Sopenharmony_ci         "%47 = OpLoad %v4float %BaseColor",
1316fd4e5da5Sopenharmony_ci               "OpStore %param %47",
1317fd4e5da5Sopenharmony_ci         "%71 = OpAccessChain %_ptr_Function_float %param %uint_0",
1318fd4e5da5Sopenharmony_ci         "%72 = OpLoad %float %71",
1319fd4e5da5Sopenharmony_ci               "OpStore %68 %72",
1320fd4e5da5Sopenharmony_ci         "%73 = OpLoad %float %68",
1321fd4e5da5Sopenharmony_ci         "%74 = OpFOrdLessThan %bool %73 %float_0",
1322fd4e5da5Sopenharmony_ci               "OpSelectionMerge %78 None",
1323fd4e5da5Sopenharmony_ci               "OpBranchConditional %74 %75 %78",
1324fd4e5da5Sopenharmony_ci         "%75 = OpLabel",
1325fd4e5da5Sopenharmony_ci         "%76 = OpLoad %float %68",
1326fd4e5da5Sopenharmony_ci         "%77 = OpFNegate %float %76",
1327fd4e5da5Sopenharmony_ci               "OpStore %68 %77",
1328fd4e5da5Sopenharmony_ci               "OpBranch %78",
1329fd4e5da5Sopenharmony_ci         "%78 = OpLabel",
1330fd4e5da5Sopenharmony_ci         "%79 = OpLoad %float %68",
1331fd4e5da5Sopenharmony_ci               "OpStore %69 %79",
1332fd4e5da5Sopenharmony_ci         "%48 = OpLoad %float %69",
1333fd4e5da5Sopenharmony_ci         "%49 = OpCompositeConstruct %v4float %48 %48 %48 %48",
1334fd4e5da5Sopenharmony_ci               "OpStore %color2 %49",
1335fd4e5da5Sopenharmony_ci         "%80 = OpSampledImage %30 %40 %41",
1336fd4e5da5Sopenharmony_ci         "%81 = OpImage %26 %80",
1337fd4e5da5Sopenharmony_ci         "%82 = OpSampledImage %30 %81 %45",
1338fd4e5da5Sopenharmony_ci         "%50 = OpImageSampleImplicitLod %v4float %82 %36",
1339fd4e5da5Sopenharmony_ci               "OpStore %color3 %50",
1340fd4e5da5Sopenharmony_ci         "%51 = OpLoad %v4float %color1",
1341fd4e5da5Sopenharmony_ci         "%52 = OpLoad %v4float %color2",
1342fd4e5da5Sopenharmony_ci         "%53 = OpFAdd %v4float %51 %52",
1343fd4e5da5Sopenharmony_ci         "%54 = OpLoad %v4float %color3",
1344fd4e5da5Sopenharmony_ci         "%55 = OpFAdd %v4float %53 %54",
1345fd4e5da5Sopenharmony_ci         "%56 = OpCompositeConstruct %v4float %float_3 %float_3 %float_3 %float_3",
1346fd4e5da5Sopenharmony_ci         "%57 = OpFDiv %v4float %55 %56",
1347fd4e5da5Sopenharmony_ci               "OpStore %FragColor %57",
1348fd4e5da5Sopenharmony_ci               "OpReturn",
1349fd4e5da5Sopenharmony_ci               "OpFunctionEnd",
1350fd4e5da5Sopenharmony_ci      // clang-format on
1351fd4e5da5Sopenharmony_ci  };
1352fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
1353fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, before), nonEntryFuncs)),
1354fd4e5da5Sopenharmony_ci      JoinAllInsts(Concat(Concat(predefs, after), nonEntryFuncs)),
1355fd4e5da5Sopenharmony_ci      /* skip_nop = */ false, /* do_validate = */ true);
1356fd4e5da5Sopenharmony_ci}
1357fd4e5da5Sopenharmony_ci
1358fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnInLoopIsNotInlined) {
1359fd4e5da5Sopenharmony_ci  // #version 140
1360fd4e5da5Sopenharmony_ci  //
1361fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
1362fd4e5da5Sopenharmony_ci  //
1363fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
1364fd4e5da5Sopenharmony_ci  // {
1365fd4e5da5Sopenharmony_ci  //     while (true) {
1366fd4e5da5Sopenharmony_ci  //         if (bar.x < 0.0)
1367fd4e5da5Sopenharmony_ci  //             return 0.0;
1368fd4e5da5Sopenharmony_ci  //         return bar.x;
1369fd4e5da5Sopenharmony_ci  //     }
1370fd4e5da5Sopenharmony_ci  // }
1371fd4e5da5Sopenharmony_ci  //
1372fd4e5da5Sopenharmony_ci  // void main()
1373fd4e5da5Sopenharmony_ci  // {
1374fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
1375fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
1376fd4e5da5Sopenharmony_ci  // }
1377fd4e5da5Sopenharmony_ci
1378fd4e5da5Sopenharmony_ci  const std::string assembly =
1379fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1380fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1381fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1382fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
1383fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1384fd4e5da5Sopenharmony_ciOpSource GLSL 140
1385fd4e5da5Sopenharmony_ciOpName %main "main"
1386fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;"
1387fd4e5da5Sopenharmony_ciOpName %bar "bar"
1388fd4e5da5Sopenharmony_ciOpName %color "color"
1389fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
1390fd4e5da5Sopenharmony_ciOpName %param "param"
1391fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
1392fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1393fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
1394fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1395fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1396fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1397fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float
1398fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1399fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1400fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1401fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1402fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
1403fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
1404fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1405fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
1406fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1407fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
1408fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10
1409fd4e5da5Sopenharmony_ci%23 = OpLabel
1410fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
1411fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
1412fd4e5da5Sopenharmony_ci%24 = OpLoad %v4float %BaseColor
1413fd4e5da5Sopenharmony_ciOpStore %param %24
1414fd4e5da5Sopenharmony_ci%25 = OpFunctionCall %float %foo_vf4_ %param
1415fd4e5da5Sopenharmony_ci%26 = OpCompositeConstruct %v4float %25 %25 %25 %25
1416fd4e5da5Sopenharmony_ciOpStore %color %26
1417fd4e5da5Sopenharmony_ci%27 = OpLoad %v4float %color
1418fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %27
1419fd4e5da5Sopenharmony_ciOpReturn
1420fd4e5da5Sopenharmony_ciOpFunctionEnd
1421fd4e5da5Sopenharmony_ci%foo_vf4_ = OpFunction %float None %14
1422fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float
1423fd4e5da5Sopenharmony_ci%28 = OpLabel
1424fd4e5da5Sopenharmony_ciOpBranch %29
1425fd4e5da5Sopenharmony_ci%29 = OpLabel
1426fd4e5da5Sopenharmony_ciOpLoopMerge %30 %31 None
1427fd4e5da5Sopenharmony_ciOpBranch %32
1428fd4e5da5Sopenharmony_ci%32 = OpLabel
1429fd4e5da5Sopenharmony_ciOpBranchConditional %true %33 %30
1430fd4e5da5Sopenharmony_ci%33 = OpLabel
1431fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %bar %uint_0
1432fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34
1433fd4e5da5Sopenharmony_ci%36 = OpFOrdLessThan %bool %35 %float_0
1434fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None
1435fd4e5da5Sopenharmony_ciOpBranchConditional %36 %38 %37
1436fd4e5da5Sopenharmony_ci%38 = OpLabel
1437fd4e5da5Sopenharmony_ciOpReturnValue %float_0
1438fd4e5da5Sopenharmony_ci%37 = OpLabel
1439fd4e5da5Sopenharmony_ci%39 = OpAccessChain %_ptr_Function_float %bar %uint_0
1440fd4e5da5Sopenharmony_ci%40 = OpLoad %float %39
1441fd4e5da5Sopenharmony_ciOpReturnValue %40
1442fd4e5da5Sopenharmony_ci%31 = OpLabel
1443fd4e5da5Sopenharmony_ciOpBranch %29
1444fd4e5da5Sopenharmony_ci%30 = OpLabel
1445fd4e5da5Sopenharmony_ci%41 = OpUndef %float
1446fd4e5da5Sopenharmony_ciOpReturnValue %41
1447fd4e5da5Sopenharmony_ciOpFunctionEnd
1448fd4e5da5Sopenharmony_ci)";
1449fd4e5da5Sopenharmony_ci
1450fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(assembly, assembly, false, true);
1451fd4e5da5Sopenharmony_ci}
1452fd4e5da5Sopenharmony_ci
1453fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ExternalFunctionIsNotInlined) {
1454fd4e5da5Sopenharmony_ci  // In particular, don't crash.
1455fd4e5da5Sopenharmony_ci  // See report https://github.com/KhronosGroup/SPIRV-Tools/issues/605
1456fd4e5da5Sopenharmony_ci  const std::string assembly =
1457fd4e5da5Sopenharmony_ci      R"(OpCapability Addresses
1458fd4e5da5Sopenharmony_ciOpCapability Kernel
1459fd4e5da5Sopenharmony_ciOpCapability Linkage
1460fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL
1461fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %1 "entry_pt"
1462fd4e5da5Sopenharmony_ciOpDecorate %2 LinkageAttributes "external" Import
1463fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1464fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
1465fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4
1466fd4e5da5Sopenharmony_ciOpFunctionEnd
1467fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %4
1468fd4e5da5Sopenharmony_ci%5 = OpLabel
1469fd4e5da5Sopenharmony_ci%6 = OpFunctionCall %void %2
1470fd4e5da5Sopenharmony_ciOpReturn
1471fd4e5da5Sopenharmony_ciOpFunctionEnd
1472fd4e5da5Sopenharmony_ci)";
1473fd4e5da5Sopenharmony_ci
1474fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(assembly, assembly, false, true);
1475fd4e5da5Sopenharmony_ci}
1476fd4e5da5Sopenharmony_ci
1477fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SingleBlockLoopCallsMultiBlockCallee) {
1478fd4e5da5Sopenharmony_ci  // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/787
1479fd4e5da5Sopenharmony_ci  //
1480fd4e5da5Sopenharmony_ci  // CFG structure is:
1481fd4e5da5Sopenharmony_ci  //    foo:
1482fd4e5da5Sopenharmony_ci  //       fooentry -> fooexit
1483fd4e5da5Sopenharmony_ci  //
1484fd4e5da5Sopenharmony_ci  //    main:
1485fd4e5da5Sopenharmony_ci  //       entry -> loop
1486fd4e5da5Sopenharmony_ci  //       loop -> loop, merge
1487fd4e5da5Sopenharmony_ci  //         loop calls foo()
1488fd4e5da5Sopenharmony_ci  //       merge
1489fd4e5da5Sopenharmony_ci  //
1490fd4e5da5Sopenharmony_ci  // Since the callee has multiple blocks, it will split the calling block
1491fd4e5da5Sopenharmony_ci  // into at least two, resulting in a new "back-half" block that contains
1492fd4e5da5Sopenharmony_ci  // the instructions after the inlined function call.  If the calling block
1493fd4e5da5Sopenharmony_ci  // has an OpLoopMerge that points back to the calling block itself, then
1494fd4e5da5Sopenharmony_ci  // the OpLoopMerge can't remain in the back-half block, but must be
1495fd4e5da5Sopenharmony_ci  // moved to the end of the original calling block, and it continue target
1496fd4e5da5Sopenharmony_ci  // operand updated to point to the back-half block.
1497fd4e5da5Sopenharmony_ci
1498fd4e5da5Sopenharmony_ci  const std::string predefs =
1499fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1500fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1501fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main"
1502fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120
1503fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1504fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1505fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1506fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void
1507fd4e5da5Sopenharmony_ci)";
1508fd4e5da5Sopenharmony_ci
1509fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
1510fd4e5da5Sopenharmony_ci      R"(%6 = OpFunction %void None %5
1511fd4e5da5Sopenharmony_ci%7 = OpLabel
1512fd4e5da5Sopenharmony_ciOpBranch %8
1513fd4e5da5Sopenharmony_ci%8 = OpLabel
1514fd4e5da5Sopenharmony_ciOpReturn
1515fd4e5da5Sopenharmony_ciOpFunctionEnd
1516fd4e5da5Sopenharmony_ci)";
1517fd4e5da5Sopenharmony_ci
1518fd4e5da5Sopenharmony_ci  const std::string before =
1519fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %5
1520fd4e5da5Sopenharmony_ci%9 = OpLabel
1521fd4e5da5Sopenharmony_ciOpBranch %10
1522fd4e5da5Sopenharmony_ci%10 = OpLabel
1523fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %void %6
1524fd4e5da5Sopenharmony_ciOpLoopMerge %12 %10 None
1525fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %12
1526fd4e5da5Sopenharmony_ci%12 = OpLabel
1527fd4e5da5Sopenharmony_ciOpReturn
1528fd4e5da5Sopenharmony_ciOpFunctionEnd
1529fd4e5da5Sopenharmony_ci)";
1530fd4e5da5Sopenharmony_ci
1531fd4e5da5Sopenharmony_ci  const std::string after =
1532fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %5
1533fd4e5da5Sopenharmony_ci%9 = OpLabel
1534fd4e5da5Sopenharmony_ciOpBranch %10
1535fd4e5da5Sopenharmony_ci%10 = OpLabel
1536fd4e5da5Sopenharmony_ciOpLoopMerge %12 %15 None
1537fd4e5da5Sopenharmony_ciOpBranch %14
1538fd4e5da5Sopenharmony_ci%14 = OpLabel
1539fd4e5da5Sopenharmony_ciOpBranch %15
1540fd4e5da5Sopenharmony_ci%15 = OpLabel
1541fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %12
1542fd4e5da5Sopenharmony_ci%12 = OpLabel
1543fd4e5da5Sopenharmony_ciOpReturn
1544fd4e5da5Sopenharmony_ciOpFunctionEnd
1545fd4e5da5Sopenharmony_ci)";
1546fd4e5da5Sopenharmony_ci
1547fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before,
1548fd4e5da5Sopenharmony_ci                                              predefs + nonEntryFuncs + after,
1549fd4e5da5Sopenharmony_ci                                              false, true);
1550fd4e5da5Sopenharmony_ci}
1551fd4e5da5Sopenharmony_ci
1552fd4e5da5Sopenharmony_ciTEST_F(InlineTest, MultiBlockLoopHeaderCallsMultiBlockCallee) {
1553fd4e5da5Sopenharmony_ci  // Like SingleBlockLoopCallsMultiBlockCallee but the loop has several
1554fd4e5da5Sopenharmony_ci  // blocks, but the function call still occurs in the loop header.
1555fd4e5da5Sopenharmony_ci  // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/800
1556fd4e5da5Sopenharmony_ci
1557fd4e5da5Sopenharmony_ci  const std::string predefs =
1558fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1559fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1560fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main"
1561fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120
1562fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1563fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1564fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1565fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
1566fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2
1567fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3
1568fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
1569fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5
1570fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1571fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
1572fd4e5da5Sopenharmony_ci)";
1573fd4e5da5Sopenharmony_ci
1574fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
1575fd4e5da5Sopenharmony_ci      R"(%12 = OpFunction %void None %11
1576fd4e5da5Sopenharmony_ci%13 = OpLabel
1577fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_1
1578fd4e5da5Sopenharmony_ciOpBranch %15
1579fd4e5da5Sopenharmony_ci%15 = OpLabel
1580fd4e5da5Sopenharmony_ci%16 = OpCopyObject %int %int_2
1581fd4e5da5Sopenharmony_ciOpReturn
1582fd4e5da5Sopenharmony_ciOpFunctionEnd
1583fd4e5da5Sopenharmony_ci)";
1584fd4e5da5Sopenharmony_ci
1585fd4e5da5Sopenharmony_ci  const std::string before =
1586fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %11
1587fd4e5da5Sopenharmony_ci%17 = OpLabel
1588fd4e5da5Sopenharmony_ciOpBranch %18
1589fd4e5da5Sopenharmony_ci%18 = OpLabel
1590fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3
1591fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %void %12
1592fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4
1593fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None
1594fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22
1595fd4e5da5Sopenharmony_ci%23 = OpLabel
1596fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5
1597fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22
1598fd4e5da5Sopenharmony_ci%22 = OpLabel
1599fd4e5da5Sopenharmony_ciOpReturn
1600fd4e5da5Sopenharmony_ciOpFunctionEnd
1601fd4e5da5Sopenharmony_ci)";
1602fd4e5da5Sopenharmony_ci
1603fd4e5da5Sopenharmony_ci  const std::string after =
1604fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %11
1605fd4e5da5Sopenharmony_ci%17 = OpLabel
1606fd4e5da5Sopenharmony_ciOpBranch %18
1607fd4e5da5Sopenharmony_ci%18 = OpLabel
1608fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3
1609fd4e5da5Sopenharmony_ci%26 = OpCopyObject %int %int_1
1610fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None
1611fd4e5da5Sopenharmony_ciOpBranch %27
1612fd4e5da5Sopenharmony_ci%27 = OpLabel
1613fd4e5da5Sopenharmony_ci%28 = OpCopyObject %int %int_2
1614fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4
1615fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22
1616fd4e5da5Sopenharmony_ci%23 = OpLabel
1617fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5
1618fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22
1619fd4e5da5Sopenharmony_ci%22 = OpLabel
1620fd4e5da5Sopenharmony_ciOpReturn
1621fd4e5da5Sopenharmony_ciOpFunctionEnd
1622fd4e5da5Sopenharmony_ci)";
1623fd4e5da5Sopenharmony_ci
1624fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before,
1625fd4e5da5Sopenharmony_ci                                              predefs + nonEntryFuncs + after,
1626fd4e5da5Sopenharmony_ci                                              false, true);
1627fd4e5da5Sopenharmony_ci}
1628fd4e5da5Sopenharmony_ci
1629fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SingleBlockLoopCallsMultiBlockCalleeHavingSelectionMerge) {
1630fd4e5da5Sopenharmony_ci  // This is similar to SingleBlockLoopCallsMultiBlockCallee except
1631fd4e5da5Sopenharmony_ci  // that calleee block also has a merge instruction in its first block.
1632fd4e5da5Sopenharmony_ci  // That merge instruction must be an OpSelectionMerge (because the entry
1633fd4e5da5Sopenharmony_ci  // block of a function can't be the header of a loop since the entry
1634fd4e5da5Sopenharmony_ci  // block can't be the target of a branch).
1635fd4e5da5Sopenharmony_ci  //
1636fd4e5da5Sopenharmony_ci  // In this case the OpLoopMerge can't be placed in the same block as
1637fd4e5da5Sopenharmony_ci  // the OpSelectionMerge, so inlining must create a new block to contain
1638fd4e5da5Sopenharmony_ci  // the callee contents.
1639fd4e5da5Sopenharmony_ci  //
1640fd4e5da5Sopenharmony_ci  // Additionally, we have two extra OpCopyObject instructions to prove that
1641fd4e5da5Sopenharmony_ci  // the OpLoopMerge is moved to the right location.
1642fd4e5da5Sopenharmony_ci  //
1643fd4e5da5Sopenharmony_ci  // Also ensure that OpPhis within the cloned callee code are valid.
1644fd4e5da5Sopenharmony_ci  // We need to test that the predecessor blocks are remapped correctly so that
1645fd4e5da5Sopenharmony_ci  // dominance rules are satisfied
1646fd4e5da5Sopenharmony_ci
1647fd4e5da5Sopenharmony_ci  const std::string predefs =
1648fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1649fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1650fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main"
1651fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120
1652fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1653fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1654fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool
1655fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1656fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void
1657fd4e5da5Sopenharmony_ci)";
1658fd4e5da5Sopenharmony_ci
1659fd4e5da5Sopenharmony_ci  // This callee has multiple blocks, and an OpPhi in the last block
1660fd4e5da5Sopenharmony_ci  // that references a value from the first block.  This tests that
1661fd4e5da5Sopenharmony_ci  // cloned block IDs are remapped appropriately.  The OpPhi dominance
1662fd4e5da5Sopenharmony_ci  // requires that the remapped %9 must be in a block that dominates
1663fd4e5da5Sopenharmony_ci  // the remapped %8.
1664fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
1665fd4e5da5Sopenharmony_ci      R"(%7 = OpFunction %void None %6
1666fd4e5da5Sopenharmony_ci%8 = OpLabel
1667fd4e5da5Sopenharmony_ci%9 = OpCopyObject %bool %true
1668fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None
1669fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %10
1670fd4e5da5Sopenharmony_ci%10 = OpLabel
1671fd4e5da5Sopenharmony_ci%11 = OpPhi %bool %9 %8
1672fd4e5da5Sopenharmony_ciOpReturn
1673fd4e5da5Sopenharmony_ciOpFunctionEnd
1674fd4e5da5Sopenharmony_ci)";
1675fd4e5da5Sopenharmony_ci
1676fd4e5da5Sopenharmony_ci  const std::string before =
1677fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %6
1678fd4e5da5Sopenharmony_ci%12 = OpLabel
1679fd4e5da5Sopenharmony_ciOpBranch %13
1680fd4e5da5Sopenharmony_ci%13 = OpLabel
1681fd4e5da5Sopenharmony_ci%14 = OpCopyObject %bool %false
1682fd4e5da5Sopenharmony_ci%15 = OpFunctionCall %void %7
1683fd4e5da5Sopenharmony_ciOpLoopMerge %16 %13 None
1684fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %16
1685fd4e5da5Sopenharmony_ci%16 = OpLabel
1686fd4e5da5Sopenharmony_ciOpReturn
1687fd4e5da5Sopenharmony_ciOpFunctionEnd
1688fd4e5da5Sopenharmony_ci)";
1689fd4e5da5Sopenharmony_ci
1690fd4e5da5Sopenharmony_ci  // Note the remapped Phi uses %17 as the parent instead
1691fd4e5da5Sopenharmony_ci  // of %13, demonstrating that the parent block has been remapped
1692fd4e5da5Sopenharmony_ci  // correctly.
1693fd4e5da5Sopenharmony_ci  const std::string after =
1694fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %6
1695fd4e5da5Sopenharmony_ci%12 = OpLabel
1696fd4e5da5Sopenharmony_ciOpBranch %13
1697fd4e5da5Sopenharmony_ci%13 = OpLabel
1698fd4e5da5Sopenharmony_ci%14 = OpCopyObject %bool %false
1699fd4e5da5Sopenharmony_ciOpLoopMerge %16 %22 None
1700fd4e5da5Sopenharmony_ciOpBranch %17
1701fd4e5da5Sopenharmony_ci%17 = OpLabel
1702fd4e5da5Sopenharmony_ci%19 = OpCopyObject %bool %true
1703fd4e5da5Sopenharmony_ciOpSelectionMerge %20 None
1704fd4e5da5Sopenharmony_ciOpBranchConditional %true %20 %20
1705fd4e5da5Sopenharmony_ci%20 = OpLabel
1706fd4e5da5Sopenharmony_ci%21 = OpPhi %bool %19 %17
1707fd4e5da5Sopenharmony_ciOpBranch %22
1708fd4e5da5Sopenharmony_ci%22 = OpLabel
1709fd4e5da5Sopenharmony_ciOpBranchConditional %true %13 %16
1710fd4e5da5Sopenharmony_ci%16 = OpLabel
1711fd4e5da5Sopenharmony_ciOpReturn
1712fd4e5da5Sopenharmony_ciOpFunctionEnd
1713fd4e5da5Sopenharmony_ci)";
1714fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before,
1715fd4e5da5Sopenharmony_ci                                              predefs + nonEntryFuncs + after,
1716fd4e5da5Sopenharmony_ci                                              false, true);
1717fd4e5da5Sopenharmony_ci}
1718fd4e5da5Sopenharmony_ci
1719fd4e5da5Sopenharmony_ciTEST_F(InlineTest,
1720fd4e5da5Sopenharmony_ci       MultiBlockLoopHeaderCallsFromToMultiBlockCalleeHavingSelectionMerge) {
1721fd4e5da5Sopenharmony_ci  // This is similar to SingleBlockLoopCallsMultiBlockCalleeHavingSelectionMerge
1722fd4e5da5Sopenharmony_ci  // but the call is in the header block of a multi block loop.
1723fd4e5da5Sopenharmony_ci
1724fd4e5da5Sopenharmony_ci  const std::string predefs =
1725fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1726fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1727fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %1 "main"
1728fd4e5da5Sopenharmony_ciOpSource OpenCL_C 120
1729fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1730fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1731fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1732fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
1733fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2
1734fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3
1735fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
1736fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5
1737fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1738fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
1739fd4e5da5Sopenharmony_ci)";
1740fd4e5da5Sopenharmony_ci
1741fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
1742fd4e5da5Sopenharmony_ci      R"(%12 = OpFunction %void None %11
1743fd4e5da5Sopenharmony_ci%13 = OpLabel
1744fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_1
1745fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None
1746fd4e5da5Sopenharmony_ciOpBranchConditional %true %15 %15
1747fd4e5da5Sopenharmony_ci%15 = OpLabel
1748fd4e5da5Sopenharmony_ci%16 = OpCopyObject %int %int_2
1749fd4e5da5Sopenharmony_ciOpReturn
1750fd4e5da5Sopenharmony_ciOpFunctionEnd
1751fd4e5da5Sopenharmony_ci)";
1752fd4e5da5Sopenharmony_ci
1753fd4e5da5Sopenharmony_ci  const std::string before =
1754fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %11
1755fd4e5da5Sopenharmony_ci%17 = OpLabel
1756fd4e5da5Sopenharmony_ciOpBranch %18
1757fd4e5da5Sopenharmony_ci%18 = OpLabel
1758fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3
1759fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %void %12
1760fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4
1761fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None
1762fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22
1763fd4e5da5Sopenharmony_ci%23 = OpLabel
1764fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5
1765fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22
1766fd4e5da5Sopenharmony_ci%22 = OpLabel
1767fd4e5da5Sopenharmony_ciOpReturn
1768fd4e5da5Sopenharmony_ciOpFunctionEnd
1769fd4e5da5Sopenharmony_ci)";
1770fd4e5da5Sopenharmony_ci
1771fd4e5da5Sopenharmony_ci  const std::string after =
1772fd4e5da5Sopenharmony_ci      R"(%1 = OpFunction %void None %11
1773fd4e5da5Sopenharmony_ci%17 = OpLabel
1774fd4e5da5Sopenharmony_ciOpBranch %18
1775fd4e5da5Sopenharmony_ci%18 = OpLabel
1776fd4e5da5Sopenharmony_ci%19 = OpCopyObject %int %int_3
1777fd4e5da5Sopenharmony_ciOpLoopMerge %22 %23 None
1778fd4e5da5Sopenharmony_ciOpBranch %25
1779fd4e5da5Sopenharmony_ci%25 = OpLabel
1780fd4e5da5Sopenharmony_ci%27 = OpCopyObject %int %int_1
1781fd4e5da5Sopenharmony_ciOpSelectionMerge %28 None
1782fd4e5da5Sopenharmony_ciOpBranchConditional %true %28 %28
1783fd4e5da5Sopenharmony_ci%28 = OpLabel
1784fd4e5da5Sopenharmony_ci%29 = OpCopyObject %int %int_2
1785fd4e5da5Sopenharmony_ci%21 = OpCopyObject %int %int_4
1786fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22
1787fd4e5da5Sopenharmony_ci%23 = OpLabel
1788fd4e5da5Sopenharmony_ci%24 = OpCopyObject %int %int_5
1789fd4e5da5Sopenharmony_ciOpBranchConditional %true %18 %22
1790fd4e5da5Sopenharmony_ci%22 = OpLabel
1791fd4e5da5Sopenharmony_ciOpReturn
1792fd4e5da5Sopenharmony_ciOpFunctionEnd
1793fd4e5da5Sopenharmony_ci)";
1794fd4e5da5Sopenharmony_ci
1795fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + nonEntryFuncs + before,
1796fd4e5da5Sopenharmony_ci                                              predefs + nonEntryFuncs + after,
1797fd4e5da5Sopenharmony_ci                                              false, true);
1798fd4e5da5Sopenharmony_ci}
1799fd4e5da5Sopenharmony_ci
1800fd4e5da5Sopenharmony_ciTEST_F(InlineTest, NonInlinableCalleeWithSingleReturn) {
1801fd4e5da5Sopenharmony_ci  // The case from https://github.com/KhronosGroup/SPIRV-Tools/issues/2018
1802fd4e5da5Sopenharmony_ci  //
1803fd4e5da5Sopenharmony_ci  // The callee has a single return, but cannot be inlined because the
1804fd4e5da5Sopenharmony_ci  // return is inside a loop.
1805fd4e5da5Sopenharmony_ci
1806fd4e5da5Sopenharmony_ci  const std::string predefs =
1807fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1808fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1809fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1810fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %_GLF_color
1811fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1812fd4e5da5Sopenharmony_ciOpSource ESSL 310
1813fd4e5da5Sopenharmony_ciOpName %main "main"
1814fd4e5da5Sopenharmony_ciOpName %f_ "f("
1815fd4e5da5Sopenharmony_ciOpName %i "i"
1816fd4e5da5Sopenharmony_ciOpName %_GLF_color "_GLF_color"
1817fd4e5da5Sopenharmony_ciOpDecorate %_GLF_color Location 0
1818fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1819fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
1820fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1821fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %float
1822fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
1823fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1824fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool
1825fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1826fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
1827fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1828fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
1829fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1830fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1831fd4e5da5Sopenharmony_ci%_GLF_color = OpVariable %_ptr_Output_v4float Output
1832fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
1833fd4e5da5Sopenharmony_ci%20 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
1834fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
1835fd4e5da5Sopenharmony_ci)";
1836fd4e5da5Sopenharmony_ci
1837fd4e5da5Sopenharmony_ci  const std::string caller =
1838fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
1839fd4e5da5Sopenharmony_ci%22 = OpLabel
1840fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function
1841fd4e5da5Sopenharmony_ciOpStore %i %int_0
1842fd4e5da5Sopenharmony_ciOpBranch %23
1843fd4e5da5Sopenharmony_ci%23 = OpLabel
1844fd4e5da5Sopenharmony_ciOpLoopMerge %24 %25 None
1845fd4e5da5Sopenharmony_ciOpBranch %26
1846fd4e5da5Sopenharmony_ci%26 = OpLabel
1847fd4e5da5Sopenharmony_ci%27 = OpLoad %int %i
1848fd4e5da5Sopenharmony_ci%28 = OpSLessThan %bool %27 %int_1
1849fd4e5da5Sopenharmony_ciOpBranchConditional %28 %29 %24
1850fd4e5da5Sopenharmony_ci%29 = OpLabel
1851fd4e5da5Sopenharmony_ciOpStore %_GLF_color %20
1852fd4e5da5Sopenharmony_ci%30 = OpFunctionCall %float %f_
1853fd4e5da5Sopenharmony_ciOpBranch %25
1854fd4e5da5Sopenharmony_ci%25 = OpLabel
1855fd4e5da5Sopenharmony_ci%31 = OpLoad %int %i
1856fd4e5da5Sopenharmony_ci%32 = OpIAdd %int %31 %int_1
1857fd4e5da5Sopenharmony_ciOpStore %i %32
1858fd4e5da5Sopenharmony_ciOpBranch %23
1859fd4e5da5Sopenharmony_ci%24 = OpLabel
1860fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21
1861fd4e5da5Sopenharmony_ciOpReturn
1862fd4e5da5Sopenharmony_ciOpFunctionEnd
1863fd4e5da5Sopenharmony_ci)";
1864fd4e5da5Sopenharmony_ci
1865fd4e5da5Sopenharmony_ci  const std::string callee =
1866fd4e5da5Sopenharmony_ci      R"(%f_ = OpFunction %float None %9
1867fd4e5da5Sopenharmony_ci%33 = OpLabel
1868fd4e5da5Sopenharmony_ciOpBranch %34
1869fd4e5da5Sopenharmony_ci%34 = OpLabel
1870fd4e5da5Sopenharmony_ciOpLoopMerge %35 %36 None
1871fd4e5da5Sopenharmony_ciOpBranch %37
1872fd4e5da5Sopenharmony_ci%37 = OpLabel
1873fd4e5da5Sopenharmony_ciOpReturnValue %float_1
1874fd4e5da5Sopenharmony_ci%36 = OpLabel
1875fd4e5da5Sopenharmony_ciOpBranch %34
1876fd4e5da5Sopenharmony_ci%35 = OpLabel
1877fd4e5da5Sopenharmony_ciOpUnreachable
1878fd4e5da5Sopenharmony_ciOpFunctionEnd
1879fd4e5da5Sopenharmony_ci)";
1880fd4e5da5Sopenharmony_ci
1881fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(
1882fd4e5da5Sopenharmony_ci      predefs + caller + callee, predefs + caller + callee, false, true);
1883fd4e5da5Sopenharmony_ci}
1884fd4e5da5Sopenharmony_ci
1885fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Decorated1) {
1886fd4e5da5Sopenharmony_ci  // Same test as Simple with the difference
1887fd4e5da5Sopenharmony_ci  // that OpFAdd in the outlined function is
1888fd4e5da5Sopenharmony_ci  // decorated with RelaxedPrecision
1889fd4e5da5Sopenharmony_ci  // Expected result is an equal decoration
1890fd4e5da5Sopenharmony_ci  // of the corresponding inlined instruction
1891fd4e5da5Sopenharmony_ci  //
1892fd4e5da5Sopenharmony_ci  // #version 140
1893fd4e5da5Sopenharmony_ci  //
1894fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
1895fd4e5da5Sopenharmony_ci  //
1896fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
1897fd4e5da5Sopenharmony_ci  // {
1898fd4e5da5Sopenharmony_ci  //     return bar.x + bar.y;
1899fd4e5da5Sopenharmony_ci  // }
1900fd4e5da5Sopenharmony_ci  //
1901fd4e5da5Sopenharmony_ci  // void main()
1902fd4e5da5Sopenharmony_ci  // {
1903fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
1904fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
1905fd4e5da5Sopenharmony_ci  // }
1906fd4e5da5Sopenharmony_ci
1907fd4e5da5Sopenharmony_ci  const std::string predefs =
1908fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1909fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1910fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1911fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
1912fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1913fd4e5da5Sopenharmony_ciOpSource GLSL 140
1914fd4e5da5Sopenharmony_ciOpName %main "main"
1915fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;"
1916fd4e5da5Sopenharmony_ciOpName %bar "bar"
1917fd4e5da5Sopenharmony_ciOpName %color "color"
1918fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
1919fd4e5da5Sopenharmony_ciOpName %param "param"
1920fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
1921fd4e5da5Sopenharmony_ciOpDecorate %9 RelaxedPrecision
1922fd4e5da5Sopenharmony_ci)";
1923fd4e5da5Sopenharmony_ci
1924fd4e5da5Sopenharmony_ci  const std::string before =
1925fd4e5da5Sopenharmony_ci      R"(%void = OpTypeVoid
1926fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
1927fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1928fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1929fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1930fd4e5da5Sopenharmony_ci%15 = OpTypeFunction %float %_ptr_Function_v4float
1931fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1932fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1933fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
1934fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1935fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1936fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
1937fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1938fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
1939fd4e5da5Sopenharmony_ci%main = OpFunction %void None %11
1940fd4e5da5Sopenharmony_ci%22 = OpLabel
1941fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
1942fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
1943fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
1944fd4e5da5Sopenharmony_ciOpStore %param %23
1945fd4e5da5Sopenharmony_ci%24 = OpFunctionCall %float %foo_vf4_ %param
1946fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24
1947fd4e5da5Sopenharmony_ciOpStore %color %25
1948fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color
1949fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26
1950fd4e5da5Sopenharmony_ciOpReturn
1951fd4e5da5Sopenharmony_ciOpFunctionEnd
1952fd4e5da5Sopenharmony_ci)";
1953fd4e5da5Sopenharmony_ci
1954fd4e5da5Sopenharmony_ci  const std::string after =
1955fd4e5da5Sopenharmony_ci      R"(OpDecorate %38 RelaxedPrecision
1956fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1957fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
1958fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1959fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1960fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1961fd4e5da5Sopenharmony_ci%15 = OpTypeFunction %float %_ptr_Function_v4float
1962fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1963fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1964fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
1965fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1966fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1967fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
1968fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1969fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
1970fd4e5da5Sopenharmony_ci%main = OpFunction %void None %11
1971fd4e5da5Sopenharmony_ci%22 = OpLabel
1972fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_float Function
1973fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
1974fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
1975fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
1976fd4e5da5Sopenharmony_ciOpStore %param %23
1977fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %param %uint_0
1978fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34
1979fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_float %param %uint_1
1980fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36
1981fd4e5da5Sopenharmony_ci%38 = OpFAdd %float %35 %37
1982fd4e5da5Sopenharmony_ciOpStore %32 %38
1983fd4e5da5Sopenharmony_ci%24 = OpLoad %float %32
1984fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24
1985fd4e5da5Sopenharmony_ciOpStore %color %25
1986fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color
1987fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26
1988fd4e5da5Sopenharmony_ciOpReturn
1989fd4e5da5Sopenharmony_ciOpFunctionEnd
1990fd4e5da5Sopenharmony_ci)";
1991fd4e5da5Sopenharmony_ci
1992fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
1993fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %float None %15
1994fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float
1995fd4e5da5Sopenharmony_ci%27 = OpLabel
1996fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0
1997fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28
1998fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Function_float %bar %uint_1
1999fd4e5da5Sopenharmony_ci%31 = OpLoad %float %30
2000fd4e5da5Sopenharmony_ci%9 = OpFAdd %float %29 %31
2001fd4e5da5Sopenharmony_ciOpReturnValue %9
2002fd4e5da5Sopenharmony_ciOpFunctionEnd
2003fd4e5da5Sopenharmony_ci)";
2004fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + before + nonEntryFuncs,
2005fd4e5da5Sopenharmony_ci                                              predefs + after + nonEntryFuncs,
2006fd4e5da5Sopenharmony_ci                                              false, true);
2007fd4e5da5Sopenharmony_ci}
2008fd4e5da5Sopenharmony_ci
2009fd4e5da5Sopenharmony_ciTEST_F(InlineTest, Decorated2) {
2010fd4e5da5Sopenharmony_ci  // Same test as Simple with the difference
2011fd4e5da5Sopenharmony_ci  // that the Result <id> of the outlined OpFunction
2012fd4e5da5Sopenharmony_ci  // is decorated with RelaxedPrecision
2013fd4e5da5Sopenharmony_ci  // Expected result is an equal decoration
2014fd4e5da5Sopenharmony_ci  // of the created return variable
2015fd4e5da5Sopenharmony_ci  //
2016fd4e5da5Sopenharmony_ci  // #version 140
2017fd4e5da5Sopenharmony_ci  //
2018fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
2019fd4e5da5Sopenharmony_ci  //
2020fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
2021fd4e5da5Sopenharmony_ci  // {
2022fd4e5da5Sopenharmony_ci  //     return bar.x + bar.y;
2023fd4e5da5Sopenharmony_ci  // }
2024fd4e5da5Sopenharmony_ci  //
2025fd4e5da5Sopenharmony_ci  // void main()
2026fd4e5da5Sopenharmony_ci  // {
2027fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
2028fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
2029fd4e5da5Sopenharmony_ci  // }
2030fd4e5da5Sopenharmony_ci
2031fd4e5da5Sopenharmony_ci  const std::string predefs =
2032fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2033fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2034fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2035fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
2036fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2037fd4e5da5Sopenharmony_ciOpSource GLSL 140
2038fd4e5da5Sopenharmony_ciOpName %main "main"
2039fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;"
2040fd4e5da5Sopenharmony_ciOpName %bar "bar"
2041fd4e5da5Sopenharmony_ciOpName %color "color"
2042fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
2043fd4e5da5Sopenharmony_ciOpName %param "param"
2044fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
2045fd4e5da5Sopenharmony_ciOpDecorate %foo_vf4_ RelaxedPrecision
2046fd4e5da5Sopenharmony_ci)";
2047fd4e5da5Sopenharmony_ci
2048fd4e5da5Sopenharmony_ci  const std::string before =
2049fd4e5da5Sopenharmony_ci      R"(%void = OpTypeVoid
2050fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
2051fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2052fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
2053fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
2054fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float
2055fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
2056fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
2057fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2058fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
2059fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
2060fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
2061fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
2062fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
2063fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10
2064fd4e5da5Sopenharmony_ci%21 = OpLabel
2065fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
2066fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
2067fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor
2068fd4e5da5Sopenharmony_ciOpStore %param %22
2069fd4e5da5Sopenharmony_ci%23 = OpFunctionCall %float %foo_vf4_ %param
2070fd4e5da5Sopenharmony_ci%24 = OpCompositeConstruct %v4float %23 %23 %23 %23
2071fd4e5da5Sopenharmony_ciOpStore %color %24
2072fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %color
2073fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %25
2074fd4e5da5Sopenharmony_ciOpReturn
2075fd4e5da5Sopenharmony_ciOpFunctionEnd
2076fd4e5da5Sopenharmony_ci)";
2077fd4e5da5Sopenharmony_ci
2078fd4e5da5Sopenharmony_ci  const std::string after =
2079fd4e5da5Sopenharmony_ci      R"(OpDecorate %32 RelaxedPrecision
2080fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2081fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
2082fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2083fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
2084fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
2085fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float
2086fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
2087fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
2088fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2089fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
2090fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
2091fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
2092fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
2093fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
2094fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10
2095fd4e5da5Sopenharmony_ci%21 = OpLabel
2096fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_float Function
2097fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
2098fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
2099fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor
2100fd4e5da5Sopenharmony_ciOpStore %param %22
2101fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %param %uint_0
2102fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34
2103fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_float %param %uint_1
2104fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36
2105fd4e5da5Sopenharmony_ci%38 = OpFAdd %float %35 %37
2106fd4e5da5Sopenharmony_ciOpStore %32 %38
2107fd4e5da5Sopenharmony_ci%23 = OpLoad %float %32
2108fd4e5da5Sopenharmony_ci%24 = OpCompositeConstruct %v4float %23 %23 %23 %23
2109fd4e5da5Sopenharmony_ciOpStore %color %24
2110fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %color
2111fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %25
2112fd4e5da5Sopenharmony_ciOpReturn
2113fd4e5da5Sopenharmony_ciOpFunctionEnd
2114fd4e5da5Sopenharmony_ci)";
2115fd4e5da5Sopenharmony_ci
2116fd4e5da5Sopenharmony_ci  const std::string nonEntryFuncs =
2117fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %float None %14
2118fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float
2119fd4e5da5Sopenharmony_ci%26 = OpLabel
2120fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_float %bar %uint_0
2121fd4e5da5Sopenharmony_ci%28 = OpLoad %float %27
2122fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Function_float %bar %uint_1
2123fd4e5da5Sopenharmony_ci%30 = OpLoad %float %29
2124fd4e5da5Sopenharmony_ci%31 = OpFAdd %float %28 %30
2125fd4e5da5Sopenharmony_ciOpReturnValue %31
2126fd4e5da5Sopenharmony_ciOpFunctionEnd
2127fd4e5da5Sopenharmony_ci)";
2128fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(predefs + before + nonEntryFuncs,
2129fd4e5da5Sopenharmony_ci                                              predefs + after + nonEntryFuncs,
2130fd4e5da5Sopenharmony_ci                                              false, true);
2131fd4e5da5Sopenharmony_ci}
2132fd4e5da5Sopenharmony_ci
2133fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DeleteName) {
2134fd4e5da5Sopenharmony_ci  // Test that the name of the result id of the call is deleted.
2135fd4e5da5Sopenharmony_ci  const std::string before =
2136fd4e5da5Sopenharmony_ci      R"(
2137fd4e5da5Sopenharmony_ci               OpCapability Shader
2138fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2139fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
2140fd4e5da5Sopenharmony_ci               OpName %main "main"
2141fd4e5da5Sopenharmony_ci               OpName %main_entry "main_entry"
2142fd4e5da5Sopenharmony_ci               OpName %foo_result "foo_result"
2143fd4e5da5Sopenharmony_ci               OpName %void_fn "void_fn"
2144fd4e5da5Sopenharmony_ci               OpName %foo "foo"
2145fd4e5da5Sopenharmony_ci               OpName %foo_entry "foo_entry"
2146fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
2147fd4e5da5Sopenharmony_ci    %void_fn = OpTypeFunction %void
2148fd4e5da5Sopenharmony_ci        %foo = OpFunction %void None %void_fn
2149fd4e5da5Sopenharmony_ci  %foo_entry = OpLabel
2150fd4e5da5Sopenharmony_ci               OpReturn
2151fd4e5da5Sopenharmony_ci               OpFunctionEnd
2152fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %void_fn
2153fd4e5da5Sopenharmony_ci %main_entry = OpLabel
2154fd4e5da5Sopenharmony_ci %foo_result = OpFunctionCall %void %foo
2155fd4e5da5Sopenharmony_ci               OpReturn
2156fd4e5da5Sopenharmony_ci               OpFunctionEnd
2157fd4e5da5Sopenharmony_ci)";
2158fd4e5da5Sopenharmony_ci
2159fd4e5da5Sopenharmony_ci  const std::string after =
2160fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2161fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2162fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
2163fd4e5da5Sopenharmony_ciOpName %main "main"
2164fd4e5da5Sopenharmony_ciOpName %main_entry "main_entry"
2165fd4e5da5Sopenharmony_ciOpName %void_fn "void_fn"
2166fd4e5da5Sopenharmony_ciOpName %foo "foo"
2167fd4e5da5Sopenharmony_ciOpName %foo_entry "foo_entry"
2168fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2169fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
2170fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn
2171fd4e5da5Sopenharmony_ci%foo_entry = OpLabel
2172fd4e5da5Sopenharmony_ciOpReturn
2173fd4e5da5Sopenharmony_ciOpFunctionEnd
2174fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
2175fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2176fd4e5da5Sopenharmony_ciOpReturn
2177fd4e5da5Sopenharmony_ciOpFunctionEnd
2178fd4e5da5Sopenharmony_ci)";
2179fd4e5da5Sopenharmony_ci
2180fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true);
2181fd4e5da5Sopenharmony_ci}
2182fd4e5da5Sopenharmony_ci
2183fd4e5da5Sopenharmony_ciTEST_F(InlineTest, SetParent) {
2184fd4e5da5Sopenharmony_ci  // Test that after inlining all basic blocks have the correct parent.
2185fd4e5da5Sopenharmony_ci  const std::string text =
2186fd4e5da5Sopenharmony_ci      R"(
2187fd4e5da5Sopenharmony_ci               OpCapability Shader
2188fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2189fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
2190fd4e5da5Sopenharmony_ci               OpName %main "main"
2191fd4e5da5Sopenharmony_ci               OpName %main_entry "main_entry"
2192fd4e5da5Sopenharmony_ci               OpName %foo_result "foo_result"
2193fd4e5da5Sopenharmony_ci               OpName %void_fn "void_fn"
2194fd4e5da5Sopenharmony_ci               OpName %foo "foo"
2195fd4e5da5Sopenharmony_ci               OpName %foo_entry "foo_entry"
2196fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
2197fd4e5da5Sopenharmony_ci    %void_fn = OpTypeFunction %void
2198fd4e5da5Sopenharmony_ci        %foo = OpFunction %void None %void_fn
2199fd4e5da5Sopenharmony_ci  %foo_entry = OpLabel
2200fd4e5da5Sopenharmony_ci               OpReturn
2201fd4e5da5Sopenharmony_ci               OpFunctionEnd
2202fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %void_fn
2203fd4e5da5Sopenharmony_ci %main_entry = OpLabel
2204fd4e5da5Sopenharmony_ci %foo_result = OpFunctionCall %void %foo
2205fd4e5da5Sopenharmony_ci               OpReturn
2206fd4e5da5Sopenharmony_ci               OpFunctionEnd
2207fd4e5da5Sopenharmony_ci)";
2208fd4e5da5Sopenharmony_ci
2209fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
2210fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
2211fd4e5da5Sopenharmony_ci  InlineExhaustivePass pass;
2212fd4e5da5Sopenharmony_ci  pass.Run(context.get());
2213fd4e5da5Sopenharmony_ci
2214fd4e5da5Sopenharmony_ci  for (Function& func : *context->module()) {
2215fd4e5da5Sopenharmony_ci    for (BasicBlock& bb : func) {
2216fd4e5da5Sopenharmony_ci      EXPECT_TRUE(bb.GetParent() == &func);
2217fd4e5da5Sopenharmony_ci    }
2218fd4e5da5Sopenharmony_ci  }
2219fd4e5da5Sopenharmony_ci}
2220fd4e5da5Sopenharmony_ci
2221fd4e5da5Sopenharmony_ciTEST_F(InlineTest, OpVariableWithInit) {
2222fd4e5da5Sopenharmony_ci  // Check that there is a store that corresponds to the initializer.  This
2223fd4e5da5Sopenharmony_ci  // test makes sure that is a store to the variable in the loop and before any
2224fd4e5da5Sopenharmony_ci  // load.
2225fd4e5da5Sopenharmony_ci  const std::string text = R"(
2226fd4e5da5Sopenharmony_ci; CHECK: OpFunction
2227fd4e5da5Sopenharmony_ci; CHECK-NOT: OpFunctionEnd
2228fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable %_ptr_Function_float Function %float_0
2229fd4e5da5Sopenharmony_ci; CHECK: OpLoopMerge [[outer_merge:%\w+]]
2230fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLoad %float [[var]]
2231fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] %float_0
2232fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd
2233fd4e5da5Sopenharmony_ci               OpCapability Shader
2234fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2235fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2236fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %o
2237fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
2238fd4e5da5Sopenharmony_ci               OpSource GLSL 450
2239fd4e5da5Sopenharmony_ci               OpDecorate %o Location 0
2240fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
2241fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
2242fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
2243fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %float
2244fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2245fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
2246fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
2247fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
2248fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float
2249fd4e5da5Sopenharmony_ci          %o = OpVariable %_ptr_Output_float Output
2250fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
2251fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
2252fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
2253fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
2254fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
2255fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
2256fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
2257fd4e5da5Sopenharmony_ci          %5 = OpLabel
2258fd4e5da5Sopenharmony_ci               OpStore %o %float_0
2259fd4e5da5Sopenharmony_ci               OpBranch %34
2260fd4e5da5Sopenharmony_ci         %34 = OpLabel
2261fd4e5da5Sopenharmony_ci         %39 = OpPhi %int %int_0 %5 %47 %37
2262fd4e5da5Sopenharmony_ci               OpLoopMerge %36 %37 None
2263fd4e5da5Sopenharmony_ci               OpBranch %38
2264fd4e5da5Sopenharmony_ci         %38 = OpLabel
2265fd4e5da5Sopenharmony_ci         %41 = OpSLessThan %bool %39 %int_2
2266fd4e5da5Sopenharmony_ci               OpBranchConditional %41 %35 %36
2267fd4e5da5Sopenharmony_ci         %35 = OpLabel
2268fd4e5da5Sopenharmony_ci         %42 = OpFunctionCall %float %foo_
2269fd4e5da5Sopenharmony_ci         %43 = OpLoad %float %o
2270fd4e5da5Sopenharmony_ci         %44 = OpFAdd %float %43 %42
2271fd4e5da5Sopenharmony_ci               OpStore %o %44
2272fd4e5da5Sopenharmony_ci               OpBranch %37
2273fd4e5da5Sopenharmony_ci         %37 = OpLabel
2274fd4e5da5Sopenharmony_ci         %47 = OpIAdd %int %39 %int_1
2275fd4e5da5Sopenharmony_ci               OpBranch %34
2276fd4e5da5Sopenharmony_ci         %36 = OpLabel
2277fd4e5da5Sopenharmony_ci               OpReturn
2278fd4e5da5Sopenharmony_ci               OpFunctionEnd
2279fd4e5da5Sopenharmony_ci       %foo_ = OpFunction %float None %7
2280fd4e5da5Sopenharmony_ci          %9 = OpLabel
2281fd4e5da5Sopenharmony_ci          %n = OpVariable %_ptr_Function_float Function %float_0
2282fd4e5da5Sopenharmony_ci         %13 = OpLoad %float %n
2283fd4e5da5Sopenharmony_ci         %15 = OpFOrdEqual %bool %13 %float_0
2284fd4e5da5Sopenharmony_ci               OpSelectionMerge %17 None
2285fd4e5da5Sopenharmony_ci               OpBranchConditional %15 %16 %17
2286fd4e5da5Sopenharmony_ci         %16 = OpLabel
2287fd4e5da5Sopenharmony_ci         %19 = OpLoad %float %n
2288fd4e5da5Sopenharmony_ci         %20 = OpFAdd %float %19 %float_1
2289fd4e5da5Sopenharmony_ci               OpStore %n %20
2290fd4e5da5Sopenharmony_ci               OpBranch %17
2291fd4e5da5Sopenharmony_ci         %17 = OpLabel
2292fd4e5da5Sopenharmony_ci         %21 = OpLoad %float %n
2293fd4e5da5Sopenharmony_ci               OpReturnValue %21
2294fd4e5da5Sopenharmony_ci               OpFunctionEnd
2295fd4e5da5Sopenharmony_ci)";
2296fd4e5da5Sopenharmony_ci
2297fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
2298fd4e5da5Sopenharmony_ci}
2299fd4e5da5Sopenharmony_ci
2300fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineDirectlyRecursiveFunc) {
2301fd4e5da5Sopenharmony_ci  // Test that the name of the result id of the call is deleted.
2302fd4e5da5Sopenharmony_ci  const std::string test =
2303fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2304fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2305fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main"
2306fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft
2307fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2308fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
2309fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2310fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float
2311fd4e5da5Sopenharmony_ci%15 = OpConstantNull %_struct_6
2312fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6
2313fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4
2314fd4e5da5Sopenharmony_ci%8 = OpLabel
2315fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9
2316fd4e5da5Sopenharmony_ciOpKill
2317fd4e5da5Sopenharmony_ciOpFunctionEnd
2318fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7
2319fd4e5da5Sopenharmony_ci%10 = OpLabel
2320fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %9
2321fd4e5da5Sopenharmony_ciOpReturnValue %15
2322fd4e5da5Sopenharmony_ciOpFunctionEnd
2323fd4e5da5Sopenharmony_ci)";
2324fd4e5da5Sopenharmony_ci
2325fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2326fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
2327fd4e5da5Sopenharmony_ci}
2328fd4e5da5Sopenharmony_ci
2329fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineInDirectlyRecursiveFunc) {
2330fd4e5da5Sopenharmony_ci  // Test that the name of the result id of the call is deleted.
2331fd4e5da5Sopenharmony_ci  const std::string test =
2332fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2333fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2334fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main"
2335fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft
2336fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2337fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
2338fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2339fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %float %float
2340fd4e5da5Sopenharmony_ci%15 = OpConstantNull %_struct_6
2341fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %_struct_6
2342fd4e5da5Sopenharmony_ci%1 = OpFunction %void Pure|Const %4
2343fd4e5da5Sopenharmony_ci%8 = OpLabel
2344fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %_struct_6 %9
2345fd4e5da5Sopenharmony_ciOpKill
2346fd4e5da5Sopenharmony_ciOpFunctionEnd
2347fd4e5da5Sopenharmony_ci%9 = OpFunction %_struct_6 None %7
2348fd4e5da5Sopenharmony_ci%10 = OpLabel
2349fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %_struct_6 %12
2350fd4e5da5Sopenharmony_ciOpReturnValue %15
2351fd4e5da5Sopenharmony_ciOpFunctionEnd
2352fd4e5da5Sopenharmony_ci%12 = OpFunction %_struct_6 None %7
2353fd4e5da5Sopenharmony_ci%13 = OpLabel
2354fd4e5da5Sopenharmony_ci%14 = OpFunctionCall %_struct_6 %9
2355fd4e5da5Sopenharmony_ciOpReturnValue %15
2356fd4e5da5Sopenharmony_ciOpFunctionEnd
2357fd4e5da5Sopenharmony_ci)";
2358fd4e5da5Sopenharmony_ci
2359fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2360fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
2361fd4e5da5Sopenharmony_ci}
2362fd4e5da5Sopenharmony_ci
2363fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithOpKillInContinue) {
2364fd4e5da5Sopenharmony_ci  const std::string test =
2365fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2366fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2367fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2368fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2369fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2370fd4e5da5Sopenharmony_ciOpSource GLSL 330
2371fd4e5da5Sopenharmony_ciOpName %main "main"
2372fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2373fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2374fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2375fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2376fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2377fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2378fd4e5da5Sopenharmony_ci%5 = OpLabel
2379fd4e5da5Sopenharmony_ciOpBranch %9
2380fd4e5da5Sopenharmony_ci%9 = OpLabel
2381fd4e5da5Sopenharmony_ciOpLoopMerge %11 %12 None
2382fd4e5da5Sopenharmony_ciOpBranch %13
2383fd4e5da5Sopenharmony_ci%13 = OpLabel
2384fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %11
2385fd4e5da5Sopenharmony_ci%10 = OpLabel
2386fd4e5da5Sopenharmony_ciOpBranch %12
2387fd4e5da5Sopenharmony_ci%12 = OpLabel
2388fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_
2389fd4e5da5Sopenharmony_ciOpBranch %9
2390fd4e5da5Sopenharmony_ci%11 = OpLabel
2391fd4e5da5Sopenharmony_ciOpReturn
2392fd4e5da5Sopenharmony_ciOpFunctionEnd
2393fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2394fd4e5da5Sopenharmony_ci%7 = OpLabel
2395fd4e5da5Sopenharmony_ciOpKill
2396fd4e5da5Sopenharmony_ciOpFunctionEnd
2397fd4e5da5Sopenharmony_ci)";
2398fd4e5da5Sopenharmony_ci
2399fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2400fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
2401fd4e5da5Sopenharmony_ci}
2402fd4e5da5Sopenharmony_ci
2403fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithDontInline) {
2404fd4e5da5Sopenharmony_ci  // Check that the function with DontInline flag is not inlined.
2405fd4e5da5Sopenharmony_ci  const std::string text = R"(
2406fd4e5da5Sopenharmony_ci; CHECK: %foo = OpFunction %int DontInline
2407fd4e5da5Sopenharmony_ci; CHECK: OpReturnValue %int_0
2408fd4e5da5Sopenharmony_ci
2409fd4e5da5Sopenharmony_ciOpCapability Shader
2410fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2411fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2412fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2413fd4e5da5Sopenharmony_ciOpSource HLSL 600
2414fd4e5da5Sopenharmony_ciOpName %main "main"
2415fd4e5da5Sopenharmony_ciOpName %foo "foo"
2416fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
2417fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
2418fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2419fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void
2420fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %int
2421fd4e5da5Sopenharmony_ci%main = OpFunction %void None %6
2422fd4e5da5Sopenharmony_ci%8 = OpLabel
2423fd4e5da5Sopenharmony_ci%9 = OpFunctionCall %int %foo
2424fd4e5da5Sopenharmony_ciOpReturn
2425fd4e5da5Sopenharmony_ciOpFunctionEnd
2426fd4e5da5Sopenharmony_ci%foo = OpFunction %int DontInline %7
2427fd4e5da5Sopenharmony_ci%10 = OpLabel
2428fd4e5da5Sopenharmony_ciOpReturnValue %int_0
2429fd4e5da5Sopenharmony_ciOpFunctionEnd
2430fd4e5da5Sopenharmony_ci)";
2431fd4e5da5Sopenharmony_ci
2432fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
2433fd4e5da5Sopenharmony_ci}
2434fd4e5da5Sopenharmony_ci
2435fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpKillNotInContinue) {
2436fd4e5da5Sopenharmony_ci  const std::string before =
2437fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2438fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2439fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2440fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2441fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2442fd4e5da5Sopenharmony_ciOpSource GLSL 330
2443fd4e5da5Sopenharmony_ciOpName %main "main"
2444fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2445fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2446fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2447fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2448fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2449fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2450fd4e5da5Sopenharmony_ci%5 = OpLabel
2451fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_
2452fd4e5da5Sopenharmony_ciOpReturn
2453fd4e5da5Sopenharmony_ciOpFunctionEnd
2454fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2455fd4e5da5Sopenharmony_ci%7 = OpLabel
2456fd4e5da5Sopenharmony_ciOpKill
2457fd4e5da5Sopenharmony_ciOpFunctionEnd
2458fd4e5da5Sopenharmony_ci)";
2459fd4e5da5Sopenharmony_ci
2460fd4e5da5Sopenharmony_ci  const std::string after =
2461fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2462fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2463fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2464fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2465fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2466fd4e5da5Sopenharmony_ciOpSource GLSL 330
2467fd4e5da5Sopenharmony_ciOpName %main "main"
2468fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2469fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2470fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2471fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2472fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2473fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2474fd4e5da5Sopenharmony_ci%5 = OpLabel
2475fd4e5da5Sopenharmony_ciOpKill
2476fd4e5da5Sopenharmony_ci%18 = OpLabel
2477fd4e5da5Sopenharmony_ciOpReturn
2478fd4e5da5Sopenharmony_ciOpFunctionEnd
2479fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2480fd4e5da5Sopenharmony_ci%7 = OpLabel
2481fd4e5da5Sopenharmony_ciOpKill
2482fd4e5da5Sopenharmony_ciOpFunctionEnd
2483fd4e5da5Sopenharmony_ci)";
2484fd4e5da5Sopenharmony_ci
2485fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2486fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true);
2487fd4e5da5Sopenharmony_ci}
2488fd4e5da5Sopenharmony_ci
2489fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DontInlineFuncWithOpTerminateInvocationInContinue) {
2490fd4e5da5Sopenharmony_ci  const std::string test =
2491fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2492fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation"
2493fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2494fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2495fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2496fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2497fd4e5da5Sopenharmony_ciOpSource GLSL 330
2498fd4e5da5Sopenharmony_ciOpName %main "main"
2499fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2500fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2501fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2502fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2503fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2504fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2505fd4e5da5Sopenharmony_ci%5 = OpLabel
2506fd4e5da5Sopenharmony_ciOpBranch %9
2507fd4e5da5Sopenharmony_ci%9 = OpLabel
2508fd4e5da5Sopenharmony_ciOpLoopMerge %11 %12 None
2509fd4e5da5Sopenharmony_ciOpBranch %13
2510fd4e5da5Sopenharmony_ci%13 = OpLabel
2511fd4e5da5Sopenharmony_ciOpBranchConditional %true %10 %11
2512fd4e5da5Sopenharmony_ci%10 = OpLabel
2513fd4e5da5Sopenharmony_ciOpBranch %12
2514fd4e5da5Sopenharmony_ci%12 = OpLabel
2515fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_
2516fd4e5da5Sopenharmony_ciOpBranch %9
2517fd4e5da5Sopenharmony_ci%11 = OpLabel
2518fd4e5da5Sopenharmony_ciOpReturn
2519fd4e5da5Sopenharmony_ciOpFunctionEnd
2520fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2521fd4e5da5Sopenharmony_ci%7 = OpLabel
2522fd4e5da5Sopenharmony_ciOpTerminateInvocation
2523fd4e5da5Sopenharmony_ciOpFunctionEnd
2524fd4e5da5Sopenharmony_ci)";
2525fd4e5da5Sopenharmony_ci
2526fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2527fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(test, test, false, true);
2528fd4e5da5Sopenharmony_ci}
2529fd4e5da5Sopenharmony_ci
2530fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpTerminateInvocationNotInContinue) {
2531fd4e5da5Sopenharmony_ci  const std::string before =
2532fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2533fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation"
2534fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2535fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2536fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2537fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2538fd4e5da5Sopenharmony_ciOpSource GLSL 330
2539fd4e5da5Sopenharmony_ciOpName %main "main"
2540fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2541fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2542fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2543fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2544fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2545fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2546fd4e5da5Sopenharmony_ci%5 = OpLabel
2547fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %kill_
2548fd4e5da5Sopenharmony_ciOpReturn
2549fd4e5da5Sopenharmony_ciOpFunctionEnd
2550fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2551fd4e5da5Sopenharmony_ci%7 = OpLabel
2552fd4e5da5Sopenharmony_ciOpTerminateInvocation
2553fd4e5da5Sopenharmony_ciOpFunctionEnd
2554fd4e5da5Sopenharmony_ci)";
2555fd4e5da5Sopenharmony_ci
2556fd4e5da5Sopenharmony_ci  const std::string after =
2557fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2558fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_terminate_invocation"
2559fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2560fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2561fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
2562fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2563fd4e5da5Sopenharmony_ciOpSource GLSL 330
2564fd4e5da5Sopenharmony_ciOpName %main "main"
2565fd4e5da5Sopenharmony_ciOpName %kill_ "kill("
2566fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2567fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
2568fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2569fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2570fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
2571fd4e5da5Sopenharmony_ci%5 = OpLabel
2572fd4e5da5Sopenharmony_ciOpTerminateInvocation
2573fd4e5da5Sopenharmony_ci%18 = OpLabel
2574fd4e5da5Sopenharmony_ciOpReturn
2575fd4e5da5Sopenharmony_ciOpFunctionEnd
2576fd4e5da5Sopenharmony_ci%kill_ = OpFunction %void None %3
2577fd4e5da5Sopenharmony_ci%7 = OpLabel
2578fd4e5da5Sopenharmony_ciOpTerminateInvocation
2579fd4e5da5Sopenharmony_ciOpFunctionEnd
2580fd4e5da5Sopenharmony_ci)";
2581fd4e5da5Sopenharmony_ci
2582fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2583fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true);
2584fd4e5da5Sopenharmony_ci}
2585fd4e5da5Sopenharmony_ci
2586fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineForLinkage) {
2587fd4e5da5Sopenharmony_ci  const std::string before =
2588fd4e5da5Sopenharmony_ci      R"(OpCapability SampledBuffer
2589fd4e5da5Sopenharmony_ciOpCapability ImageBuffer
2590fd4e5da5Sopenharmony_ciOpCapability Shader
2591fd4e5da5Sopenharmony_ciOpCapability Linkage
2592fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2593fd4e5da5Sopenharmony_ciOpSource HLSL 630
2594fd4e5da5Sopenharmony_ciOpName %type_buffer_image "type.buffer.image"
2595fd4e5da5Sopenharmony_ciOpName %output "output"
2596fd4e5da5Sopenharmony_ciOpName %main "main"
2597fd4e5da5Sopenharmony_ciOpName %color "color"
2598fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
2599fd4e5da5Sopenharmony_ciOpName %param_var_color "param.var.color"
2600fd4e5da5Sopenharmony_ciOpName %fn "fn"
2601fd4e5da5Sopenharmony_ciOpName %color_0 "color"
2602fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
2603fd4e5da5Sopenharmony_ciOpName %v "v"
2604fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export
2605fd4e5da5Sopenharmony_ciOpDecorate %output DescriptorSet 0
2606fd4e5da5Sopenharmony_ciOpDecorate %output Binding 1
2607fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2608fd4e5da5Sopenharmony_ci%float_0_200000003 = OpConstant %float 0.200000003
2609fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
2610fd4e5da5Sopenharmony_ci%6 = OpConstantComposite %v4float %float_0_200000003 %float_0_200000003 %float_0_200000003 %float_0_200000003
2611fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
2612fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
2613fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba32f
2614fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
2615fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
2616fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %float %_ptr_Function_v4float
2617fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2618fd4e5da5Sopenharmony_ci%output = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
2619fd4e5da5Sopenharmony_ci%main = OpFunction %float None %11
2620fd4e5da5Sopenharmony_ci%color = OpFunctionParameter %_ptr_Function_v4float
2621fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
2622fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function
2623fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %color
2624fd4e5da5Sopenharmony_ciOpStore %param_var_color %16
2625fd4e5da5Sopenharmony_ci%17 = OpFunctionCall %float %fn %param_var_color
2626fd4e5da5Sopenharmony_ciOpReturnValue %17
2627fd4e5da5Sopenharmony_ciOpFunctionEnd
2628fd4e5da5Sopenharmony_ci%fn = OpFunction %float None %11
2629fd4e5da5Sopenharmony_ci%color_0 = OpFunctionParameter %_ptr_Function_v4float
2630fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
2631fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
2632fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %color_0
2633fd4e5da5Sopenharmony_ciOpStore %v %22
2634fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v
2635fd4e5da5Sopenharmony_ci%24 = OpFMul %v4float %23 %6
2636fd4e5da5Sopenharmony_ciOpStore %v %24
2637fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Function_float %v %int_0
2638fd4e5da5Sopenharmony_ci%27 = OpLoad %float %26
2639fd4e5da5Sopenharmony_ciOpReturnValue %27
2640fd4e5da5Sopenharmony_ciOpFunctionEnd
2641fd4e5da5Sopenharmony_ci      )";
2642fd4e5da5Sopenharmony_ci
2643fd4e5da5Sopenharmony_ci  const std::string after =
2644fd4e5da5Sopenharmony_ci      R"(OpCapability SampledBuffer
2645fd4e5da5Sopenharmony_ciOpCapability ImageBuffer
2646fd4e5da5Sopenharmony_ciOpCapability Shader
2647fd4e5da5Sopenharmony_ciOpCapability Linkage
2648fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2649fd4e5da5Sopenharmony_ciOpSource HLSL 630
2650fd4e5da5Sopenharmony_ciOpName %type_buffer_image "type.buffer.image"
2651fd4e5da5Sopenharmony_ciOpName %output "output"
2652fd4e5da5Sopenharmony_ciOpName %main "main"
2653fd4e5da5Sopenharmony_ciOpName %color "color"
2654fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
2655fd4e5da5Sopenharmony_ciOpName %param_var_color "param.var.color"
2656fd4e5da5Sopenharmony_ciOpName %fn "fn"
2657fd4e5da5Sopenharmony_ciOpName %color_0 "color"
2658fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
2659fd4e5da5Sopenharmony_ciOpName %v "v"
2660fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export
2661fd4e5da5Sopenharmony_ciOpDecorate %output DescriptorSet 0
2662fd4e5da5Sopenharmony_ciOpDecorate %output Binding 1
2663fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2664fd4e5da5Sopenharmony_ci%float_0_200000003 = OpConstant %float 0.200000003
2665fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
2666fd4e5da5Sopenharmony_ci%6 = OpConstantComposite %v4float %float_0_200000003 %float_0_200000003 %float_0_200000003 %float_0_200000003
2667fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
2668fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
2669fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba32f
2670fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
2671fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
2672fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %float %_ptr_Function_v4float
2673fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2674fd4e5da5Sopenharmony_ci%output = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
2675fd4e5da5Sopenharmony_ci%main = OpFunction %float None %11
2676fd4e5da5Sopenharmony_ci%color = OpFunctionParameter %_ptr_Function_v4float
2677fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
2678fd4e5da5Sopenharmony_ci%28 = OpVariable %_ptr_Function_v4float Function
2679fd4e5da5Sopenharmony_ci%29 = OpVariable %_ptr_Function_float Function
2680fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function
2681fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %color
2682fd4e5da5Sopenharmony_ciOpStore %param_var_color %16
2683fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %param_var_color
2684fd4e5da5Sopenharmony_ciOpStore %28 %31
2685fd4e5da5Sopenharmony_ci%32 = OpLoad %v4float %28
2686fd4e5da5Sopenharmony_ci%33 = OpFMul %v4float %32 %6
2687fd4e5da5Sopenharmony_ciOpStore %28 %33
2688fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_float %28 %int_0
2689fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34
2690fd4e5da5Sopenharmony_ciOpStore %29 %35
2691fd4e5da5Sopenharmony_ci%17 = OpLoad %float %29
2692fd4e5da5Sopenharmony_ciOpReturnValue %17
2693fd4e5da5Sopenharmony_ciOpFunctionEnd
2694fd4e5da5Sopenharmony_ci%fn = OpFunction %float None %11
2695fd4e5da5Sopenharmony_ci%color_0 = OpFunctionParameter %_ptr_Function_v4float
2696fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
2697fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
2698fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %color_0
2699fd4e5da5Sopenharmony_ciOpStore %v %22
2700fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %v
2701fd4e5da5Sopenharmony_ci%24 = OpFMul %v4float %23 %6
2702fd4e5da5Sopenharmony_ciOpStore %v %24
2703fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Function_float %v %int_0
2704fd4e5da5Sopenharmony_ci%27 = OpLoad %float %26
2705fd4e5da5Sopenharmony_ciOpReturnValue %27
2706fd4e5da5Sopenharmony_ciOpFunctionEnd
2707fd4e5da5Sopenharmony_ci)";
2708fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
2709fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<InlineExhaustivePass>(before, after, false, true);
2710fd4e5da5Sopenharmony_ci}
2711fd4e5da5Sopenharmony_ci
2712fd4e5da5Sopenharmony_ciTEST_F(InlineTest, InlineFuncWithOpTerminateRayNotInContinue) {
2713fd4e5da5Sopenharmony_ci  const std::string text =
2714fd4e5da5Sopenharmony_ci      R"(
2715fd4e5da5Sopenharmony_ci               OpCapability RayTracingKHR
2716fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_ray_tracing"
2717fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2718fd4e5da5Sopenharmony_ci               OpEntryPoint AnyHitKHR %MyAHitMain2 "MyAHitMain2" %a
2719fd4e5da5Sopenharmony_ci               OpSource HLSL 630
2720fd4e5da5Sopenharmony_ci               OpName %a "a"
2721fd4e5da5Sopenharmony_ci               OpName %MyAHitMain2 "MyAHitMain2"
2722fd4e5da5Sopenharmony_ci               OpName %param_var_a "param.var.a"
2723fd4e5da5Sopenharmony_ci               OpName %src_MyAHitMain2 "src.MyAHitMain2"
2724fd4e5da5Sopenharmony_ci               OpName %a_0 "a"
2725fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
2726fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
2727fd4e5da5Sopenharmony_ci%_ptr_IncomingRayPayloadKHR_int = OpTypePointer IncomingRayPayloadKHR %int
2728fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
2729fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
2730fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
2731fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void %_ptr_Function_int
2732fd4e5da5Sopenharmony_ci          %a = OpVariable %_ptr_IncomingRayPayloadKHR_int IncomingRayPayloadKHR
2733fd4e5da5Sopenharmony_ci%MyAHitMain2 = OpFunction %void None %6
2734fd4e5da5Sopenharmony_ci          %7 = OpLabel
2735fd4e5da5Sopenharmony_ci%param_var_a = OpVariable %_ptr_Function_int Function
2736fd4e5da5Sopenharmony_ci         %10 = OpLoad %int %a
2737fd4e5da5Sopenharmony_ci               OpStore %param_var_a %10
2738fd4e5da5Sopenharmony_ci         %11 = OpFunctionCall %void %src_MyAHitMain2 %param_var_a
2739fd4e5da5Sopenharmony_ci         %13 = OpLoad %int %param_var_a
2740fd4e5da5Sopenharmony_ci               OpStore %a %13
2741fd4e5da5Sopenharmony_ci               OpReturn
2742fd4e5da5Sopenharmony_ci               OpFunctionEnd
2743fd4e5da5Sopenharmony_ci%src_MyAHitMain2 = OpFunction %void None %14
2744fd4e5da5Sopenharmony_ci        %a_0 = OpFunctionParameter %_ptr_Function_int
2745fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
2746fd4e5da5Sopenharmony_ci         %17 = OpLoad %int %a_0
2747fd4e5da5Sopenharmony_ci               OpStore %a %17
2748fd4e5da5Sopenharmony_ci               OpTerminateRayKHR
2749fd4e5da5Sopenharmony_ci               OpFunctionEnd
2750fd4e5da5Sopenharmony_ci
2751fd4e5da5Sopenharmony_ci; CHECK:      %MyAHitMain2 = OpFunction %void None
2752fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel
2753fd4e5da5Sopenharmony_ci; CHECK-NEXT:   %param_var_a = OpVariable %_ptr_Function_int Function
2754fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpLoad %int %a
2755fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpStore %param_var_a {{%\d+}}
2756fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpLoad %int %param_var_a
2757fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpStore %a {{%\d+}}
2758fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpTerminateRayKHR
2759fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel
2760fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpLoad %int %param_var_a
2761fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpStore %a %16
2762fd4e5da5Sopenharmony_ci; CHECK-NEXT:   OpReturn
2763fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpFunctionEnd
2764fd4e5da5Sopenharmony_ci)";
2765fd4e5da5Sopenharmony_ci
2766fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, false);
2767fd4e5da5Sopenharmony_ci}
2768fd4e5da5Sopenharmony_ci
2769fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnFunctionInlined) {
2770fd4e5da5Sopenharmony_ci  // #version 140
2771fd4e5da5Sopenharmony_ci  //
2772fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
2773fd4e5da5Sopenharmony_ci  //
2774fd4e5da5Sopenharmony_ci  // float foo(vec4 bar)
2775fd4e5da5Sopenharmony_ci  // {
2776fd4e5da5Sopenharmony_ci  //     if (bar.x < 0.0)
2777fd4e5da5Sopenharmony_ci  //         return 0.0;
2778fd4e5da5Sopenharmony_ci  //     return bar.x;
2779fd4e5da5Sopenharmony_ci  // }
2780fd4e5da5Sopenharmony_ci  //
2781fd4e5da5Sopenharmony_ci  // void main()
2782fd4e5da5Sopenharmony_ci  // {
2783fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(foo(BaseColor));
2784fd4e5da5Sopenharmony_ci  //     gl_FragColor = color;
2785fd4e5da5Sopenharmony_ci  // }
2786fd4e5da5Sopenharmony_ci
2787fd4e5da5Sopenharmony_ci  const std::string predefs =
2788fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2789fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
2790fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2791fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
2792fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
2793fd4e5da5Sopenharmony_ciOpSource GLSL 140
2794fd4e5da5Sopenharmony_ciOpName %main "main"
2795fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;"
2796fd4e5da5Sopenharmony_ciOpName %bar "bar"
2797fd4e5da5Sopenharmony_ciOpName %color "color"
2798fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
2799fd4e5da5Sopenharmony_ciOpName %param "param"
2800fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
2801fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2802fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
2803fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
2804fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
2805fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
2806fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %float %_ptr_Function_v4float
2807fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
2808fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
2809fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
2810fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
2811fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2812fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
2813fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
2814fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
2815fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
2816fd4e5da5Sopenharmony_ci)";
2817fd4e5da5Sopenharmony_ci
2818fd4e5da5Sopenharmony_ci  const std::string foo =
2819fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %float None %14
2820fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float
2821fd4e5da5Sopenharmony_ci%27 = OpLabel
2822fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0
2823fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28
2824fd4e5da5Sopenharmony_ci%30 = OpFOrdLessThan %bool %29 %float_0
2825fd4e5da5Sopenharmony_ciOpSelectionMerge %31 None
2826fd4e5da5Sopenharmony_ciOpBranchConditional %30 %32 %31
2827fd4e5da5Sopenharmony_ci%32 = OpLabel
2828fd4e5da5Sopenharmony_ciOpReturnValue %float_0
2829fd4e5da5Sopenharmony_ci%31 = OpLabel
2830fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Function_float %bar %uint_0
2831fd4e5da5Sopenharmony_ci%34 = OpLoad %float %33
2832fd4e5da5Sopenharmony_ciOpReturnValue %34
2833fd4e5da5Sopenharmony_ciOpFunctionEnd
2834fd4e5da5Sopenharmony_ci)";
2835fd4e5da5Sopenharmony_ci
2836fd4e5da5Sopenharmony_ci  const std::string fooMergeReturn =
2837fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %float None %14
2838fd4e5da5Sopenharmony_ci%bar = OpFunctionParameter %_ptr_Function_v4float
2839fd4e5da5Sopenharmony_ci%27 = OpLabel
2840fd4e5da5Sopenharmony_ci%41 = OpVariable %_ptr_Function_bool Function %false
2841fd4e5da5Sopenharmony_ci%36 = OpVariable %_ptr_Function_float Function
2842fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None
2843fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %38
2844fd4e5da5Sopenharmony_ci%38 = OpLabel
2845fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_float %bar %uint_0
2846fd4e5da5Sopenharmony_ci%29 = OpLoad %float %28
2847fd4e5da5Sopenharmony_ci%30 = OpFOrdLessThan %bool %29 %float_0
2848fd4e5da5Sopenharmony_ciOpSelectionMerge %31 None
2849fd4e5da5Sopenharmony_ciOpBranchConditional %30 %32 %31
2850fd4e5da5Sopenharmony_ci%32 = OpLabel
2851fd4e5da5Sopenharmony_ciOpStore %41 %true
2852fd4e5da5Sopenharmony_ciOpStore %36 %float_0
2853fd4e5da5Sopenharmony_ciOpBranch %35
2854fd4e5da5Sopenharmony_ci%31 = OpLabel
2855fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Function_float %bar %uint_0
2856fd4e5da5Sopenharmony_ci%34 = OpLoad %float %33
2857fd4e5da5Sopenharmony_ciOpStore %41 %true
2858fd4e5da5Sopenharmony_ciOpStore %36 %34
2859fd4e5da5Sopenharmony_ciOpBranch %35
2860fd4e5da5Sopenharmony_ci%35 = OpLabel
2861fd4e5da5Sopenharmony_ci%37 = OpLoad %float %36
2862fd4e5da5Sopenharmony_ciOpReturnValue %37
2863fd4e5da5Sopenharmony_ciOpFunctionEnd
2864fd4e5da5Sopenharmony_ci)";
2865fd4e5da5Sopenharmony_ci
2866fd4e5da5Sopenharmony_ci  const std::string before =
2867fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
2868fd4e5da5Sopenharmony_ci%22 = OpLabel
2869fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
2870fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
2871fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
2872fd4e5da5Sopenharmony_ciOpStore %param %23
2873fd4e5da5Sopenharmony_ci%24 = OpFunctionCall %float %foo_vf4_ %param
2874fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24
2875fd4e5da5Sopenharmony_ciOpStore %color %25
2876fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color
2877fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26
2878fd4e5da5Sopenharmony_ciOpReturn
2879fd4e5da5Sopenharmony_ciOpFunctionEnd
2880fd4e5da5Sopenharmony_ci)";
2881fd4e5da5Sopenharmony_ci
2882fd4e5da5Sopenharmony_ci  const std::string after =
2883fd4e5da5Sopenharmony_ci      R"(%false = OpConstantFalse %bool
2884fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool
2885fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2886fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10
2887fd4e5da5Sopenharmony_ci%22 = OpLabel
2888fd4e5da5Sopenharmony_ci%43 = OpVariable %_ptr_Function_bool Function %false
2889fd4e5da5Sopenharmony_ci%44 = OpVariable %_ptr_Function_float Function
2890fd4e5da5Sopenharmony_ci%45 = OpVariable %_ptr_Function_float Function
2891fd4e5da5Sopenharmony_ci%color = OpVariable %_ptr_Function_v4float Function
2892fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
2893fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
2894fd4e5da5Sopenharmony_ciOpStore %param %23
2895fd4e5da5Sopenharmony_ciOpStore %43 %false
2896fd4e5da5Sopenharmony_ciOpSelectionMerge %55 None
2897fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %47
2898fd4e5da5Sopenharmony_ci%47 = OpLabel
2899fd4e5da5Sopenharmony_ci%48 = OpAccessChain %_ptr_Function_float %param %uint_0
2900fd4e5da5Sopenharmony_ci%49 = OpLoad %float %48
2901fd4e5da5Sopenharmony_ci%50 = OpFOrdLessThan %bool %49 %float_0
2902fd4e5da5Sopenharmony_ciOpSelectionMerge %52 None
2903fd4e5da5Sopenharmony_ciOpBranchConditional %50 %51 %52
2904fd4e5da5Sopenharmony_ci%51 = OpLabel
2905fd4e5da5Sopenharmony_ciOpStore %43 %true
2906fd4e5da5Sopenharmony_ciOpStore %44 %float_0
2907fd4e5da5Sopenharmony_ciOpBranch %55
2908fd4e5da5Sopenharmony_ci%52 = OpLabel
2909fd4e5da5Sopenharmony_ci%53 = OpAccessChain %_ptr_Function_float %param %uint_0
2910fd4e5da5Sopenharmony_ci%54 = OpLoad %float %53
2911fd4e5da5Sopenharmony_ciOpStore %43 %true
2912fd4e5da5Sopenharmony_ciOpStore %44 %54
2913fd4e5da5Sopenharmony_ciOpBranch %55
2914fd4e5da5Sopenharmony_ci%55 = OpLabel
2915fd4e5da5Sopenharmony_ci%56 = OpLoad %float %44
2916fd4e5da5Sopenharmony_ciOpStore %45 %56
2917fd4e5da5Sopenharmony_ci%24 = OpLoad %float %45
2918fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %24 %24 %24 %24
2919fd4e5da5Sopenharmony_ciOpStore %color %25
2920fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %color
2921fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %26
2922fd4e5da5Sopenharmony_ciOpReturn
2923fd4e5da5Sopenharmony_ciOpFunctionEnd
2924fd4e5da5Sopenharmony_ci)";
2925fd4e5da5Sopenharmony_ci
2926fd4e5da5Sopenharmony_ci  // The early return case must be handled by merge-return first.
2927fd4e5da5Sopenharmony_ci  AddPass<MergeReturnPass>();
2928fd4e5da5Sopenharmony_ci  AddPass<InlineExhaustivePass>();
2929fd4e5da5Sopenharmony_ci  RunAndCheck(predefs + before + foo, predefs + after + fooMergeReturn);
2930fd4e5da5Sopenharmony_ci}
2931fd4e5da5Sopenharmony_ci
2932fd4e5da5Sopenharmony_ciTEST_F(InlineTest, EarlyReturnNotAppearingLastInFunctionInlined) {
2933fd4e5da5Sopenharmony_ci  // Example from https://github.com/KhronosGroup/SPIRV-Tools/issues/755
2934fd4e5da5Sopenharmony_ci  //
2935fd4e5da5Sopenharmony_ci  // Original example is derived from:
2936fd4e5da5Sopenharmony_ci  //
2937fd4e5da5Sopenharmony_ci  // #version 450
2938fd4e5da5Sopenharmony_ci  //
2939fd4e5da5Sopenharmony_ci  // float foo() {
2940fd4e5da5Sopenharmony_ci  //     if (true) {
2941fd4e5da5Sopenharmony_ci  //     }
2942fd4e5da5Sopenharmony_ci  // }
2943fd4e5da5Sopenharmony_ci  //
2944fd4e5da5Sopenharmony_ci  // void main() { foo(); }
2945fd4e5da5Sopenharmony_ci  //
2946fd4e5da5Sopenharmony_ci  // But the order of basic blocks in foo is changed so that the return
2947fd4e5da5Sopenharmony_ci  // block is listed second-last.  There is only one return in the callee
2948fd4e5da5Sopenharmony_ci  // but it does not appear last.
2949fd4e5da5Sopenharmony_ci
2950fd4e5da5Sopenharmony_ci  const std::string predefs =
2951fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
2952fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2953fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
2954fd4e5da5Sopenharmony_ciOpSource GLSL 450
2955fd4e5da5Sopenharmony_ciOpName %main "main"
2956fd4e5da5Sopenharmony_ciOpName %foo_ "foo("
2957fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2958fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
2959fd4e5da5Sopenharmony_ci%bool = OpTypeBool
2960fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
2961fd4e5da5Sopenharmony_ci)";
2962fd4e5da5Sopenharmony_ci
2963fd4e5da5Sopenharmony_ci  const std::string foo =
2964fd4e5da5Sopenharmony_ci      R"(%foo_ = OpFunction %void None %4
2965fd4e5da5Sopenharmony_ci%7 = OpLabel
2966fd4e5da5Sopenharmony_ciOpSelectionMerge %8 None
2967fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %8
2968fd4e5da5Sopenharmony_ci%8 = OpLabel
2969fd4e5da5Sopenharmony_ciOpReturn
2970fd4e5da5Sopenharmony_ci%9 = OpLabel
2971fd4e5da5Sopenharmony_ciOpBranch %8
2972fd4e5da5Sopenharmony_ciOpFunctionEnd
2973fd4e5da5Sopenharmony_ci)";
2974fd4e5da5Sopenharmony_ci
2975fd4e5da5Sopenharmony_ci  const std::string fooMergeReturn =
2976fd4e5da5Sopenharmony_ci      R"(%uint = OpTypeInt 32 0
2977fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
2978fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool
2979fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool
2980fd4e5da5Sopenharmony_ci%foo_ = OpFunction %void None %4
2981fd4e5da5Sopenharmony_ci%7 = OpLabel
2982fd4e5da5Sopenharmony_ci%18 = OpVariable %_ptr_Function_bool Function %false
2983fd4e5da5Sopenharmony_ciOpSelectionMerge %12 None
2984fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %13
2985fd4e5da5Sopenharmony_ci%13 = OpLabel
2986fd4e5da5Sopenharmony_ciOpSelectionMerge %8 None
2987fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %8
2988fd4e5da5Sopenharmony_ci%8 = OpLabel
2989fd4e5da5Sopenharmony_ciOpStore %18 %true
2990fd4e5da5Sopenharmony_ciOpBranch %12
2991fd4e5da5Sopenharmony_ci%9 = OpLabel
2992fd4e5da5Sopenharmony_ciOpBranch %8
2993fd4e5da5Sopenharmony_ci%12 = OpLabel
2994fd4e5da5Sopenharmony_ciOpReturn
2995fd4e5da5Sopenharmony_ciOpFunctionEnd
2996fd4e5da5Sopenharmony_ci)";
2997fd4e5da5Sopenharmony_ci
2998fd4e5da5Sopenharmony_ci  const std::string before =
2999fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %4
3000fd4e5da5Sopenharmony_ci%10 = OpLabel
3001fd4e5da5Sopenharmony_ci%11 = OpFunctionCall %void %foo_
3002fd4e5da5Sopenharmony_ciOpReturn
3003fd4e5da5Sopenharmony_ciOpFunctionEnd
3004fd4e5da5Sopenharmony_ci)";
3005fd4e5da5Sopenharmony_ci
3006fd4e5da5Sopenharmony_ci  const std::string after =
3007fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %4
3008fd4e5da5Sopenharmony_ci%10 = OpLabel
3009fd4e5da5Sopenharmony_ci%19 = OpVariable %_ptr_Function_bool Function %false
3010fd4e5da5Sopenharmony_ciOpStore %19 %false
3011fd4e5da5Sopenharmony_ciOpSelectionMerge %24 None
3012fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %21
3013fd4e5da5Sopenharmony_ci%21 = OpLabel
3014fd4e5da5Sopenharmony_ciOpSelectionMerge %22 None
3015fd4e5da5Sopenharmony_ciOpBranchConditional %true %23 %22
3016fd4e5da5Sopenharmony_ci%22 = OpLabel
3017fd4e5da5Sopenharmony_ciOpStore %19 %true
3018fd4e5da5Sopenharmony_ciOpBranch %24
3019fd4e5da5Sopenharmony_ci%23 = OpLabel
3020fd4e5da5Sopenharmony_ciOpBranch %22
3021fd4e5da5Sopenharmony_ci%24 = OpLabel
3022fd4e5da5Sopenharmony_ciOpReturn
3023fd4e5da5Sopenharmony_ciOpFunctionEnd
3024fd4e5da5Sopenharmony_ci)";
3025fd4e5da5Sopenharmony_ci
3026fd4e5da5Sopenharmony_ci  // The early return case must be handled by merge-return first.
3027fd4e5da5Sopenharmony_ci  AddPass<MergeReturnPass>();
3028fd4e5da5Sopenharmony_ci  AddPass<InlineExhaustivePass>();
3029fd4e5da5Sopenharmony_ci  RunAndCheck(predefs + foo + before, predefs + fooMergeReturn + after);
3030fd4e5da5Sopenharmony_ci}
3031fd4e5da5Sopenharmony_ci
3032fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CalleeWithSingleReturnNeedsSingleTripLoopWrapper) {
3033fd4e5da5Sopenharmony_ci  // The case from https://github.com/KhronosGroup/SPIRV-Tools/issues/2018
3034fd4e5da5Sopenharmony_ci  //
3035fd4e5da5Sopenharmony_ci  // The callee has a single return, but needs single-trip loop wrapper
3036fd4e5da5Sopenharmony_ci  // to be inlined because the return is in a selection structure.
3037fd4e5da5Sopenharmony_ci
3038fd4e5da5Sopenharmony_ci  const std::string predefs =
3039fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
3040fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
3041fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3042fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %_GLF_color
3043fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
3044fd4e5da5Sopenharmony_ciOpSource ESSL 310
3045fd4e5da5Sopenharmony_ciOpName %main "main"
3046fd4e5da5Sopenharmony_ciOpName %f_ "f("
3047fd4e5da5Sopenharmony_ciOpName %i "i"
3048fd4e5da5Sopenharmony_ciOpName %_GLF_color "_GLF_color"
3049fd4e5da5Sopenharmony_ciOpDecorate %_GLF_color Location 0
3050fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3051fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
3052fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
3053fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %float
3054fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
3055fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3056fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool
3057fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
3058fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
3059fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
3060fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3061fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
3062fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
3063fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3064fd4e5da5Sopenharmony_ci%_GLF_color = OpVariable %_ptr_Output_v4float Output
3065fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
3066fd4e5da5Sopenharmony_ci%21 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
3067fd4e5da5Sopenharmony_ci%22 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
3068fd4e5da5Sopenharmony_ci)";
3069fd4e5da5Sopenharmony_ci
3070fd4e5da5Sopenharmony_ci  const std::string new_predefs =
3071fd4e5da5Sopenharmony_ci      R"(%_ptr_Function_float = OpTypePointer Function %float
3072fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
3073fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
3074fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool
3075fd4e5da5Sopenharmony_ci)";
3076fd4e5da5Sopenharmony_ci
3077fd4e5da5Sopenharmony_ci  const std::string main_before =
3078fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
3079fd4e5da5Sopenharmony_ci%23 = OpLabel
3080fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function
3081fd4e5da5Sopenharmony_ciOpStore %i %int_0
3082fd4e5da5Sopenharmony_ciOpBranch %24
3083fd4e5da5Sopenharmony_ci%24 = OpLabel
3084fd4e5da5Sopenharmony_ciOpLoopMerge %25 %26 None
3085fd4e5da5Sopenharmony_ciOpBranch %27
3086fd4e5da5Sopenharmony_ci%27 = OpLabel
3087fd4e5da5Sopenharmony_ci%28 = OpLoad %int %i
3088fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %28 %int_1
3089fd4e5da5Sopenharmony_ciOpBranchConditional %29 %30 %25
3090fd4e5da5Sopenharmony_ci%30 = OpLabel
3091fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21
3092fd4e5da5Sopenharmony_ci%31 = OpFunctionCall %float %f_
3093fd4e5da5Sopenharmony_ciOpBranch %26
3094fd4e5da5Sopenharmony_ci%26 = OpLabel
3095fd4e5da5Sopenharmony_ci%32 = OpLoad %int %i
3096fd4e5da5Sopenharmony_ci%33 = OpIAdd %int %32 %int_1
3097fd4e5da5Sopenharmony_ciOpStore %i %33
3098fd4e5da5Sopenharmony_ciOpBranch %24
3099fd4e5da5Sopenharmony_ci%25 = OpLabel
3100fd4e5da5Sopenharmony_ciOpStore %_GLF_color %22
3101fd4e5da5Sopenharmony_ciOpReturn
3102fd4e5da5Sopenharmony_ciOpFunctionEnd
3103fd4e5da5Sopenharmony_ci)";
3104fd4e5da5Sopenharmony_ci
3105fd4e5da5Sopenharmony_ci  const std::string main_after =
3106fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
3107fd4e5da5Sopenharmony_ci%23 = OpLabel
3108fd4e5da5Sopenharmony_ci%46 = OpVariable %_ptr_Function_bool Function %false
3109fd4e5da5Sopenharmony_ci%47 = OpVariable %_ptr_Function_float Function
3110fd4e5da5Sopenharmony_ci%48 = OpVariable %_ptr_Function_float Function
3111fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function
3112fd4e5da5Sopenharmony_ciOpStore %i %int_0
3113fd4e5da5Sopenharmony_ciOpBranch %24
3114fd4e5da5Sopenharmony_ci%24 = OpLabel
3115fd4e5da5Sopenharmony_ciOpLoopMerge %25 %26 None
3116fd4e5da5Sopenharmony_ciOpBranch %27
3117fd4e5da5Sopenharmony_ci%27 = OpLabel
3118fd4e5da5Sopenharmony_ci%28 = OpLoad %int %i
3119fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %28 %int_1
3120fd4e5da5Sopenharmony_ciOpBranchConditional %29 %30 %25
3121fd4e5da5Sopenharmony_ci%30 = OpLabel
3122fd4e5da5Sopenharmony_ciOpStore %_GLF_color %21
3123fd4e5da5Sopenharmony_ciOpStore %46 %false
3124fd4e5da5Sopenharmony_ciOpSelectionMerge %53 None
3125fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %50
3126fd4e5da5Sopenharmony_ci%50 = OpLabel
3127fd4e5da5Sopenharmony_ciOpSelectionMerge %52 None
3128fd4e5da5Sopenharmony_ciOpBranchConditional %true %51 %52
3129fd4e5da5Sopenharmony_ci%51 = OpLabel
3130fd4e5da5Sopenharmony_ciOpStore %46 %true
3131fd4e5da5Sopenharmony_ciOpStore %47 %float_1
3132fd4e5da5Sopenharmony_ciOpBranch %53
3133fd4e5da5Sopenharmony_ci%52 = OpLabel
3134fd4e5da5Sopenharmony_ciOpStore %46 %true
3135fd4e5da5Sopenharmony_ciOpStore %47 %float_1
3136fd4e5da5Sopenharmony_ciOpBranch %53
3137fd4e5da5Sopenharmony_ci%53 = OpLabel
3138fd4e5da5Sopenharmony_ci%54 = OpLoad %float %47
3139fd4e5da5Sopenharmony_ciOpStore %48 %54
3140fd4e5da5Sopenharmony_ci%31 = OpLoad %float %48
3141fd4e5da5Sopenharmony_ciOpBranch %26
3142fd4e5da5Sopenharmony_ci%26 = OpLabel
3143fd4e5da5Sopenharmony_ci%32 = OpLoad %int %i
3144fd4e5da5Sopenharmony_ci%33 = OpIAdd %int %32 %int_1
3145fd4e5da5Sopenharmony_ciOpStore %i %33
3146fd4e5da5Sopenharmony_ciOpBranch %24
3147fd4e5da5Sopenharmony_ci%25 = OpLabel
3148fd4e5da5Sopenharmony_ciOpStore %_GLF_color %22
3149fd4e5da5Sopenharmony_ciOpReturn
3150fd4e5da5Sopenharmony_ciOpFunctionEnd
3151fd4e5da5Sopenharmony_ci)";
3152fd4e5da5Sopenharmony_ci
3153fd4e5da5Sopenharmony_ci  const std::string callee =
3154fd4e5da5Sopenharmony_ci      R"(%f_ = OpFunction %float None %9
3155fd4e5da5Sopenharmony_ci%34 = OpLabel
3156fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None
3157fd4e5da5Sopenharmony_ciOpBranchConditional %true %36 %35
3158fd4e5da5Sopenharmony_ci%36 = OpLabel
3159fd4e5da5Sopenharmony_ciOpReturnValue %float_1
3160fd4e5da5Sopenharmony_ci%35 = OpLabel
3161fd4e5da5Sopenharmony_ciOpReturnValue %float_1
3162fd4e5da5Sopenharmony_ciOpFunctionEnd
3163fd4e5da5Sopenharmony_ci)";
3164fd4e5da5Sopenharmony_ci
3165fd4e5da5Sopenharmony_ci  const std::string calleeMergeReturn =
3166fd4e5da5Sopenharmony_ci      R"(%f_ = OpFunction %float None %9
3167fd4e5da5Sopenharmony_ci%34 = OpLabel
3168fd4e5da5Sopenharmony_ci%45 = OpVariable %_ptr_Function_bool Function %false
3169fd4e5da5Sopenharmony_ci%39 = OpVariable %_ptr_Function_float Function
3170fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None
3171fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %41
3172fd4e5da5Sopenharmony_ci%41 = OpLabel
3173fd4e5da5Sopenharmony_ciOpSelectionMerge %35 None
3174fd4e5da5Sopenharmony_ciOpBranchConditional %true %36 %35
3175fd4e5da5Sopenharmony_ci%36 = OpLabel
3176fd4e5da5Sopenharmony_ciOpStore %45 %true
3177fd4e5da5Sopenharmony_ciOpStore %39 %float_1
3178fd4e5da5Sopenharmony_ciOpBranch %37
3179fd4e5da5Sopenharmony_ci%35 = OpLabel
3180fd4e5da5Sopenharmony_ciOpStore %45 %true
3181fd4e5da5Sopenharmony_ciOpStore %39 %float_1
3182fd4e5da5Sopenharmony_ciOpBranch %37
3183fd4e5da5Sopenharmony_ci%37 = OpLabel
3184fd4e5da5Sopenharmony_ci%40 = OpLoad %float %39
3185fd4e5da5Sopenharmony_ciOpReturnValue %40
3186fd4e5da5Sopenharmony_ciOpFunctionEnd
3187fd4e5da5Sopenharmony_ci)";
3188fd4e5da5Sopenharmony_ci
3189fd4e5da5Sopenharmony_ci  // The early return case must be handled by merge-return first.
3190fd4e5da5Sopenharmony_ci  AddPass<MergeReturnPass>();
3191fd4e5da5Sopenharmony_ci  AddPass<InlineExhaustivePass>();
3192fd4e5da5Sopenharmony_ci  RunAndCheck(predefs + main_before + callee,
3193fd4e5da5Sopenharmony_ci              predefs + new_predefs + main_after + calleeMergeReturn);
3194fd4e5da5Sopenharmony_ci}
3195fd4e5da5Sopenharmony_ci
3196fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ForwardReferencesInPhiInlined) {
3197fd4e5da5Sopenharmony_ci  // The basic structure of the test case is like this:
3198fd4e5da5Sopenharmony_ci  //
3199fd4e5da5Sopenharmony_ci  // int foo() {
3200fd4e5da5Sopenharmony_ci  //   int result = 1;
3201fd4e5da5Sopenharmony_ci  //   if (true) {
3202fd4e5da5Sopenharmony_ci  //      result = 1;
3203fd4e5da5Sopenharmony_ci  //   }
3204fd4e5da5Sopenharmony_ci  //   return result;
3205fd4e5da5Sopenharmony_ci  // }
3206fd4e5da5Sopenharmony_ci  //
3207fd4e5da5Sopenharmony_ci  // void main() {
3208fd4e5da5Sopenharmony_ci  //  int x = foo();
3209fd4e5da5Sopenharmony_ci  // }
3210fd4e5da5Sopenharmony_ci  //
3211fd4e5da5Sopenharmony_ci  // but with modifications: Using Phi instead of load/store, and the
3212fd4e5da5Sopenharmony_ci  // return block in foo appears before the "then" block.
3213fd4e5da5Sopenharmony_ci
3214fd4e5da5Sopenharmony_ci  const std::string predefs =
3215fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
3216fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
3217fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3218fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
3219fd4e5da5Sopenharmony_ciOpSource GLSL 450
3220fd4e5da5Sopenharmony_ciOpName %main "main"
3221fd4e5da5Sopenharmony_ciOpName %foo_ "foo("
3222fd4e5da5Sopenharmony_ciOpName %x "x"
3223fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3224fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void
3225fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
3226fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %int
3227fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3228fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
3229fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3230fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
3231fd4e5da5Sopenharmony_ci)";
3232fd4e5da5Sopenharmony_ci
3233fd4e5da5Sopenharmony_ci  const std::string callee =
3234fd4e5da5Sopenharmony_ci      R"(%foo_ = OpFunction %int None %8
3235fd4e5da5Sopenharmony_ci%13 = OpLabel
3236fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_0
3237fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None
3238fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %15
3239fd4e5da5Sopenharmony_ci%15 = OpLabel
3240fd4e5da5Sopenharmony_ci%17 = OpPhi %int %14 %13 %18 %16
3241fd4e5da5Sopenharmony_ciOpReturnValue %17
3242fd4e5da5Sopenharmony_ci%16 = OpLabel
3243fd4e5da5Sopenharmony_ci%18 = OpCopyObject %int %int_0
3244fd4e5da5Sopenharmony_ciOpBranch %15
3245fd4e5da5Sopenharmony_ciOpFunctionEnd
3246fd4e5da5Sopenharmony_ci)";
3247fd4e5da5Sopenharmony_ci
3248fd4e5da5Sopenharmony_ci  const std::string calleeMergeReturn =
3249fd4e5da5Sopenharmony_ci      R"(%uint = OpTypeInt 32 0
3250fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
3251fd4e5da5Sopenharmony_ci%false = OpConstantFalse %bool
3252fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool
3253fd4e5da5Sopenharmony_ci%foo_ = OpFunction %int None %8
3254fd4e5da5Sopenharmony_ci%13 = OpLabel
3255fd4e5da5Sopenharmony_ci%29 = OpVariable %_ptr_Function_bool Function %false
3256fd4e5da5Sopenharmony_ci%22 = OpVariable %_ptr_Function_int Function
3257fd4e5da5Sopenharmony_ciOpSelectionMerge %21 None
3258fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %24
3259fd4e5da5Sopenharmony_ci%24 = OpLabel
3260fd4e5da5Sopenharmony_ci%14 = OpCopyObject %int %int_0
3261fd4e5da5Sopenharmony_ciOpSelectionMerge %15 None
3262fd4e5da5Sopenharmony_ciOpBranchConditional %true %16 %15
3263fd4e5da5Sopenharmony_ci%15 = OpLabel
3264fd4e5da5Sopenharmony_ci%17 = OpPhi %int %14 %24 %18 %16
3265fd4e5da5Sopenharmony_ciOpStore %29 %true
3266fd4e5da5Sopenharmony_ciOpStore %22 %17
3267fd4e5da5Sopenharmony_ciOpBranch %21
3268fd4e5da5Sopenharmony_ci%16 = OpLabel
3269fd4e5da5Sopenharmony_ci%18 = OpCopyObject %int %int_0
3270fd4e5da5Sopenharmony_ciOpBranch %15
3271fd4e5da5Sopenharmony_ci%21 = OpLabel
3272fd4e5da5Sopenharmony_ci%23 = OpLoad %int %22
3273fd4e5da5Sopenharmony_ciOpReturnValue %23
3274fd4e5da5Sopenharmony_ciOpFunctionEnd
3275fd4e5da5Sopenharmony_ci)";
3276fd4e5da5Sopenharmony_ci
3277fd4e5da5Sopenharmony_ci  const std::string before =
3278fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %6
3279fd4e5da5Sopenharmony_ci%19 = OpLabel
3280fd4e5da5Sopenharmony_ci%x = OpVariable %_ptr_Function_int Function
3281fd4e5da5Sopenharmony_ci%20 = OpFunctionCall %int %foo_
3282fd4e5da5Sopenharmony_ciOpStore %x %20
3283fd4e5da5Sopenharmony_ciOpReturn
3284fd4e5da5Sopenharmony_ciOpFunctionEnd
3285fd4e5da5Sopenharmony_ci)";
3286fd4e5da5Sopenharmony_ci
3287fd4e5da5Sopenharmony_ci  const std::string after =
3288fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %6
3289fd4e5da5Sopenharmony_ci%19 = OpLabel
3290fd4e5da5Sopenharmony_ci%30 = OpVariable %_ptr_Function_bool Function %false
3291fd4e5da5Sopenharmony_ci%31 = OpVariable %_ptr_Function_int Function
3292fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_int Function
3293fd4e5da5Sopenharmony_ci%x = OpVariable %_ptr_Function_int Function
3294fd4e5da5Sopenharmony_ciOpStore %30 %false
3295fd4e5da5Sopenharmony_ciOpSelectionMerge %40 None
3296fd4e5da5Sopenharmony_ciOpSwitch %uint_0 %34
3297fd4e5da5Sopenharmony_ci%34 = OpLabel
3298fd4e5da5Sopenharmony_ci%35 = OpCopyObject %int %int_0
3299fd4e5da5Sopenharmony_ciOpSelectionMerge %36 None
3300fd4e5da5Sopenharmony_ciOpBranchConditional %true %38 %36
3301fd4e5da5Sopenharmony_ci%36 = OpLabel
3302fd4e5da5Sopenharmony_ci%37 = OpPhi %int %35 %34 %39 %38
3303fd4e5da5Sopenharmony_ciOpStore %30 %true
3304fd4e5da5Sopenharmony_ciOpStore %31 %37
3305fd4e5da5Sopenharmony_ciOpBranch %40
3306fd4e5da5Sopenharmony_ci%38 = OpLabel
3307fd4e5da5Sopenharmony_ci%39 = OpCopyObject %int %int_0
3308fd4e5da5Sopenharmony_ciOpBranch %36
3309fd4e5da5Sopenharmony_ci%40 = OpLabel
3310fd4e5da5Sopenharmony_ci%41 = OpLoad %int %31
3311fd4e5da5Sopenharmony_ciOpStore %32 %41
3312fd4e5da5Sopenharmony_ci%20 = OpLoad %int %32
3313fd4e5da5Sopenharmony_ciOpStore %x %20
3314fd4e5da5Sopenharmony_ciOpReturn
3315fd4e5da5Sopenharmony_ciOpFunctionEnd
3316fd4e5da5Sopenharmony_ci)";
3317fd4e5da5Sopenharmony_ci
3318fd4e5da5Sopenharmony_ci  AddPass<MergeReturnPass>();
3319fd4e5da5Sopenharmony_ci  AddPass<InlineExhaustivePass>();
3320fd4e5da5Sopenharmony_ci  RunAndCheck(predefs + callee + before, predefs + calleeMergeReturn + after);
3321fd4e5da5Sopenharmony_ci}
3322fd4e5da5Sopenharmony_ci
3323fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugSimple) {
3324fd4e5da5Sopenharmony_ci  // Check that it correctly generates DebugInlinedAt and maps it to DebugScope
3325fd4e5da5Sopenharmony_ci  // for the inlined function foo().
3326fd4e5da5Sopenharmony_ci  const std::string text = R"(
3327fd4e5da5Sopenharmony_ci; CHECK: [[main_name:%\d+]] = OpString "main"
3328fd4e5da5Sopenharmony_ci; CHECK: [[foo_name:%\d+]] = OpString "foo"
3329fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[main_name]] {{%\d+}} {{%\d+}} 4 1 {{%\d+}} [[main_name]] FlagIsProtected|FlagIsPrivate 4 [[main:%\d+]]
3330fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[foo_name]] {{%\d+}} {{%\d+}} 1 1 {{%\d+}} [[foo_name]] FlagIsProtected|FlagIsPrivate 1 [[foo:%\d+]]
3331fd4e5da5Sopenharmony_ci; CHECK: [[foo_bb:%\d+]] = OpExtInst %void {{%\d+}} DebugLexicalBlock {{%\d+}} 1 14 [[dbg_foo]]
3332fd4e5da5Sopenharmony_ci; CHECK: [[inlined_at:%\d+]] = OpExtInst %void {{%\d+}} DebugInlinedAt 4 [[dbg_main]]
3333fd4e5da5Sopenharmony_ci; CHECK: [[main]] = OpFunction %void None
3334fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void {{%\d+}} DebugScope [[foo_bb]] [[inlined_at]]
3335fd4e5da5Sopenharmony_ci; CHECK: [[foo]] = OpFunction %v4float None
3336fd4e5da5Sopenharmony_ci               OpCapability Shader
3337fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.DebugInfo.100"
3338fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3339fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %3 %4
3340fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
3341fd4e5da5Sopenharmony_ci          %5 = OpString "ps.hlsl"
3342fd4e5da5Sopenharmony_ci               OpSource HLSL 600 %5
3343fd4e5da5Sopenharmony_ci          %6 = OpString "float"
3344fd4e5da5Sopenharmony_ci  %main_name = OpString "main"
3345fd4e5da5Sopenharmony_ci   %foo_name = OpString "foo"
3346fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
3347fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
3348fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
3349fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
3350fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
3351fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
3352fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
3353fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3354fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3355fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3356fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
3357fd4e5da5Sopenharmony_ci         %18 = OpTypeFunction %void
3358fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %v4float
3359fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
3360fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
3361fd4e5da5Sopenharmony_ci         %20 = OpExtInst %void %1 DebugSource %5
3362fd4e5da5Sopenharmony_ci         %21 = OpExtInst %void %1 DebugCompilationUnit 1 4 %20 HLSL
3363fd4e5da5Sopenharmony_ci         %22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float
3364fd4e5da5Sopenharmony_ci         %23 = OpExtInst %void %1 DebugTypeVector %22 4
3365fd4e5da5Sopenharmony_ci         %24 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 %23
3366fd4e5da5Sopenharmony_ci         %25 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23
3367fd4e5da5Sopenharmony_ci   %dbg_main = OpExtInst %void %1 DebugFunction %main_name %24 %20 4 1 %21 %main_name FlagIsProtected|FlagIsPrivate 4 %main
3368fd4e5da5Sopenharmony_ci    %dbg_foo = OpExtInst %void %1 DebugFunction %foo_name %25 %20 1 1 %21 %foo_name FlagIsProtected|FlagIsPrivate 1 %foo
3369fd4e5da5Sopenharmony_ci         %29 = OpExtInst %void %1 DebugLexicalBlock %20 1 14 %dbg_foo
3370fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %18
3371fd4e5da5Sopenharmony_ci         %30 = OpLabel
3372fd4e5da5Sopenharmony_ci         %31 = OpExtInst %void %1 DebugScope %dbg_main
3373fd4e5da5Sopenharmony_ci         %32 = OpFunctionCall %v4float %foo
3374fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
3375fd4e5da5Sopenharmony_ci         %34 = OpFAdd %v4float %32 %33
3376fd4e5da5Sopenharmony_ci               OpStore %4 %34
3377fd4e5da5Sopenharmony_ci               OpReturn
3378fd4e5da5Sopenharmony_ci               OpFunctionEnd
3379fd4e5da5Sopenharmony_ci        %foo = OpFunction %v4float None %19
3380fd4e5da5Sopenharmony_ci         %35 = OpExtInst %void %1 DebugScope %dbg_foo
3381fd4e5da5Sopenharmony_ci         %36 = OpLabel
3382fd4e5da5Sopenharmony_ci         %37 = OpExtInst %void %1 DebugScope %29
3383fd4e5da5Sopenharmony_ci               OpReturnValue %14
3384fd4e5da5Sopenharmony_ci               OpFunctionEnd
3385fd4e5da5Sopenharmony_ci)";
3386fd4e5da5Sopenharmony_ci
3387fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3388fd4e5da5Sopenharmony_ci}
3389fd4e5da5Sopenharmony_ci
3390fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ShaderDebugSimple) {
3391fd4e5da5Sopenharmony_ci  // Same as DebugSimple but for NonSemantic.Shader.DebugInfo.100.
3392fd4e5da5Sopenharmony_ci  const std::string text = R"(
3393fd4e5da5Sopenharmony_ci; CHECK: [[main_name:%\d+]] = OpString "main"
3394fd4e5da5Sopenharmony_ci; CHECK: [[foo_name:%\d+]] = OpString "foo"
3395fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[main_name]] {{%\d+}} {{%\d+}} %uint_4 %uint_1 {{%\d+}} [[main_name]] %uint_3 %uint_4
3396fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void {{%\d+}} DebugFunction [[foo_name]] {{%\d+}} {{%\d+}} %uint_1 %uint_1 {{%\d+}} [[foo_name]] %uint_3 %uint_1
3397fd4e5da5Sopenharmony_ci; CHECK: [[foo_bb:%\d+]] = OpExtInst %void {{%\d+}} DebugLexicalBlock {{%\d+}} %uint_1 %uint_14 [[dbg_foo]]
3398fd4e5da5Sopenharmony_ci; CHECK: [[inlined_at:%\d+]] = OpExtInst %void {{%\d+}} DebugInlinedAt %uint_4 [[dbg_main]]
3399fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpFunction %void None
3400fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void {{%\d+}} DebugScope [[foo_bb]] [[inlined_at]]
3401fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpFunction %v4float None
3402fd4e5da5Sopenharmony_ci               OpCapability Shader
3403fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_non_semantic_info"
3404fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
3405fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3406fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %3 %4
3407fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
3408fd4e5da5Sopenharmony_ci          %5 = OpString "ps.hlsl"
3409fd4e5da5Sopenharmony_ci               OpSource HLSL 600 %5
3410fd4e5da5Sopenharmony_ci          %6 = OpString "float"
3411fd4e5da5Sopenharmony_ci  %main_name = OpString "main"
3412fd4e5da5Sopenharmony_ci   %foo_name = OpString "foo"
3413fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
3414fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
3415fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
3416fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
3417fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
3418fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
3419fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
3420fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
3421fd4e5da5Sopenharmony_ci     %uint_5 = OpConstant %uint 5
3422fd4e5da5Sopenharmony_ci    %uint_14 = OpConstant %uint 14
3423fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
3424fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
3425fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
3426fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
3427fd4e5da5Sopenharmony_ci         %14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3428fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3429fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3430fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
3431fd4e5da5Sopenharmony_ci         %18 = OpTypeFunction %void
3432fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %v4float
3433fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
3434fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
3435fd4e5da5Sopenharmony_ci         %20 = OpExtInst %void %1 DebugSource %5
3436fd4e5da5Sopenharmony_ci         %21 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %20 %uint_5
3437fd4e5da5Sopenharmony_ci         %22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 %uint_3 %uint_0
3438fd4e5da5Sopenharmony_ci         %23 = OpExtInst %void %1 DebugTypeVector %22 %uint_4
3439fd4e5da5Sopenharmony_ci         %24 = OpExtInst %void %1 DebugTypeFunction %uint_3 %23 %23
3440fd4e5da5Sopenharmony_ci         %25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %23
3441fd4e5da5Sopenharmony_ci   %dbg_main = OpExtInst %void %1 DebugFunction %main_name %24 %20 %uint_4 %uint_1 %21 %main_name %uint_3 %uint_4
3442fd4e5da5Sopenharmony_ci    %dbg_foo = OpExtInst %void %1 DebugFunction %foo_name %25 %20 %uint_1 %uint_1 %21 %foo_name %uint_3 %uint_1
3443fd4e5da5Sopenharmony_ci         %29 = OpExtInst %void %1 DebugLexicalBlock %20 %uint_1 %uint_14 %dbg_foo
3444fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %18
3445fd4e5da5Sopenharmony_ci         %30 = OpLabel
3446fd4e5da5Sopenharmony_ci%dbg_main_def = OpExtInst %void %1 DebugFunctionDefinition %dbg_main %main
3447fd4e5da5Sopenharmony_ci         %31 = OpExtInst %void %1 DebugScope %dbg_main
3448fd4e5da5Sopenharmony_ci         %32 = OpFunctionCall %v4float %foo
3449fd4e5da5Sopenharmony_ci         %33 = OpLoad %v4float %3
3450fd4e5da5Sopenharmony_ci         %34 = OpFAdd %v4float %32 %33
3451fd4e5da5Sopenharmony_ci               OpStore %4 %34
3452fd4e5da5Sopenharmony_ci               OpReturn
3453fd4e5da5Sopenharmony_ci               OpFunctionEnd
3454fd4e5da5Sopenharmony_ci        %foo = OpFunction %v4float None %19
3455fd4e5da5Sopenharmony_ci         %36 = OpLabel
3456fd4e5da5Sopenharmony_ci%dbg_foo_def = OpExtInst %void %1 DebugFunctionDefinition %dbg_foo %foo
3457fd4e5da5Sopenharmony_ci         %35 = OpExtInst %void %1 DebugScope %dbg_foo
3458fd4e5da5Sopenharmony_ci         %37 = OpExtInst %void %1 DebugScope %29
3459fd4e5da5Sopenharmony_ci               OpReturnValue %14
3460fd4e5da5Sopenharmony_ci               OpFunctionEnd
3461fd4e5da5Sopenharmony_ci)";
3462fd4e5da5Sopenharmony_ci
3463fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3464fd4e5da5Sopenharmony_ci}
3465fd4e5da5Sopenharmony_ci
3466fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugNested) {
3467fd4e5da5Sopenharmony_ci  // When function main() calls function zoo() and function zoo() calls
3468fd4e5da5Sopenharmony_ci  // function bar() and function bar() calls function foo(), check that
3469fd4e5da5Sopenharmony_ci  // the inline pass correctly generates DebugInlinedAt instructions
3470fd4e5da5Sopenharmony_ci  // for the nested function calls.
3471fd4e5da5Sopenharmony_ci  const std::string text = R"(
3472fd4e5da5Sopenharmony_ci; CHECK: [[v4f1:%\d+]] = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3473fd4e5da5Sopenharmony_ci; CHECK: [[v4f2:%\d+]] = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
3474fd4e5da5Sopenharmony_ci; CHECK: [[v4f3:%\d+]] = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3
3475fd4e5da5Sopenharmony_ci; CHECK: [[color:%\d+]] = OpVariable %_ptr_Input_v4float Input
3476fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 10 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 10 [[main:%\d+]]
3477fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 [[foo:%\d+]]
3478fd4e5da5Sopenharmony_ci; CHECK: [[dbg_bar:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 4 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 4 [[bar:%\d+]]
3479fd4e5da5Sopenharmony_ci; CHECK: [[dbg_zoo:%\d+]] = OpExtInst %void [[ext]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 7 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 7 [[zoo:%\d+]]
3480fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 600 [[dbg_main]]
3481fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_zoo:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 700 [[dbg_zoo]] [[inlined_to_main]]
3482fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_bar:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 300 [[dbg_bar]] [[inlined_to_zoo]]
3483fd4e5da5Sopenharmony_ci; CHECK: [[main]] = OpFunction %void None
3484fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_foo]] [[inlined_to_bar]]
3485fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 100 0
3486fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpStore {{%\d+}} [[v4f1]]
3487fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_bar]] [[inlined_to_zoo]]
3488fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 300 0
3489fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[foo_ret:%\d+]] = OpLoad %v4float
3490fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 400 0
3491fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[foo_ret]] [[v4f2]]
3492fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_zoo]] [[inlined_to_main]]
3493fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 700 0
3494fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[bar_ret:%\d+]] = OpLoad %v4float
3495fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[bar_ret]] [[v4f3]]
3496fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]]
3497fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLine {{%\d+}} 600 0
3498fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[zoo_ret:%\d+]] = OpLoad %v4float
3499fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[color_val:%\d+]] = OpLoad %v4float [[color]]
3500fd4e5da5Sopenharmony_ci; CHECK-NEXT: {{%\d+}} = OpFAdd %v4float [[zoo_ret]] [[color_val]]
3501fd4e5da5Sopenharmony_ci; CHECK: [[foo]] = OpFunction %v4float None
3502fd4e5da5Sopenharmony_ci; CHECK: [[bar]] = OpFunction %v4float None
3503fd4e5da5Sopenharmony_ci; CHECK: [[zoo]] = OpFunction %v4float None
3504fd4e5da5Sopenharmony_ci               OpCapability Shader
3505fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.DebugInfo.100"
3506fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3507fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %3 %4
3508fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
3509fd4e5da5Sopenharmony_ci          %5 = OpString "ps.hlsl"
3510fd4e5da5Sopenharmony_ci               OpSource HLSL 600 %5
3511fd4e5da5Sopenharmony_ci          %6 = OpString "float"
3512fd4e5da5Sopenharmony_ci          %7 = OpString "main"
3513fd4e5da5Sopenharmony_ci          %8 = OpString "foo"
3514fd4e5da5Sopenharmony_ci          %9 = OpString "bar"
3515fd4e5da5Sopenharmony_ci         %10 = OpString "zoo"
3516fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
3517fd4e5da5Sopenharmony_ci               OpDecorate %4 Location 0
3518fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
3519fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
3520fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
3521fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
3522fd4e5da5Sopenharmony_ci    %float_2 = OpConstant %float 2
3523fd4e5da5Sopenharmony_ci    %float_3 = OpConstant %float 3
3524fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
3525fd4e5da5Sopenharmony_ci         %18 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3526fd4e5da5Sopenharmony_ci         %19 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
3527fd4e5da5Sopenharmony_ci         %20 = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3
3528fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3529fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3530fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
3531fd4e5da5Sopenharmony_ci         %24 = OpTypeFunction %void
3532fd4e5da5Sopenharmony_ci         %25 = OpTypeFunction %v4float
3533fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Input_v4float Input
3534fd4e5da5Sopenharmony_ci          %4 = OpVariable %_ptr_Output_v4float Output
3535fd4e5da5Sopenharmony_ci         %26 = OpExtInst %void %1 DebugSource %5
3536fd4e5da5Sopenharmony_ci         %27 = OpExtInst %void %1 DebugCompilationUnit 1 4 %26 HLSL
3537fd4e5da5Sopenharmony_ci         %28 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float
3538fd4e5da5Sopenharmony_ci         %29 = OpExtInst %void %1 DebugTypeVector %28 4
3539fd4e5da5Sopenharmony_ci         %30 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %29 %29
3540fd4e5da5Sopenharmony_ci         %31 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %29
3541fd4e5da5Sopenharmony_ci         %32 = OpExtInst %void %1 DebugFunction %7 %30 %26 10 1 %27 %7 FlagIsProtected|FlagIsPrivate 10 %main
3542fd4e5da5Sopenharmony_ci         %33 = OpExtInst %void %1 DebugFunction %8 %31 %26 1 1 %27 %8 FlagIsProtected|FlagIsPrivate 1 %foo
3543fd4e5da5Sopenharmony_ci         %35 = OpExtInst %void %1 DebugFunction %9 %31 %26 4 1 %27 %9 FlagIsProtected|FlagIsPrivate 4 %bar
3544fd4e5da5Sopenharmony_ci         %37 = OpExtInst %void %1 DebugFunction %10 %31 %26 7 1 %27 %10 FlagIsProtected|FlagIsPrivate 7 %zoo
3545fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %24
3546fd4e5da5Sopenharmony_ci         %39 = OpLabel
3547fd4e5da5Sopenharmony_ci         %40 = OpExtInst %void %1 DebugScope %32
3548fd4e5da5Sopenharmony_ci               OpLine %5 600 0
3549fd4e5da5Sopenharmony_ci         %41 = OpFunctionCall %v4float %zoo
3550fd4e5da5Sopenharmony_ci         %42 = OpLoad %v4float %3
3551fd4e5da5Sopenharmony_ci         %43 = OpFAdd %v4float %41 %42
3552fd4e5da5Sopenharmony_ci               OpStore %4 %43
3553fd4e5da5Sopenharmony_ci               OpReturn
3554fd4e5da5Sopenharmony_ci               OpFunctionEnd
3555fd4e5da5Sopenharmony_ci        %foo = OpFunction %v4float None %25
3556fd4e5da5Sopenharmony_ci         %44 = OpExtInst %void %1 DebugScope %33
3557fd4e5da5Sopenharmony_ci         %45 = OpLabel
3558fd4e5da5Sopenharmony_ci               OpLine %5 100 0
3559fd4e5da5Sopenharmony_ci               OpReturnValue %18
3560fd4e5da5Sopenharmony_ci               OpFunctionEnd
3561fd4e5da5Sopenharmony_ci               OpLine %5 200 0
3562fd4e5da5Sopenharmony_ci        %bar = OpFunction %v4float None %25
3563fd4e5da5Sopenharmony_ci         %46 = OpExtInst %void %1 DebugScope %35
3564fd4e5da5Sopenharmony_ci         %47 = OpLabel
3565fd4e5da5Sopenharmony_ci               OpLine %5 300 0
3566fd4e5da5Sopenharmony_ci         %48 = OpFunctionCall %v4float %foo
3567fd4e5da5Sopenharmony_ci               OpLine %5 400 0
3568fd4e5da5Sopenharmony_ci         %49 = OpFAdd %v4float %48 %19
3569fd4e5da5Sopenharmony_ci               OpLine %5 500 0
3570fd4e5da5Sopenharmony_ci               OpReturnValue %49
3571fd4e5da5Sopenharmony_ci               OpFunctionEnd
3572fd4e5da5Sopenharmony_ci        %zoo = OpFunction %v4float None %25
3573fd4e5da5Sopenharmony_ci         %50 = OpExtInst %void %1 DebugScope %37
3574fd4e5da5Sopenharmony_ci         %51 = OpLabel
3575fd4e5da5Sopenharmony_ci               OpLine %5 700 0
3576fd4e5da5Sopenharmony_ci         %52 = OpFunctionCall %v4float %bar
3577fd4e5da5Sopenharmony_ci         %53 = OpFAdd %v4float %52 %20
3578fd4e5da5Sopenharmony_ci               OpReturnValue %53
3579fd4e5da5Sopenharmony_ci               OpFunctionEnd
3580fd4e5da5Sopenharmony_ci)";
3581fd4e5da5Sopenharmony_ci
3582fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3583fd4e5da5Sopenharmony_ci}
3584fd4e5da5Sopenharmony_ci
3585fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugSimpleHLSLPixelShader) {
3586fd4e5da5Sopenharmony_ci  const std::string text = R"(
3587fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 %src_main
3588fd4e5da5Sopenharmony_ci; CHECK: [[lex_blk:%\d+]] = OpExtInst %void [[ext]] DebugLexicalBlock {{%\d+}} 1 47 [[dbg_main]]
3589fd4e5da5Sopenharmony_ci; CHECK: %main = OpFunction %void None
3590fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]]
3591fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare {{%\d+}} %param_var_color
3592fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[lex_blk]]
3593fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\d+}} 2 10
3594fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpLoad %v4float %param_var_color
3595fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\d+}} 2 3
3596fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd
3597fd4e5da5Sopenharmony_ci; CHECK: %src_main = OpFunction %v4float None
3598fd4e5da5Sopenharmony_ci               OpCapability Shader
3599fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.DebugInfo.100"
3600fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3601fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
3602fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
3603fd4e5da5Sopenharmony_ci          %5 = OpString "ps.hlsl"
3604fd4e5da5Sopenharmony_ci               OpSource HLSL 600 %5
3605fd4e5da5Sopenharmony_ci         %14 = OpString "#line 1 \"ps.hlsl\"
3606fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET {
3607fd4e5da5Sopenharmony_ci  return color;
3608fd4e5da5Sopenharmony_ci}
3609fd4e5da5Sopenharmony_ci"
3610fd4e5da5Sopenharmony_ci         %17 = OpString "float"
3611fd4e5da5Sopenharmony_ci         %21 = OpString "src.main"
3612fd4e5da5Sopenharmony_ci         %24 = OpString "color"
3613fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR "in.var.COLOR"
3614fd4e5da5Sopenharmony_ci               OpName %out_var_SV_TARGET "out.var.SV_TARGET"
3615fd4e5da5Sopenharmony_ci               OpName %main "main"
3616fd4e5da5Sopenharmony_ci               OpName %param_var_color "param.var.color"
3617fd4e5da5Sopenharmony_ci               OpName %src_main "src.main"
3618fd4e5da5Sopenharmony_ci               OpName %color "color"
3619fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
3620fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR Location 0
3621fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_TARGET Location 0
3622fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
3623fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
3624fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
3625fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
3626fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3627fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3628fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
3629fd4e5da5Sopenharmony_ci         %27 = OpTypeFunction %void
3630fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
3631fd4e5da5Sopenharmony_ci         %33 = OpTypeFunction %v4float %_ptr_Function_v4float
3632fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
3633fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
3634fd4e5da5Sopenharmony_ci         %13 = OpExtInst %void %1 DebugExpression
3635fd4e5da5Sopenharmony_ci         %15 = OpExtInst %void %1 DebugSource %5 %14
3636fd4e5da5Sopenharmony_ci         %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
3637fd4e5da5Sopenharmony_ci         %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
3638fd4e5da5Sopenharmony_ci         %19 = OpExtInst %void %1 DebugTypeVector %18 4
3639fd4e5da5Sopenharmony_ci         %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %19 %19
3640fd4e5da5Sopenharmony_ci         %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %src_main
3641fd4e5da5Sopenharmony_ci         %25 = OpExtInst %void %1 DebugLocalVariable %24 %19 %15 1 20 %22 FlagIsLocal 0
3642fd4e5da5Sopenharmony_ci         %26 = OpExtInst %void %1 DebugLexicalBlock %15 1 47 %22
3643fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %27
3644fd4e5da5Sopenharmony_ci         %28 = OpLabel
3645fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function
3646fd4e5da5Sopenharmony_ci         %31 = OpLoad %v4float %in_var_COLOR
3647fd4e5da5Sopenharmony_ci               OpStore %param_var_color %31
3648fd4e5da5Sopenharmony_ci         %32 = OpFunctionCall %v4float %src_main %param_var_color
3649fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_TARGET %32
3650fd4e5da5Sopenharmony_ci               OpReturn
3651fd4e5da5Sopenharmony_ci               OpFunctionEnd
3652fd4e5da5Sopenharmony_ci               OpLine %5 1 1
3653fd4e5da5Sopenharmony_ci   %src_main = OpFunction %v4float None %33
3654fd4e5da5Sopenharmony_ci         %34 = OpExtInst %void %1 DebugScope %22
3655fd4e5da5Sopenharmony_ci      %color = OpFunctionParameter %_ptr_Function_v4float
3656fd4e5da5Sopenharmony_ci         %36 = OpExtInst %void %1 DebugDeclare %25 %color %13
3657fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
3658fd4e5da5Sopenharmony_ci         %38 = OpExtInst %void %1 DebugScope %26
3659fd4e5da5Sopenharmony_ci               OpLine %5 2 10
3660fd4e5da5Sopenharmony_ci         %39 = OpLoad %v4float %color
3661fd4e5da5Sopenharmony_ci               OpLine %5 2 3
3662fd4e5da5Sopenharmony_ci               OpReturnValue %39
3663fd4e5da5Sopenharmony_ci               OpFunctionEnd
3664fd4e5da5Sopenharmony_ci)";
3665fd4e5da5Sopenharmony_ci
3666fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3667fd4e5da5Sopenharmony_ci}
3668fd4e5da5Sopenharmony_ci
3669fd4e5da5Sopenharmony_ciTEST_F(InlineTest, ShaderDebugSimpleHLSLPixelShader) {
3670fd4e5da5Sopenharmony_ci  // Same as DebugSimpleHLSLPixelShader but for
3671fd4e5da5Sopenharmony_ci  // NonSemantic.Shader.DebugInfo.100.
3672fd4e5da5Sopenharmony_ci  const std::string text = R"(
3673fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction {{%\d+}} {{%\d+}} {{%\d+}} %uint_1 %uint_1 {{%\d+}} {{%\d+}} %uint_3 %uint_1
3674fd4e5da5Sopenharmony_ci; CHECK: [[lex_blk:%\d+]] = OpExtInst %void [[ext]] DebugLexicalBlock {{%\d+}} %uint_1 %uint_47 [[dbg_main]]
3675fd4e5da5Sopenharmony_ci; CHECK: %main = OpFunction %void None
3676fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]]
3677fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare {{%\d+}} %param_var_color
3678fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[lex_blk]]
3679fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugLine {{%\d+}} %uint_2 %uint_2 %uint_10 %uint_10
3680fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpLoad %v4float %param_var_color
3681fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugLine {{%\d+}} %uint_2 %uint_2 %uint_3 %uint_3
3682fd4e5da5Sopenharmony_ci; CHECK: OpFunctionEnd
3683fd4e5da5Sopenharmony_ci; CHECK: %src_main = OpFunction %v4float None
3684fd4e5da5Sopenharmony_ci               OpCapability Shader
3685fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_non_semantic_info"
3686fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
3687fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3688fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
3689fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
3690fd4e5da5Sopenharmony_ci          %5 = OpString "ps.hlsl"
3691fd4e5da5Sopenharmony_ci               OpSource HLSL 600 %5
3692fd4e5da5Sopenharmony_ci         %14 = OpString "#line 1 \"ps.hlsl\"
3693fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET {
3694fd4e5da5Sopenharmony_ci  return color;
3695fd4e5da5Sopenharmony_ci}
3696fd4e5da5Sopenharmony_ci"
3697fd4e5da5Sopenharmony_ci         %17 = OpString "float"
3698fd4e5da5Sopenharmony_ci         %21 = OpString "src.main"
3699fd4e5da5Sopenharmony_ci         %24 = OpString "color"
3700fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR "in.var.COLOR"
3701fd4e5da5Sopenharmony_ci               OpName %out_var_SV_TARGET "out.var.SV_TARGET"
3702fd4e5da5Sopenharmony_ci               OpName %main "main"
3703fd4e5da5Sopenharmony_ci               OpName %param_var_color "param.var.color"
3704fd4e5da5Sopenharmony_ci               OpName %src_main "src.main"
3705fd4e5da5Sopenharmony_ci               OpName %color "color"
3706fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
3707fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR Location 0
3708fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_TARGET Location 0
3709fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
3710fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
3711fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
3712fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
3713fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
3714fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
3715fd4e5da5Sopenharmony_ci     %uint_5 = OpConstant %uint 5
3716fd4e5da5Sopenharmony_ci    %uint_10 = OpConstant %uint 10
3717fd4e5da5Sopenharmony_ci    %uint_20 = OpConstant %uint 20
3718fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
3719fd4e5da5Sopenharmony_ci    %uint_47 = OpConstant %uint 47
3720fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
3721fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
3722fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3723fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3724fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
3725fd4e5da5Sopenharmony_ci         %27 = OpTypeFunction %void
3726fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
3727fd4e5da5Sopenharmony_ci         %33 = OpTypeFunction %v4float %_ptr_Function_v4float
3728fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
3729fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
3730fd4e5da5Sopenharmony_ci         %13 = OpExtInst %void %1 DebugExpression
3731fd4e5da5Sopenharmony_ci         %15 = OpExtInst %void %1 DebugSource %5 %14
3732fd4e5da5Sopenharmony_ci         %16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5
3733fd4e5da5Sopenharmony_ci         %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 %uint_3 %uint_0
3734fd4e5da5Sopenharmony_ci         %19 = OpExtInst %void %1 DebugTypeVector %18 %uint_4
3735fd4e5da5Sopenharmony_ci         %20 = OpExtInst %void %1 DebugTypeFunction %uint_3 %19 %19
3736fd4e5da5Sopenharmony_ci         %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 %uint_1 %uint_1 %16 %21 %uint_3 %uint_1
3737fd4e5da5Sopenharmony_ci         %25 = OpExtInst %void %1 DebugLocalVariable %24 %19 %15 %uint_1 %uint_20 %22 %uint_4 %uint_0
3738fd4e5da5Sopenharmony_ci         %26 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_1 %uint_47 %22
3739fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %27
3740fd4e5da5Sopenharmony_ci         %28 = OpLabel
3741fd4e5da5Sopenharmony_ci%param_var_color = OpVariable %_ptr_Function_v4float Function
3742fd4e5da5Sopenharmony_ci         %31 = OpLoad %v4float %in_var_COLOR
3743fd4e5da5Sopenharmony_ci               OpStore %param_var_color %31
3744fd4e5da5Sopenharmony_ci         %32 = OpFunctionCall %v4float %src_main %param_var_color
3745fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_TARGET %32
3746fd4e5da5Sopenharmony_ci               OpReturn
3747fd4e5da5Sopenharmony_ci               OpFunctionEnd
3748fd4e5da5Sopenharmony_ci   %src_main = OpFunction %v4float None %33
3749fd4e5da5Sopenharmony_ci      %color = OpFunctionParameter %_ptr_Function_v4float
3750fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
3751fd4e5da5Sopenharmony_ci        %140 = OpExtInst %void %1 DebugFunctionDefinition %22 %src_main
3752fd4e5da5Sopenharmony_ci        %141 = OpExtInst %void %1 DebugLine %5 %uint_1 %uint_1 %uint_1 %uint_1
3753fd4e5da5Sopenharmony_ci         %34 = OpExtInst %void %1 DebugScope %22
3754fd4e5da5Sopenharmony_ci         %36 = OpExtInst %void %1 DebugDeclare %25 %color %13
3755fd4e5da5Sopenharmony_ci         %38 = OpExtInst %void %1 DebugScope %26
3756fd4e5da5Sopenharmony_ci        %142 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_10 %uint_10
3757fd4e5da5Sopenharmony_ci         %39 = OpLoad %v4float %color
3758fd4e5da5Sopenharmony_ci        %143 = OpExtInst %void %1 DebugLine %5 %uint_2 %uint_2 %uint_3 %uint_3
3759fd4e5da5Sopenharmony_ci               OpReturnValue %39
3760fd4e5da5Sopenharmony_ci               OpFunctionEnd
3761fd4e5da5Sopenharmony_ci)";
3762fd4e5da5Sopenharmony_ci
3763fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3764fd4e5da5Sopenharmony_ci}
3765fd4e5da5Sopenharmony_ci
3766fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareForCalleeFunctionParam) {
3767fd4e5da5Sopenharmony_ci  // Check that InlinePass correctly generates DebugDeclare instructions
3768fd4e5da5Sopenharmony_ci  // for callee function's parameters and maps them to corresponding
3769fd4e5da5Sopenharmony_ci  // local variables of caller function.
3770fd4e5da5Sopenharmony_ci  const std::string text = R"(
3771fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add"
3772fd4e5da5Sopenharmony_ci; CHECK: [[a:%\d+]] = OpString "a"
3773fd4e5da5Sopenharmony_ci; CHECK: [[b:%\d+]] = OpString "b"
3774fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]]
3775fd4e5da5Sopenharmony_ci; CHECK: [[dbg_a:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[a]]
3776fd4e5da5Sopenharmony_ci; CHECK: [[dbg_b:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[b]]
3777fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5
3778fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_a:%\d+]]
3779fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_b:%\d+]]
3780fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]]
3781fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_a]] [[param_a]]
3782fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_b]] [[param_b]]
3783fd4e5da5Sopenharmony_ci
3784fd4e5da5Sopenharmony_ciOpCapability Shader
3785fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
3786fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3787fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
3788fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
3789fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl"
3790fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name
3791fd4e5da5Sopenharmony_ci%float_name = OpString "float"
3792fd4e5da5Sopenharmony_ci%main_name = OpString "main"
3793fd4e5da5Sopenharmony_ci%add_name = OpString "add"
3794fd4e5da5Sopenharmony_ci%a_name = OpString "a"
3795fd4e5da5Sopenharmony_ci%b_name = OpString "b"
3796fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0
3797fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0
3798fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
3799fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
3800fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
3801fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
3802fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
3803fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
3804fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3805fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
3806fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3807fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3808fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
3809fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
3810fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3811fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void
3812fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float
3813fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
3814fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
3815fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression
3816fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
3817fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3818fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3819fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4
3820fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
3821fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f
3822fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3823fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add
3824fd4e5da5Sopenharmony_ci%dbg_a = OpExtInst %void %ext DebugLocalVariable %a_name %dbg_v4f %src 1 13 %dbg_add FlagIsLocal 0
3825fd4e5da5Sopenharmony_ci%dbg_b = OpExtInst %void %ext DebugLocalVariable %b_name %dbg_v4f %src 1 20 %dbg_add FlagIsLocal 1
3826fd4e5da5Sopenharmony_ci%add_lb = OpExtInst %void %ext DebugLexicalBlock %src 1 23 %dbg_add
3827fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type
3828fd4e5da5Sopenharmony_ci%main_bb = OpLabel
3829fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function
3830fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function
3831fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main
3832fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1
3833fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2
3834fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b
3835fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result
3836fd4e5da5Sopenharmony_ciOpReturn
3837fd4e5da5Sopenharmony_ciOpFunctionEnd
3838fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type
3839fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add
3840fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float
3841fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float
3842fd4e5da5Sopenharmony_ci%decl0 = OpExtInst %void %ext DebugDeclare %dbg_a %a %null_expr
3843fd4e5da5Sopenharmony_ci%decl1 = OpExtInst %void %ext DebugDeclare %dbg_b %b %null_expr
3844fd4e5da5Sopenharmony_ci%add_bb = OpLabel
3845fd4e5da5Sopenharmony_ci%scope2 = OpExtInst %void %ext DebugScope %add_lb
3846fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a
3847fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b
3848fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val
3849fd4e5da5Sopenharmony_ciOpReturnValue %res
3850fd4e5da5Sopenharmony_ciOpFunctionEnd
3851fd4e5da5Sopenharmony_ci)";
3852fd4e5da5Sopenharmony_ci
3853fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3854fd4e5da5Sopenharmony_ci}
3855fd4e5da5Sopenharmony_ci
3856fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareForCalleeLocalVar) {
3857fd4e5da5Sopenharmony_ci  // Check that InlinePass correctly generates DebugDeclare instructions
3858fd4e5da5Sopenharmony_ci  // for callee function's local variables and maps them to corresponding
3859fd4e5da5Sopenharmony_ci  // local variables of caller function.
3860fd4e5da5Sopenharmony_ci  const std::string text = R"(
3861fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add"
3862fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo"
3863fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]]
3864fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[foo]] {{%\d+}} {{%\d+}} 2 2 [[dbg_add]]
3865fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5
3866fd4e5da5Sopenharmony_ci
3867fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]]
3868fd4e5da5Sopenharmony_ci; CHECK: [[new_foo:%\d+]] = OpVariable %_ptr_Function_v4float Function
3869fd4e5da5Sopenharmony_ci
3870fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]]
3871fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float
3872fd4e5da5Sopenharmony_ci; CHECK: [[b_val:%\d+]] = OpLoad %v4float
3873fd4e5da5Sopenharmony_ci; CHECK: [[res:%\d+]] = OpFAdd %v4float [[a_val]] [[b_val]]
3874fd4e5da5Sopenharmony_ci; CHECK: OpStore [[new_foo]] [[res]]
3875fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_foo]] [[new_foo]]
3876fd4e5da5Sopenharmony_ci
3877fd4e5da5Sopenharmony_ciOpCapability Shader
3878fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
3879fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3880fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
3881fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
3882fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl"
3883fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name
3884fd4e5da5Sopenharmony_ci%float_name = OpString "float"
3885fd4e5da5Sopenharmony_ci%main_name = OpString "main"
3886fd4e5da5Sopenharmony_ci%add_name = OpString "add"
3887fd4e5da5Sopenharmony_ci%foo_name = OpString "foo"
3888fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0
3889fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0
3890fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
3891fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
3892fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
3893fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
3894fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
3895fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
3896fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3897fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
3898fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3899fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3900fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
3901fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
3902fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3903fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void
3904fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float
3905fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
3906fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
3907fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression
3908fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
3909fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3910fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3911fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4
3912fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
3913fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f
3914fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3915fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add
3916fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugLocalVariable %foo_name %dbg_v4f %src 2 2 %dbg_add FlagIsLocal
3917fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type
3918fd4e5da5Sopenharmony_ci%main_bb = OpLabel
3919fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function
3920fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function
3921fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main
3922fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1
3923fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2
3924fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b
3925fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result
3926fd4e5da5Sopenharmony_ciOpReturn
3927fd4e5da5Sopenharmony_ciOpFunctionEnd
3928fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type
3929fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add
3930fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float
3931fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float
3932fd4e5da5Sopenharmony_ci%add_bb = OpLabel
3933fd4e5da5Sopenharmony_ci%foo = OpVariable %_ptr_Function_v4float Function
3934fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a
3935fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b
3936fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val
3937fd4e5da5Sopenharmony_ciOpStore %foo %res
3938fd4e5da5Sopenharmony_ci%decl = OpExtInst %void %ext DebugDeclare %dbg_foo %foo %null_expr
3939fd4e5da5Sopenharmony_ci%foo_val = OpLoad %v4float %foo
3940fd4e5da5Sopenharmony_ciOpReturnValue %foo_val
3941fd4e5da5Sopenharmony_ciOpFunctionEnd
3942fd4e5da5Sopenharmony_ci)";
3943fd4e5da5Sopenharmony_ci
3944fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
3945fd4e5da5Sopenharmony_ci}
3946fd4e5da5Sopenharmony_ci
3947fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugDeclareMultiple) {
3948fd4e5da5Sopenharmony_ci  // Check that InlinePass correctly generates DebugDeclare instructions
3949fd4e5da5Sopenharmony_ci  // for callee function's parameters and maps them to corresponding
3950fd4e5da5Sopenharmony_ci  // local variables of caller function.
3951fd4e5da5Sopenharmony_ci  const std::string text = R"(
3952fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add"
3953fd4e5da5Sopenharmony_ci; CHECK: [[a:%\d+]] = OpString "a"
3954fd4e5da5Sopenharmony_ci; CHECK: [[b:%\d+]] = OpString "b"
3955fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]]
3956fd4e5da5Sopenharmony_ci; CHECK: [[dbg_a:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[a]]
3957fd4e5da5Sopenharmony_ci; CHECK: [[dbg_b:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[b]]
3958fd4e5da5Sopenharmony_ci; CHECK: OpFunction
3959fd4e5da5Sopenharmony_ci; CHECK-NOT: OpFunctionEnd
3960fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_a:%\d+]]
3961fd4e5da5Sopenharmony_ci; CHECK: OpStore [[param_b:%\d+]]
3962fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]]
3963fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_a]] [[param_a]]
3964fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugDeclare [[dbg_b]] [[param_b]]
3965fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float [[param_a]]
3966fd4e5da5Sopenharmony_ci; CHECK: OpStore [[foo:%\d+]] [[a_val]]
3967fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugValue [[dbg_a]] [[foo]]
3968fd4e5da5Sopenharmony_ci
3969fd4e5da5Sopenharmony_ciOpCapability Shader
3970fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
3971fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3972fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
3973fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
3974fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl"
3975fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name
3976fd4e5da5Sopenharmony_ci%float_name = OpString "float"
3977fd4e5da5Sopenharmony_ci%main_name = OpString "main"
3978fd4e5da5Sopenharmony_ci%add_name = OpString "add"
3979fd4e5da5Sopenharmony_ci%a_name = OpString "a"
3980fd4e5da5Sopenharmony_ci%b_name = OpString "b"
3981fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0
3982fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0
3983fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
3984fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
3985fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
3986fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
3987fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
3988fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
3989fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3990fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
3991fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
3992fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
3993fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
3994fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
3995fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3996fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void
3997fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float
3998fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
3999fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
4000fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression
4001fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
4002fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
4003fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
4004fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4
4005fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
4006fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f
4007fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
4008fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add
4009fd4e5da5Sopenharmony_ci%dbg_a = OpExtInst %void %ext DebugLocalVariable %a_name %dbg_v4f %src 1 13 %dbg_add FlagIsLocal 0
4010fd4e5da5Sopenharmony_ci%dbg_b = OpExtInst %void %ext DebugLocalVariable %b_name %dbg_v4f %src 1 20 %dbg_add FlagIsLocal 1
4011fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type
4012fd4e5da5Sopenharmony_ci%main_bb = OpLabel
4013fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function
4014fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function
4015fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main
4016fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1
4017fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2
4018fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b
4019fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result
4020fd4e5da5Sopenharmony_ciOpReturn
4021fd4e5da5Sopenharmony_ciOpFunctionEnd
4022fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type
4023fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add
4024fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float
4025fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float
4026fd4e5da5Sopenharmony_ci%decl0 = OpExtInst %void %ext DebugDeclare %dbg_a %a %null_expr
4027fd4e5da5Sopenharmony_ci%add_bb = OpLabel
4028fd4e5da5Sopenharmony_ci%decl1 = OpExtInst %void %ext DebugDeclare %dbg_b %b %null_expr
4029fd4e5da5Sopenharmony_ci%foo = OpVariable %_ptr_Function_v4float Function
4030fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a
4031fd4e5da5Sopenharmony_ciOpStore %foo %a_val
4032fd4e5da5Sopenharmony_ci%dbg_val = OpExtInst %void %ext DebugValue %dbg_a %foo %null_expr
4033fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b
4034fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val
4035fd4e5da5Sopenharmony_ciOpReturnValue %res
4036fd4e5da5Sopenharmony_ciOpFunctionEnd
4037fd4e5da5Sopenharmony_ci)";
4038fd4e5da5Sopenharmony_ci
4039fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
4040fd4e5da5Sopenharmony_ci}
4041fd4e5da5Sopenharmony_ci
4042fd4e5da5Sopenharmony_ciTEST_F(InlineTest, DebugValueForFunctionCallReturn) {
4043fd4e5da5Sopenharmony_ci  // Check that InlinePass correctly generates DebugValue instruction
4044fd4e5da5Sopenharmony_ci  // for function call's return value and maps it to a corresponding
4045fd4e5da5Sopenharmony_ci  // value in the caller function.
4046fd4e5da5Sopenharmony_ci  const std::string text = R"(
4047fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpString "main"
4048fd4e5da5Sopenharmony_ci; CHECK: [[add:%\d+]] = OpString "add"
4049fd4e5da5Sopenharmony_ci; CHECK: [[result:%\d+]] = OpString "result"
4050fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[main]]
4051fd4e5da5Sopenharmony_ci; CHECK: [[dbg_add:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[add]]
4052fd4e5da5Sopenharmony_ci; CHECK: [[dbg_result:%\d+]] = OpExtInst %void [[ext]] DebugLocalVariable [[result]] {{%\d+}} {{%\d+}} 6 2 [[dbg_main]]
4053fd4e5da5Sopenharmony_ci; CHECK: [[inlinedat:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 5
4054fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_add]] [[inlinedat]]
4055fd4e5da5Sopenharmony_ci; CHECK: [[a_val:%\d+]] = OpLoad %v4float
4056fd4e5da5Sopenharmony_ci; CHECK: [[b_val:%\d+]] = OpLoad %v4float
4057fd4e5da5Sopenharmony_ci; CHECK: [[res:%\d+]] = OpFAdd %v4float [[a_val]] [[b_val]]
4058fd4e5da5Sopenharmony_ci; CHECK: OpStore [[new_result:%\d+]] [[res]]
4059fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]]
4060fd4e5da5Sopenharmony_ci; CHECK: [[result_val:%\d+]] = OpLoad %v4float [[new_result]]
4061fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugValue [[dbg_result]] [[result_val]]
4062fd4e5da5Sopenharmony_ci
4063fd4e5da5Sopenharmony_ciOpCapability Shader
4064fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
4065fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4066fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
4067fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4068fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl"
4069fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name
4070fd4e5da5Sopenharmony_ci%float_name = OpString "float"
4071fd4e5da5Sopenharmony_ci%main_name = OpString "main"
4072fd4e5da5Sopenharmony_ci%add_name = OpString "add"
4073fd4e5da5Sopenharmony_ci%result_name = OpString "result"
4074fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0
4075fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0
4076fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4077fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
4078fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
4079fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
4080fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
4081fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
4082fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
4083fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
4084fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
4085fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
4086fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
4087fd4e5da5Sopenharmony_ci%add_fn_type = OpTypeFunction %v4float %_ptr_Function_v4float %_ptr_Function_v4float
4088fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4089fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void
4090fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float
4091fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
4092fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
4093fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression
4094fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
4095fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
4096fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
4097fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4
4098fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
4099fd4e5da5Sopenharmony_ci%add_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f %dbg_v4f
4100fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 5 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
4101fd4e5da5Sopenharmony_ci%dbg_add = OpExtInst %void %ext DebugFunction %add_name %add_ty %src 1 1 %cu %add_name FlagIsProtected|FlagIsPrivate 1 %add
4102fd4e5da5Sopenharmony_ci%dbg_result = OpExtInst %void %ext DebugLocalVariable %result_name %dbg_v4f %src 6 2 %dbg_main FlagIsLocal
4103fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type
4104fd4e5da5Sopenharmony_ci%main_bb = OpLabel
4105fd4e5da5Sopenharmony_ci%param_a = OpVariable %_ptr_Function_v4float Function
4106fd4e5da5Sopenharmony_ci%param_b = OpVariable %_ptr_Function_v4float Function
4107fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main
4108fd4e5da5Sopenharmony_ciOpStore %param_a %v4f1
4109fd4e5da5Sopenharmony_ciOpStore %param_b %v4f2
4110fd4e5da5Sopenharmony_ci%result = OpFunctionCall %v4float %add %param_a %param_b
4111fd4e5da5Sopenharmony_ci%value = OpExtInst %void %ext DebugValue %dbg_result %result %null_expr
4112fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result
4113fd4e5da5Sopenharmony_ciOpReturn
4114fd4e5da5Sopenharmony_ciOpFunctionEnd
4115fd4e5da5Sopenharmony_ci%add = OpFunction %v4float None %add_fn_type
4116fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_add
4117fd4e5da5Sopenharmony_ci%a = OpFunctionParameter %_ptr_Function_v4float
4118fd4e5da5Sopenharmony_ci%b = OpFunctionParameter %_ptr_Function_v4float
4119fd4e5da5Sopenharmony_ci%add_bb = OpLabel
4120fd4e5da5Sopenharmony_ci%a_val = OpLoad %v4float %a
4121fd4e5da5Sopenharmony_ci%b_val = OpLoad %v4float %b
4122fd4e5da5Sopenharmony_ci%res = OpFAdd %v4float %a_val %b_val
4123fd4e5da5Sopenharmony_ciOpReturnValue %res
4124fd4e5da5Sopenharmony_ciOpFunctionEnd
4125fd4e5da5Sopenharmony_ci)";
4126fd4e5da5Sopenharmony_ci
4127fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
4128fd4e5da5Sopenharmony_ci}
4129fd4e5da5Sopenharmony_ci
4130fd4e5da5Sopenharmony_ciTEST_F(InlineTest, NestedWithAnExistingDebugInlinedAt) {
4131fd4e5da5Sopenharmony_ci  // When a DebugScope instruction in a callee function already has a
4132fd4e5da5Sopenharmony_ci  // DebugInlinedAt information, we have to create a recursive
4133fd4e5da5Sopenharmony_ci  // DebugInlinedAt chain. See inlined_to_zoo and inlined_to_bar in
4134fd4e5da5Sopenharmony_ci  // the following code.
4135fd4e5da5Sopenharmony_ci  const std::string text = R"(
4136fd4e5da5Sopenharmony_ci; CHECK: [[main:%\d+]] = OpString "main"
4137fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo"
4138fd4e5da5Sopenharmony_ci; CHECK: [[bar:%\d+]] = OpString "bar"
4139fd4e5da5Sopenharmony_ci; CHECK: [[zoo:%\d+]] = OpString "zoo"
4140fd4e5da5Sopenharmony_ci; CHECK: [[v4f1:%\d+]] = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
4141fd4e5da5Sopenharmony_ci; CHECK: [[v4f2:%\d+]] = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
4142fd4e5da5Sopenharmony_ci; CHECK: [[v4f3:%\d+]] = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3
4143fd4e5da5Sopenharmony_ci; CHECK: [[dbg_main:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugFunction [[main]]
4144fd4e5da5Sopenharmony_ci; CHECK: [[dbg_foo:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[foo]]
4145fd4e5da5Sopenharmony_ci; CHECK: [[dbg_bar:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[bar]]
4146fd4e5da5Sopenharmony_ci; CHECK: [[dbg_zoo:%\d+]] = OpExtInst %void [[ext]] DebugFunction [[zoo]]
4147fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 10 [[dbg_main]]
4148fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_zoo:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 7 [[dbg_zoo]] [[inlined_to_main]]
4149fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_main:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 10 [[dbg_main]]
4150fd4e5da5Sopenharmony_ci; CHECK: [[inlined_to_bar:%\d+]] = OpExtInst %void [[ext]] DebugInlinedAt 4 [[dbg_bar]] [[inlined_to_zoo]]
4151fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_foo]] [[inlined_to_bar]]
4152fd4e5da5Sopenharmony_ci; CHECK: OpStore [[foo_ret:%\d+]] [[v4f1]]
4153fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_bar]] [[inlined_to_zoo]]
4154fd4e5da5Sopenharmony_ci; CHECK: [[foo_ret_val:%\d+]] = OpLoad %v4float [[foo_ret]]
4155fd4e5da5Sopenharmony_ci; CHECK: [[bar_ret:%\d+]] = OpFAdd %v4float [[foo_ret_val]] [[v4f2]]
4156fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_zoo]] [[inlined_to_main]]
4157fd4e5da5Sopenharmony_ci; CHECK: [[zoo_result:%\d+]] = OpFAdd %v4float [[bar_ret]] [[v4f3]]
4158fd4e5da5Sopenharmony_ci; CHECK: OpStore [[zoo_ret:%\d+]] [[zoo_result]]
4159fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void [[ext]] DebugScope [[dbg_main]]
4160fd4e5da5Sopenharmony_ci; CHECK: [[zoo_ret_val:%\d+]] = OpLoad %v4float [[zoo_ret]]
4161fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpFAdd %v4float [[zoo_ret_val]] {{%\d+}}
4162fd4e5da5Sopenharmony_ci
4163fd4e5da5Sopenharmony_ciOpCapability Shader
4164fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
4165fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4166fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
4167fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4168fd4e5da5Sopenharmony_ci%file_name = OpString "ps.hlsl"
4169fd4e5da5Sopenharmony_ciOpSource HLSL 600 %file_name
4170fd4e5da5Sopenharmony_ci%float_name = OpString "float"
4171fd4e5da5Sopenharmony_ci%main_name = OpString "main"
4172fd4e5da5Sopenharmony_ci%foo_name = OpString "foo"
4173fd4e5da5Sopenharmony_ci%bar_name = OpString "bar"
4174fd4e5da5Sopenharmony_ci%zoo_name = OpString "zoo"
4175fd4e5da5Sopenharmony_ciOpDecorate %in_var_COLOR Location 0
4176fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_TARGET Location 0
4177fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4178fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
4179fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
4180fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
4181fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
4182fd4e5da5Sopenharmony_ci%float_3 = OpConstant %float 3
4183fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
4184fd4e5da5Sopenharmony_ci%v4f1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
4185fd4e5da5Sopenharmony_ci%v4f2 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
4186fd4e5da5Sopenharmony_ci%v4f3 = OpConstantComposite %v4float %float_3 %float_3 %float_3 %float_3
4187fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
4188fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
4189fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4190fd4e5da5Sopenharmony_ci%void_fn_type = OpTypeFunction %void
4191fd4e5da5Sopenharmony_ci%v4f_fn_type = OpTypeFunction %v4float
4192fd4e5da5Sopenharmony_ci%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
4193fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
4194fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
4195fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
4196fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
4197fd4e5da5Sopenharmony_ci%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_f 4
4198fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
4199fd4e5da5Sopenharmony_ci%foo_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f
4200fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 10 1 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
4201fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugFunction %foo_name %foo_ty %src 1 1 %cu %foo_name FlagIsProtected|FlagIsPrivate 1 %foo
4202fd4e5da5Sopenharmony_ci%dbg_bar = OpExtInst %void %ext DebugFunction %bar_name %foo_ty %src 4 1 %cu %bar_name FlagIsProtected|FlagIsPrivate 4 %bar
4203fd4e5da5Sopenharmony_ci%dbg_zoo = OpExtInst %void %ext DebugFunction %zoo_name %foo_ty %src 7 1 %cu %zoo_name FlagIsProtected|FlagIsPrivate 7 %zoo
4204fd4e5da5Sopenharmony_ci%inlined_to_zoo = OpExtInst %void %ext DebugInlinedAt 7 %dbg_zoo
4205fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn_type
4206fd4e5da5Sopenharmony_ci%main_bb = OpLabel
4207fd4e5da5Sopenharmony_ci%scope0 = OpExtInst %void %ext DebugScope %dbg_main
4208fd4e5da5Sopenharmony_ci%zoo_val = OpFunctionCall %v4float %zoo
4209fd4e5da5Sopenharmony_ci%color = OpLoad %v4float %in_var_COLOR
4210fd4e5da5Sopenharmony_ci%result = OpFAdd %v4float %zoo_val %color
4211fd4e5da5Sopenharmony_ciOpStore %out_var_SV_TARGET %result
4212fd4e5da5Sopenharmony_ciOpReturn
4213fd4e5da5Sopenharmony_ciOpFunctionEnd
4214fd4e5da5Sopenharmony_ci%foo = OpFunction %v4float None %v4f_fn_type
4215fd4e5da5Sopenharmony_ci%scope1 = OpExtInst %void %ext DebugScope %dbg_foo
4216fd4e5da5Sopenharmony_ci%foo_bb = OpLabel
4217fd4e5da5Sopenharmony_ciOpReturnValue %v4f1
4218fd4e5da5Sopenharmony_ciOpFunctionEnd
4219fd4e5da5Sopenharmony_ci%zoo = OpFunction %v4float None %v4f_fn_type
4220fd4e5da5Sopenharmony_ci%scope3 = OpExtInst %void %ext DebugScope %dbg_zoo
4221fd4e5da5Sopenharmony_ci%zoo_bb = OpLabel
4222fd4e5da5Sopenharmony_ci%scope2 = OpExtInst %void %ext DebugScope %dbg_bar %inlined_to_zoo
4223fd4e5da5Sopenharmony_ci%foo_val = OpFunctionCall %v4float %foo
4224fd4e5da5Sopenharmony_ci%bar_val = OpFAdd %v4float %foo_val %v4f2
4225fd4e5da5Sopenharmony_ci%scope4 = OpExtInst %void %ext DebugScope %dbg_zoo
4226fd4e5da5Sopenharmony_ci%zoo_ret = OpFAdd %v4float %bar_val %v4f3
4227fd4e5da5Sopenharmony_ciOpReturnValue %zoo_ret
4228fd4e5da5Sopenharmony_ciOpFunctionEnd
4229fd4e5da5Sopenharmony_ci%bar = OpFunction %v4float None %v4f_fn_type
4230fd4e5da5Sopenharmony_ci%scope5 = OpExtInst %void %ext DebugScope %dbg_bar
4231fd4e5da5Sopenharmony_ci%bar_bb = OpLabel
4232fd4e5da5Sopenharmony_ci%foo_val0 = OpFunctionCall %v4float %foo
4233fd4e5da5Sopenharmony_ci%bar_ret = OpFAdd %v4float %foo_val0 %v4f2
4234fd4e5da5Sopenharmony_ciOpReturnValue %bar_ret
4235fd4e5da5Sopenharmony_ciOpFunctionEnd
4236fd4e5da5Sopenharmony_ci)";
4237fd4e5da5Sopenharmony_ci
4238fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
4239fd4e5da5Sopenharmony_ci}
4240fd4e5da5Sopenharmony_ci
4241fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CreateConstantForInlinedAt) {
4242fd4e5da5Sopenharmony_ci  // This shader causes CreateDebugInlinedAt to generate a constant.
4243fd4e5da5Sopenharmony_ci  // Using the Constant manager would attempt to build the invalidated
4244fd4e5da5Sopenharmony_ci  // DefUse manager during inlining which could cause an assert because
4245fd4e5da5Sopenharmony_ci  // the function is in an inconsistent state. This test verifies that
4246fd4e5da5Sopenharmony_ci  // CreateDebugInlinedAt detects that the DefUse manager is disabled
4247fd4e5da5Sopenharmony_ci  // and creates a duplicate constant safely without the Constant manager.
4248fd4e5da5Sopenharmony_ci  //
4249fd4e5da5Sopenharmony_ci  // int function1() {
4250fd4e5da5Sopenharmony_ci  //   return 1;
4251fd4e5da5Sopenharmony_ci  // }
4252fd4e5da5Sopenharmony_ci  //
4253fd4e5da5Sopenharmony_ci  // void main() {
4254fd4e5da5Sopenharmony_ci  //   function1();
4255fd4e5da5Sopenharmony_ci  // }
4256fd4e5da5Sopenharmony_ci
4257fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
4258fd4e5da5Sopenharmony_ci; CHECK: %uint_7 = OpConstant %uint 7
4259fd4e5da5Sopenharmony_ci; CHECK: %uint_7_0 = OpConstant %uint 7
4260fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void %1 DebugInlinedAt %uint_7_0
4261fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info"
4262fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
4263fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4264fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4265fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4266fd4e5da5Sopenharmony_ci%3 = OpString "parent3.hlsl"
4267fd4e5da5Sopenharmony_ci%8 = OpString "int"
4268fd4e5da5Sopenharmony_ci%19 = OpString "function1"
4269fd4e5da5Sopenharmony_ci%20 = OpString ""
4270fd4e5da5Sopenharmony_ci%26 = OpString "main"
4271fd4e5da5Sopenharmony_ciOpName %main "main"
4272fd4e5da5Sopenharmony_ciOpName %src_main "src.main"
4273fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
4274fd4e5da5Sopenharmony_ciOpName %function1 "function1"
4275fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
4276fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
4277fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
4278fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4279fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
4280fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4281fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
4282fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
4283fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
4284fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
4285fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5
4286fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
4287fd4e5da5Sopenharmony_ci%uint_17 = OpConstant %uint 17
4288fd4e5da5Sopenharmony_ci%uint_6 = OpConstant %uint 6
4289fd4e5da5Sopenharmony_ci%uint_13 = OpConstant %uint 13
4290fd4e5da5Sopenharmony_ci%uint_7 = OpConstant %uint 7
4291fd4e5da5Sopenharmony_ci%31 = OpTypeFunction %void
4292fd4e5da5Sopenharmony_ci%42 = OpTypeFunction %int
4293fd4e5da5Sopenharmony_ci%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0
4294fd4e5da5Sopenharmony_ci%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10
4295fd4e5da5Sopenharmony_ci%15 = OpExtInst %void %1 DebugSource %3
4296fd4e5da5Sopenharmony_ci%16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5
4297fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %1 DebugFunction %19 %13 %15 %uint_2 %uint_1 %16 %20 %uint_3 %uint_2
4298fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_2 %uint_17 %21
4299fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
4300fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %26 %25 %15 %uint_6 %uint_1 %16 %20 %uint_3 %uint_6
4301fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_6 %uint_13 %27
4302fd4e5da5Sopenharmony_ci%main = OpFunction %void None %31
4303fd4e5da5Sopenharmony_ci%32 = OpLabel
4304fd4e5da5Sopenharmony_ci%33 = OpFunctionCall %void %src_main
4305fd4e5da5Sopenharmony_ciOpLine %3 8 1
4306fd4e5da5Sopenharmony_ciOpReturn
4307fd4e5da5Sopenharmony_ciOpFunctionEnd
4308fd4e5da5Sopenharmony_ciOpLine %3 6 1
4309fd4e5da5Sopenharmony_ci%src_main = OpFunction %void None %31
4310fd4e5da5Sopenharmony_ciOpNoLine
4311fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
4312fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugScope %27
4313fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main
4314fd4e5da5Sopenharmony_ci%48 = OpExtInst %void %1 DebugScope %29
4315fd4e5da5Sopenharmony_ciOpLine %3 7 3
4316fd4e5da5Sopenharmony_ci%39 = OpFunctionCall %int %function1
4317fd4e5da5Sopenharmony_ci%49 = OpExtInst %void %1 DebugScope %27
4318fd4e5da5Sopenharmony_ciOpLine %3 8 1
4319fd4e5da5Sopenharmony_ciOpReturn
4320fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugNoScope
4321fd4e5da5Sopenharmony_ciOpFunctionEnd
4322fd4e5da5Sopenharmony_ciOpLine %3 2 1
4323fd4e5da5Sopenharmony_ci%function1 = OpFunction %int None %42
4324fd4e5da5Sopenharmony_ciOpNoLine
4325fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
4326fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugScope %21
4327fd4e5da5Sopenharmony_ci%45 = OpExtInst %void %1 DebugFunctionDefinition %21 %function1
4328fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugScope %23
4329fd4e5da5Sopenharmony_ciOpLine %3 3 3
4330fd4e5da5Sopenharmony_ciOpReturnValue %int_1
4331fd4e5da5Sopenharmony_ci%53 = OpExtInst %void %1 DebugNoScope
4332fd4e5da5Sopenharmony_ciOpFunctionEnd
4333fd4e5da5Sopenharmony_ci)";
4334fd4e5da5Sopenharmony_ci
4335fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_2);
4336fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
4337fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
4338fd4e5da5Sopenharmony_ci}
4339fd4e5da5Sopenharmony_ci
4340fd4e5da5Sopenharmony_ciTEST_F(InlineTest, CreateDebugInlinedAtFromDebugLine) {
4341fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
4342fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void %1 DebugInlinedAt %uint_6
4343fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info"
4344fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
4345fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4346fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4347fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4348fd4e5da5Sopenharmony_ci%3 = OpString "debuginlinedat.frag"
4349fd4e5da5Sopenharmony_ci%8 = OpString "int"
4350fd4e5da5Sopenharmony_ci%15 = OpString "int function1() {
4351fd4e5da5Sopenharmony_ci	return 1;
4352fd4e5da5Sopenharmony_ci}
4353fd4e5da5Sopenharmony_ci
4354fd4e5da5Sopenharmony_civoid main() {
4355fd4e5da5Sopenharmony_ci	function1();
4356fd4e5da5Sopenharmony_ci}
4357fd4e5da5Sopenharmony_ci"
4358fd4e5da5Sopenharmony_ci%20 = OpString "function1"
4359fd4e5da5Sopenharmony_ci%21 = OpString ""
4360fd4e5da5Sopenharmony_ci%26 = OpString "main"
4361fd4e5da5Sopenharmony_ciOpName %main "main"
4362fd4e5da5Sopenharmony_ciOpName %src_main "src.main"
4363fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
4364fd4e5da5Sopenharmony_ciOpName %function1 "function1"
4365fd4e5da5Sopenharmony_ciOpName %bb_entry_0 "bb.entry"
4366fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
4367fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
4368fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4369fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
4370fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4371fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
4372fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
4373fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
4374fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
4375fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5
4376fd4e5da5Sopenharmony_ci%uint_17 = OpConstant %uint 17
4377fd4e5da5Sopenharmony_ci%uint_13 = OpConstant %uint 13
4378fd4e5da5Sopenharmony_ci%30 = OpTypeFunction %void
4379fd4e5da5Sopenharmony_ci%uint_7 = OpConstant %uint 7
4380fd4e5da5Sopenharmony_ci%uint_6 = OpConstant %uint 6
4381fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
4382fd4e5da5Sopenharmony_ci%uint_12 = OpConstant %uint 12
4383fd4e5da5Sopenharmony_ci%48 = OpTypeFunction %int
4384fd4e5da5Sopenharmony_ci%uint_9 = OpConstant %uint 9
4385fd4e5da5Sopenharmony_ci%10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0
4386fd4e5da5Sopenharmony_ci%13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10
4387fd4e5da5Sopenharmony_ci%16 = OpExtInst %void %1 DebugSource %3 %15
4388fd4e5da5Sopenharmony_ci%17 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %16 %uint_5
4389fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugFunction %20 %13 %16 %uint_1 %uint_1 %17 %21 %uint_3 %uint_1
4390fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_1 %uint_17 %22
4391fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
4392fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %26 %25 %16 %uint_5 %uint_1 %17 %21 %uint_3 %uint_5
4393fd4e5da5Sopenharmony_ci%28 = OpExtInst %void %1 DebugLexicalBlock %16 %uint_5 %uint_13 %27
4394fd4e5da5Sopenharmony_ci%main = OpFunction %void None %30
4395fd4e5da5Sopenharmony_ci%31 = OpLabel
4396fd4e5da5Sopenharmony_ci%32 = OpFunctionCall %void %src_main
4397fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1
4398fd4e5da5Sopenharmony_ciOpReturn
4399fd4e5da5Sopenharmony_ciOpFunctionEnd
4400fd4e5da5Sopenharmony_ci%src_main = OpFunction %void None %30
4401fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
4402fd4e5da5Sopenharmony_ci%37 = OpExtInst %void %1 DebugScope %27
4403fd4e5da5Sopenharmony_ci%38 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main
4404fd4e5da5Sopenharmony_ci%39 = OpExtInst %void %1 DebugScope %28
4405fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugLine %16 %uint_6 %uint_6 %uint_2 %uint_12
4406fd4e5da5Sopenharmony_ci%44 = OpFunctionCall %int %function1
4407fd4e5da5Sopenharmony_ci%46 = OpExtInst %void %1 DebugScope %27
4408fd4e5da5Sopenharmony_ci%47 = OpExtInst %void %1 DebugLine %16 %uint_7 %uint_7 %uint_1 %uint_1
4409fd4e5da5Sopenharmony_ciOpReturn
4410fd4e5da5Sopenharmony_ciOpFunctionEnd
4411fd4e5da5Sopenharmony_ci%function1 = OpFunction %int None %48
4412fd4e5da5Sopenharmony_ci%bb_entry_0 = OpLabel
4413fd4e5da5Sopenharmony_ci%50 = OpExtInst %void %1 DebugScope %22
4414fd4e5da5Sopenharmony_ci%51 = OpExtInst %void %1 DebugFunctionDefinition %22 %function1
4415fd4e5da5Sopenharmony_ci%52 = OpExtInst %void %1 DebugScope %23
4416fd4e5da5Sopenharmony_ci%53 = OpExtInst %void %1 DebugLine %16 %uint_2 %uint_2 %uint_2 %uint_9
4417fd4e5da5Sopenharmony_ciOpReturnValue %int_1
4418fd4e5da5Sopenharmony_ciOpFunctionEnd
4419fd4e5da5Sopenharmony_ci)";
4420fd4e5da5Sopenharmony_ci
4421fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_2);
4422fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
4423fd4e5da5Sopenharmony_ci}
4424fd4e5da5Sopenharmony_ci
4425fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases:
4426fd4e5da5Sopenharmony_ci//
4427fd4e5da5Sopenharmony_ci//    Empty modules
4428fd4e5da5Sopenharmony_ci//    Modules without function definitions
4429fd4e5da5Sopenharmony_ci//    Modules in which all functions do not call other functions
4430fd4e5da5Sopenharmony_ci//    Caller and callee both accessing the same global variable
4431fd4e5da5Sopenharmony_ci//    Functions with OpLine & OpNoLine
4432fd4e5da5Sopenharmony_ci//    Others?
4433fd4e5da5Sopenharmony_ci
4434fd4e5da5Sopenharmony_ci// TODO(dneto): Test suggestions from code review
4435fd4e5da5Sopenharmony_ci// https://github.com/KhronosGroup/SPIRV-Tools/pull/534
4436fd4e5da5Sopenharmony_ci//
4437fd4e5da5Sopenharmony_ci//    Callee function returns a value generated outside the callee,
4438fd4e5da5Sopenharmony_ci//      e.g. a constant value. This might exercise some logic not yet
4439fd4e5da5Sopenharmony_ci//      exercised by the current tests: the false branch in the "if"
4440fd4e5da5Sopenharmony_ci//      inside the spv::Op::OpReturnValue case in InlinePass::GenInlineCode?
4441fd4e5da5Sopenharmony_ci//    SampledImage before function call, but callee is only single block.
4442fd4e5da5Sopenharmony_ci//      Then the SampledImage instruction is not cloned. Documents existing
4443fd4e5da5Sopenharmony_ci//      behaviour.
4444fd4e5da5Sopenharmony_ci//    SampledImage after function call. It is not cloned or changed.
4445fd4e5da5Sopenharmony_ci
4446fd4e5da5Sopenharmony_ci}  // namespace
4447fd4e5da5Sopenharmony_ci}  // namespace opt
4448fd4e5da5Sopenharmony_ci}  // namespace spvtools
4449