1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include "assembly_builder.h"
16fd4e5da5Sopenharmony_ci#include "pass_fixture.h"
17fd4e5da5Sopenharmony_ci#include "pass_utils.h"
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_cinamespace {
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_ciusing namespace spvtools;
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_ciusing EliminateDeadMemberTest = opt::PassTest<::testing::Test>;
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMember1) {
26fd4e5da5Sopenharmony_ci  // Test that the member "y" is removed.
27fd4e5da5Sopenharmony_ci  // Update OpMemberName for |y| and |z|.
28fd4e5da5Sopenharmony_ci  // Update OpMemberDecorate for |y| and |z|.
29fd4e5da5Sopenharmony_ci  // Update OpAccessChain for access to |z|.
30fd4e5da5Sopenharmony_ci  const std::string text = R"(
31fd4e5da5Sopenharmony_ci; CHECK: OpName
32fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
33fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
34fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
35fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
36fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
37fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
38fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0
39fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
40fd4e5da5Sopenharmony_ci               OpCapability Shader
41fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
42fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
43fd4e5da5Sopenharmony_ci               OpSource HLSL 600
44fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
45fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
46fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
47fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
48fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
49fd4e5da5Sopenharmony_ci               OpName %in_var_Position "in.var.Position"
50fd4e5da5Sopenharmony_ci               OpName %main "main"
51fd4e5da5Sopenharmony_ci               OpDecorate %gl_Position BuiltIn Position
52fd4e5da5Sopenharmony_ci               OpDecorate %in_var_Position Location 0
53fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
54fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
55fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
56fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
57fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
58fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
59fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
60fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
61fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
62fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
63fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
64fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
65fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
66fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
67fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
68fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
69fd4e5da5Sopenharmony_ci         %15 = OpTypeFunction %void
70fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
71fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
72fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input
73fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
74fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %15
75fd4e5da5Sopenharmony_ci         %17 = OpLabel
76fd4e5da5Sopenharmony_ci         %18 = OpLoad %v4float %in_var_Position
77fd4e5da5Sopenharmony_ci         %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0
78fd4e5da5Sopenharmony_ci         %20 = OpLoad %float %19
79fd4e5da5Sopenharmony_ci         %21 = OpCompositeExtract %float %18 0
80fd4e5da5Sopenharmony_ci         %22 = OpFAdd %float %21 %20
81fd4e5da5Sopenharmony_ci         %23 = OpCompositeInsert %v4float %22 %18 0
82fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %float %18 1
83fd4e5da5Sopenharmony_ci         %25 = OpCompositeInsert %v4float %24 %23 1
84fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
85fd4e5da5Sopenharmony_ci         %27 = OpLoad %float %26
86fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %float %18 2
87fd4e5da5Sopenharmony_ci         %29 = OpFAdd %float %28 %27
88fd4e5da5Sopenharmony_ci         %30 = OpCompositeInsert %v4float %29 %25 2
89fd4e5da5Sopenharmony_ci               OpStore %gl_Position %30
90fd4e5da5Sopenharmony_ci               OpReturn
91fd4e5da5Sopenharmony_ci               OpFunctionEnd
92fd4e5da5Sopenharmony_ci)";
93fd4e5da5Sopenharmony_ci
94fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
95fd4e5da5Sopenharmony_ci}
96fd4e5da5Sopenharmony_ci
97fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberWithGroupDecorations) {
98fd4e5da5Sopenharmony_ci  // Test that the member "y" is removed.
99fd4e5da5Sopenharmony_ci  // Update OpGroupMemberDecorate for %type__Globals member 1 and 2.
100fd4e5da5Sopenharmony_ci  // Update OpAccessChain for access to %type__Globals member 2.
101fd4e5da5Sopenharmony_ci  const std::string text = R"(
102fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr1:%\w+]] Offset 0
103fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr2:%\w+]] Offset 4
104fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr3:%\w+]] Offset 8
105fd4e5da5Sopenharmony_ci; CHECK: [[gr1]] = OpDecorationGroup
106fd4e5da5Sopenharmony_ci; CHECK: [[gr2]] = OpDecorationGroup
107fd4e5da5Sopenharmony_ci; CHECK: [[gr3]] = OpDecorationGroup
108fd4e5da5Sopenharmony_ci; CHECK: OpGroupMemberDecorate [[gr1]] %type__Globals 0
109fd4e5da5Sopenharmony_ci; CHECK-NOT: OpGroupMemberDecorate [[gr2]]
110fd4e5da5Sopenharmony_ci; CHECK: OpGroupMemberDecorate [[gr3]] %type__Globals 1
111fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
112fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0
113fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
114fd4e5da5Sopenharmony_ci               OpCapability Shader
115fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
116fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
117fd4e5da5Sopenharmony_ci               OpSource HLSL 600
118fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
119fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
120fd4e5da5Sopenharmony_ci               OpDecorate %gl_Position BuiltIn Position
121fd4e5da5Sopenharmony_ci               OpDecorate %in_var_Position Location 0
122fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
123fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
124fd4e5da5Sopenharmony_ci               OpDecorate %gr1 Offset 0
125fd4e5da5Sopenharmony_ci               OpDecorate %gr2 Offset 4
126fd4e5da5Sopenharmony_ci               OpDecorate %gr3 Offset 8
127fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
128fd4e5da5Sopenharmony_ci        %gr1 = OpDecorationGroup
129fd4e5da5Sopenharmony_ci        %gr2 = OpDecorationGroup
130fd4e5da5Sopenharmony_ci        %gr3 = OpDecorationGroup
131fd4e5da5Sopenharmony_ci               OpGroupMemberDecorate %gr1 %type__Globals 0
132fd4e5da5Sopenharmony_ci               OpGroupMemberDecorate %gr2 %type__Globals 1
133fd4e5da5Sopenharmony_ci               OpGroupMemberDecorate %gr3 %type__Globals 2
134fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
135fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
136fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
137fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
138fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
139fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
140fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
141fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
142fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
143fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
144fd4e5da5Sopenharmony_ci         %15 = OpTypeFunction %void
145fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
146fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
147fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input
148fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
149fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %15
150fd4e5da5Sopenharmony_ci         %17 = OpLabel
151fd4e5da5Sopenharmony_ci         %18 = OpLoad %v4float %in_var_Position
152fd4e5da5Sopenharmony_ci         %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0
153fd4e5da5Sopenharmony_ci         %20 = OpLoad %float %19
154fd4e5da5Sopenharmony_ci         %21 = OpCompositeExtract %float %18 0
155fd4e5da5Sopenharmony_ci         %22 = OpFAdd %float %21 %20
156fd4e5da5Sopenharmony_ci         %23 = OpCompositeInsert %v4float %22 %18 0
157fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %float %18 1
158fd4e5da5Sopenharmony_ci         %25 = OpCompositeInsert %v4float %24 %23 1
159fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
160fd4e5da5Sopenharmony_ci         %27 = OpLoad %float %26
161fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %float %18 2
162fd4e5da5Sopenharmony_ci         %29 = OpFAdd %float %28 %27
163fd4e5da5Sopenharmony_ci         %30 = OpCompositeInsert %v4float %29 %25 2
164fd4e5da5Sopenharmony_ci               OpStore %gl_Position %30
165fd4e5da5Sopenharmony_ci               OpReturn
166fd4e5da5Sopenharmony_ci               OpFunctionEnd
167fd4e5da5Sopenharmony_ci)";
168fd4e5da5Sopenharmony_ci
169fd4e5da5Sopenharmony_ci  // Skipping validation because of a bug in the validator.  See issue #2376.
170fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, false);
171fd4e5da5Sopenharmony_ci}
172fd4e5da5Sopenharmony_ci
173fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberUpdateConstant) {
174fd4e5da5Sopenharmony_ci  // Test that the member "x" is removed.
175fd4e5da5Sopenharmony_ci  // Update the OpConstantComposite instruction.
176fd4e5da5Sopenharmony_ci  const std::string text = R"(
177fd4e5da5Sopenharmony_ci; CHECK: OpName
178fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
179fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
180fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
181fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
182fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
183fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
184fd4e5da5Sopenharmony_ci; CHECK: OpConstantComposite %type__Globals %float_1 %float_2
185fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0
186fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
187fd4e5da5Sopenharmony_ci               OpCapability Shader
188fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
189fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
190fd4e5da5Sopenharmony_ci               OpSource HLSL 600
191fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
192fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
193fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
194fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
195fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
196fd4e5da5Sopenharmony_ci               OpName %in_var_Position "in.var.Position"
197fd4e5da5Sopenharmony_ci               OpName %main "main"
198fd4e5da5Sopenharmony_ci               OpDecorate %gl_Position BuiltIn Position
199fd4e5da5Sopenharmony_ci               OpDecorate %in_var_Position Location 0
200fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
201fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
202fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
203fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
204fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
205fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
206fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
207fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
208fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
209fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
210fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
211fd4e5da5Sopenharmony_ci    %float_2 = OpConstant %float 2
212fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
213fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
214fd4e5da5Sopenharmony_ci         %13 = OpConstantComposite %type__Globals %float_0 %float_1 %float_2
215fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
216fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
217fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
218fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
219fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
220fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %void
221fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
222fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
223fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input
224fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
225fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %19
226fd4e5da5Sopenharmony_ci         %21 = OpLabel
227fd4e5da5Sopenharmony_ci         %22 = OpLoad %v4float %in_var_Position
228fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1
229fd4e5da5Sopenharmony_ci         %24 = OpLoad %float %23
230fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %float %22 0
231fd4e5da5Sopenharmony_ci         %26 = OpFAdd %float %25 %24
232fd4e5da5Sopenharmony_ci         %27 = OpCompositeInsert %v4float %26 %22 0
233fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %float %22 1
234fd4e5da5Sopenharmony_ci         %29 = OpCompositeInsert %v4float %28 %27 1
235fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
236fd4e5da5Sopenharmony_ci         %31 = OpLoad %float %30
237fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %float %22 2
238fd4e5da5Sopenharmony_ci         %33 = OpFAdd %float %32 %31
239fd4e5da5Sopenharmony_ci         %34 = OpCompositeInsert %v4float %33 %29 2
240fd4e5da5Sopenharmony_ci               OpStore %gl_Position %34
241fd4e5da5Sopenharmony_ci               OpReturn
242fd4e5da5Sopenharmony_ci               OpFunctionEnd
243fd4e5da5Sopenharmony_ci)";
244fd4e5da5Sopenharmony_ci
245fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
246fd4e5da5Sopenharmony_ci}
247fd4e5da5Sopenharmony_ci
248fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberUpdateCompositeConstruct) {
249fd4e5da5Sopenharmony_ci  // Test that the member "x" is removed.
250fd4e5da5Sopenharmony_ci  // Update the OpConstantComposite instruction.
251fd4e5da5Sopenharmony_ci  const std::string text = R"(
252fd4e5da5Sopenharmony_ci; CHECK: OpName
253fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
254fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
255fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
256fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
257fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
258fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
259fd4e5da5Sopenharmony_ci; CHECK: OpCompositeConstruct %type__Globals %float_1 %float_2
260fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0
261fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
262fd4e5da5Sopenharmony_ci               OpCapability Shader
263fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
264fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
265fd4e5da5Sopenharmony_ci               OpSource HLSL 600
266fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
267fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
268fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
269fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
270fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
271fd4e5da5Sopenharmony_ci               OpName %in_var_Position "in.var.Position"
272fd4e5da5Sopenharmony_ci               OpName %main "main"
273fd4e5da5Sopenharmony_ci               OpDecorate %gl_Position BuiltIn Position
274fd4e5da5Sopenharmony_ci               OpDecorate %in_var_Position Location 0
275fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
276fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
277fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
278fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
279fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
280fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
281fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
282fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
283fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
284fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
285fd4e5da5Sopenharmony_ci    %float_1 = OpConstant %float 1
286fd4e5da5Sopenharmony_ci    %float_2 = OpConstant %float 2
287fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
288fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
289fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
290fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
291fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
292fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
293fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
294fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %void
295fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
296fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
297fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input
298fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
299fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %19
300fd4e5da5Sopenharmony_ci         %21 = OpLabel
301fd4e5da5Sopenharmony_ci         %13 = OpCompositeConstruct %type__Globals %float_0 %float_1 %float_2
302fd4e5da5Sopenharmony_ci         %22 = OpLoad %v4float %in_var_Position
303fd4e5da5Sopenharmony_ci         %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1
304fd4e5da5Sopenharmony_ci         %24 = OpLoad %float %23
305fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %float %22 0
306fd4e5da5Sopenharmony_ci         %26 = OpFAdd %float %25 %24
307fd4e5da5Sopenharmony_ci         %27 = OpCompositeInsert %v4float %26 %22 0
308fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %float %22 1
309fd4e5da5Sopenharmony_ci         %29 = OpCompositeInsert %v4float %28 %27 1
310fd4e5da5Sopenharmony_ci         %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
311fd4e5da5Sopenharmony_ci         %31 = OpLoad %float %30
312fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %float %22 2
313fd4e5da5Sopenharmony_ci         %33 = OpFAdd %float %32 %31
314fd4e5da5Sopenharmony_ci         %34 = OpCompositeInsert %v4float %33 %29 2
315fd4e5da5Sopenharmony_ci               OpStore %gl_Position %34
316fd4e5da5Sopenharmony_ci               OpReturn
317fd4e5da5Sopenharmony_ci               OpFunctionEnd
318fd4e5da5Sopenharmony_ci)";
319fd4e5da5Sopenharmony_ci
320fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
321fd4e5da5Sopenharmony_ci}
322fd4e5da5Sopenharmony_ci
323fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract1) {
324fd4e5da5Sopenharmony_ci  // Test that the members "x" and "z" are removed.
325fd4e5da5Sopenharmony_ci  // Update the OpCompositeExtract instruction.
326fd4e5da5Sopenharmony_ci  // Remove the OpCompositeInsert instruction since the member being inserted is
327fd4e5da5Sopenharmony_ci  // dead.
328fd4e5da5Sopenharmony_ci  const std::string text = R"(
329fd4e5da5Sopenharmony_ci; CHECK: OpName
330fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
331fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
332fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
333fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
334fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float
335fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
336fd4e5da5Sopenharmony_ci; CHECK: OpCompositeExtract %float [[ld]] 0
337fd4e5da5Sopenharmony_ci; CHECK-NOT: OpCompositeInsert
338fd4e5da5Sopenharmony_ci; CHECK: OpReturn
339fd4e5da5Sopenharmony_ci               OpCapability Shader
340fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
341fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
342fd4e5da5Sopenharmony_ci               OpSource HLSL 600
343fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
344fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
345fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
346fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
347fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
348fd4e5da5Sopenharmony_ci               OpName %main "main"
349fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
350fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
351fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
352fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
353fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
354fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
355fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
356fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
357fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
358fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
359fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
360fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
361fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %7
362fd4e5da5Sopenharmony_ci          %8 = OpLabel
363fd4e5da5Sopenharmony_ci          %9 = OpLoad %type__Globals %_Globals
364fd4e5da5Sopenharmony_ci         %10 = OpCompositeExtract %float %9 1
365fd4e5da5Sopenharmony_ci         %11 = OpCompositeInsert %type__Globals %10 %9 2
366fd4e5da5Sopenharmony_ci               OpReturn
367fd4e5da5Sopenharmony_ci               OpFunctionEnd
368fd4e5da5Sopenharmony_ci
369fd4e5da5Sopenharmony_ci)";
370fd4e5da5Sopenharmony_ci
371fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
372fd4e5da5Sopenharmony_ci}
373fd4e5da5Sopenharmony_ci
374fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract2) {
375fd4e5da5Sopenharmony_ci  // Test that the members "x" and "z" are removed.
376fd4e5da5Sopenharmony_ci  // Update the OpCompositeExtract instruction.
377fd4e5da5Sopenharmony_ci  // Update the OpCompositeInsert instruction.
378fd4e5da5Sopenharmony_ci  const std::string text = R"(
379fd4e5da5Sopenharmony_ci; CHECK: OpName
380fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
381fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
382fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
383fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
384fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float
385fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
386fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0
387fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0
388fd4e5da5Sopenharmony_ci; CHECK: OpReturn
389fd4e5da5Sopenharmony_ci               OpCapability Shader
390fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
391fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
392fd4e5da5Sopenharmony_ci               OpSource HLSL 600
393fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
394fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
395fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
396fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
397fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
398fd4e5da5Sopenharmony_ci               OpName %main "main"
399fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
400fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
401fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
402fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
403fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
404fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
405fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
406fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
407fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
408fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
409fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
410fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
411fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %7
412fd4e5da5Sopenharmony_ci          %8 = OpLabel
413fd4e5da5Sopenharmony_ci          %9 = OpLoad %type__Globals %_Globals
414fd4e5da5Sopenharmony_ci         %10 = OpCompositeExtract %float %9 1
415fd4e5da5Sopenharmony_ci         %11 = OpCompositeInsert %type__Globals %10 %9 1
416fd4e5da5Sopenharmony_ci               OpReturn
417fd4e5da5Sopenharmony_ci               OpFunctionEnd
418fd4e5da5Sopenharmony_ci
419fd4e5da5Sopenharmony_ci)";
420fd4e5da5Sopenharmony_ci
421fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
422fd4e5da5Sopenharmony_ci}
423fd4e5da5Sopenharmony_ci
424fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract3) {
425fd4e5da5Sopenharmony_ci  // Test that the members "x" and "z" are removed, and one member from the
426fd4e5da5Sopenharmony_ci  // substruct. Update the OpCompositeExtract instruction. Update the
427fd4e5da5Sopenharmony_ci  // OpCompositeInsert instruction.
428fd4e5da5Sopenharmony_ci  const std::string text = R"(
429fd4e5da5Sopenharmony_ci; CHECK: OpName
430fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
431fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
432fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
433fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
434fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
435fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct %float
436fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[struct]]
437fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
438fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 0
439fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 0
440fd4e5da5Sopenharmony_ci; CHECK: OpReturn
441fd4e5da5Sopenharmony_ci               OpCapability Shader
442fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
443fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
444fd4e5da5Sopenharmony_ci               OpSource HLSL 600
445fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
446fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
447fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
448fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
449fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
450fd4e5da5Sopenharmony_ci               OpName %main "main"
451fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
452fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
453fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
454fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 16
455fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 24
456fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_6 0 Offset 0
457fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_6 1 Offset 4
458fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
459fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
460fd4e5da5Sopenharmony_ci  %_struct_6 = OpTypeStruct %float %float
461fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %_struct_6 %float
462fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
463fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
464fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
465fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
466fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %7
467fd4e5da5Sopenharmony_ci          %8 = OpLabel
468fd4e5da5Sopenharmony_ci          %9 = OpLoad %type__Globals %_Globals
469fd4e5da5Sopenharmony_ci         %10 = OpCompositeExtract %float %9 1 1
470fd4e5da5Sopenharmony_ci         %11 = OpCompositeInsert %type__Globals %10 %9 1 1
471fd4e5da5Sopenharmony_ci               OpReturn
472fd4e5da5Sopenharmony_ci               OpFunctionEnd
473fd4e5da5Sopenharmony_ci
474fd4e5da5Sopenharmony_ci)";
475fd4e5da5Sopenharmony_ci
476fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
477fd4e5da5Sopenharmony_ci}
478fd4e5da5Sopenharmony_ci
479fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract4) {
480fd4e5da5Sopenharmony_ci  // Test that the members "x" and "z" are removed, and one member from the
481fd4e5da5Sopenharmony_ci  // substruct. Update the OpCompositeExtract instruction. Update the
482fd4e5da5Sopenharmony_ci  // OpCompositeInsert instruction.
483fd4e5da5Sopenharmony_ci  const std::string text = R"(
484fd4e5da5Sopenharmony_ci; CHECK: OpName
485fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
486fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
487fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
488fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
489fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
490fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct %float
491fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[struct]]
492fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[array]]
493fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
494fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 1 0
495fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 1 0
496fd4e5da5Sopenharmony_ci; CHECK: OpReturn
497fd4e5da5Sopenharmony_ci               OpCapability Shader
498fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
499fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
500fd4e5da5Sopenharmony_ci               OpSource HLSL 600
501fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
502fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
503fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
504fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
505fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
506fd4e5da5Sopenharmony_ci               OpName %main "main"
507fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
508fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
509fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
510fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 16
511fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 80
512fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_6 0 Offset 0
513fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_6 1 Offset 4
514fd4e5da5Sopenharmony_ci               OpDecorate %array ArrayStride 16
515fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
516fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0                         ; 32-bit int, sign-less
517fd4e5da5Sopenharmony_ci     %uint_4 = OpConstant %uint 4
518fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
519fd4e5da5Sopenharmony_ci  %_struct_6 = OpTypeStruct %float %float
520fd4e5da5Sopenharmony_ci  %array = OpTypeArray %_struct_6 %uint_4
521fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %array %float
522fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
523fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
524fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %void
525fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
526fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %7
527fd4e5da5Sopenharmony_ci          %8 = OpLabel
528fd4e5da5Sopenharmony_ci          %9 = OpLoad %type__Globals %_Globals
529fd4e5da5Sopenharmony_ci         %10 = OpCompositeExtract %float %9 1 1 1
530fd4e5da5Sopenharmony_ci         %11 = OpCompositeInsert %type__Globals %10 %9 1 1 1
531fd4e5da5Sopenharmony_ci               OpReturn
532fd4e5da5Sopenharmony_ci               OpFunctionEnd
533fd4e5da5Sopenharmony_ci
534fd4e5da5Sopenharmony_ci)";
535fd4e5da5Sopenharmony_ci
536fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
537fd4e5da5Sopenharmony_ci}
538fd4e5da5Sopenharmony_ci
539fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateArrayLength) {
540fd4e5da5Sopenharmony_ci  // Test that the members "x" and "y" are removed.
541fd4e5da5Sopenharmony_ci  // Member "z" is live because of the OpArrayLength instruction.
542fd4e5da5Sopenharmony_ci  // Update the OpArrayLength instruction.
543fd4e5da5Sopenharmony_ci  const std::string text = R"(
544fd4e5da5Sopenharmony_ci; CHECK: OpName
545fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "z"
546fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
547fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
548fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
549fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %_runtimearr_float
550fd4e5da5Sopenharmony_ci; CHECK: OpArrayLength %uint %_Globals 0
551fd4e5da5Sopenharmony_ci               OpCapability Shader
552fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
553fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
554fd4e5da5Sopenharmony_ci               OpSource HLSL 600
555fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
556fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
557fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
558fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
559fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
560fd4e5da5Sopenharmony_ci               OpName %main "main"
561fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
562fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
563fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_float ArrayStride 16
564fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
565fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
566fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
567fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
568fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
569fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
570fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
571fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %_runtimearr_float
572fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
573fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
574fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
575fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
576fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %9
577fd4e5da5Sopenharmony_ci         %10 = OpLabel
578fd4e5da5Sopenharmony_ci         %12 = OpArrayLength %uint %_Globals 2
579fd4e5da5Sopenharmony_ci               OpReturn
580fd4e5da5Sopenharmony_ci               OpFunctionEnd
581fd4e5da5Sopenharmony_ci)";
582fd4e5da5Sopenharmony_ci
583fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
584fd4e5da5Sopenharmony_ci}
585fd4e5da5Sopenharmony_ci
586fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpStore) {
587fd4e5da5Sopenharmony_ci  // Test that all members are kept because of an OpStore.
588fd4e5da5Sopenharmony_ci  // No change expected.
589fd4e5da5Sopenharmony_ci  const std::string text = R"(
590fd4e5da5Sopenharmony_ci               OpCapability Shader
591fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
592fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
593fd4e5da5Sopenharmony_ci               OpSource HLSL 600
594fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
595fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
596fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
597fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
598fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
599fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals2"
600fd4e5da5Sopenharmony_ci               OpName %main "main"
601fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
602fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
603fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
604fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
605fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
606fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
607fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
608fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
609fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
610fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
611fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
612fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
613fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
614fd4e5da5Sopenharmony_ci   %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
615fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %9
616fd4e5da5Sopenharmony_ci         %10 = OpLabel
617fd4e5da5Sopenharmony_ci         %11 = OpLoad %type__Globals %_Globals
618fd4e5da5Sopenharmony_ci               OpStore %_Globals2 %11
619fd4e5da5Sopenharmony_ci               OpReturn
620fd4e5da5Sopenharmony_ci               OpFunctionEnd
621fd4e5da5Sopenharmony_ci)";
622fd4e5da5Sopenharmony_ci
623fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
624fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
625fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
626fd4e5da5Sopenharmony_ci}
627fd4e5da5Sopenharmony_ci
628fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepStorageBufferMembers) {
629fd4e5da5Sopenharmony_ci  // Test that all members of the storage buffer struct %S are kept.
630fd4e5da5Sopenharmony_ci  // No change expected.
631fd4e5da5Sopenharmony_ci  const std::string text = R"(
632fd4e5da5Sopenharmony_ci               OpCapability Shader
633fd4e5da5Sopenharmony_ci               OpExtension "SPV_GOOGLE_hlsl_functionality1"
634fd4e5da5Sopenharmony_ci               OpExtension "SPV_GOOGLE_user_type"
635fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
636fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
637fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %PSMain "PSMain" %out_var_SV_TARGET
638fd4e5da5Sopenharmony_ci               OpExecutionMode %PSMain OriginUpperLeft
639fd4e5da5Sopenharmony_ci               OpSource HLSL 600
640fd4e5da5Sopenharmony_ci               OpName %type_StructuredBuffer_S "type.StructuredBuffer.S"
641fd4e5da5Sopenharmony_ci               OpName %S "S"
642fd4e5da5Sopenharmony_ci               OpMemberName %S 0 "A"
643fd4e5da5Sopenharmony_ci               OpMemberName %S 1 "B"
644fd4e5da5Sopenharmony_ci               OpName %Buf "Buf"
645fd4e5da5Sopenharmony_ci               OpName %out_var_SV_TARGET "out.var.SV_TARGET"
646fd4e5da5Sopenharmony_ci               OpName %PSMain "PSMain"
647fd4e5da5Sopenharmony_ci               OpDecorateString %out_var_SV_TARGET UserSemantic "SV_TARGET"
648fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_TARGET Location 0
649fd4e5da5Sopenharmony_ci               OpDecorate %Buf DescriptorSet 0
650fd4e5da5Sopenharmony_ci               OpDecorate %Buf Binding 0
651fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 0 Offset 0
652fd4e5da5Sopenharmony_ci               OpMemberDecorate %S 1 Offset 16
653fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_S ArrayStride 32
654fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 Offset 0
655fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_StructuredBuffer_S 0 NonWritable
656fd4e5da5Sopenharmony_ci               OpDecorate %type_StructuredBuffer_S BufferBlock
657fd4e5da5Sopenharmony_ci               OpDecorateString %Buf UserTypeGOOGLE "structuredbuffer"
658fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
659fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
660fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
661fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
662fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
663fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
664fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
665fd4e5da5Sopenharmony_ci          %S = OpTypeStruct %v4float %v4float
666fd4e5da5Sopenharmony_ci%_runtimearr_S = OpTypeRuntimeArray %S
667fd4e5da5Sopenharmony_ci%type_StructuredBuffer_S = OpTypeStruct %_runtimearr_S
668fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_StructuredBuffer_S = OpTypePointer Uniform %type_StructuredBuffer_S
669fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
670fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
671fd4e5da5Sopenharmony_ci         %18 = OpTypeFunction %void
672fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
673fd4e5da5Sopenharmony_ci        %Buf = OpVariable %_ptr_Uniform_type_StructuredBuffer_S Uniform
674fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
675fd4e5da5Sopenharmony_ci     %PSMain = OpFunction %void None %18
676fd4e5da5Sopenharmony_ci         %20 = OpLabel
677fd4e5da5Sopenharmony_ci         %21 = OpAccessChain %_ptr_Uniform_v4float %Buf %int_0 %uint_0 %int_1
678fd4e5da5Sopenharmony_ci         %22 = OpLoad %v4float %21
679fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_TARGET %22
680fd4e5da5Sopenharmony_ci               OpReturn
681fd4e5da5Sopenharmony_ci               OpFunctionEnd
682fd4e5da5Sopenharmony_ci)";
683fd4e5da5Sopenharmony_ci
684fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
685fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
686fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
687fd4e5da5Sopenharmony_ci}
688fd4e5da5Sopenharmony_ci
689fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemory) {
690fd4e5da5Sopenharmony_ci  // Test that all members are kept because of an OpCopyMemory.
691fd4e5da5Sopenharmony_ci  // No change expected.
692fd4e5da5Sopenharmony_ci  const std::string text = R"(
693fd4e5da5Sopenharmony_ci               OpCapability Shader
694fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
695fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
696fd4e5da5Sopenharmony_ci               OpSource HLSL 600
697fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
698fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
699fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
700fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
701fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
702fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals2"
703fd4e5da5Sopenharmony_ci               OpName %main "main"
704fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
705fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
706fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
707fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
708fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
709fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
710fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
711fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
712fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
713fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
714fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
715fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
716fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
717fd4e5da5Sopenharmony_ci   %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
718fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %9
719fd4e5da5Sopenharmony_ci         %10 = OpLabel
720fd4e5da5Sopenharmony_ci               OpCopyMemory %_Globals2 %_Globals
721fd4e5da5Sopenharmony_ci               OpReturn
722fd4e5da5Sopenharmony_ci               OpFunctionEnd
723fd4e5da5Sopenharmony_ci)";
724fd4e5da5Sopenharmony_ci
725fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
726fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
727fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
728fd4e5da5Sopenharmony_ci}
729fd4e5da5Sopenharmony_ci
730fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemorySized) {
731fd4e5da5Sopenharmony_ci  // Test that all members are kept because of an OpCopyMemorySized.
732fd4e5da5Sopenharmony_ci  // No change expected.
733fd4e5da5Sopenharmony_ci  const std::string text = R"(
734fd4e5da5Sopenharmony_ci               OpCapability Shader
735fd4e5da5Sopenharmony_ci               OpCapability Addresses
736fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
737fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
738fd4e5da5Sopenharmony_ci               OpSource HLSL 600
739fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
740fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
741fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
742fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
743fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
744fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals2"
745fd4e5da5Sopenharmony_ci               OpName %main "main"
746fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
747fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
748fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
749fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
750fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
751fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
752fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
753fd4e5da5Sopenharmony_ci    %uint_20 = OpConstant %uint 20
754fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
755fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
756fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
757fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
758fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %void
759fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
760fd4e5da5Sopenharmony_ci   %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
761fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %9
762fd4e5da5Sopenharmony_ci         %10 = OpLabel
763fd4e5da5Sopenharmony_ci               OpCopyMemorySized %_Globals2 %_Globals %uint_20
764fd4e5da5Sopenharmony_ci               OpReturn
765fd4e5da5Sopenharmony_ci               OpFunctionEnd
766fd4e5da5Sopenharmony_ci)";
767fd4e5da5Sopenharmony_ci
768fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
769fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
770fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
771fd4e5da5Sopenharmony_ci}
772fd4e5da5Sopenharmony_ci
773fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpReturnValue) {
774fd4e5da5Sopenharmony_ci  // Test that all members are kept because of an OpCopyMemorySized.
775fd4e5da5Sopenharmony_ci  // No change expected.
776fd4e5da5Sopenharmony_ci  const std::string text = R"(
777fd4e5da5Sopenharmony_ci               OpCapability Shader
778fd4e5da5Sopenharmony_ci               OpCapability Linkage
779fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
780fd4e5da5Sopenharmony_ci               OpSource HLSL 600
781fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
782fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
783fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
784fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
785fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
786fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals2"
787fd4e5da5Sopenharmony_ci               OpName %main "main"
788fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
789fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
790fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
791fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
792fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
793fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
794fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
795fd4e5da5Sopenharmony_ci    %uint_20 = OpConstant %uint 20
796fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
797fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
798fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
799fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
800fd4e5da5Sopenharmony_ci          %9 = OpTypeFunction %type__Globals
801fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
802fd4e5da5Sopenharmony_ci   %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
803fd4e5da5Sopenharmony_ci       %main = OpFunction %type__Globals None %9
804fd4e5da5Sopenharmony_ci         %10 = OpLabel
805fd4e5da5Sopenharmony_ci         %11 = OpLoad %type__Globals %_Globals
806fd4e5da5Sopenharmony_ci               OpReturnValue %11
807fd4e5da5Sopenharmony_ci               OpFunctionEnd
808fd4e5da5Sopenharmony_ci)";
809fd4e5da5Sopenharmony_ci
810fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
811fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
812fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
813fd4e5da5Sopenharmony_ci}
814fd4e5da5Sopenharmony_ci
815fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberAccessChainWithArrays) {
816fd4e5da5Sopenharmony_ci  // Leave only 1 member in each of the structs.
817fd4e5da5Sopenharmony_ci  // Update OpMemberName, OpMemberDecorate, and OpAccessChain.
818fd4e5da5Sopenharmony_ci  const std::string text = R"(
819fd4e5da5Sopenharmony_ci; CHECK: OpName
820fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
821fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
822fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
823fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
824fd4e5da5Sopenharmony_ci; CHECK: [[struct]] = OpTypeStruct %float
825fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[struct]]
826fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[array]]
827fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef %uint
828fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals [[undef]] %uint_0 [[undef]] %uint_0
829fd4e5da5Sopenharmony_ci               OpCapability Shader
830fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
831fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
832fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
833fd4e5da5Sopenharmony_ci               OpSource HLSL 600
834fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
835fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
836fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
837fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
838fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
839fd4e5da5Sopenharmony_ci               OpName %main "main"
840fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
841fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
842fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
843fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 16
844fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 48
845fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_4 0 Offset 0
846fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_4 1 Offset 4
847fd4e5da5Sopenharmony_ci               OpDecorate %_arr__struct_4_uint_2 ArrayStride 16
848fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
849fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
850fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
851fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
852fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
853fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
854fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
855fd4e5da5Sopenharmony_ci  %_struct_4 = OpTypeStruct %float %float
856fd4e5da5Sopenharmony_ci%_arr__struct_4_uint_2 = OpTypeArray %_struct_4 %uint_2
857fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %_arr__struct_4_uint_2 %float
858fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
859fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
860fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
861fd4e5da5Sopenharmony_ci         %15 = OpTypeFunction %void
862fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
863fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
864fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %15
865fd4e5da5Sopenharmony_ci         %17 = OpLabel
866fd4e5da5Sopenharmony_ci         %18 = OpUndef %uint
867fd4e5da5Sopenharmony_ci         %19 = OpAccessChain %_ptr_Uniform_float %_Globals %18 %uint_1 %18 %uint_1
868fd4e5da5Sopenharmony_ci               OpReturn
869fd4e5da5Sopenharmony_ci               OpFunctionEnd
870fd4e5da5Sopenharmony_ci)";
871fd4e5da5Sopenharmony_ci
872fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
873fd4e5da5Sopenharmony_ci}
874fd4e5da5Sopenharmony_ci
875fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberInboundsAccessChain) {
876fd4e5da5Sopenharmony_ci  // Test that the member "y" is removed.
877fd4e5da5Sopenharmony_ci  // Update OpMemberName for |y| and |z|.
878fd4e5da5Sopenharmony_ci  // Update OpMemberDecorate for |y| and |z|.
879fd4e5da5Sopenharmony_ci  // Update OpInboundsAccessChain for access to |z|.
880fd4e5da5Sopenharmony_ci  const std::string text = R"(
881fd4e5da5Sopenharmony_ci; CHECK: OpName
882fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
883fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
884fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
885fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
886fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
887fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
888fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0
889fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %uint_1
890fd4e5da5Sopenharmony_ci               OpCapability Shader
891fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
892fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
893fd4e5da5Sopenharmony_ci               OpSource HLSL 600
894fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
895fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
896fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
897fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
898fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
899fd4e5da5Sopenharmony_ci               OpName %in_var_Position "in.var.Position"
900fd4e5da5Sopenharmony_ci               OpName %main "main"
901fd4e5da5Sopenharmony_ci               OpDecorate %gl_Position BuiltIn Position
902fd4e5da5Sopenharmony_ci               OpDecorate %in_var_Position Location 0
903fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
904fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
905fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
906fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
907fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 8
908fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
909fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
910fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
911fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
912fd4e5da5Sopenharmony_ci      %int_2 = OpConstant %int 2
913fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
914fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
915fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
916fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
917fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
918fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
919fd4e5da5Sopenharmony_ci         %15 = OpTypeFunction %void
920fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
921fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
922fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input
923fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output
924fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %15
925fd4e5da5Sopenharmony_ci         %17 = OpLabel
926fd4e5da5Sopenharmony_ci         %18 = OpLoad %v4float %in_var_Position
927fd4e5da5Sopenharmony_ci         %19 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0
928fd4e5da5Sopenharmony_ci         %20 = OpLoad %float %19
929fd4e5da5Sopenharmony_ci         %21 = OpCompositeExtract %float %18 0
930fd4e5da5Sopenharmony_ci         %22 = OpFAdd %float %21 %20
931fd4e5da5Sopenharmony_ci         %23 = OpCompositeInsert %v4float %22 %18 0
932fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %float %18 1
933fd4e5da5Sopenharmony_ci         %25 = OpCompositeInsert %v4float %24 %23 1
934fd4e5da5Sopenharmony_ci         %26 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_2
935fd4e5da5Sopenharmony_ci         %27 = OpLoad %float %26
936fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %float %18 2
937fd4e5da5Sopenharmony_ci         %29 = OpFAdd %float %28 %27
938fd4e5da5Sopenharmony_ci         %30 = OpCompositeInsert %v4float %29 %25 2
939fd4e5da5Sopenharmony_ci               OpStore %gl_Position %30
940fd4e5da5Sopenharmony_ci               OpReturn
941fd4e5da5Sopenharmony_ci               OpFunctionEnd
942fd4e5da5Sopenharmony_ci)";
943fd4e5da5Sopenharmony_ci
944fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
945fd4e5da5Sopenharmony_ci}
946fd4e5da5Sopenharmony_ci
947fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberPtrAccessChain) {
948fd4e5da5Sopenharmony_ci  // Test that the member "y" is removed.
949fd4e5da5Sopenharmony_ci  // Update OpMemberName for |y| and |z|.
950fd4e5da5Sopenharmony_ci  // Update OpMemberDecorate for |y| and |z|.
951fd4e5da5Sopenharmony_ci  // Update OpInboundsAccessChain for access to |z|.
952fd4e5da5Sopenharmony_ci  const std::string text = R"(
953fd4e5da5Sopenharmony_ci; CHECK: OpName
954fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
955fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
956fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
957fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
958fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 16
959fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
960fd4e5da5Sopenharmony_ci; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
961fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0
962fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1
963fd4e5da5Sopenharmony_ci               OpCapability Shader
964fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
965fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
966fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
967fd4e5da5Sopenharmony_ci               OpSource HLSL 600
968fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
969fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
970fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
971fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
972fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
973fd4e5da5Sopenharmony_ci               OpName %main "main"
974fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
975fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
976fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
977fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
978fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
979fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
980fd4e5da5Sopenharmony_ci               OpDecorate %_ptr_Uniform_type__Globals ArrayStride 8
981fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
982fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
983fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
984fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
985fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
986fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
987fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
988fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
989fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
990fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
991fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
992fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
993fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
994fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
995fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
996fd4e5da5Sopenharmony_ci         %16 = OpLabel
997fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
998fd4e5da5Sopenharmony_ci         %18 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0
999fd4e5da5Sopenharmony_ci         %19 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2
1000fd4e5da5Sopenharmony_ci               OpReturn
1001fd4e5da5Sopenharmony_ci               OpFunctionEnd
1002fd4e5da5Sopenharmony_ci)";
1003fd4e5da5Sopenharmony_ci
1004fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
1005fd4e5da5Sopenharmony_ci}
1006fd4e5da5Sopenharmony_ci
1007fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberInBoundsPtrAccessChain) {
1008fd4e5da5Sopenharmony_ci  // Test that the member "y" is removed.
1009fd4e5da5Sopenharmony_ci  // Update OpMemberName for |y| and |z|.
1010fd4e5da5Sopenharmony_ci  // Update OpMemberDecorate for |y| and |z|.
1011fd4e5da5Sopenharmony_ci  // Update OpInboundsAccessChain for access to |z|.
1012fd4e5da5Sopenharmony_ci  const std::string text = R"(
1013fd4e5da5Sopenharmony_ci; CHECK: OpName
1014fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
1015fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
1016fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
1017fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
1018fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 16
1019fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float
1020fd4e5da5Sopenharmony_ci; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
1021fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0
1022fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1
1023fd4e5da5Sopenharmony_ci               OpCapability Shader
1024fd4e5da5Sopenharmony_ci               OpCapability Addresses
1025fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1026fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
1027fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1028fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
1029fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
1030fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
1031fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
1032fd4e5da5Sopenharmony_ci               OpName %_Globals "$Globals"
1033fd4e5da5Sopenharmony_ci               OpName %main "main"
1034fd4e5da5Sopenharmony_ci               OpDecorate %_Globals DescriptorSet 0
1035fd4e5da5Sopenharmony_ci               OpDecorate %_Globals Binding 0
1036fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
1037fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
1038fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
1039fd4e5da5Sopenharmony_ci               OpDecorate %type__Globals Block
1040fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1041fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
1042fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
1043fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
1044fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
1045fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1046fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float
1047fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
1048fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
1049fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
1050fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1051fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
1052fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float
1053fd4e5da5Sopenharmony_ci   %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
1054fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
1055fd4e5da5Sopenharmony_ci         %16 = OpLabel
1056fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
1057fd4e5da5Sopenharmony_ci         %18 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0
1058fd4e5da5Sopenharmony_ci         %19 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2
1059fd4e5da5Sopenharmony_ci               OpReturn
1060fd4e5da5Sopenharmony_ci               OpFunctionEnd
1061fd4e5da5Sopenharmony_ci)";
1062fd4e5da5Sopenharmony_ci
1063fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
1064fd4e5da5Sopenharmony_ci}
1065fd4e5da5Sopenharmony_ci
1066fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontRemoveModfStructResultTypeMembers) {
1067fd4e5da5Sopenharmony_ci  const std::string text = R"(
1068fd4e5da5Sopenharmony_ci               OpCapability Shader
1069fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1070fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1071fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
1072fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
1073fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1074fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1075fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1076fd4e5da5Sopenharmony_ci         %21 = OpTypeFunction %void
1077fd4e5da5Sopenharmony_ci%ModfStructType = OpTypeStruct %float %float
1078fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21
1079fd4e5da5Sopenharmony_ci         %22 = OpLabel
1080fd4e5da5Sopenharmony_ci         %23 = OpUndef %float
1081fd4e5da5Sopenharmony_ci         %24 = OpExtInst %ModfStructType %1 ModfStruct %23
1082fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %float %24 1
1083fd4e5da5Sopenharmony_ci               OpReturn
1084fd4e5da5Sopenharmony_ci               OpFunctionEnd
1085fd4e5da5Sopenharmony_ci)";
1086fd4e5da5Sopenharmony_ci
1087fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
1088fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
1089fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
1090fd4e5da5Sopenharmony_ci}
1091fd4e5da5Sopenharmony_ci
1092fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontChangeInputStructs) {
1093fd4e5da5Sopenharmony_ci  // The input for a shader has to match the type of the output from the
1094fd4e5da5Sopenharmony_ci  // previous shader in the pipeline.  Because of that, we cannot change the
1095fd4e5da5Sopenharmony_ci  // types of input variables.
1096fd4e5da5Sopenharmony_ci  const std::string text = R"(
1097fd4e5da5Sopenharmony_ci               OpCapability Shader
1098fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1099fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1100fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %input_var
1101fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
1102fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1103fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1104fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1105fd4e5da5Sopenharmony_ci         %21 = OpTypeFunction %void
1106fd4e5da5Sopenharmony_ci%in_var_type = OpTypeStruct %float %float
1107fd4e5da5Sopenharmony_ci%in_ptr_type = OpTypePointer Input %in_var_type
1108fd4e5da5Sopenharmony_ci%input_var = OpVariable %in_ptr_type Input
1109fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21
1110fd4e5da5Sopenharmony_ci         %22 = OpLabel
1111fd4e5da5Sopenharmony_ci               OpReturn
1112fd4e5da5Sopenharmony_ci               OpFunctionEnd
1113fd4e5da5Sopenharmony_ci)";
1114fd4e5da5Sopenharmony_ci
1115fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
1116fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
1117fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
1118fd4e5da5Sopenharmony_ci}
1119fd4e5da5Sopenharmony_ci
1120fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontChangeOutputStructs) {
1121fd4e5da5Sopenharmony_ci  // The output for a shader has to match the type of the output from the
1122fd4e5da5Sopenharmony_ci  // previous shader in the pipeline.  Because of that, we cannot change the
1123fd4e5da5Sopenharmony_ci  // types of output variables.
1124fd4e5da5Sopenharmony_ci  const std::string text = R"(
1125fd4e5da5Sopenharmony_ci               OpCapability Shader
1126fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1127fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1128fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %output_var
1129fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
1130fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1131fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1132fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1133fd4e5da5Sopenharmony_ci         %21 = OpTypeFunction %void
1134fd4e5da5Sopenharmony_ci%out_var_type = OpTypeStruct %float %float
1135fd4e5da5Sopenharmony_ci%out_ptr_type = OpTypePointer Output %out_var_type
1136fd4e5da5Sopenharmony_ci%output_var = OpVariable %out_ptr_type Output
1137fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21
1138fd4e5da5Sopenharmony_ci         %22 = OpLabel
1139fd4e5da5Sopenharmony_ci               OpReturn
1140fd4e5da5Sopenharmony_ci               OpFunctionEnd
1141fd4e5da5Sopenharmony_ci)";
1142fd4e5da5Sopenharmony_ci
1143fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
1144fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
1145fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
1146fd4e5da5Sopenharmony_ci}
1147fd4e5da5Sopenharmony_ci
1148fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, UpdateSpecConstOpExtract) {
1149fd4e5da5Sopenharmony_ci  // Test that an extract in an OpSpecConstantOp is correctly updated.
1150fd4e5da5Sopenharmony_ci  const std::string text = R"(
1151fd4e5da5Sopenharmony_ci; CHECK: OpName
1152fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
1153fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
1154fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1
1155fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
1156fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %uint
1157fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]]
1158fd4e5da5Sopenharmony_ci; CHECK: OpSpecConstantOp %uint CompositeExtract [[struct]] 0
1159fd4e5da5Sopenharmony_ci               OpCapability Shader
1160fd4e5da5Sopenharmony_ci               OpCapability Addresses
1161fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1162fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
1163fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1164fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
1165fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
1166fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
1167fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
1168fd4e5da5Sopenharmony_ci               OpName %main "main"
1169fd4e5da5Sopenharmony_ci               OpDecorate %c_0 SpecId 0
1170fd4e5da5Sopenharmony_ci               OpDecorate %c_1 SpecId 1
1171fd4e5da5Sopenharmony_ci               OpDecorate %c_2 SpecId 2
1172fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
1173fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
1174fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
1175fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1176fd4e5da5Sopenharmony_ci        %c_0 = OpSpecConstant %uint 0
1177fd4e5da5Sopenharmony_ci        %c_1 = OpSpecConstant %uint 1
1178fd4e5da5Sopenharmony_ci        %c_2 = OpSpecConstant %uint 2
1179fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
1180fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
1181fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
1182fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
1183fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %uint %uint %uint
1184fd4e5da5Sopenharmony_ci%spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2
1185fd4e5da5Sopenharmony_ci%extract = OpSpecConstantOp %uint CompositeExtract %spec_const_global 1
1186fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1187fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
1188fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
1189fd4e5da5Sopenharmony_ci         %16 = OpLabel
1190fd4e5da5Sopenharmony_ci               OpReturn
1191fd4e5da5Sopenharmony_ci               OpFunctionEnd
1192fd4e5da5Sopenharmony_ci)";
1193fd4e5da5Sopenharmony_ci
1194fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
1195fd4e5da5Sopenharmony_ci}
1196fd4e5da5Sopenharmony_ci
1197fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, UpdateSpecConstOpInsert) {
1198fd4e5da5Sopenharmony_ci  // Test that an insert in an OpSpecConstantOp is correctly updated.
1199fd4e5da5Sopenharmony_ci  const std::string text = R"(
1200fd4e5da5Sopenharmony_ci; CHECK: OpName
1201fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
1202fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName
1203fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1
1204fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
1205fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %uint
1206fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]]
1207fd4e5da5Sopenharmony_ci; CHECK: OpSpecConstantOp %type__Globals CompositeInsert %uint_3 [[struct]] 0
1208fd4e5da5Sopenharmony_ci               OpCapability Shader
1209fd4e5da5Sopenharmony_ci               OpCapability Addresses
1210fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1211fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
1212fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1213fd4e5da5Sopenharmony_ci               OpName %type__Globals "type.$Globals"
1214fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 0 "x"
1215fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 1 "y"
1216fd4e5da5Sopenharmony_ci               OpMemberName %type__Globals 2 "z"
1217fd4e5da5Sopenharmony_ci               OpName %main "main"
1218fd4e5da5Sopenharmony_ci               OpDecorate %c_0 SpecId 0
1219fd4e5da5Sopenharmony_ci               OpDecorate %c_1 SpecId 1
1220fd4e5da5Sopenharmony_ci               OpDecorate %c_2 SpecId 2
1221fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 0 Offset 0
1222fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 1 Offset 4
1223fd4e5da5Sopenharmony_ci               OpMemberDecorate %type__Globals 2 Offset 16
1224fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1225fd4e5da5Sopenharmony_ci        %c_0 = OpSpecConstant %uint 0
1226fd4e5da5Sopenharmony_ci        %c_1 = OpSpecConstant %uint 1
1227fd4e5da5Sopenharmony_ci        %c_2 = OpSpecConstant %uint 2
1228fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
1229fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
1230fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
1231fd4e5da5Sopenharmony_ci     %uint_3 = OpConstant %uint 3
1232fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %uint %uint %uint
1233fd4e5da5Sopenharmony_ci%spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2
1234fd4e5da5Sopenharmony_ci%insert = OpSpecConstantOp %type__Globals CompositeInsert %uint_3 %spec_const_global 1
1235fd4e5da5Sopenharmony_ci%extract = OpSpecConstantOp %uint CompositeExtract %insert 1
1236fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1237fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
1238fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
1239fd4e5da5Sopenharmony_ci         %16 = OpLabel
1240fd4e5da5Sopenharmony_ci               OpReturn
1241fd4e5da5Sopenharmony_ci               OpFunctionEnd
1242fd4e5da5Sopenharmony_ci)";
1243fd4e5da5Sopenharmony_ci
1244fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
1245fd4e5da5Sopenharmony_ci}
1246fd4e5da5Sopenharmony_ci
1247fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, 8BitIndexNoChange) {
1248fd4e5da5Sopenharmony_ci  // Test that the pass does not crash when an 8 bit index is used in an
1249fd4e5da5Sopenharmony_ci  // OpAccessChain. No change is expected.
1250fd4e5da5Sopenharmony_ci  const std::string text = R"(
1251fd4e5da5Sopenharmony_ci               OpCapability ImageQuery
1252fd4e5da5Sopenharmony_ci               OpCapability Int8
1253fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1254fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "OpnSeman/" %2
1255fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
1256fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1257fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %void
1258fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1259fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
1260fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %v4float
1261fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
1262fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1263fd4e5da5Sopenharmony_ci         %10 = OpTypeFunction %v4float %_ptr_Function__struct_7
1264fd4e5da5Sopenharmony_ci       %char = OpTypeInt 8 1
1265fd4e5da5Sopenharmony_ci     %char_0 = OpConstant %char 0
1266fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1267fd4e5da5Sopenharmony_ci          %2 = OpVariable %_ptr_Output_v4float Output
1268fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %4
1269fd4e5da5Sopenharmony_ci         %14 = OpLabel
1270fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function__struct_7 Function
1271fd4e5da5Sopenharmony_ci         %16 = OpFunctionCall %v4float %17 %15
1272fd4e5da5Sopenharmony_ci               OpReturn
1273fd4e5da5Sopenharmony_ci               OpFunctionEnd
1274fd4e5da5Sopenharmony_ci         %17 = OpFunction %v4float DontInline %10
1275fd4e5da5Sopenharmony_ci         %18 = OpFunctionParameter %_ptr_Function__struct_7
1276fd4e5da5Sopenharmony_ci         %19 = OpLabel
1277fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %_ptr_Function_v4float %18 %char_0
1278fd4e5da5Sopenharmony_ci         %21 = OpLoad %v4float %20
1279fd4e5da5Sopenharmony_ci               OpReturnValue %21
1280fd4e5da5Sopenharmony_ci               OpFunctionEnd
1281fd4e5da5Sopenharmony_ci)";
1282fd4e5da5Sopenharmony_ci
1283fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
1284fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ true);
1285fd4e5da5Sopenharmony_ci  EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
1286fd4e5da5Sopenharmony_ci}
1287fd4e5da5Sopenharmony_ci
1288fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, 8BitIndexWithChange) {
1289fd4e5da5Sopenharmony_ci  // Test that the pass does not crash when an 8 bit index is used in an
1290fd4e5da5Sopenharmony_ci  // OpAccessChain. The index in the access change should be changed to 0.
1291fd4e5da5Sopenharmony_ci  const std::string text = R"(
1292fd4e5da5Sopenharmony_ci               OpCapability ImageQuery
1293fd4e5da5Sopenharmony_ci               OpCapability Int8
1294fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1295fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "OpnSeman/" %2
1296fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
1297fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1298fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %void
1299fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1300fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
1301fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %v4float %v4float
1302fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
1303fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1304fd4e5da5Sopenharmony_ci         %10 = OpTypeFunction %v4float %_ptr_Function__struct_7
1305fd4e5da5Sopenharmony_ci       %char = OpTypeInt 8 1
1306fd4e5da5Sopenharmony_ci     %char_1 = OpConstant %char 1
1307fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1308fd4e5da5Sopenharmony_ci          %2 = OpVariable %_ptr_Output_v4float Output
1309fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %4
1310fd4e5da5Sopenharmony_ci         %14 = OpLabel
1311fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function__struct_7 Function
1312fd4e5da5Sopenharmony_ci         %16 = OpFunctionCall %v4float %17 %15
1313fd4e5da5Sopenharmony_ci               OpReturn
1314fd4e5da5Sopenharmony_ci               OpFunctionEnd
1315fd4e5da5Sopenharmony_ci         %17 = OpFunction %v4float DontInline %10
1316fd4e5da5Sopenharmony_ci; CHECK: [[param:%\w+]] = OpFunctionParameter
1317fd4e5da5Sopenharmony_ci         %18 = OpFunctionParameter %_ptr_Function__struct_7
1318fd4e5da5Sopenharmony_ci         %19 = OpLabel
1319fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Function_v4float [[param]] %uint_0
1320fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %_ptr_Function_v4float %18 %char_1
1321fd4e5da5Sopenharmony_ci         %21 = OpLoad %v4float %20
1322fd4e5da5Sopenharmony_ci               OpReturnValue %21
1323fd4e5da5Sopenharmony_ci               OpFunctionEnd
1324fd4e5da5Sopenharmony_ci)";
1325fd4e5da5Sopenharmony_ci
1326fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
1327fd4e5da5Sopenharmony_ci}
1328fd4e5da5Sopenharmony_ci
1329fd4e5da5Sopenharmony_ci}  // namespace
1330