1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 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 <string>
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
18fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h"
19fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace opt {
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciusing CopyPropArrayPassTest = PassTest<::testing::Test>;
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BasicPropagateArray) {
28fd4e5da5Sopenharmony_ci  const std::string before =
29fd4e5da5Sopenharmony_ci      R"(
30fd4e5da5Sopenharmony_ciOpCapability Shader
31fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
32fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
33fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
34fd4e5da5Sopenharmony_ciOpSource HLSL 600
35fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
36fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
37fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
38fd4e5da5Sopenharmony_ciOpName %main "main"
39fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
40fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
41fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
42fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
43fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
44fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
45fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
46fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
47fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
48fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
49fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
50fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
51fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
52fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
53fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
54fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
55fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
56fd4e5da5Sopenharmony_ci%void = OpTypeVoid
57fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
58fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
59fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
60fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
61fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
62fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
63fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
64fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
65fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
66fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
67fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
68fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
69fd4e5da5Sopenharmony_ci; CHECK: OpFunction
70fd4e5da5Sopenharmony_ci; CHECK: OpLabel
71fd4e5da5Sopenharmony_ci; CHECK: OpVariable
72fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
73fd4e5da5Sopenharmony_ci; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
74fd4e5da5Sopenharmony_ci; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
75fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
76fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
77fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
78fd4e5da5Sopenharmony_ci%22 = OpLabel
79fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
80fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
81fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
82fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
83fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
84fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
85fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
86fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
87fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
88fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
89fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
90fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
91fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
92fd4e5da5Sopenharmony_ciOpStore %23 %35
93fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
94fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
95fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
96fd4e5da5Sopenharmony_ciOpReturn
97fd4e5da5Sopenharmony_ciOpFunctionEnd
98fd4e5da5Sopenharmony_ci)";
99fd4e5da5Sopenharmony_ci
100fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
101fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
102fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
103fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
104fd4e5da5Sopenharmony_ci}
105fd4e5da5Sopenharmony_ci
106fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BasicPropagateArrayWithName) {
107fd4e5da5Sopenharmony_ci  const std::string before =
108fd4e5da5Sopenharmony_ci      R"(
109fd4e5da5Sopenharmony_ciOpCapability Shader
110fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
111fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
112fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
113fd4e5da5Sopenharmony_ciOpSource HLSL 600
114fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
115fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
116fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
117fd4e5da5Sopenharmony_ciOpName %main "main"
118fd4e5da5Sopenharmony_ciOpName %local "local"
119fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
120fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
121fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
122fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
123fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
124fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
125fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
126fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
127fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
128fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
129fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
130fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
131fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
132fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
133fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
134fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
135fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
136fd4e5da5Sopenharmony_ci%void = OpTypeVoid
137fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
138fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
139fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
140fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
141fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
142fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
143fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
144fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
145fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
146fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
147fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
148fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
149fd4e5da5Sopenharmony_ci; CHECK: OpFunction
150fd4e5da5Sopenharmony_ci; CHECK: OpLabel
151fd4e5da5Sopenharmony_ci; CHECK: OpVariable
152fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
153fd4e5da5Sopenharmony_ci; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
154fd4e5da5Sopenharmony_ci; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
155fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
156fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
157fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
158fd4e5da5Sopenharmony_ci%22 = OpLabel
159fd4e5da5Sopenharmony_ci%local = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
160fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
161fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
162fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
163fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
164fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
165fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
166fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
167fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
168fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
169fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
170fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
171fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
172fd4e5da5Sopenharmony_ciOpStore %local %35
173fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %local %24
174fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
175fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
176fd4e5da5Sopenharmony_ciOpReturn
177fd4e5da5Sopenharmony_ciOpFunctionEnd
178fd4e5da5Sopenharmony_ci)";
179fd4e5da5Sopenharmony_ci
180fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
181fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
182fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
183fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
184fd4e5da5Sopenharmony_ci}
185fd4e5da5Sopenharmony_ci
186fd4e5da5Sopenharmony_ci// Propagate 2d array.  This test identifying a copy through multiple levels.
187fd4e5da5Sopenharmony_ci// Also has to traverse multiple OpAccessChains.
188fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, Propagate2DArray) {
189fd4e5da5Sopenharmony_ci  const std::string text =
190fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
191fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
192fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
193fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
194fd4e5da5Sopenharmony_ciOpSource HLSL 600
195fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
196fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
197fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
198fd4e5da5Sopenharmony_ciOpName %main "main"
199fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
200fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
201fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_2 ArrayStride 16
202fd4e5da5Sopenharmony_ciOpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
203fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
204fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
205fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
206fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
207fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
208fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
209fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
210fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
211fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
212fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
213fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
214fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
215fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
216fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
217fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
218fd4e5da5Sopenharmony_ci%void = OpTypeVoid
219fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %void
220fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
221fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
222fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
223fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
224fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
225fd4e5da5Sopenharmony_ci%_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
226fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
227fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
228fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
229fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
230fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
231fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
232fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
233fd4e5da5Sopenharmony_ci; CHECK: OpFunction
234fd4e5da5Sopenharmony_ci; CHECK: OpLabel
235fd4e5da5Sopenharmony_ci; CHECK: OpVariable
236fd4e5da5Sopenharmony_ci; CHECK: OpVariable
237fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
238fd4e5da5Sopenharmony_ci; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
239fd4e5da5Sopenharmony_ci%main = OpFunction %void None %14
240fd4e5da5Sopenharmony_ci%25 = OpLabel
241fd4e5da5Sopenharmony_ci%26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
242fd4e5da5Sopenharmony_ci%27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
243fd4e5da5Sopenharmony_ci%28 = OpLoad %int %in_var_INDEX
244fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
245fd4e5da5Sopenharmony_ci%30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
246fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %_arr_v4float_uint_2 %30 0
247fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %31 0
248fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %31 1
249fd4e5da5Sopenharmony_ci%34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
250fd4e5da5Sopenharmony_ci%35 = OpCompositeExtract %_arr_v4float_uint_2 %30 1
251fd4e5da5Sopenharmony_ci%36 = OpCompositeExtract %v4float %35 0
252fd4e5da5Sopenharmony_ci%37 = OpCompositeExtract %v4float %35 1
253fd4e5da5Sopenharmony_ci%38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
254fd4e5da5Sopenharmony_ci%39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
255fd4e5da5Sopenharmony_ci; CHECK: OpStore
256fd4e5da5Sopenharmony_ciOpStore %27 %39
257fd4e5da5Sopenharmony_ci%40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
258fd4e5da5Sopenharmony_ci%42 = OpAccessChain %_ptr_Function_v4float %40 %28
259fd4e5da5Sopenharmony_ci%43 = OpLoad %v4float %42
260fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 [[new_address]] %28
261fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[ac1]] %28
262fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[ac2]]
263fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
264fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %43
265fd4e5da5Sopenharmony_ciOpReturn
266fd4e5da5Sopenharmony_ciOpFunctionEnd
267fd4e5da5Sopenharmony_ci)";
268fd4e5da5Sopenharmony_ci
269fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
270fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
271fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
272fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
273fd4e5da5Sopenharmony_ci}
274fd4e5da5Sopenharmony_ci
275fd4e5da5Sopenharmony_ci// Propagate 2d array.  This test identifying a copy through multiple levels.
276fd4e5da5Sopenharmony_ci// Also has to traverse multiple OpAccessChains.
277fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, Propagate2DArrayWithMultiLevelExtract) {
278fd4e5da5Sopenharmony_ci  const std::string text =
279fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
280fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
281fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
282fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
283fd4e5da5Sopenharmony_ciOpSource HLSL 600
284fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
285fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
286fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
287fd4e5da5Sopenharmony_ciOpName %main "main"
288fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
289fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
290fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_2 ArrayStride 16
291fd4e5da5Sopenharmony_ciOpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
292fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
293fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
294fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
295fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
296fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
297fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
298fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
299fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
300fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
301fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
302fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
303fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
304fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
305fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
306fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
307fd4e5da5Sopenharmony_ci%void = OpTypeVoid
308fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %void
309fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
310fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
311fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
312fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
313fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
314fd4e5da5Sopenharmony_ci%_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
315fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
316fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
317fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
318fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
319fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
320fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
321fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
322fd4e5da5Sopenharmony_ci; CHECK: OpFunction
323fd4e5da5Sopenharmony_ci; CHECK: OpLabel
324fd4e5da5Sopenharmony_ci; CHECK: OpVariable
325fd4e5da5Sopenharmony_ci; CHECK: OpVariable
326fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
327fd4e5da5Sopenharmony_ci; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
328fd4e5da5Sopenharmony_ci%main = OpFunction %void None %14
329fd4e5da5Sopenharmony_ci%25 = OpLabel
330fd4e5da5Sopenharmony_ci%26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
331fd4e5da5Sopenharmony_ci%27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
332fd4e5da5Sopenharmony_ci%28 = OpLoad %int %in_var_INDEX
333fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
334fd4e5da5Sopenharmony_ci%30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
335fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %30 0 0
336fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %30 0 1
337fd4e5da5Sopenharmony_ci%34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
338fd4e5da5Sopenharmony_ci%36 = OpCompositeExtract %v4float %30 1 0
339fd4e5da5Sopenharmony_ci%37 = OpCompositeExtract %v4float %30 1 1
340fd4e5da5Sopenharmony_ci%38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
341fd4e5da5Sopenharmony_ci%39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
342fd4e5da5Sopenharmony_ci; CHECK: OpStore
343fd4e5da5Sopenharmony_ciOpStore %27 %39
344fd4e5da5Sopenharmony_ci%40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
345fd4e5da5Sopenharmony_ci%42 = OpAccessChain %_ptr_Function_v4float %40 %28
346fd4e5da5Sopenharmony_ci%43 = OpLoad %v4float %42
347fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 [[new_address]] %28
348fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[ac1]] %28
349fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[ac2]]
350fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
351fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %43
352fd4e5da5Sopenharmony_ciOpReturn
353fd4e5da5Sopenharmony_ciOpFunctionEnd
354fd4e5da5Sopenharmony_ci)";
355fd4e5da5Sopenharmony_ci
356fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
357fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
358fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
359fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
360fd4e5da5Sopenharmony_ci}
361fd4e5da5Sopenharmony_ci
362fd4e5da5Sopenharmony_ci// Test decomposing an object when we need to "rewrite" a store.
363fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, DecomposeObjectForArrayStore) {
364fd4e5da5Sopenharmony_ci  const std::string text =
365fd4e5da5Sopenharmony_ci      R"(               OpCapability Shader
366fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
367fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
368fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
369fd4e5da5Sopenharmony_ci               OpSource HLSL 600
370fd4e5da5Sopenharmony_ci               OpName %type_MyCBuffer "type.MyCBuffer"
371fd4e5da5Sopenharmony_ci               OpMemberName %type_MyCBuffer 0 "Data"
372fd4e5da5Sopenharmony_ci               OpName %MyCBuffer "MyCBuffer"
373fd4e5da5Sopenharmony_ci               OpName %main "main"
374fd4e5da5Sopenharmony_ci               OpName %in_var_INDEX "in.var.INDEX"
375fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
376fd4e5da5Sopenharmony_ci               OpDecorate %_arr_v4float_uint_2 ArrayStride 16
377fd4e5da5Sopenharmony_ci               OpDecorate %_arr__arr_v4float_uint_2_uint_2 ArrayStride 32
378fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_MyCBuffer 0 Offset 0
379fd4e5da5Sopenharmony_ci               OpDecorate %type_MyCBuffer Block
380fd4e5da5Sopenharmony_ci               OpDecorate %in_var_INDEX Flat
381fd4e5da5Sopenharmony_ci               OpDecorate %in_var_INDEX Location 0
382fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
383fd4e5da5Sopenharmony_ci               OpDecorate %MyCBuffer DescriptorSet 0
384fd4e5da5Sopenharmony_ci               OpDecorate %MyCBuffer Binding 0
385fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
386fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
387fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
388fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
389fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2 = OpTypeArray %v4float %uint_2
390fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_uint_2 = OpTypeArray %_arr_v4float_uint_2 %uint_2
391fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr__arr_v4float_uint_2_uint_2
392fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
393fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
394fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
395fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
396fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
397fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
398fd4e5da5Sopenharmony_ci%_arr_v4float_uint_2_0 = OpTypeArray %v4float %uint_2
399fd4e5da5Sopenharmony_ci%_arr__arr_v4float_uint_2_0_uint_2 = OpTypeArray %_arr_v4float_uint_2_0 %uint_2
400fd4e5da5Sopenharmony_ci%_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 = OpTypePointer Function %_arr__arr_v4float_uint_2_0_uint_2
401fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
402fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_v4float_uint_2_uint_2
403fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_2_0 = OpTypePointer Function %_arr_v4float_uint_2_0
404fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
405fd4e5da5Sopenharmony_ci  %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
406fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
407fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
408fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
409fd4e5da5Sopenharmony_ci         %25 = OpLabel
410fd4e5da5Sopenharmony_ci         %26 = OpVariable %_ptr_Function__arr_v4float_uint_2_0 Function
411fd4e5da5Sopenharmony_ci         %27 = OpVariable %_ptr_Function__arr__arr_v4float_uint_2_0_uint_2 Function
412fd4e5da5Sopenharmony_ci         %28 = OpLoad %int %in_var_INDEX
413fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %_ptr_Uniform__arr__arr_v4float_uint_2_uint_2 %MyCBuffer %int_0
414fd4e5da5Sopenharmony_ci         %30 = OpLoad %_arr__arr_v4float_uint_2_uint_2 %29
415fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %_arr_v4float_uint_2 %30 0
416fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %v4float %31 0
417fd4e5da5Sopenharmony_ci         %33 = OpCompositeExtract %v4float %31 1
418fd4e5da5Sopenharmony_ci         %34 = OpCompositeConstruct %_arr_v4float_uint_2_0 %32 %33
419fd4e5da5Sopenharmony_ci         %35 = OpCompositeExtract %_arr_v4float_uint_2 %30 1
420fd4e5da5Sopenharmony_ci         %36 = OpCompositeExtract %v4float %35 0
421fd4e5da5Sopenharmony_ci         %37 = OpCompositeExtract %v4float %35 1
422fd4e5da5Sopenharmony_ci         %38 = OpCompositeConstruct %_arr_v4float_uint_2_0 %36 %37
423fd4e5da5Sopenharmony_ci         %39 = OpCompositeConstruct %_arr__arr_v4float_uint_2_0_uint_2 %34 %38
424fd4e5da5Sopenharmony_ci               OpStore %27 %39
425fd4e5da5Sopenharmony_ci; CHECK: [[access_chain:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2
426fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %27 %28
427fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %_arr_v4float_uint_2 [[access_chain]]
428fd4e5da5Sopenharmony_ci         %41 = OpLoad %_arr_v4float_uint_2_0 %40
429fd4e5da5Sopenharmony_ci; CHECK: [[extract1:%\w+]] = OpCompositeExtract %v4float [[load]] 0
430fd4e5da5Sopenharmony_ci; CHECK: [[extract2:%\w+]] = OpCompositeExtract %v4float [[load]] 1
431fd4e5da5Sopenharmony_ci; CHECK: [[construct:%\w+]] = OpCompositeConstruct %_arr_v4float_uint_2_0 [[extract1]] [[extract2]]
432fd4e5da5Sopenharmony_ci; CHECK: OpStore %26 [[construct]]
433fd4e5da5Sopenharmony_ci               OpStore %26 %41
434fd4e5da5Sopenharmony_ci         %42 = OpAccessChain %_ptr_Function_v4float %26 %28
435fd4e5da5Sopenharmony_ci         %43 = OpLoad %v4float %42
436fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %43
437fd4e5da5Sopenharmony_ci               OpReturn
438fd4e5da5Sopenharmony_ci               OpFunctionEnd
439fd4e5da5Sopenharmony_ci)";
440fd4e5da5Sopenharmony_ci
441fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
442fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
443fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
444fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
445fd4e5da5Sopenharmony_ci}
446fd4e5da5Sopenharmony_ci
447fd4e5da5Sopenharmony_ci// Test decomposing an object when we need to "rewrite" a store.
448fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, DecomposeObjectForStructStore) {
449fd4e5da5Sopenharmony_ci  const std::string text =
450fd4e5da5Sopenharmony_ci      R"(               OpCapability Shader
451fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
452fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
453fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
454fd4e5da5Sopenharmony_ci               OpSource HLSL 600
455fd4e5da5Sopenharmony_ci               OpName %type_MyCBuffer "type.MyCBuffer"
456fd4e5da5Sopenharmony_ci               OpMemberName %type_MyCBuffer 0 "Data"
457fd4e5da5Sopenharmony_ci               OpName %MyCBuffer "MyCBuffer"
458fd4e5da5Sopenharmony_ci               OpName %main "main"
459fd4e5da5Sopenharmony_ci               OpName %in_var_INDEX "in.var.INDEX"
460fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target "out.var.SV_Target"
461fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_MyCBuffer 0 Offset 0
462fd4e5da5Sopenharmony_ci               OpDecorate %type_MyCBuffer Block
463fd4e5da5Sopenharmony_ci               OpDecorate %in_var_INDEX Flat
464fd4e5da5Sopenharmony_ci               OpDecorate %in_var_INDEX Location 0
465fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target Location 0
466fd4e5da5Sopenharmony_ci               OpDecorate %MyCBuffer DescriptorSet 0
467fd4e5da5Sopenharmony_ci               OpDecorate %MyCBuffer Binding 0
468fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[decorated_type:%\w+]] GLSLPacked
469fd4e5da5Sopenharmony_ci               OpDecorate %struct GLSLPacked
470fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
471fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
472fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
473fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
474fd4e5da5Sopenharmony_ci; CHECK: [[decorated_type]] = OpTypeStruct
475fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %float %uint
476fd4e5da5Sopenharmony_ci%_arr_struct_uint_2 = OpTypeArray %struct %uint_2
477fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_struct_uint_2
478fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
479fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
480fd4e5da5Sopenharmony_ci         %14 = OpTypeFunction %void
481fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
482fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
483fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
484fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct %float %uint
485fd4e5da5Sopenharmony_ci%struct_0 = OpTypeStruct %float %uint
486fd4e5da5Sopenharmony_ci%_arr_struct_0_uint_2 = OpTypeArray %struct_0 %uint_2
487fd4e5da5Sopenharmony_ci%_ptr_Function__arr_struct_0_uint_2 = OpTypePointer Function %_arr_struct_0_uint_2
488fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
489fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_struct_uint_2 = OpTypePointer Uniform %_arr_struct_uint_2
490fd4e5da5Sopenharmony_ci; CHECK: [[decorated_ptr:%\w+]] = OpTypePointer Uniform [[decorated_type]]
491fd4e5da5Sopenharmony_ci%_ptr_Function_struct_0 = OpTypePointer Function %struct_0
492fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
493fd4e5da5Sopenharmony_ci  %MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
494fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
495fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
496fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %14
497fd4e5da5Sopenharmony_ci         %25 = OpLabel
498fd4e5da5Sopenharmony_ci         %26 = OpVariable %_ptr_Function_struct_0 Function
499fd4e5da5Sopenharmony_ci         %27 = OpVariable %_ptr_Function__arr_struct_0_uint_2 Function
500fd4e5da5Sopenharmony_ci         %28 = OpLoad %int %in_var_INDEX
501fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %_ptr_Uniform__arr_struct_uint_2 %MyCBuffer %int_0
502fd4e5da5Sopenharmony_ci         %30 = OpLoad %_arr_struct_uint_2 %29
503fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %struct %30 0
504fd4e5da5Sopenharmony_ci         %32 = OpCompositeExtract %v4float %31 0
505fd4e5da5Sopenharmony_ci         %33 = OpCompositeExtract %v4float %31 1
506fd4e5da5Sopenharmony_ci         %34 = OpCompositeConstruct %struct_0 %32 %33
507fd4e5da5Sopenharmony_ci         %35 = OpCompositeExtract %struct %30 1
508fd4e5da5Sopenharmony_ci         %36 = OpCompositeExtract %float %35 0
509fd4e5da5Sopenharmony_ci         %37 = OpCompositeExtract %uint %35 1
510fd4e5da5Sopenharmony_ci         %38 = OpCompositeConstruct %struct_0 %36 %37
511fd4e5da5Sopenharmony_ci         %39 = OpCompositeConstruct %_arr_struct_0_uint_2 %34 %38
512fd4e5da5Sopenharmony_ci               OpStore %27 %39
513fd4e5da5Sopenharmony_ci; CHECK: [[access_chain:%\w+]] = OpAccessChain [[decorated_ptr]]
514fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Function_struct_0 %27 %28
515fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad [[decorated_type]] [[access_chain]]
516fd4e5da5Sopenharmony_ci         %41 = OpLoad %struct_0 %40
517fd4e5da5Sopenharmony_ci; CHECK: [[extract1:%\w+]] = OpCompositeExtract %float [[load]] 0
518fd4e5da5Sopenharmony_ci; CHECK: [[extract2:%\w+]] = OpCompositeExtract %uint [[load]] 1
519fd4e5da5Sopenharmony_ci; CHECK: [[construct:%\w+]] = OpCompositeConstruct [[struct]] [[extract1]] [[extract2]]
520fd4e5da5Sopenharmony_ci; CHECK: OpStore %26 [[construct]]
521fd4e5da5Sopenharmony_ci               OpStore %26 %41
522fd4e5da5Sopenharmony_ci         %42 = OpAccessChain %_ptr_Function_v4float %26 %28
523fd4e5da5Sopenharmony_ci         %43 = OpLoad %v4float %42
524fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target %43
525fd4e5da5Sopenharmony_ci               OpReturn
526fd4e5da5Sopenharmony_ci               OpFunctionEnd
527fd4e5da5Sopenharmony_ci)";
528fd4e5da5Sopenharmony_ci
529fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
530fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
531fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
532fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(text, false);
533fd4e5da5Sopenharmony_ci}
534fd4e5da5Sopenharmony_ci
535fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, CopyViaInserts) {
536fd4e5da5Sopenharmony_ci  const std::string before =
537fd4e5da5Sopenharmony_ci      R"(
538fd4e5da5Sopenharmony_ciOpCapability Shader
539fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
540fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
541fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
542fd4e5da5Sopenharmony_ciOpSource HLSL 600
543fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
544fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
545fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
546fd4e5da5Sopenharmony_ciOpName %main "main"
547fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
548fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
549fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
550fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
551fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
552fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
553fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
554fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
555fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
556fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
557fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
558fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
559fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
560fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
561fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
562fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
563fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
564fd4e5da5Sopenharmony_ci%void = OpTypeVoid
565fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
566fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
567fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
568fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
569fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
570fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
571fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
572fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
573fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
574fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
575fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
576fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
577fd4e5da5Sopenharmony_ci; CHECK: OpFunction
578fd4e5da5Sopenharmony_ci; CHECK: OpLabel
579fd4e5da5Sopenharmony_ci; CHECK: OpVariable
580fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
581fd4e5da5Sopenharmony_ci; CHECK: [[new_address:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
582fd4e5da5Sopenharmony_ci; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[new_address]] %24
583fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
584fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
585fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
586fd4e5da5Sopenharmony_ci%22 = OpLabel
587fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
588fd4e5da5Sopenharmony_ci%undef = OpUndef %_arr_v4float_uint_8_0
589fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
590fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
591fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
592fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
593fd4e5da5Sopenharmony_ci%i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
594fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
595fd4e5da5Sopenharmony_ci%i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
596fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
597fd4e5da5Sopenharmony_ci%i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
598fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
599fd4e5da5Sopenharmony_ci%i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
600fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
601fd4e5da5Sopenharmony_ci%i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
602fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
603fd4e5da5Sopenharmony_ci%i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
604fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
605fd4e5da5Sopenharmony_ci%i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
606fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
607fd4e5da5Sopenharmony_ci%i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
608fd4e5da5Sopenharmony_ciOpStore %23 %i7
609fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
610fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
611fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
612fd4e5da5Sopenharmony_ciOpReturn
613fd4e5da5Sopenharmony_ciOpFunctionEnd
614fd4e5da5Sopenharmony_ci)";
615fd4e5da5Sopenharmony_ci
616fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
617fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
618fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
619fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
620fd4e5da5Sopenharmony_ci}
621fd4e5da5Sopenharmony_ci
622fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, IsomorphicTypes1) {
623fd4e5da5Sopenharmony_ci  const std::string before =
624fd4e5da5Sopenharmony_ci      R"(
625fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
626fd4e5da5Sopenharmony_ci; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
627fd4e5da5Sopenharmony_ci; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
628fd4e5da5Sopenharmony_ci; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
629fd4e5da5Sopenharmony_ci; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
630fd4e5da5Sopenharmony_ci; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
631fd4e5da5Sopenharmony_ci; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
632fd4e5da5Sopenharmony_ci; CHECK: [[p_a1:%\w+]] = OpTypePointer Uniform [[a1]]
633fd4e5da5Sopenharmony_ci; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
634fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_a1]] [[global_var]] %uint_0
635fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s2]] [[ac1]] %uint_0
636fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad [[s2]] [[ac2]]
637fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract [[s1]] [[ld]]
638fd4e5da5Sopenharmony_ci               OpCapability Shader
639fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
640fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
641fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "PS_main"
642fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
643fd4e5da5Sopenharmony_ci               OpSource HLSL 600
644fd4e5da5Sopenharmony_ci               OpDecorate %3 DescriptorSet 0
645fd4e5da5Sopenharmony_ci               OpDecorate %3 Binding 101
646fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
647fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
648fd4e5da5Sopenharmony_ci  %s1 = OpTypeStruct %uint
649fd4e5da5Sopenharmony_ci  %s2 = OpTypeStruct %s1
650fd4e5da5Sopenharmony_ci%a1 = OpTypeArray %s2 %uint_1
651fd4e5da5Sopenharmony_ci  %s3 = OpTypeStruct %a1
652fd4e5da5Sopenharmony_ci %s1_1 = OpTypeStruct %uint
653fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
654fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
655fd4e5da5Sopenharmony_ci         %13 = OpTypeFunction %void
656fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
657fd4e5da5Sopenharmony_ci %s1_0 = OpTypeStruct %uint
658fd4e5da5Sopenharmony_ci %s2_0 = OpTypeStruct %s1_0
659fd4e5da5Sopenharmony_ci%a1_0 = OpTypeArray %s2_0 %uint_1
660fd4e5da5Sopenharmony_ci %s3_0 = OpTypeStruct %a1_0
661fd4e5da5Sopenharmony_ci%p_s3 = OpTypePointer Uniform %s3
662fd4e5da5Sopenharmony_ci%p_s3_0 = OpTypePointer Function %s3_0
663fd4e5da5Sopenharmony_ci          %3 = OpVariable %p_s3 Uniform
664fd4e5da5Sopenharmony_ci%p_a1_0 = OpTypePointer Function %a1_0
665fd4e5da5Sopenharmony_ci%p_s2_0 = OpTypePointer Function %s2_0
666fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %13
667fd4e5da5Sopenharmony_ci         %20 = OpLabel
668fd4e5da5Sopenharmony_ci         %21 = OpVariable %p_a1_0 Function
669fd4e5da5Sopenharmony_ci         %22 = OpLoad %s3 %3
670fd4e5da5Sopenharmony_ci         %23 = OpCompositeExtract %a1 %22 0
671fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %s2 %23 0
672fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %s1 %24 0
673fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %uint %25 0
674fd4e5da5Sopenharmony_ci         %27 = OpCompositeConstruct %s1_0 %26
675fd4e5da5Sopenharmony_ci         %32 = OpCompositeConstruct %s2_0 %27
676fd4e5da5Sopenharmony_ci         %28 = OpCompositeConstruct %a1_0 %32
677fd4e5da5Sopenharmony_ci               OpStore %21 %28
678fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %p_s2_0 %21 %uint_0
679fd4e5da5Sopenharmony_ci         %30 = OpLoad %s2 %29
680fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %s1 %30 0
681fd4e5da5Sopenharmony_ci               OpReturn
682fd4e5da5Sopenharmony_ci               OpFunctionEnd
683fd4e5da5Sopenharmony_ci)";
684fd4e5da5Sopenharmony_ci
685fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
686fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
687fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
688fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
689fd4e5da5Sopenharmony_ci}
690fd4e5da5Sopenharmony_ci
691fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, IsomorphicTypes2) {
692fd4e5da5Sopenharmony_ci  const std::string before =
693fd4e5da5Sopenharmony_ci      R"(
694fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
695fd4e5da5Sopenharmony_ci; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
696fd4e5da5Sopenharmony_ci; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
697fd4e5da5Sopenharmony_ci; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
698fd4e5da5Sopenharmony_ci; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
699fd4e5da5Sopenharmony_ci; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
700fd4e5da5Sopenharmony_ci; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
701fd4e5da5Sopenharmony_ci; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
702fd4e5da5Sopenharmony_ci; CHECK: [[p_s1:%\w+]] = OpTypePointer Uniform [[s1]]
703fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_s2]] [[global_var]] %uint_0 %uint_0
704fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s1]] [[ac1]] %uint_0
705fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad [[s1]] [[ac2]]
706fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract [[int]] [[ld]]
707fd4e5da5Sopenharmony_ci               OpCapability Shader
708fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
709fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
710fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "PS_main"
711fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
712fd4e5da5Sopenharmony_ci               OpSource HLSL 600
713fd4e5da5Sopenharmony_ci               OpDecorate %3 DescriptorSet 0
714fd4e5da5Sopenharmony_ci               OpDecorate %3 Binding 101
715fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
716fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
717fd4e5da5Sopenharmony_ci  %_struct_6 = OpTypeStruct %uint
718fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_struct_6
719fd4e5da5Sopenharmony_ci%_arr__struct_7_uint_1 = OpTypeArray %_struct_7 %uint_1
720fd4e5da5Sopenharmony_ci  %_struct_9 = OpTypeStruct %_arr__struct_7_uint_1
721fd4e5da5Sopenharmony_ci %_struct_10 = OpTypeStruct %uint
722fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
723fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
724fd4e5da5Sopenharmony_ci         %13 = OpTypeFunction %void
725fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
726fd4e5da5Sopenharmony_ci %_struct_15 = OpTypeStruct %uint
727fd4e5da5Sopenharmony_ci%_arr__struct_15_uint_1 = OpTypeArray %_struct_15 %uint_1
728fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
729fd4e5da5Sopenharmony_ci%_ptr_Function__struct_15 = OpTypePointer Function %_struct_15
730fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Uniform__struct_9 Uniform
731fd4e5da5Sopenharmony_ci%_ptr_Function__arr__struct_15_uint_1 = OpTypePointer Function %_arr__struct_15_uint_1
732fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %13
733fd4e5da5Sopenharmony_ci         %20 = OpLabel
734fd4e5da5Sopenharmony_ci         %21 = OpVariable %_ptr_Function__arr__struct_15_uint_1 Function
735fd4e5da5Sopenharmony_ci         %22 = OpLoad %_struct_9 %3
736fd4e5da5Sopenharmony_ci         %23 = OpCompositeExtract %_arr__struct_7_uint_1 %22 0
737fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %_struct_7 %23 0
738fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %_struct_6 %24 0
739fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %uint %25 0
740fd4e5da5Sopenharmony_ci         %27 = OpCompositeConstruct %_struct_15 %26
741fd4e5da5Sopenharmony_ci         %28 = OpCompositeConstruct %_arr__struct_15_uint_1 %27
742fd4e5da5Sopenharmony_ci               OpStore %21 %28
743fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %_ptr_Function__struct_15 %21 %uint_0
744fd4e5da5Sopenharmony_ci         %30 = OpLoad %_struct_15 %29
745fd4e5da5Sopenharmony_ci         %31 = OpCompositeExtract %uint %30 0
746fd4e5da5Sopenharmony_ci               OpReturn
747fd4e5da5Sopenharmony_ci               OpFunctionEnd
748fd4e5da5Sopenharmony_ci)";
749fd4e5da5Sopenharmony_ci
750fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
751fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
752fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
753fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
754fd4e5da5Sopenharmony_ci}
755fd4e5da5Sopenharmony_ci
756fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, IsomorphicTypes3) {
757fd4e5da5Sopenharmony_ci  const std::string before =
758fd4e5da5Sopenharmony_ci      R"(
759fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
760fd4e5da5Sopenharmony_ci; CHECK: [[s1:%\w+]] = OpTypeStruct [[int]]
761fd4e5da5Sopenharmony_ci; CHECK: [[s2:%\w+]] = OpTypeStruct [[s1]]
762fd4e5da5Sopenharmony_ci; CHECK: [[a1:%\w+]] = OpTypeArray [[s2]]
763fd4e5da5Sopenharmony_ci; CHECK: [[s3:%\w+]] = OpTypeStruct [[a1]]
764fd4e5da5Sopenharmony_ci; CHECK: [[s1_1:%\w+]] = OpTypeStruct [[int]]
765fd4e5da5Sopenharmony_ci; CHECK: [[p_s3:%\w+]] = OpTypePointer Uniform [[s3]]
766fd4e5da5Sopenharmony_ci; CHECK: [[p_s1_1:%\w+]] = OpTypePointer Function [[s1_1]]
767fd4e5da5Sopenharmony_ci; CHECK: [[global_var:%\w+]] = OpVariable [[p_s3]] Uniform
768fd4e5da5Sopenharmony_ci; CHECK: [[p_s2:%\w+]] = OpTypePointer Uniform [[s2]]
769fd4e5da5Sopenharmony_ci; CHECK: [[p_s1:%\w+]] = OpTypePointer Uniform [[s1]]
770fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable [[p_s1_1]] Function
771fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain [[p_s2]] [[global_var]] %uint_0 %uint_0
772fd4e5da5Sopenharmony_ci; CHECK: [[ac2:%\w+]] = OpAccessChain [[p_s1]] [[ac1]] %uint_0
773fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad [[s1]] [[ac2]]
774fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract [[int]] [[ld]]
775fd4e5da5Sopenharmony_ci; CHECK: [[copy:%\w+]] = OpCompositeConstruct [[s1_1]] [[ex]]
776fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] [[copy]]
777fd4e5da5Sopenharmony_ci               OpCapability Shader
778fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
779fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
780fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "PS_main"
781fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
782fd4e5da5Sopenharmony_ci               OpSource HLSL 600
783fd4e5da5Sopenharmony_ci               OpDecorate %3 DescriptorSet 0
784fd4e5da5Sopenharmony_ci               OpDecorate %3 Binding 101
785fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
786fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
787fd4e5da5Sopenharmony_ci  %_struct_6 = OpTypeStruct %uint
788fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_struct_6
789fd4e5da5Sopenharmony_ci%_arr__struct_7_uint_1 = OpTypeArray %_struct_7 %uint_1
790fd4e5da5Sopenharmony_ci  %_struct_9 = OpTypeStruct %_arr__struct_7_uint_1
791fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
792fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
793fd4e5da5Sopenharmony_ci         %13 = OpTypeFunction %void
794fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
795fd4e5da5Sopenharmony_ci %_struct_15 = OpTypeStruct %uint
796fd4e5da5Sopenharmony_ci %_struct_10 = OpTypeStruct %uint
797fd4e5da5Sopenharmony_ci%_arr__struct_15_uint_1 = OpTypeArray %_struct_15 %uint_1
798fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
799fd4e5da5Sopenharmony_ci%_ptr_Function__struct_15 = OpTypePointer Function %_struct_15
800fd4e5da5Sopenharmony_ci          %3 = OpVariable %_ptr_Uniform__struct_9 Uniform
801fd4e5da5Sopenharmony_ci%_ptr_Function__arr__struct_15_uint_1 = OpTypePointer Function %_arr__struct_15_uint_1
802fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %13
803fd4e5da5Sopenharmony_ci         %20 = OpLabel
804fd4e5da5Sopenharmony_ci         %21 = OpVariable %_ptr_Function__arr__struct_15_uint_1 Function
805fd4e5da5Sopenharmony_ci        %var = OpVariable %_ptr_Function__struct_15 Function
806fd4e5da5Sopenharmony_ci         %22 = OpLoad %_struct_9 %3
807fd4e5da5Sopenharmony_ci         %23 = OpCompositeExtract %_arr__struct_7_uint_1 %22 0
808fd4e5da5Sopenharmony_ci         %24 = OpCompositeExtract %_struct_7 %23 0
809fd4e5da5Sopenharmony_ci         %25 = OpCompositeExtract %_struct_6 %24 0
810fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %uint %25 0
811fd4e5da5Sopenharmony_ci         %27 = OpCompositeConstruct %_struct_15 %26
812fd4e5da5Sopenharmony_ci         %28 = OpCompositeConstruct %_arr__struct_15_uint_1 %27
813fd4e5da5Sopenharmony_ci               OpStore %21 %28
814fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %_ptr_Function__struct_15 %21 %uint_0
815fd4e5da5Sopenharmony_ci         %30 = OpLoad %_struct_15 %29
816fd4e5da5Sopenharmony_ci               OpStore %var %30
817fd4e5da5Sopenharmony_ci               OpReturn
818fd4e5da5Sopenharmony_ci               OpFunctionEnd
819fd4e5da5Sopenharmony_ci)";
820fd4e5da5Sopenharmony_ci
821fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
822fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
823fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
824fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
825fd4e5da5Sopenharmony_ci}
826fd4e5da5Sopenharmony_ci
827fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BadMergingTwoObjects) {
828fd4e5da5Sopenharmony_ci  // The second element in the |OpCompositeConstruct| is from a different
829fd4e5da5Sopenharmony_ci  // object.
830fd4e5da5Sopenharmony_ci  const std::string text =
831fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
832fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
833fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
834fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
835fd4e5da5Sopenharmony_ciOpName %type_ConstBuf "type.ConstBuf"
836fd4e5da5Sopenharmony_ciOpMemberName %type_ConstBuf 0 "TexSizeU"
837fd4e5da5Sopenharmony_ciOpMemberName %type_ConstBuf 1 "TexSizeV"
838fd4e5da5Sopenharmony_ciOpName %ConstBuf "ConstBuf"
839fd4e5da5Sopenharmony_ciOpName %main "main"
840fd4e5da5Sopenharmony_ciOpMemberDecorate %type_ConstBuf 0 Offset 0
841fd4e5da5Sopenharmony_ciOpMemberDecorate %type_ConstBuf 1 Offset 8
842fd4e5da5Sopenharmony_ciOpDecorate %type_ConstBuf Block
843fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf DescriptorSet 0
844fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf Binding 2
845fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
846fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
847fd4e5da5Sopenharmony_ci%type_ConstBuf = OpTypeStruct %v2float %v2float
848fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_ConstBuf = OpTypePointer Uniform %type_ConstBuf
849fd4e5da5Sopenharmony_ci%void = OpTypeVoid
850fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %void
851fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
852fd4e5da5Sopenharmony_ci%int_0 = OpConstant %uint 0
853fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
854fd4e5da5Sopenharmony_ci%_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
855fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v2float_uint_2 = OpTypePointer Function %_arr_v2float_uint_2
856fd4e5da5Sopenharmony_ci%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
857fd4e5da5Sopenharmony_ci%ConstBuf = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
858fd4e5da5Sopenharmony_ci%main = OpFunction %void None %9
859fd4e5da5Sopenharmony_ci%24 = OpLabel
860fd4e5da5Sopenharmony_ci%25 = OpVariable %_ptr_Function__arr_v2float_uint_2 Function
861fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
862fd4e5da5Sopenharmony_ci%28 = OpLoad %v2float %27
863fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
864fd4e5da5Sopenharmony_ci%30 = OpLoad %v2float %29
865fd4e5da5Sopenharmony_ci%31 = OpFNegate %v2float %30
866fd4e5da5Sopenharmony_ci%37 = OpCompositeConstruct %_arr_v2float_uint_2 %28 %31
867fd4e5da5Sopenharmony_ciOpStore %25 %37
868fd4e5da5Sopenharmony_ciOpReturn
869fd4e5da5Sopenharmony_ciOpFunctionEnd
870fd4e5da5Sopenharmony_ci)";
871fd4e5da5Sopenharmony_ci
872fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
873fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
874fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
875fd4e5da5Sopenharmony_ci}
876fd4e5da5Sopenharmony_ci
877fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, SecondElementNotContained) {
878fd4e5da5Sopenharmony_ci  // The second element in the |OpCompositeConstruct| is not a memory object.
879fd4e5da5Sopenharmony_ci  // Make sure no change happends.
880fd4e5da5Sopenharmony_ci  const std::string text =
881fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
882fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
883fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
884fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
885fd4e5da5Sopenharmony_ciOpName %type_ConstBuf "type.ConstBuf"
886fd4e5da5Sopenharmony_ciOpMemberName %type_ConstBuf 0 "TexSizeU"
887fd4e5da5Sopenharmony_ciOpMemberName %type_ConstBuf 1 "TexSizeV"
888fd4e5da5Sopenharmony_ciOpName %ConstBuf "ConstBuf"
889fd4e5da5Sopenharmony_ciOpName %main "main"
890fd4e5da5Sopenharmony_ciOpMemberDecorate %type_ConstBuf 0 Offset 0
891fd4e5da5Sopenharmony_ciOpMemberDecorate %type_ConstBuf 1 Offset 8
892fd4e5da5Sopenharmony_ciOpDecorate %type_ConstBuf Block
893fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf DescriptorSet 0
894fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf Binding 2
895fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf2 DescriptorSet 1
896fd4e5da5Sopenharmony_ciOpDecorate %ConstBuf2 Binding 2
897fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
898fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
899fd4e5da5Sopenharmony_ci%type_ConstBuf = OpTypeStruct %v2float %v2float
900fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_ConstBuf = OpTypePointer Uniform %type_ConstBuf
901fd4e5da5Sopenharmony_ci%void = OpTypeVoid
902fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %void
903fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
904fd4e5da5Sopenharmony_ci%int_0 = OpConstant %uint 0
905fd4e5da5Sopenharmony_ci%int_1 = OpConstant %uint 1
906fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
907fd4e5da5Sopenharmony_ci%_arr_v2float_uint_2 = OpTypeArray %v2float %uint_2
908fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v2float_uint_2 = OpTypePointer Function %_arr_v2float_uint_2
909fd4e5da5Sopenharmony_ci%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
910fd4e5da5Sopenharmony_ci%ConstBuf = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
911fd4e5da5Sopenharmony_ci%ConstBuf2 = OpVariable %_ptr_Uniform_type_ConstBuf Uniform
912fd4e5da5Sopenharmony_ci%main = OpFunction %void None %9
913fd4e5da5Sopenharmony_ci%24 = OpLabel
914fd4e5da5Sopenharmony_ci%25 = OpVariable %_ptr_Function__arr_v2float_uint_2 Function
915fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf %int_0
916fd4e5da5Sopenharmony_ci%28 = OpLoad %v2float %27
917fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Uniform_v2float %ConstBuf2 %int_1
918fd4e5da5Sopenharmony_ci%30 = OpLoad %v2float %29
919fd4e5da5Sopenharmony_ci%37 = OpCompositeConstruct %_arr_v2float_uint_2 %28 %30
920fd4e5da5Sopenharmony_ciOpStore %25 %37
921fd4e5da5Sopenharmony_ciOpReturn
922fd4e5da5Sopenharmony_ciOpFunctionEnd
923fd4e5da5Sopenharmony_ci)";
924fd4e5da5Sopenharmony_ci
925fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
926fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
927fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
928fd4e5da5Sopenharmony_ci}
929fd4e5da5Sopenharmony_ci// This test will place a load before the store.  We cannot propagate in this
930fd4e5da5Sopenharmony_ci// case.
931fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, LoadBeforeStore) {
932fd4e5da5Sopenharmony_ci  const std::string text =
933fd4e5da5Sopenharmony_ci      R"(
934fd4e5da5Sopenharmony_ciOpCapability Shader
935fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
936fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
937fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
938fd4e5da5Sopenharmony_ciOpSource HLSL 600
939fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
940fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
941fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
942fd4e5da5Sopenharmony_ciOpName %main "main"
943fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
944fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
945fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
946fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
947fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
948fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
949fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
950fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
951fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
952fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
953fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
954fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
955fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
956fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
957fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
958fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
959fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
960fd4e5da5Sopenharmony_ci%void = OpTypeVoid
961fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
962fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
963fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
964fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
965fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
966fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
967fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
968fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
969fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
970fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
971fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
972fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
973fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
974fd4e5da5Sopenharmony_ci%22 = OpLabel
975fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
976fd4e5da5Sopenharmony_ci%38 = OpAccessChain %_ptr_Function_v4float %23 %24
977fd4e5da5Sopenharmony_ci%39 = OpLoad %v4float %36
978fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
979fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
980fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
981fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
982fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
983fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
984fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
985fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
986fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
987fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
988fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
989fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
990fd4e5da5Sopenharmony_ciOpStore %23 %35
991fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
992fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
993fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
994fd4e5da5Sopenharmony_ciOpReturn
995fd4e5da5Sopenharmony_ciOpFunctionEnd
996fd4e5da5Sopenharmony_ci)";
997fd4e5da5Sopenharmony_ci
998fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
999fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1000fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1001fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1002fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1003fd4e5da5Sopenharmony_ci
1004fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1005fd4e5da5Sopenharmony_ci}
1006fd4e5da5Sopenharmony_ci
1007fd4e5da5Sopenharmony_ci// This test will place a load where it is not dominated by the store.  We
1008fd4e5da5Sopenharmony_ci// cannot propagate in this case.
1009fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, LoadNotDominated) {
1010fd4e5da5Sopenharmony_ci  const std::string text =
1011fd4e5da5Sopenharmony_ci      R"(
1012fd4e5da5Sopenharmony_ciOpCapability Shader
1013fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1014fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1015fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1016fd4e5da5Sopenharmony_ciOpSource HLSL 600
1017fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1018fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1019fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1020fd4e5da5Sopenharmony_ciOpName %main "main"
1021fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1022fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1023fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1024fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1025fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1026fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1027fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1028fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1029fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1030fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1031fd4e5da5Sopenharmony_ci%bool = OpTypeBool
1032fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
1033fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1034fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1035fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1036fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1037fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1038fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1039fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1040fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1041fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1042fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1043fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1044fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1045fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1046fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1047fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1048fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1049fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1050fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1051fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1052fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1053fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1054fd4e5da5Sopenharmony_ci%22 = OpLabel
1055fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1056fd4e5da5Sopenharmony_ciOpSelectionMerge %merge None
1057fd4e5da5Sopenharmony_ciOpBranchConditional %true %if %else
1058fd4e5da5Sopenharmony_ci%if = OpLabel
1059fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1060fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1061fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1062fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1063fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1064fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1065fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1066fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1067fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1068fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1069fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1070fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
1071fd4e5da5Sopenharmony_ciOpStore %23 %35
1072fd4e5da5Sopenharmony_ci%38 = OpAccessChain %_ptr_Function_v4float %23 %24
1073fd4e5da5Sopenharmony_ci%39 = OpLoad %v4float %36
1074fd4e5da5Sopenharmony_ciOpBranch %merge
1075fd4e5da5Sopenharmony_ci%else = OpLabel
1076fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1077fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1078fd4e5da5Sopenharmony_ciOpBranch %merge
1079fd4e5da5Sopenharmony_ci%merge = OpLabel
1080fd4e5da5Sopenharmony_ci%phi = OpPhi %out_var_SV_Target %39 %if %37 %else
1081fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %phi
1082fd4e5da5Sopenharmony_ciOpReturn
1083fd4e5da5Sopenharmony_ciOpFunctionEnd
1084fd4e5da5Sopenharmony_ci)";
1085fd4e5da5Sopenharmony_ci
1086fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1087fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1088fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1089fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1090fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1091fd4e5da5Sopenharmony_ci
1092fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1093fd4e5da5Sopenharmony_ci}
1094fd4e5da5Sopenharmony_ci
1095fd4e5da5Sopenharmony_ci// This test has a partial store to the variable.  We cannot propagate in this
1096fd4e5da5Sopenharmony_ci// case.
1097fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, PartialStore) {
1098fd4e5da5Sopenharmony_ci  const std::string text =
1099fd4e5da5Sopenharmony_ci      R"(
1100fd4e5da5Sopenharmony_ciOpCapability Shader
1101fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1102fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1103fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1104fd4e5da5Sopenharmony_ciOpSource HLSL 600
1105fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1106fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1107fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1108fd4e5da5Sopenharmony_ciOpName %main "main"
1109fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1110fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1111fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1112fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1113fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1114fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1115fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1116fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1117fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1118fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1119fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1120fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1121fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1122fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1123fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1124fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1125fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1126fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1127fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1128fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1129fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1130fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1131fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1132fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1133fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1134fd4e5da5Sopenharmony_ci%f0 = OpConstant %float 0
1135fd4e5da5Sopenharmony_ci%v4const = OpConstantComposite %v4float %f0 %f0 %f0 %f0
1136fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1137fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1138fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1139fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1140fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1141fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1142fd4e5da5Sopenharmony_ci%22 = OpLabel
1143fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1144fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1145fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1146fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1147fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1148fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1149fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1150fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1151fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1152fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1153fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1154fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1155fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
1156fd4e5da5Sopenharmony_ciOpStore %23 %35
1157fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1158fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1159fd4e5da5Sopenharmony_ci      OpStore %36 %v4const
1160fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1161fd4e5da5Sopenharmony_ciOpReturn
1162fd4e5da5Sopenharmony_ciOpFunctionEnd
1163fd4e5da5Sopenharmony_ci)";
1164fd4e5da5Sopenharmony_ci
1165fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1166fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1167fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1168fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1169fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1170fd4e5da5Sopenharmony_ci
1171fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1172fd4e5da5Sopenharmony_ci}
1173fd4e5da5Sopenharmony_ci
1174fd4e5da5Sopenharmony_ci// This test does not have a proper copy of an object.  We cannot propagate in
1175fd4e5da5Sopenharmony_ci// this case.
1176fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, NotACopy) {
1177fd4e5da5Sopenharmony_ci  const std::string text =
1178fd4e5da5Sopenharmony_ci      R"(
1179fd4e5da5Sopenharmony_ciOpCapability Shader
1180fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1181fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1182fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1183fd4e5da5Sopenharmony_ciOpSource HLSL 600
1184fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1185fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1186fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1187fd4e5da5Sopenharmony_ciOpName %main "main"
1188fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1189fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1190fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1191fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1192fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1193fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1194fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1195fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1196fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1197fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1198fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1199fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1200fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1201fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1202fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1203fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1204fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1205fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1206fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1207fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1208fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1209fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1210fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1211fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1212fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1213fd4e5da5Sopenharmony_ci%f0 = OpConstant %float 0
1214fd4e5da5Sopenharmony_ci%v4const = OpConstantComposite %v4float %f0 %f0 %f0 %f0
1215fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1216fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1217fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1218fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1219fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1220fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1221fd4e5da5Sopenharmony_ci%22 = OpLabel
1222fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1223fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1224fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1225fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1226fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1227fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 0
1228fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1229fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1230fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1231fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1232fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1233fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1234fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
1235fd4e5da5Sopenharmony_ciOpStore %23 %35
1236fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1237fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1238fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1239fd4e5da5Sopenharmony_ciOpReturn
1240fd4e5da5Sopenharmony_ciOpFunctionEnd
1241fd4e5da5Sopenharmony_ci)";
1242fd4e5da5Sopenharmony_ci
1243fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1244fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1245fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1246fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1247fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1248fd4e5da5Sopenharmony_ci
1249fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1250fd4e5da5Sopenharmony_ci}
1251fd4e5da5Sopenharmony_ci
1252fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BadCopyViaInserts1) {
1253fd4e5da5Sopenharmony_ci  const std::string text =
1254fd4e5da5Sopenharmony_ci      R"(
1255fd4e5da5Sopenharmony_ciOpCapability Shader
1256fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1257fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1258fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1259fd4e5da5Sopenharmony_ciOpSource HLSL 600
1260fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1261fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1262fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1263fd4e5da5Sopenharmony_ciOpName %main "main"
1264fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1265fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1266fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1267fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1268fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1269fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1270fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1271fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1272fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1273fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1274fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1275fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1276fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1277fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1278fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1279fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1280fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1281fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1282fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1283fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1284fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1285fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1286fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1287fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1288fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1289fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1290fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1291fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1292fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1293fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1294fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1295fd4e5da5Sopenharmony_ci%22 = OpLabel
1296fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1297fd4e5da5Sopenharmony_ci%undef = OpUndef %_arr_v4float_uint_8_0
1298fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1299fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1300fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1301fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1302fd4e5da5Sopenharmony_ci%i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
1303fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1304fd4e5da5Sopenharmony_ci%i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
1305fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1306fd4e5da5Sopenharmony_ci%i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 3
1307fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1308fd4e5da5Sopenharmony_ci%i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
1309fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1310fd4e5da5Sopenharmony_ci%i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
1311fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1312fd4e5da5Sopenharmony_ci%i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
1313fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1314fd4e5da5Sopenharmony_ci%i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
1315fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1316fd4e5da5Sopenharmony_ci%i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
1317fd4e5da5Sopenharmony_ciOpStore %23 %i7
1318fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1319fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1320fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1321fd4e5da5Sopenharmony_ciOpReturn
1322fd4e5da5Sopenharmony_ciOpFunctionEnd
1323fd4e5da5Sopenharmony_ci)";
1324fd4e5da5Sopenharmony_ci
1325fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1326fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1327fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1328fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1329fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1330fd4e5da5Sopenharmony_ci
1331fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1332fd4e5da5Sopenharmony_ci}
1333fd4e5da5Sopenharmony_ci
1334fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BadCopyViaInserts2) {
1335fd4e5da5Sopenharmony_ci  const std::string text =
1336fd4e5da5Sopenharmony_ci      R"(
1337fd4e5da5Sopenharmony_ciOpCapability Shader
1338fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1339fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1340fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1341fd4e5da5Sopenharmony_ciOpSource HLSL 600
1342fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1343fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1344fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1345fd4e5da5Sopenharmony_ciOpName %main "main"
1346fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1347fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1348fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1349fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1350fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1351fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1352fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1353fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1354fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1355fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1356fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1357fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1358fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1359fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1360fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1361fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1362fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1363fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1364fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1365fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1366fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1367fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1368fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1369fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1370fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1371fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1372fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1373fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1374fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1375fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1376fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1377fd4e5da5Sopenharmony_ci%22 = OpLabel
1378fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1379fd4e5da5Sopenharmony_ci%undef = OpUndef %_arr_v4float_uint_8_0
1380fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1381fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1382fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1383fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1384fd4e5da5Sopenharmony_ci%i0 = OpCompositeInsert %_arr_v4float_uint_8_0 %27 %undef 0
1385fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1386fd4e5da5Sopenharmony_ci%i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %i0 1
1387fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 3
1388fd4e5da5Sopenharmony_ci%i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
1389fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1390fd4e5da5Sopenharmony_ci%i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
1391fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1392fd4e5da5Sopenharmony_ci%i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
1393fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1394fd4e5da5Sopenharmony_ci%i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
1395fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1396fd4e5da5Sopenharmony_ci%i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
1397fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1398fd4e5da5Sopenharmony_ci%i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
1399fd4e5da5Sopenharmony_ciOpStore %23 %i7
1400fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1401fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1402fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1403fd4e5da5Sopenharmony_ciOpReturn
1404fd4e5da5Sopenharmony_ciOpFunctionEnd
1405fd4e5da5Sopenharmony_ci)";
1406fd4e5da5Sopenharmony_ci
1407fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1408fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1409fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1410fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1411fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1412fd4e5da5Sopenharmony_ci
1413fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1414fd4e5da5Sopenharmony_ci}
1415fd4e5da5Sopenharmony_ci
1416fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, BadCopyViaInserts3) {
1417fd4e5da5Sopenharmony_ci  const std::string text =
1418fd4e5da5Sopenharmony_ci      R"(
1419fd4e5da5Sopenharmony_ciOpCapability Shader
1420fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1421fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1422fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1423fd4e5da5Sopenharmony_ciOpSource HLSL 600
1424fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1425fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1426fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1427fd4e5da5Sopenharmony_ciOpName %main "main"
1428fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1429fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1430fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1431fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1432fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1433fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1434fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1435fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1436fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1437fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1438fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1439fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1440fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1441fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1442fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1443fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1444fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1445fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1446fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1447fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1448fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1449fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1450fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1451fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1452fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1453fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1454fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1455fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1456fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1457fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1458fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1459fd4e5da5Sopenharmony_ci%22 = OpLabel
1460fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1461fd4e5da5Sopenharmony_ci%undef = OpUndef %_arr_v4float_uint_8_0
1462fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1463fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1464fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1465fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1466fd4e5da5Sopenharmony_ci%i1 = OpCompositeInsert %_arr_v4float_uint_8_0 %28 %undef 1
1467fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1468fd4e5da5Sopenharmony_ci%i2 = OpCompositeInsert %_arr_v4float_uint_8_0 %29 %i1 2
1469fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1470fd4e5da5Sopenharmony_ci%i3 = OpCompositeInsert %_arr_v4float_uint_8_0 %30 %i2 3
1471fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1472fd4e5da5Sopenharmony_ci%i4 = OpCompositeInsert %_arr_v4float_uint_8_0 %31 %i3 4
1473fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1474fd4e5da5Sopenharmony_ci%i5 = OpCompositeInsert %_arr_v4float_uint_8_0 %32 %i4 5
1475fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1476fd4e5da5Sopenharmony_ci%i6 = OpCompositeInsert %_arr_v4float_uint_8_0 %33 %i5 6
1477fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1478fd4e5da5Sopenharmony_ci%i7 = OpCompositeInsert %_arr_v4float_uint_8_0 %34 %i6 7
1479fd4e5da5Sopenharmony_ciOpStore %23 %i7
1480fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1481fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1482fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1483fd4e5da5Sopenharmony_ciOpReturn
1484fd4e5da5Sopenharmony_ciOpFunctionEnd
1485fd4e5da5Sopenharmony_ci)";
1486fd4e5da5Sopenharmony_ci
1487fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1488fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1489fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1490fd4e5da5Sopenharmony_ci  auto result = SinglePassRunAndDisassemble<CopyPropagateArrays>(
1491fd4e5da5Sopenharmony_ci      text, /* skip_nop = */ true, /* do_validation = */ false);
1492fd4e5da5Sopenharmony_ci
1493fd4e5da5Sopenharmony_ci  EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
1494fd4e5da5Sopenharmony_ci}
1495fd4e5da5Sopenharmony_ci
1496fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, AtomicAdd) {
1497fd4e5da5Sopenharmony_ci  const std::string before = R"(OpCapability SampledBuffer
1498fd4e5da5Sopenharmony_ciOpCapability StorageImageExtendedFormats
1499fd4e5da5Sopenharmony_ciOpCapability ImageBuffer
1500fd4e5da5Sopenharmony_ciOpCapability Shader
1501fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1502fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1503fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID
1504fd4e5da5Sopenharmony_ciOpExecutionMode %2 LocalSize 64 1 1
1505fd4e5da5Sopenharmony_ciOpSource HLSL 600
1506fd4e5da5Sopenharmony_ciOpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
1507fd4e5da5Sopenharmony_ciOpDecorate %4 DescriptorSet 4
1508fd4e5da5Sopenharmony_ciOpDecorate %4 Binding 70
1509fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1510fd4e5da5Sopenharmony_ci%6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
1511fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
1512fd4e5da5Sopenharmony_ci%_ptr_Function_6 = OpTypePointer Function %6
1513fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1514fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
1515fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1516fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1517fd4e5da5Sopenharmony_ci%v3uint = OpTypeVector %uint 3
1518fd4e5da5Sopenharmony_ci%_ptr_Input_v3uint = OpTypePointer Input %v3uint
1519fd4e5da5Sopenharmony_ci%_ptr_Image_uint = OpTypePointer Image %uint
1520fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
1521fd4e5da5Sopenharmony_ci%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
1522fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %10
1523fd4e5da5Sopenharmony_ci%17 = OpLabel
1524fd4e5da5Sopenharmony_ci%16 = OpVariable %_ptr_Function_6 Function
1525fd4e5da5Sopenharmony_ci%18 = OpLoad %6 %4
1526fd4e5da5Sopenharmony_ciOpStore %16 %18
1527fd4e5da5Sopenharmony_ci%19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0
1528fd4e5da5Sopenharmony_ci%20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
1529fd4e5da5Sopenharmony_ciOpReturn
1530fd4e5da5Sopenharmony_ciOpFunctionEnd
1531fd4e5da5Sopenharmony_ci)";
1532fd4e5da5Sopenharmony_ci
1533fd4e5da5Sopenharmony_ci  const std::string after = R"(OpCapability SampledBuffer
1534fd4e5da5Sopenharmony_ciOpCapability StorageImageExtendedFormats
1535fd4e5da5Sopenharmony_ciOpCapability ImageBuffer
1536fd4e5da5Sopenharmony_ciOpCapability Shader
1537fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1538fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1539fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID
1540fd4e5da5Sopenharmony_ciOpExecutionMode %2 LocalSize 64 1 1
1541fd4e5da5Sopenharmony_ciOpSource HLSL 600
1542fd4e5da5Sopenharmony_ciOpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
1543fd4e5da5Sopenharmony_ciOpDecorate %4 DescriptorSet 4
1544fd4e5da5Sopenharmony_ciOpDecorate %4 Binding 70
1545fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1546fd4e5da5Sopenharmony_ci%6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
1547fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
1548fd4e5da5Sopenharmony_ci%_ptr_Function_6 = OpTypePointer Function %6
1549fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1550fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
1551fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1552fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1553fd4e5da5Sopenharmony_ci%v3uint = OpTypeVector %uint 3
1554fd4e5da5Sopenharmony_ci%_ptr_Input_v3uint = OpTypePointer Input %v3uint
1555fd4e5da5Sopenharmony_ci%_ptr_Image_uint = OpTypePointer Image %uint
1556fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
1557fd4e5da5Sopenharmony_ci%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
1558fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %10
1559fd4e5da5Sopenharmony_ci%17 = OpLabel
1560fd4e5da5Sopenharmony_ci%16 = OpVariable %_ptr_Function_6 Function
1561fd4e5da5Sopenharmony_ci%18 = OpLoad %6 %4
1562fd4e5da5Sopenharmony_ciOpStore %16 %18
1563fd4e5da5Sopenharmony_ci%19 = OpImageTexelPointer %_ptr_Image_uint %4 %uint_0 %uint_0
1564fd4e5da5Sopenharmony_ci%20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
1565fd4e5da5Sopenharmony_ciOpReturn
1566fd4e5da5Sopenharmony_ciOpFunctionEnd
1567fd4e5da5Sopenharmony_ci)";
1568fd4e5da5Sopenharmony_ci
1569fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1570fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<CopyPropagateArrays>(before, after, true, true);
1571fd4e5da5Sopenharmony_ci}
1572fd4e5da5Sopenharmony_ci
1573fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, IndexIsNullConstnat) {
1574fd4e5da5Sopenharmony_ci  const std::string text = R"(
1575fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Uniform
1576fd4e5da5Sopenharmony_ci; CHECK: [[null:%\w+]] = OpConstantNull %uint
1577fd4e5da5Sopenharmony_ci; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform__arr_uint_uint_1 [[var]] %uint_0 %uint_0
1578fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_uint [[ac1]] [[null]]
1579fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpReturn
1580fd4e5da5Sopenharmony_ci               OpCapability Shader
1581fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1582fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %main "main"
1583fd4e5da5Sopenharmony_ci               OpExecutionMode %main OriginUpperLeft
1584fd4e5da5Sopenharmony_ci               OpSource HLSL 600
1585fd4e5da5Sopenharmony_ci               OpDecorate %myCBuffer DescriptorSet 0
1586fd4e5da5Sopenharmony_ci               OpDecorate %myCBuffer Binding 0
1587fd4e5da5Sopenharmony_ci               OpDecorate %_arr_v4float_uint_1 ArrayStride 16
1588fd4e5da5Sopenharmony_ci               OpMemberDecorate %MyConstantBuffer 0 Offset 0
1589fd4e5da5Sopenharmony_ci               OpMemberDecorate %type_myCBuffer 0 Offset 0
1590fd4e5da5Sopenharmony_ci               OpDecorate %type_myCBuffer Block
1591fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1592fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %uint 0
1593fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
1594fd4e5da5Sopenharmony_ci%_arr_v4float_uint_1 = OpTypeArray %uint %uint_1
1595fd4e5da5Sopenharmony_ci%MyConstantBuffer = OpTypeStruct %_arr_v4float_uint_1
1596fd4e5da5Sopenharmony_ci%type_myCBuffer = OpTypeStruct %MyConstantBuffer
1597fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_myCBuffer = OpTypePointer Uniform %type_myCBuffer
1598fd4e5da5Sopenharmony_ci%_arr_v4float_uint_1_0 = OpTypeArray %uint %uint_1
1599fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1600fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %void
1601fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %uint
1602fd4e5da5Sopenharmony_ci%_ptr_Uniform_MyConstantBuffer = OpTypePointer Uniform %MyConstantBuffer
1603fd4e5da5Sopenharmony_ci  %myCBuffer = OpVariable %_ptr_Uniform_type_myCBuffer Uniform
1604fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_1_0 = OpTypePointer Function %_arr_v4float_uint_1_0
1605fd4e5da5Sopenharmony_ci         %23 = OpConstantNull %uint
1606fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %19
1607fd4e5da5Sopenharmony_ci         %24 = OpLabel
1608fd4e5da5Sopenharmony_ci         %25 = OpVariable %_ptr_Function__arr_v4float_uint_1_0 Function
1609fd4e5da5Sopenharmony_ci         %26 = OpAccessChain %_ptr_Uniform_MyConstantBuffer %myCBuffer %int_0
1610fd4e5da5Sopenharmony_ci         %27 = OpLoad %MyConstantBuffer %26
1611fd4e5da5Sopenharmony_ci         %28 = OpCompositeExtract %_arr_v4float_uint_1 %27 0
1612fd4e5da5Sopenharmony_ci         %29 = OpCompositeExtract %uint %28 0
1613fd4e5da5Sopenharmony_ci         %30 = OpCompositeConstruct %_arr_v4float_uint_1_0 %29
1614fd4e5da5Sopenharmony_ci               OpStore %25 %30
1615fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %_ptr_Function_v4float %25 %23
1616fd4e5da5Sopenharmony_ci               OpReturn
1617fd4e5da5Sopenharmony_ci               OpFunctionEnd
1618fd4e5da5Sopenharmony_ci)";
1619fd4e5da5Sopenharmony_ci
1620fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1621fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(text, true);
1622fd4e5da5Sopenharmony_ci}
1623fd4e5da5Sopenharmony_ci
1624fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, DebugDeclare) {
1625fd4e5da5Sopenharmony_ci  const std::string before =
1626fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1627fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
1628fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1629fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1630fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1631fd4e5da5Sopenharmony_ciOpSource HLSL 600
1632fd4e5da5Sopenharmony_ci%file_name = OpString "test"
1633fd4e5da5Sopenharmony_ci%float_name = OpString "float"
1634fd4e5da5Sopenharmony_ci%main_name = OpString "main"
1635fd4e5da5Sopenharmony_ci%f_name = OpString "f"
1636fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1637fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1638fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1639fd4e5da5Sopenharmony_ciOpName %main "main"
1640fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1641fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1642fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1643fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1644fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1645fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1646fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1647fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1648fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1649fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1650fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1651fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1652fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1653fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1654fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
1655fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1656fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1657fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1658fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1659fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1660fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1661fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1662fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1663fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1664fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1665fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1666fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1667fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1668fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1669fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1670fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1671fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression
1672fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
1673fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
1674fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
1675fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_tf
1676fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
1677fd4e5da5Sopenharmony_ci
1678fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref
1679fd4e5da5Sopenharmony_ci; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable
1680fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
1681fd4e5da5Sopenharmony_ci
1682fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]]
1683fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
1684fd4e5da5Sopenharmony_ci; CHECK: [[newptr:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1685fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[newptr]] [[deref_expr]]
1686fd4e5da5Sopenharmony_ci; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[newptr]] %24
1687fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
1688fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
1689fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1690fd4e5da5Sopenharmony_ci%22 = OpLabel
1691fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1692fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1693fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1694fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1695fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1696fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1697fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1698fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1699fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1700fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1701fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1702fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1703fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
1704fd4e5da5Sopenharmony_ciOpStore %23 %35
1705fd4e5da5Sopenharmony_ci%decl = OpExtInst %void %ext DebugDeclare %dbg_f %23 %null_expr
1706fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1707fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1708fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1709fd4e5da5Sopenharmony_ciOpReturn
1710fd4e5da5Sopenharmony_ciOpFunctionEnd
1711fd4e5da5Sopenharmony_ci)";
1712fd4e5da5Sopenharmony_ci
1713fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1714fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1715fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1716fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
1717fd4e5da5Sopenharmony_ci}
1718fd4e5da5Sopenharmony_ci
1719fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, DebugValue) {
1720fd4e5da5Sopenharmony_ci  const std::string before =
1721fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1722fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
1723fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1724fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %in_var_INDEX %out_var_SV_Target
1725fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1726fd4e5da5Sopenharmony_ciOpSource HLSL 600
1727fd4e5da5Sopenharmony_ci%file_name = OpString "test"
1728fd4e5da5Sopenharmony_ci%float_name = OpString "float"
1729fd4e5da5Sopenharmony_ci%main_name = OpString "main"
1730fd4e5da5Sopenharmony_ci%f_name = OpString "f"
1731fd4e5da5Sopenharmony_ciOpName %type_MyCBuffer "type.MyCBuffer"
1732fd4e5da5Sopenharmony_ciOpMemberName %type_MyCBuffer 0 "Data"
1733fd4e5da5Sopenharmony_ciOpName %MyCBuffer "MyCBuffer"
1734fd4e5da5Sopenharmony_ciOpName %main "main"
1735fd4e5da5Sopenharmony_ciOpName %in_var_INDEX "in.var.INDEX"
1736fd4e5da5Sopenharmony_ciOpName %out_var_SV_Target "out.var.SV_Target"
1737fd4e5da5Sopenharmony_ciOpDecorate %_arr_v4float_uint_8 ArrayStride 16
1738fd4e5da5Sopenharmony_ciOpMemberDecorate %type_MyCBuffer 0 Offset 0
1739fd4e5da5Sopenharmony_ciOpDecorate %type_MyCBuffer Block
1740fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Flat
1741fd4e5da5Sopenharmony_ciOpDecorate %in_var_INDEX Location 0
1742fd4e5da5Sopenharmony_ciOpDecorate %out_var_SV_Target Location 0
1743fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer DescriptorSet 0
1744fd4e5da5Sopenharmony_ciOpDecorate %MyCBuffer Binding 0
1745fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1746fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1747fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1748fd4e5da5Sopenharmony_ci%uint_8 = OpConstant %uint 8
1749fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
1750fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8 = OpTypeArray %v4float %uint_8
1751fd4e5da5Sopenharmony_ci%type_MyCBuffer = OpTypeStruct %_arr_v4float_uint_8
1752fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_MyCBuffer = OpTypePointer Uniform %type_MyCBuffer
1753fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1754fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1755fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1756fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1757fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1758fd4e5da5Sopenharmony_ci%_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8
1759fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_8_0 = OpTypePointer Function %_arr_v4float_uint_8_0
1760fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1761fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_v4float_uint_8 = OpTypePointer Uniform %_arr_v4float_uint_8
1762fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1763fd4e5da5Sopenharmony_ci%MyCBuffer = OpVariable %_ptr_Uniform_type_MyCBuffer Uniform
1764fd4e5da5Sopenharmony_ci%in_var_INDEX = OpVariable %_ptr_Input_int Input
1765fd4e5da5Sopenharmony_ci%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
1766fd4e5da5Sopenharmony_ci
1767fd4e5da5Sopenharmony_ci; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref
1768fd4e5da5Sopenharmony_ci; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]]
1769fd4e5da5Sopenharmony_ci%deref = OpExtInst %void %ext DebugOperation Deref
1770fd4e5da5Sopenharmony_ci%expr = OpExtInst %void %ext DebugExpression %deref
1771fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
1772fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
1773fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
1774fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_tf
1775fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
1776fd4e5da5Sopenharmony_ci
1777fd4e5da5Sopenharmony_ci; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable
1778fd4e5da5Sopenharmony_ci%dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
1779fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1780fd4e5da5Sopenharmony_ci%22 = OpLabel
1781fd4e5da5Sopenharmony_ci%23 = OpVariable %_ptr_Function__arr_v4float_uint_8_0 Function
1782fd4e5da5Sopenharmony_ci%24 = OpLoad %int %in_var_INDEX
1783fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1784fd4e5da5Sopenharmony_ci%26 = OpLoad %_arr_v4float_uint_8 %25
1785fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %v4float %26 0
1786fd4e5da5Sopenharmony_ci%28 = OpCompositeExtract %v4float %26 1
1787fd4e5da5Sopenharmony_ci%29 = OpCompositeExtract %v4float %26 2
1788fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %v4float %26 3
1789fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %v4float %26 4
1790fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v4float %26 5
1791fd4e5da5Sopenharmony_ci%33 = OpCompositeExtract %v4float %26 6
1792fd4e5da5Sopenharmony_ci%34 = OpCompositeExtract %v4float %26 7
1793fd4e5da5Sopenharmony_ci%35 = OpCompositeConstruct %_arr_v4float_uint_8_0 %27 %28 %29 %30 %31 %32 %33 %34
1794fd4e5da5Sopenharmony_ciOpStore %23 %35
1795fd4e5da5Sopenharmony_ci
1796fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain
1797fd4e5da5Sopenharmony_ci; CHECK: [[newptr:%\w+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_8 %MyCBuffer %int_0
1798fd4e5da5Sopenharmony_ci; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[newptr]] [[deref_expr]]
1799fd4e5da5Sopenharmony_ci; CHECK: [[element_ptr:%\w+]] = OpAccessChain %_ptr_Uniform_v4float [[newptr]] %24
1800fd4e5da5Sopenharmony_ci; CHECK: [[load:%\w+]] = OpLoad %v4float [[element_ptr]]
1801fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_SV_Target [[load]]
1802fd4e5da5Sopenharmony_ci%decl = OpExtInst %void %ext DebugValue %dbg_f %23 %expr
1803fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v4float %23 %24
1804fd4e5da5Sopenharmony_ci%37 = OpLoad %v4float %36
1805fd4e5da5Sopenharmony_ciOpStore %out_var_SV_Target %37
1806fd4e5da5Sopenharmony_ciOpReturn
1807fd4e5da5Sopenharmony_ciOpFunctionEnd
1808fd4e5da5Sopenharmony_ci)";
1809fd4e5da5Sopenharmony_ci
1810fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1811fd4e5da5Sopenharmony_ci  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
1812fd4e5da5Sopenharmony_ci                        SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
1813fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
1814fd4e5da5Sopenharmony_ci}
1815fd4e5da5Sopenharmony_ci
1816fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, FunctionDeclaration) {
1817fd4e5da5Sopenharmony_ci  // Make sure the pass works with a function declaration that is called.
1818fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Addresses
1819fd4e5da5Sopenharmony_ciOpCapability Linkage
1820fd4e5da5Sopenharmony_ciOpCapability Kernel
1821fd4e5da5Sopenharmony_ciOpCapability Int8
1822fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.std"
1823fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL
1824fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool"
1825fd4e5da5Sopenharmony_ciOpExecutionMode %2 ContractionOff
1826fd4e5da5Sopenharmony_ciOpSource Unknown 0
1827fd4e5da5Sopenharmony_ciOpDecorate %3 LinkageAttributes "julia_error_7712" Import
1828fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1829fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void
1830fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %5
1831fd4e5da5Sopenharmony_ciOpFunctionEnd
1832fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5
1833fd4e5da5Sopenharmony_ci%6 = OpLabel
1834fd4e5da5Sopenharmony_ci%7 = OpFunctionCall %void %3
1835fd4e5da5Sopenharmony_ciOpReturn
1836fd4e5da5Sopenharmony_ciOpFunctionEnd
1837fd4e5da5Sopenharmony_ci)";
1838fd4e5da5Sopenharmony_ci
1839fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<CopyPropagateArrays>(text, text, false);
1840fd4e5da5Sopenharmony_ci}
1841fd4e5da5Sopenharmony_ci
1842fd4e5da5Sopenharmony_ci// Since Spir-V 1.4, resources that are used by a shader must be on the
1843fd4e5da5Sopenharmony_ci// OpEntryPoint instruction with the inputs and outputs. This test ensures that
1844fd4e5da5Sopenharmony_ci// this does not stop the pass from working.
1845fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, EntryPointUser) {
1846fd4e5da5Sopenharmony_ci  const std::string before = R"(OpCapability Shader
1847fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1848fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %g_rwTexture3d
1849fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 256 1 1
1850fd4e5da5Sopenharmony_ciOpSource HLSL 660
1851fd4e5da5Sopenharmony_ciOpName %type_3d_image "type.3d.image"
1852fd4e5da5Sopenharmony_ciOpName %g_rwTexture3d "g_rwTexture3d"
1853fd4e5da5Sopenharmony_ciOpName %main "main"
1854fd4e5da5Sopenharmony_ciOpDecorate %g_rwTexture3d DescriptorSet 0
1855fd4e5da5Sopenharmony_ciOpDecorate %g_rwTexture3d Binding 0
1856fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1857fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1858fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1859fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
1860fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
1861fd4e5da5Sopenharmony_ci%v3uint = OpTypeVector %uint 3
1862fd4e5da5Sopenharmony_ci%10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
1863fd4e5da5Sopenharmony_ci%type_3d_image = OpTypeImage %uint 3D 2 0 0 2 R32ui
1864fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_3d_image = OpTypePointer UniformConstant %type_3d_image
1865fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1866fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
1867fd4e5da5Sopenharmony_ci%_ptr_Function_type_3d_image = OpTypePointer Function %type_3d_image
1868fd4e5da5Sopenharmony_ci%_ptr_Image_uint = OpTypePointer Image %uint
1869fd4e5da5Sopenharmony_ci%g_rwTexture3d = OpVariable %_ptr_UniformConstant_type_3d_image UniformConstant
1870fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
1871fd4e5da5Sopenharmony_ci%16 = OpLabel
1872fd4e5da5Sopenharmony_ci%17 = OpVariable %_ptr_Function_type_3d_image Function
1873fd4e5da5Sopenharmony_ci%18 = OpLoad %type_3d_image %g_rwTexture3d
1874fd4e5da5Sopenharmony_ciOpStore %17 %18
1875fd4e5da5Sopenharmony_ci; CHECK: %19 = OpImageTexelPointer %_ptr_Image_uint %g_rwTexture3d %10 %uint_0
1876fd4e5da5Sopenharmony_ci%19 = OpImageTexelPointer %_ptr_Image_uint %17 %10 %uint_0
1877fd4e5da5Sopenharmony_ci%20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
1878fd4e5da5Sopenharmony_ciOpReturn
1879fd4e5da5Sopenharmony_ciOpFunctionEnd
1880fd4e5da5Sopenharmony_ci)";
1881fd4e5da5Sopenharmony_ci
1882fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1883fd4e5da5Sopenharmony_ci  SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1884fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CopyPropagateArrays>(before, false);
1885fd4e5da5Sopenharmony_ci}
1886fd4e5da5Sopenharmony_ci
1887fd4e5da5Sopenharmony_ci// As per SPIRV spec, struct cannot be indexed with non-constant indices
1888fd4e5da5Sopenharmony_ci// through OpAccessChain, only arrays.
1889fd4e5da5Sopenharmony_ci// The copy-propagate-array pass tries to remove superfluous copies when the
1890fd4e5da5Sopenharmony_ci// original array could be indexed instead of the copy.
1891fd4e5da5Sopenharmony_ci//
1892fd4e5da5Sopenharmony_ci// This test verifies we handle this case:
1893fd4e5da5Sopenharmony_ci//  struct SRC { int field1; ...; int fieldN }
1894fd4e5da5Sopenharmony_ci//  int tmp_arr[N] = { SRC.field1, ..., SRC.fieldN }
1895fd4e5da5Sopenharmony_ci//  return tmp_arr[index];
1896fd4e5da5Sopenharmony_ci//
1897fd4e5da5Sopenharmony_ci// In such case, we cannot optimize the access: this array was added to allow
1898fd4e5da5Sopenharmony_ci// dynamic indexing in the struct.
1899fd4e5da5Sopenharmony_ciTEST_F(CopyPropArrayPassTest, StructIndexCannotBecomeDynamic) {
1900fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Shader
1901fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1902fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %1 "main"
1903fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 0
1904fd4e5da5Sopenharmony_ciOpDecorate %2 Binding 0
1905fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_3 0 Offset 0
1906fd4e5da5Sopenharmony_ciOpDecorate %_struct_3 Block
1907fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1908fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
1909fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1910fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1911fd4e5da5Sopenharmony_ci%_struct_3 = OpTypeStruct %v4float
1912fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
1913fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1914fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1915fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
1916fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
1917fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %v4float %_ptr_Function_uint
1918fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1919fd4e5da5Sopenharmony_ci%_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1
1920fd4e5da5Sopenharmony_ci%_ptr_Function__arr_v4float_uint_1 = OpTypePointer Function %_arr_v4float_uint_1
1921fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1922fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
1923fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Uniform__struct_3 Uniform
1924fd4e5da5Sopenharmony_ci%19 = OpUndef %v4float
1925fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %11
1926fd4e5da5Sopenharmony_ci%20 = OpLabel
1927fd4e5da5Sopenharmony_ciOpReturn
1928fd4e5da5Sopenharmony_ciOpFunctionEnd
1929fd4e5da5Sopenharmony_ci%21 = OpFunction %v4float None %13
1930fd4e5da5Sopenharmony_ci%22 = OpFunctionParameter %_ptr_Function_uint
1931fd4e5da5Sopenharmony_ci%23 = OpLabel
1932fd4e5da5Sopenharmony_ci%24 = OpVariable %_ptr_Function__arr_v4float_uint_1 Function
1933fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Uniform_v4float %2 %int_0
1934fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %25
1935fd4e5da5Sopenharmony_ci%27 = OpCompositeConstruct %_arr_v4float_uint_1 %26
1936fd4e5da5Sopenharmony_ciOpStore %24 %27
1937fd4e5da5Sopenharmony_ci%28 = OpLoad %uint %22
1938fd4e5da5Sopenharmony_ci%29 = OpAccessChain %_ptr_Function_v4float %24 %28
1939fd4e5da5Sopenharmony_ciOpReturnValue %19
1940fd4e5da5Sopenharmony_ciOpFunctionEnd
1941fd4e5da5Sopenharmony_ci)";
1942fd4e5da5Sopenharmony_ci
1943fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<CopyPropagateArrays>(text, text, false);
1944fd4e5da5Sopenharmony_ci}
1945fd4e5da5Sopenharmony_ci}  // namespace
1946fd4e5da5Sopenharmony_ci}  // namespace opt
1947fd4e5da5Sopenharmony_ci}  // namespace spvtools
1948