1fd4e5da5Sopenharmony_ci// Copyright (c) 2022 The Khronos Group Inc.
2fd4e5da5Sopenharmony_ci// Copyright (c) 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 <unordered_set>
17fd4e5da5Sopenharmony_ci
18fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
19fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace opt {
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciusing AnalyzeLiveInputTest = PassTest<::testing::Test>;
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, FragMultipleLocations) {
28fd4e5da5Sopenharmony_ci  // Should report locations {2, 5}
29fd4e5da5Sopenharmony_ci  //
30fd4e5da5Sopenharmony_ci  // #version 450
31fd4e5da5Sopenharmony_ci  //
32fd4e5da5Sopenharmony_ci  // layout(location = 2) in Vertex
33fd4e5da5Sopenharmony_ci  // {
34fd4e5da5Sopenharmony_ci  //         vec4 color0;
35fd4e5da5Sopenharmony_ci  //         vec4 color1;
36fd4e5da5Sopenharmony_ci  //         vec4 color2[3];
37fd4e5da5Sopenharmony_ci  // } iVert;
38fd4e5da5Sopenharmony_ci  //
39fd4e5da5Sopenharmony_ci  // layout(location = 0) out vec4 oFragColor;
40fd4e5da5Sopenharmony_ci  //
41fd4e5da5Sopenharmony_ci  // void main()
42fd4e5da5Sopenharmony_ci  // {
43fd4e5da5Sopenharmony_ci  //     oFragColor = iVert.color0 + iVert.color2[1];
44fd4e5da5Sopenharmony_ci  // }
45fd4e5da5Sopenharmony_ci  const std::string text = R"(
46fd4e5da5Sopenharmony_ci               OpCapability Shader
47fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
48fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
49fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %oFragColor %iVert
50fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
51fd4e5da5Sopenharmony_ci               OpSource GLSL 450
52fd4e5da5Sopenharmony_ci               OpName %main "main"
53fd4e5da5Sopenharmony_ci               OpName %oFragColor "oFragColor"
54fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
55fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "color0"
56fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "color1"
57fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 2 "color2"
58fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
59fd4e5da5Sopenharmony_ci               OpDecorate %oFragColor Location 0
60fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
61fd4e5da5Sopenharmony_ci               OpDecorate %iVert Location 2
62fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
63fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
64fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
65fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
66fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
67fd4e5da5Sopenharmony_ci %oFragColor = OpVariable %_ptr_Output_v4float Output
68fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
69fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
70fd4e5da5Sopenharmony_ci%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
71fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4float %v4float %_arr_v4float_uint_3
72fd4e5da5Sopenharmony_ci%_ptr_Input_Vertex = OpTypePointer Input %Vertex
73fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input_Vertex Input
74fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
75fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
76fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
77fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
78fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
79fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
80fd4e5da5Sopenharmony_ci          %5 = OpLabel
81fd4e5da5Sopenharmony_ci         %19 = OpAccessChain %_ptr_Input_v4float %iVert %int_0
82fd4e5da5Sopenharmony_ci         %20 = OpLoad %v4float %19
83fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %_ptr_Input_v4float %iVert %int_2 %int_1
84fd4e5da5Sopenharmony_ci         %24 = OpLoad %v4float %23
85fd4e5da5Sopenharmony_ci         %25 = OpFAdd %v4float %20 %24
86fd4e5da5Sopenharmony_ci               OpStore %oFragColor %25
87fd4e5da5Sopenharmony_ci               OpReturn
88fd4e5da5Sopenharmony_ci               OpFunctionEnd
89fd4e5da5Sopenharmony_ci)";
90fd4e5da5Sopenharmony_ci
91fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
92fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
93fd4e5da5Sopenharmony_ci
94fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
95fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
96fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
97fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
100fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
101fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
102fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
103fd4e5da5Sopenharmony_ci  auto itr4 = live_inputs.find(4);
104fd4e5da5Sopenharmony_ci  auto itr5 = live_inputs.find(5);
105fd4e5da5Sopenharmony_ci  auto itr6 = live_inputs.find(6);
106fd4e5da5Sopenharmony_ci
107fd4e5da5Sopenharmony_ci  // Expect live_inputs == {2, 5}
108fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
109fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 == live_inputs.end());
110fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 != live_inputs.end());
111fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 == live_inputs.end());
112fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr4 == live_inputs.end());
113fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr5 != live_inputs.end());
114fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr6 == live_inputs.end());
115fd4e5da5Sopenharmony_ci}
116fd4e5da5Sopenharmony_ci
117fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, FragMatrix) {
118fd4e5da5Sopenharmony_ci  // Should report locations {2, 8, 9, 10, 11}
119fd4e5da5Sopenharmony_ci  //
120fd4e5da5Sopenharmony_ci  // #version 450
121fd4e5da5Sopenharmony_ci  //
122fd4e5da5Sopenharmony_ci  // uniform ui_name {
123fd4e5da5Sopenharmony_ci  //     int i;
124fd4e5da5Sopenharmony_ci  // } ui_inst;
125fd4e5da5Sopenharmony_ci  //
126fd4e5da5Sopenharmony_ci  // layout(location = 2) in Vertex
127fd4e5da5Sopenharmony_ci  // {
128fd4e5da5Sopenharmony_ci  //         vec4 color0;
129fd4e5da5Sopenharmony_ci  //         vec4 color1;
130fd4e5da5Sopenharmony_ci  //         mat4 color2;
131fd4e5da5Sopenharmony_ci  //         mat4 color3;
132fd4e5da5Sopenharmony_ci  //         mat4 color4;
133fd4e5da5Sopenharmony_ci  // } iVert;
134fd4e5da5Sopenharmony_ci  //
135fd4e5da5Sopenharmony_ci  // // Output variable for the color
136fd4e5da5Sopenharmony_ci  // layout(location = 0) out vec4 oFragColor;
137fd4e5da5Sopenharmony_ci  //
138fd4e5da5Sopenharmony_ci  // void main()
139fd4e5da5Sopenharmony_ci  // {
140fd4e5da5Sopenharmony_ci  //     oFragColor = iVert.color0 + iVert.color3[ui_inst.i];
141fd4e5da5Sopenharmony_ci  // }
142fd4e5da5Sopenharmony_ci  const std::string text = R"(
143fd4e5da5Sopenharmony_ci               OpCapability Shader
144fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
145fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
146fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %oFragColor %iVert %ui_inst
147fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
148fd4e5da5Sopenharmony_ci               OpSource GLSL 450
149fd4e5da5Sopenharmony_ci               OpName %main "main"
150fd4e5da5Sopenharmony_ci               OpName %oFragColor "oFragColor"
151fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
152fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "color0"
153fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "color1"
154fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 2 "color2"
155fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 3 "color3"
156fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 4 "color4"
157fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
158fd4e5da5Sopenharmony_ci               OpName %ui_name "ui_name"
159fd4e5da5Sopenharmony_ci               OpMemberName %ui_name 0 "i"
160fd4e5da5Sopenharmony_ci               OpName %ui_inst "ui_inst"
161fd4e5da5Sopenharmony_ci               OpDecorate %oFragColor Location 0
162fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
163fd4e5da5Sopenharmony_ci               OpDecorate %iVert Location 2
164fd4e5da5Sopenharmony_ci               OpMemberDecorate %ui_name 0 Offset 0
165fd4e5da5Sopenharmony_ci               OpDecorate %ui_name Block
166fd4e5da5Sopenharmony_ci               OpDecorate %ui_inst DescriptorSet 0
167fd4e5da5Sopenharmony_ci               OpDecorate %ui_inst Binding 0
168fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
169fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
170fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
171fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
172fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
173fd4e5da5Sopenharmony_ci %oFragColor = OpVariable %_ptr_Output_v4float Output
174fd4e5da5Sopenharmony_ci%mat4v4float = OpTypeMatrix %v4float 4
175fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4float %v4float %mat4v4float %mat4v4float %mat4v4float
176fd4e5da5Sopenharmony_ci%_ptr_Input_Vertex = OpTypePointer Input %Vertex
177fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input_Vertex Input
178fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
179fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
180fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
181fd4e5da5Sopenharmony_ci      %int_3 = OpConstant %int 3
182fd4e5da5Sopenharmony_ci    %ui_name = OpTypeStruct %int
183fd4e5da5Sopenharmony_ci%_ptr_Uniform_ui_name = OpTypePointer Uniform %ui_name
184fd4e5da5Sopenharmony_ci    %ui_inst = OpVariable %_ptr_Uniform_ui_name Uniform
185fd4e5da5Sopenharmony_ci%_ptr_Uniform_int = OpTypePointer Uniform %int
186fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
187fd4e5da5Sopenharmony_ci          %5 = OpLabel
188fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0
189fd4e5da5Sopenharmony_ci         %18 = OpLoad %v4float %17
190fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %_ptr_Uniform_int %ui_inst %int_0
191fd4e5da5Sopenharmony_ci         %25 = OpLoad %int %24
192fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %_ptr_Input_v4float %iVert %int_3 %25
193fd4e5da5Sopenharmony_ci         %27 = OpLoad %v4float %26
194fd4e5da5Sopenharmony_ci         %28 = OpFAdd %v4float %18 %27
195fd4e5da5Sopenharmony_ci               OpStore %oFragColor %28
196fd4e5da5Sopenharmony_ci               OpReturn
197fd4e5da5Sopenharmony_ci               OpFunctionEnd
198fd4e5da5Sopenharmony_ci)";
199fd4e5da5Sopenharmony_ci
200fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
201fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
202fd4e5da5Sopenharmony_ci
203fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
204fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
205fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
206fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
207fd4e5da5Sopenharmony_ci
208fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
209fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
210fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
211fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
212fd4e5da5Sopenharmony_ci  auto itr4 = live_inputs.find(4);
213fd4e5da5Sopenharmony_ci  auto itr5 = live_inputs.find(5);
214fd4e5da5Sopenharmony_ci  auto itr6 = live_inputs.find(6);
215fd4e5da5Sopenharmony_ci  auto itr7 = live_inputs.find(7);
216fd4e5da5Sopenharmony_ci  auto itr8 = live_inputs.find(8);
217fd4e5da5Sopenharmony_ci  auto itr9 = live_inputs.find(9);
218fd4e5da5Sopenharmony_ci  auto itr10 = live_inputs.find(10);
219fd4e5da5Sopenharmony_ci  auto itr11 = live_inputs.find(11);
220fd4e5da5Sopenharmony_ci  auto itr12 = live_inputs.find(12);
221fd4e5da5Sopenharmony_ci  auto itr13 = live_inputs.find(13);
222fd4e5da5Sopenharmony_ci  auto itr14 = live_inputs.find(14);
223fd4e5da5Sopenharmony_ci  auto itr15 = live_inputs.find(15);
224fd4e5da5Sopenharmony_ci
225fd4e5da5Sopenharmony_ci  // Expect live_inputs == {2, 8, 9, 10, 11}
226fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
227fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 == live_inputs.end());
228fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 != live_inputs.end());
229fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 == live_inputs.end());
230fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr4 == live_inputs.end());
231fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr5 == live_inputs.end());
232fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr6 == live_inputs.end());
233fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr7 == live_inputs.end());
234fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr8 != live_inputs.end());
235fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr9 != live_inputs.end());
236fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr10 != live_inputs.end());
237fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr11 != live_inputs.end());
238fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr12 == live_inputs.end());
239fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr13 == live_inputs.end());
240fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr14 == live_inputs.end());
241fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr15 == live_inputs.end());
242fd4e5da5Sopenharmony_ci}
243fd4e5da5Sopenharmony_ci
244fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, FragMemberLocs) {
245fd4e5da5Sopenharmony_ci  // Should report location {1}
246fd4e5da5Sopenharmony_ci  //
247fd4e5da5Sopenharmony_ci  // #version 450
248fd4e5da5Sopenharmony_ci  //
249fd4e5da5Sopenharmony_ci  // in Vertex
250fd4e5da5Sopenharmony_ci  // {
251fd4e5da5Sopenharmony_ci  //     layout (location = 1) vec4 Cd;
252fd4e5da5Sopenharmony_ci  //     layout (location = 0) vec2 uv;
253fd4e5da5Sopenharmony_ci  // } iVert;
254fd4e5da5Sopenharmony_ci  //
255fd4e5da5Sopenharmony_ci  // layout (location = 0) out vec4 fragColor;
256fd4e5da5Sopenharmony_ci  //
257fd4e5da5Sopenharmony_ci  // void main()
258fd4e5da5Sopenharmony_ci  // {
259fd4e5da5Sopenharmony_ci  //     vec4 color = vec4(iVert.Cd);
260fd4e5da5Sopenharmony_ci  //     fragColor = color;
261fd4e5da5Sopenharmony_ci  // }
262fd4e5da5Sopenharmony_ci  const std::string text = R"(
263fd4e5da5Sopenharmony_ci               OpCapability Shader
264fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
265fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
266fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %iVert %fragColor
267fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
268fd4e5da5Sopenharmony_ci               OpSource GLSL 450
269fd4e5da5Sopenharmony_ci               OpName %main "main"
270fd4e5da5Sopenharmony_ci               OpName %color "color"
271fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
272fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "Cd"
273fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "uv"
274fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
275fd4e5da5Sopenharmony_ci               OpName %fragColor "fragColor"
276fd4e5da5Sopenharmony_ci               OpMemberDecorate %Vertex 0 Location 1
277fd4e5da5Sopenharmony_ci               OpMemberDecorate %Vertex 1 Location 0
278fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
279fd4e5da5Sopenharmony_ci               OpDecorate %fragColor Location 0
280fd4e5da5Sopenharmony_ci               OpDecorate %_struct_27 Block
281fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_27 0 Location 1
282fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
283fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
284fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
285fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
286fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
287fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
288fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4float %v2float
289fd4e5da5Sopenharmony_ci%_ptr_Input_Vertex = OpTypePointer Input %Vertex
290fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
291fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
292fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
293fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
294fd4e5da5Sopenharmony_ci  %fragColor = OpVariable %_ptr_Output_v4float Output
295fd4e5da5Sopenharmony_ci %_struct_27 = OpTypeStruct %v4float
296fd4e5da5Sopenharmony_ci%_ptr_Input__struct_27 = OpTypePointer Input %_struct_27
297fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input__struct_27 Input
298fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
299fd4e5da5Sopenharmony_ci          %5 = OpLabel
300fd4e5da5Sopenharmony_ci      %color = OpVariable %_ptr_Function_v4float Function
301fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %_ptr_Input_v4float %iVert %int_0
302fd4e5da5Sopenharmony_ci         %18 = OpLoad %v4float %17
303fd4e5da5Sopenharmony_ci         %19 = OpCompositeExtract %float %18 0
304fd4e5da5Sopenharmony_ci         %20 = OpCompositeExtract %float %18 1
305fd4e5da5Sopenharmony_ci         %21 = OpCompositeExtract %float %18 2
306fd4e5da5Sopenharmony_ci         %22 = OpCompositeExtract %float %18 3
307fd4e5da5Sopenharmony_ci         %23 = OpCompositeConstruct %v4float %19 %20 %21 %22
308fd4e5da5Sopenharmony_ci               OpStore %color %23
309fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %color
310fd4e5da5Sopenharmony_ci               OpStore %fragColor %26
311fd4e5da5Sopenharmony_ci               OpReturn
312fd4e5da5Sopenharmony_ci               OpFunctionEnd
313fd4e5da5Sopenharmony_ci)";
314fd4e5da5Sopenharmony_ci
315fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
316fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
317fd4e5da5Sopenharmony_ci
318fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
319fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
320fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
321fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
322fd4e5da5Sopenharmony_ci
323fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
324fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
325fd4e5da5Sopenharmony_ci
326fd4e5da5Sopenharmony_ci  // Expect live_inputs == {2, 5}
327fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
328fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 != live_inputs.end());
329fd4e5da5Sopenharmony_ci}
330fd4e5da5Sopenharmony_ci
331fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, ArrayedInput) {
332fd4e5da5Sopenharmony_ci  // Tests handling of arrayed input seen in Tesc, Tese and Geom shaders.
333fd4e5da5Sopenharmony_ci  //
334fd4e5da5Sopenharmony_ci  // Should report location {1, 10}.
335fd4e5da5Sopenharmony_ci  //
336fd4e5da5Sopenharmony_ci  // #version 450
337fd4e5da5Sopenharmony_ci  //
338fd4e5da5Sopenharmony_ci  // layout (vertices = 4) out;
339fd4e5da5Sopenharmony_ci  //
340fd4e5da5Sopenharmony_ci  // layout (location = 1) in Vertex
341fd4e5da5Sopenharmony_ci  // {
342fd4e5da5Sopenharmony_ci  //                 vec4 p;
343fd4e5da5Sopenharmony_ci  //                 vec3 n;
344fd4e5da5Sopenharmony_ci  //                 vec4 f[100];
345fd4e5da5Sopenharmony_ci  // } iVert[];
346fd4e5da5Sopenharmony_ci  //
347fd4e5da5Sopenharmony_ci  // layout (location = 0) out vec4 position[4];
348fd4e5da5Sopenharmony_ci  //
349fd4e5da5Sopenharmony_ci  // void main()
350fd4e5da5Sopenharmony_ci  // {
351fd4e5da5Sopenharmony_ci  //                 vec4 pos = iVert[gl_InvocationID].p *
352fd4e5da5Sopenharmony_ci  //                            iVert[gl_InvocationID].f[7];
353fd4e5da5Sopenharmony_ci  //                 position[gl_InvocationID] = pos;
354fd4e5da5Sopenharmony_ci  // }
355fd4e5da5Sopenharmony_ci  const std::string text = R"(
356fd4e5da5Sopenharmony_ci               OpCapability Tessellation
357fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
358fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
359fd4e5da5Sopenharmony_ci               OpEntryPoint TessellationControl %main "main" %iVert %gl_InvocationID %position
360fd4e5da5Sopenharmony_ci               OpExecutionMode %main OutputVertices 4
361fd4e5da5Sopenharmony_ci               OpSource GLSL 450
362fd4e5da5Sopenharmony_ci               OpName %main "main"
363fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
364fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "p"
365fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "n"
366fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 2 "f"
367fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
368fd4e5da5Sopenharmony_ci               OpName %gl_InvocationID "gl_InvocationID"
369fd4e5da5Sopenharmony_ci               OpName %position "position"
370fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
371fd4e5da5Sopenharmony_ci               OpDecorate %iVert Location 1
372fd4e5da5Sopenharmony_ci               OpDecorate %gl_InvocationID BuiltIn InvocationId
373fd4e5da5Sopenharmony_ci               OpDecorate %position Location 0
374fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
375fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
376fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
377fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
378fd4e5da5Sopenharmony_ci    %v3float = OpTypeVector %float 3
379fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
380fd4e5da5Sopenharmony_ci   %uint_100 = OpConstant %uint 100
381fd4e5da5Sopenharmony_ci%_arr_v4float_uint_100 = OpTypeArray %v4float %uint_100
382fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4float %v3float %_arr_v4float_uint_100
383fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
384fd4e5da5Sopenharmony_ci%_arr_Vertex_uint_32 = OpTypeArray %Vertex %uint_32
385fd4e5da5Sopenharmony_ci%_ptr_Input__arr_Vertex_uint_32 = OpTypePointer Input %_arr_Vertex_uint_32
386fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input__arr_Vertex_uint_32 Input
387fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
388fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
389fd4e5da5Sopenharmony_ci%gl_InvocationID = OpVariable %_ptr_Input_int Input
390fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
391fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
392fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
393fd4e5da5Sopenharmony_ci      %int_7 = OpConstant %int 7
394fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
395fd4e5da5Sopenharmony_ci%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
396fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4
397fd4e5da5Sopenharmony_ci   %position = OpVariable %_ptr_Output__arr_v4float_uint_4 Output
398fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
399fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
400fd4e5da5Sopenharmony_ci          %5 = OpLabel
401fd4e5da5Sopenharmony_ci         %22 = OpLoad %int %gl_InvocationID
402fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_0
403fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %25
404fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_2 %int_7
405fd4e5da5Sopenharmony_ci         %31 = OpLoad %v4float %30
406fd4e5da5Sopenharmony_ci         %32 = OpFMul %v4float %26 %31
407fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Output_v4float %position %22
408fd4e5da5Sopenharmony_ci               OpStore %40 %32
409fd4e5da5Sopenharmony_ci               OpReturn
410fd4e5da5Sopenharmony_ci               OpFunctionEnd
411fd4e5da5Sopenharmony_ci)";
412fd4e5da5Sopenharmony_ci
413fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
414fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
415fd4e5da5Sopenharmony_ci
416fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
417fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
418fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
419fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
420fd4e5da5Sopenharmony_ci
421fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
422fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
423fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
424fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
425fd4e5da5Sopenharmony_ci  auto itr4 = live_inputs.find(4);
426fd4e5da5Sopenharmony_ci  auto itr5 = live_inputs.find(5);
427fd4e5da5Sopenharmony_ci  auto itr6 = live_inputs.find(6);
428fd4e5da5Sopenharmony_ci  auto itr7 = live_inputs.find(7);
429fd4e5da5Sopenharmony_ci  auto itr8 = live_inputs.find(8);
430fd4e5da5Sopenharmony_ci  auto itr9 = live_inputs.find(9);
431fd4e5da5Sopenharmony_ci  auto itr10 = live_inputs.find(10);
432fd4e5da5Sopenharmony_ci  auto itr11 = live_inputs.find(11);
433fd4e5da5Sopenharmony_ci
434fd4e5da5Sopenharmony_ci  // Expect live_inputs == {1, 10}
435fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
436fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 != live_inputs.end());
437fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 == live_inputs.end());
438fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 == live_inputs.end());
439fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr4 == live_inputs.end());
440fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr5 == live_inputs.end());
441fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr6 == live_inputs.end());
442fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr7 == live_inputs.end());
443fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr8 == live_inputs.end());
444fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr9 == live_inputs.end());
445fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr10 != live_inputs.end());
446fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr11 == live_inputs.end());
447fd4e5da5Sopenharmony_ci}
448fd4e5da5Sopenharmony_ci
449fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, ArrayedInputMemberLocs) {
450fd4e5da5Sopenharmony_ci  // Tests handling of member locs with arrayed input seen in Tesc, Tese
451fd4e5da5Sopenharmony_ci  // and Geom shaders.
452fd4e5da5Sopenharmony_ci  //
453fd4e5da5Sopenharmony_ci  // Should report location {1, 12}.
454fd4e5da5Sopenharmony_ci  //
455fd4e5da5Sopenharmony_ci  // #version 450
456fd4e5da5Sopenharmony_ci  //
457fd4e5da5Sopenharmony_ci  // layout (vertices = 4) out;
458fd4e5da5Sopenharmony_ci  //
459fd4e5da5Sopenharmony_ci  // in Vertex
460fd4e5da5Sopenharmony_ci  // {
461fd4e5da5Sopenharmony_ci  //     layout (location = 1) vec4 p;
462fd4e5da5Sopenharmony_ci  //     layout (location = 3) vec3 n;
463fd4e5da5Sopenharmony_ci  //     layout (location = 5) vec4 f[100];
464fd4e5da5Sopenharmony_ci  // } iVert[];
465fd4e5da5Sopenharmony_ci  //
466fd4e5da5Sopenharmony_ci  // layout (location = 0) out vec4 position[4];
467fd4e5da5Sopenharmony_ci  //
468fd4e5da5Sopenharmony_ci  // void main()
469fd4e5da5Sopenharmony_ci  // {
470fd4e5da5Sopenharmony_ci  //                 vec4 pos = iVert[gl_InvocationID].p *
471fd4e5da5Sopenharmony_ci  //                            iVert[gl_InvocationID].f[7];
472fd4e5da5Sopenharmony_ci  //                 position[gl_InvocationID] = pos;
473fd4e5da5Sopenharmony_ci  // }
474fd4e5da5Sopenharmony_ci  const std::string text = R"(
475fd4e5da5Sopenharmony_ci               OpCapability Tessellation
476fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
477fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
478fd4e5da5Sopenharmony_ci               OpEntryPoint TessellationControl %main "main" %iVert %gl_InvocationID %position
479fd4e5da5Sopenharmony_ci               OpExecutionMode %main OutputVertices 4
480fd4e5da5Sopenharmony_ci               OpSource GLSL 450
481fd4e5da5Sopenharmony_ci               OpName %main "main"
482fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
483fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "p"
484fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "n"
485fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 2 "f"
486fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
487fd4e5da5Sopenharmony_ci               OpName %gl_InvocationID "gl_InvocationID"
488fd4e5da5Sopenharmony_ci               OpName %position "position"
489fd4e5da5Sopenharmony_ci               OpMemberDecorate %Vertex 0 Location 1
490fd4e5da5Sopenharmony_ci               OpMemberDecorate %Vertex 1 Location 3
491fd4e5da5Sopenharmony_ci               OpMemberDecorate %Vertex 2 Location 5
492fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
493fd4e5da5Sopenharmony_ci               OpDecorate %gl_InvocationID BuiltIn InvocationId
494fd4e5da5Sopenharmony_ci               OpDecorate %position Location 0
495fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
496fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
497fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
498fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
499fd4e5da5Sopenharmony_ci    %v3float = OpTypeVector %float 3
500fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
501fd4e5da5Sopenharmony_ci   %uint_100 = OpConstant %uint 100
502fd4e5da5Sopenharmony_ci%_arr_v4float_uint_100 = OpTypeArray %v4float %uint_100
503fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4float %v3float %_arr_v4float_uint_100
504fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
505fd4e5da5Sopenharmony_ci%_arr_Vertex_uint_32 = OpTypeArray %Vertex %uint_32
506fd4e5da5Sopenharmony_ci%_ptr_Input__arr_Vertex_uint_32 = OpTypePointer Input %_arr_Vertex_uint_32
507fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input__arr_Vertex_uint_32 Input
508fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
509fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
510fd4e5da5Sopenharmony_ci%gl_InvocationID = OpVariable %_ptr_Input_int Input
511fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
512fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
513fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
514fd4e5da5Sopenharmony_ci      %int_7 = OpConstant %int 7
515fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
516fd4e5da5Sopenharmony_ci%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
517fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4
518fd4e5da5Sopenharmony_ci   %position = OpVariable %_ptr_Output__arr_v4float_uint_4 Output
519fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
520fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
521fd4e5da5Sopenharmony_ci          %5 = OpLabel
522fd4e5da5Sopenharmony_ci         %22 = OpLoad %int %gl_InvocationID
523fd4e5da5Sopenharmony_ci         %25 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_0
524fd4e5da5Sopenharmony_ci         %26 = OpLoad %v4float %25
525fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_Input_v4float %iVert %22 %int_2 %int_7
526fd4e5da5Sopenharmony_ci         %31 = OpLoad %v4float %30
527fd4e5da5Sopenharmony_ci         %32 = OpFMul %v4float %26 %31
528fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Output_v4float %position %22
529fd4e5da5Sopenharmony_ci               OpStore %40 %32
530fd4e5da5Sopenharmony_ci               OpReturn
531fd4e5da5Sopenharmony_ci               OpFunctionEnd
532fd4e5da5Sopenharmony_ci)";
533fd4e5da5Sopenharmony_ci
534fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
535fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
536fd4e5da5Sopenharmony_ci
537fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
538fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
539fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
540fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
541fd4e5da5Sopenharmony_ci
542fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
543fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
544fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
545fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
546fd4e5da5Sopenharmony_ci  auto itr4 = live_inputs.find(4);
547fd4e5da5Sopenharmony_ci  auto itr5 = live_inputs.find(5);
548fd4e5da5Sopenharmony_ci  auto itr6 = live_inputs.find(6);
549fd4e5da5Sopenharmony_ci  auto itr7 = live_inputs.find(7);
550fd4e5da5Sopenharmony_ci  auto itr8 = live_inputs.find(8);
551fd4e5da5Sopenharmony_ci  auto itr9 = live_inputs.find(9);
552fd4e5da5Sopenharmony_ci  auto itr10 = live_inputs.find(10);
553fd4e5da5Sopenharmony_ci  auto itr11 = live_inputs.find(11);
554fd4e5da5Sopenharmony_ci  auto itr12 = live_inputs.find(12);
555fd4e5da5Sopenharmony_ci  auto itr13 = live_inputs.find(13);
556fd4e5da5Sopenharmony_ci
557fd4e5da5Sopenharmony_ci  // Expect live_inputs == {1, 12}
558fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
559fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 != live_inputs.end());
560fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 == live_inputs.end());
561fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 == live_inputs.end());
562fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr4 == live_inputs.end());
563fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr5 == live_inputs.end());
564fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr6 == live_inputs.end());
565fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr7 == live_inputs.end());
566fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr8 == live_inputs.end());
567fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr9 == live_inputs.end());
568fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr10 == live_inputs.end());
569fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr11 == live_inputs.end());
570fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr12 != live_inputs.end());
571fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr13 == live_inputs.end());
572fd4e5da5Sopenharmony_ci}
573fd4e5da5Sopenharmony_ci
574fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, Builtins) {
575fd4e5da5Sopenharmony_ci  // Tests handling of builtin input seen in Tesc, Tese and Geom shaders.
576fd4e5da5Sopenharmony_ci  //
577fd4e5da5Sopenharmony_ci  // Should report builtin gl_PointSize only.
578fd4e5da5Sopenharmony_ci  //
579fd4e5da5Sopenharmony_ci  // #version 460
580fd4e5da5Sopenharmony_ci  //
581fd4e5da5Sopenharmony_ci  // layout(triangle_strip, max_vertices = 3) out;
582fd4e5da5Sopenharmony_ci  // layout(triangles) in;
583fd4e5da5Sopenharmony_ci  //
584fd4e5da5Sopenharmony_ci  // void main()
585fd4e5da5Sopenharmony_ci  // {
586fd4e5da5Sopenharmony_ci  //         for (int i = 0; i < 3; i++)
587fd4e5da5Sopenharmony_ci  //         {
588fd4e5da5Sopenharmony_ci  //                 gl_Position = gl_in[i].gl_Position;
589fd4e5da5Sopenharmony_ci  //                 gl_PointSize = gl_in[i].gl_PointSize;
590fd4e5da5Sopenharmony_ci  //
591fd4e5da5Sopenharmony_ci  //                 EmitVertex();
592fd4e5da5Sopenharmony_ci  //         }
593fd4e5da5Sopenharmony_ci  //
594fd4e5da5Sopenharmony_ci  //         EndPrimitive();
595fd4e5da5Sopenharmony_ci  // }
596fd4e5da5Sopenharmony_ci  const std::string text = R"(
597fd4e5da5Sopenharmony_ci               OpCapability Geometry
598fd4e5da5Sopenharmony_ci               OpCapability GeometryPointSize
599fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
600fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
601fd4e5da5Sopenharmony_ci               OpEntryPoint Geometry %main "main" %_ %gl_in
602fd4e5da5Sopenharmony_ci               OpExecutionMode %main Triangles
603fd4e5da5Sopenharmony_ci               OpExecutionMode %main Invocations 1
604fd4e5da5Sopenharmony_ci               OpExecutionMode %main OutputTriangleStrip
605fd4e5da5Sopenharmony_ci               OpExecutionMode %main OutputVertices 3
606fd4e5da5Sopenharmony_ci               OpSource GLSL 460
607fd4e5da5Sopenharmony_ci               OpName %main "main"
608fd4e5da5Sopenharmony_ci               OpName %i "i"
609fd4e5da5Sopenharmony_ci               OpName %gl_PerVertex "gl_PerVertex"
610fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex 0 "gl_Position"
611fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex 1 "gl_PointSize"
612fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
613fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex 3 "gl_CullDistance"
614fd4e5da5Sopenharmony_ci               OpName %_ ""
615fd4e5da5Sopenharmony_ci               OpName %gl_PerVertex_0 "gl_PerVertex"
616fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex_0 0 "gl_Position"
617fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
618fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance"
619fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex_0 3 "gl_CullDistance"
620fd4e5da5Sopenharmony_ci               OpName %gl_in "gl_in"
621fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
622fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
623fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
624fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
625fd4e5da5Sopenharmony_ci               OpDecorate %gl_PerVertex Block
626fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
627fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
628fd4e5da5Sopenharmony_ci               OpDecorate %gl_PerVertex_0 Block
629fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
630fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
631fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
632fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
633fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
634fd4e5da5Sopenharmony_ci      %int_3 = OpConstant %int 3
635fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
636fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
637fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
638fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
639fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
640fd4e5da5Sopenharmony_ci%_arr_float_uint_1 = OpTypeArray %float %uint_1
641fd4e5da5Sopenharmony_ci%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
642fd4e5da5Sopenharmony_ci%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
643fd4e5da5Sopenharmony_ci          %_ = OpVariable %_ptr_Output_gl_PerVertex Output
644fd4e5da5Sopenharmony_ci%gl_PerVertex_0 = OpTypeStruct %v4float %float
645fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
646fd4e5da5Sopenharmony_ci%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
647fd4e5da5Sopenharmony_ci%_ptr_Input__arr_gl_PerVertex_0_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_3
648fd4e5da5Sopenharmony_ci      %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_3 Input
649fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
650fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
651fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
652fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
653fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float
654fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
655fd4e5da5Sopenharmony_ci          %5 = OpLabel
656fd4e5da5Sopenharmony_ci          %i = OpVariable %_ptr_Function_int Function
657fd4e5da5Sopenharmony_ci               OpStore %i %int_0
658fd4e5da5Sopenharmony_ci               OpBranch %10
659fd4e5da5Sopenharmony_ci         %10 = OpLabel
660fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
661fd4e5da5Sopenharmony_ci               OpBranch %14
662fd4e5da5Sopenharmony_ci         %14 = OpLabel
663fd4e5da5Sopenharmony_ci         %15 = OpLoad %int %i
664fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %bool %15 %int_3
665fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
666fd4e5da5Sopenharmony_ci         %11 = OpLabel
667fd4e5da5Sopenharmony_ci         %32 = OpLoad %int %i
668fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %_ptr_Input_v4float %gl_in %32 %int_0
669fd4e5da5Sopenharmony_ci         %35 = OpLoad %v4float %34
670fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0
671fd4e5da5Sopenharmony_ci               OpStore %37 %35
672fd4e5da5Sopenharmony_ci         %39 = OpLoad %int %i
673fd4e5da5Sopenharmony_ci         %41 = OpAccessChain %_ptr_Input_float %gl_in %39 %int_1
674fd4e5da5Sopenharmony_ci         %42 = OpLoad %float %41
675fd4e5da5Sopenharmony_ci         %44 = OpAccessChain %_ptr_Output_float %_ %int_1
676fd4e5da5Sopenharmony_ci               OpStore %44 %42
677fd4e5da5Sopenharmony_ci               OpEmitVertex
678fd4e5da5Sopenharmony_ci               OpBranch %13
679fd4e5da5Sopenharmony_ci         %13 = OpLabel
680fd4e5da5Sopenharmony_ci         %45 = OpLoad %int %i
681fd4e5da5Sopenharmony_ci         %46 = OpIAdd %int %45 %int_1
682fd4e5da5Sopenharmony_ci               OpStore %i %46
683fd4e5da5Sopenharmony_ci               OpBranch %10
684fd4e5da5Sopenharmony_ci         %12 = OpLabel
685fd4e5da5Sopenharmony_ci               OpEndPrimitive
686fd4e5da5Sopenharmony_ci               OpReturn
687fd4e5da5Sopenharmony_ci               OpFunctionEnd
688fd4e5da5Sopenharmony_ci)";
689fd4e5da5Sopenharmony_ci
690fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
691fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
692fd4e5da5Sopenharmony_ci
693fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
694fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
695fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
696fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
697fd4e5da5Sopenharmony_ci
698fd4e5da5Sopenharmony_ci  auto itr0 = live_builtins.find((uint32_t)spv::BuiltIn::PointSize);
699fd4e5da5Sopenharmony_ci  auto itr1 = live_builtins.find((uint32_t)spv::BuiltIn::ClipDistance);
700fd4e5da5Sopenharmony_ci  auto itr2 = live_builtins.find((uint32_t)spv::BuiltIn::CullDistance);
701fd4e5da5Sopenharmony_ci
702fd4e5da5Sopenharmony_ci  // Expect live_builtins == { spv::BuiltIn::PointSize }
703fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 != live_builtins.end());
704fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 == live_builtins.end());
705fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 == live_builtins.end());
706fd4e5da5Sopenharmony_ci}
707fd4e5da5Sopenharmony_ci
708fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, ArrayedInputPatchLocs) {
709fd4e5da5Sopenharmony_ci  // Tests handling of locs with arrayed input patch seen in Tese
710fd4e5da5Sopenharmony_ci  //
711fd4e5da5Sopenharmony_ci  // Should report location {3}.
712fd4e5da5Sopenharmony_ci  //
713fd4e5da5Sopenharmony_ci  // #version 450 core
714fd4e5da5Sopenharmony_ci  //
715fd4e5da5Sopenharmony_ci  // layout(triangles, ccw) in;
716fd4e5da5Sopenharmony_ci  //
717fd4e5da5Sopenharmony_ci  // layout(fractional_odd_spacing) in;
718fd4e5da5Sopenharmony_ci  //
719fd4e5da5Sopenharmony_ci  // layout(point_mode) in;
720fd4e5da5Sopenharmony_ci  //
721fd4e5da5Sopenharmony_ci  // layout(location=2) patch in float patchIn1[2];
722fd4e5da5Sopenharmony_ci  //
723fd4e5da5Sopenharmony_ci  // void main()
724fd4e5da5Sopenharmony_ci  // {
725fd4e5da5Sopenharmony_ci  //     vec4 p = gl_in[1].gl_Position;
726fd4e5da5Sopenharmony_ci  //     gl_Position = p * patchIn1[1];
727fd4e5da5Sopenharmony_ci  // }
728fd4e5da5Sopenharmony_ci  const std::string text = R"(
729fd4e5da5Sopenharmony_ci               OpCapability Tessellation
730fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
731fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
732fd4e5da5Sopenharmony_ci               OpEntryPoint TessellationEvaluation %main "main" %gl_in %_ %patchIn1
733fd4e5da5Sopenharmony_ci               OpExecutionMode %main Triangles
734fd4e5da5Sopenharmony_ci               OpExecutionMode %main SpacingFractionalOdd
735fd4e5da5Sopenharmony_ci               OpExecutionMode %main VertexOrderCcw
736fd4e5da5Sopenharmony_ci               OpExecutionMode %main PointMode
737fd4e5da5Sopenharmony_ci               OpSource GLSL 450
738fd4e5da5Sopenharmony_ci               OpName %main "main"
739fd4e5da5Sopenharmony_ci               OpName %p "p"
740fd4e5da5Sopenharmony_ci               OpName %gl_PerVertex "gl_PerVertex"
741fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex 0 "gl_Position"
742fd4e5da5Sopenharmony_ci               OpName %gl_in "gl_in"
743fd4e5da5Sopenharmony_ci               OpName %gl_PerVertex_0 "gl_PerVertex"
744fd4e5da5Sopenharmony_ci               OpMemberName %gl_PerVertex_0 0 "gl_Position"
745fd4e5da5Sopenharmony_ci               OpName %_ ""
746fd4e5da5Sopenharmony_ci               OpName %patchIn1 "patchIn1"
747fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
748fd4e5da5Sopenharmony_ci               OpDecorate %gl_PerVertex Block
749fd4e5da5Sopenharmony_ci               OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
750fd4e5da5Sopenharmony_ci               OpDecorate %gl_PerVertex_0 Block
751fd4e5da5Sopenharmony_ci               OpDecorate %patchIn1 Patch
752fd4e5da5Sopenharmony_ci               OpDecorate %patchIn1 Location 2
753fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
754fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
755fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
756fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
757fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
758fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
759fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
760fd4e5da5Sopenharmony_ci%_arr_float_uint_1 = OpTypeArray %float %uint_1
761fd4e5da5Sopenharmony_ci%gl_PerVertex = OpTypeStruct %v4float
762fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
763fd4e5da5Sopenharmony_ci%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
764fd4e5da5Sopenharmony_ci%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
765fd4e5da5Sopenharmony_ci      %gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
766fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
767fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
768fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
769fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
770fd4e5da5Sopenharmony_ci%gl_PerVertex_0 = OpTypeStruct %v4float
771fd4e5da5Sopenharmony_ci%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
772fd4e5da5Sopenharmony_ci          %_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
773fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
774fd4e5da5Sopenharmony_ci%_arr_float_uint_2 = OpTypeArray %float %uint_2
775fd4e5da5Sopenharmony_ci%_ptr_Input__arr_float_uint_2 = OpTypePointer Input %_arr_float_uint_2
776fd4e5da5Sopenharmony_ci   %patchIn1 = OpVariable %_ptr_Input__arr_float_uint_2 Input
777fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
778fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
779fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
780fd4e5da5Sopenharmony_ci          %5 = OpLabel
781fd4e5da5Sopenharmony_ci          %p = OpVariable %_ptr_Function_v4float Function
782fd4e5da5Sopenharmony_ci         %22 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
783fd4e5da5Sopenharmony_ci         %23 = OpLoad %v4float %22
784fd4e5da5Sopenharmony_ci               OpStore %p %23
785fd4e5da5Sopenharmony_ci         %27 = OpLoad %v4float %p
786fd4e5da5Sopenharmony_ci         %33 = OpAccessChain %_ptr_Input_float %patchIn1 %int_1
787fd4e5da5Sopenharmony_ci         %34 = OpLoad %float %33
788fd4e5da5Sopenharmony_ci         %35 = OpVectorTimesScalar %v4float %27 %34
789fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %_ptr_Output_v4float %_ %int_0
790fd4e5da5Sopenharmony_ci               OpStore %37 %35
791fd4e5da5Sopenharmony_ci               OpReturn
792fd4e5da5Sopenharmony_ci               OpFunctionEnd
793fd4e5da5Sopenharmony_ci)";
794fd4e5da5Sopenharmony_ci
795fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
796fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
797fd4e5da5Sopenharmony_ci
798fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
799fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
800fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
801fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
802fd4e5da5Sopenharmony_ci
803fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
804fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
805fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
806fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
807fd4e5da5Sopenharmony_ci
808fd4e5da5Sopenharmony_ci  // Expect live_inputs == {3}
809fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
810fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 == live_inputs.end());
811fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 == live_inputs.end());
812fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 != live_inputs.end());
813fd4e5da5Sopenharmony_ci}
814fd4e5da5Sopenharmony_ci
815fd4e5da5Sopenharmony_ciTEST_F(AnalyzeLiveInputTest, FragMultipleLocationsF16) {
816fd4e5da5Sopenharmony_ci  // Should report locations {2, 5}
817fd4e5da5Sopenharmony_ci  //
818fd4e5da5Sopenharmony_ci  // #version 450
819fd4e5da5Sopenharmony_ci  //
820fd4e5da5Sopenharmony_ci  // layout(location = 2) in Vertex
821fd4e5da5Sopenharmony_ci  // {
822fd4e5da5Sopenharmony_ci  //         f16vec4 color0;
823fd4e5da5Sopenharmony_ci  //         f16vec4 color1;
824fd4e5da5Sopenharmony_ci  //         f16vec4 color2[3];
825fd4e5da5Sopenharmony_ci  // } iVert;
826fd4e5da5Sopenharmony_ci  //
827fd4e5da5Sopenharmony_ci  // layout(location = 0) out f16vec4 oFragColor;
828fd4e5da5Sopenharmony_ci  //
829fd4e5da5Sopenharmony_ci  // void main()
830fd4e5da5Sopenharmony_ci  // {
831fd4e5da5Sopenharmony_ci  //     oFragColor = iVert.color0 + iVert.color2[1];
832fd4e5da5Sopenharmony_ci  // }
833fd4e5da5Sopenharmony_ci  const std::string text = R"(
834fd4e5da5Sopenharmony_ci               OpCapability Shader
835fd4e5da5Sopenharmony_ci               OpCapability Float16
836fd4e5da5Sopenharmony_ci               OpCapability StorageInputOutput16
837fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
838fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
839fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %oFragColor %iVert
840fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
841fd4e5da5Sopenharmony_ci               OpSource GLSL 450
842fd4e5da5Sopenharmony_ci               OpName %main "main"
843fd4e5da5Sopenharmony_ci               OpName %oFragColor "oFragColor"
844fd4e5da5Sopenharmony_ci               OpName %Vertex "Vertex"
845fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 0 "color0"
846fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 1 "color1"
847fd4e5da5Sopenharmony_ci               OpMemberName %Vertex 2 "color2"
848fd4e5da5Sopenharmony_ci               OpName %iVert "iVert"
849fd4e5da5Sopenharmony_ci               OpDecorate %oFragColor Location 0
850fd4e5da5Sopenharmony_ci               OpDecorate %Vertex Block
851fd4e5da5Sopenharmony_ci               OpDecorate %iVert Location 2
852fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
853fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
854fd4e5da5Sopenharmony_ci       %half = OpTypeFloat 16
855fd4e5da5Sopenharmony_ci     %v4half = OpTypeVector %half 4
856fd4e5da5Sopenharmony_ci%_ptr_Output_v4half = OpTypePointer Output %v4half
857fd4e5da5Sopenharmony_ci %oFragColor = OpVariable %_ptr_Output_v4half Output
858fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
859fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
860fd4e5da5Sopenharmony_ci%_arr_v4half_uint_3 = OpTypeArray %v4half %uint_3
861fd4e5da5Sopenharmony_ci     %Vertex = OpTypeStruct %v4half %v4half %_arr_v4half_uint_3
862fd4e5da5Sopenharmony_ci%_ptr_Input_Vertex = OpTypePointer Input %Vertex
863fd4e5da5Sopenharmony_ci      %iVert = OpVariable %_ptr_Input_Vertex Input
864fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
865fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
866fd4e5da5Sopenharmony_ci%_ptr_Input_v4half = OpTypePointer Input %v4half
867fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
868fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
869fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
870fd4e5da5Sopenharmony_ci          %5 = OpLabel
871fd4e5da5Sopenharmony_ci         %19 = OpAccessChain %_ptr_Input_v4half %iVert %int_0
872fd4e5da5Sopenharmony_ci         %20 = OpLoad %v4half %19
873fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %_ptr_Input_v4half %iVert %int_2 %int_1
874fd4e5da5Sopenharmony_ci         %24 = OpLoad %v4half %23
875fd4e5da5Sopenharmony_ci         %25 = OpFAdd %v4half %20 %24
876fd4e5da5Sopenharmony_ci               OpStore %oFragColor %25
877fd4e5da5Sopenharmony_ci               OpReturn
878fd4e5da5Sopenharmony_ci               OpFunctionEnd
879fd4e5da5Sopenharmony_ci)";
880fd4e5da5Sopenharmony_ci
881fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_VULKAN_1_3);
882fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
883fd4e5da5Sopenharmony_ci
884fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_inputs;
885fd4e5da5Sopenharmony_ci  std::unordered_set<uint32_t> live_builtins;
886fd4e5da5Sopenharmony_ci  auto result = SinglePassRunToBinary<AnalyzeLiveInputPass>(
887fd4e5da5Sopenharmony_ci      text, true, &live_inputs, &live_builtins);
888fd4e5da5Sopenharmony_ci
889fd4e5da5Sopenharmony_ci  auto itr0 = live_inputs.find(0);
890fd4e5da5Sopenharmony_ci  auto itr1 = live_inputs.find(1);
891fd4e5da5Sopenharmony_ci  auto itr2 = live_inputs.find(2);
892fd4e5da5Sopenharmony_ci  auto itr3 = live_inputs.find(3);
893fd4e5da5Sopenharmony_ci  auto itr4 = live_inputs.find(4);
894fd4e5da5Sopenharmony_ci  auto itr5 = live_inputs.find(5);
895fd4e5da5Sopenharmony_ci  auto itr6 = live_inputs.find(6);
896fd4e5da5Sopenharmony_ci
897fd4e5da5Sopenharmony_ci  // Expect live_inputs == {2, 5}
898fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr0 == live_inputs.end());
899fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr1 == live_inputs.end());
900fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr2 != live_inputs.end());
901fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr3 == live_inputs.end());
902fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr4 == live_inputs.end());
903fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr5 != live_inputs.end());
904fd4e5da5Sopenharmony_ci  EXPECT_TRUE(itr6 == live_inputs.end());
905fd4e5da5Sopenharmony_ci}
906fd4e5da5Sopenharmony_ci
907fd4e5da5Sopenharmony_ci}  // namespace
908fd4e5da5Sopenharmony_ci}  // namespace opt
909fd4e5da5Sopenharmony_ci}  // namespace spvtools
910