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 "test/opt/pass_fixture.h"
18fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_cinamespace spvtools {
21fd4e5da5Sopenharmony_cinamespace opt {
22fd4e5da5Sopenharmony_cinamespace {
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_ciusing CombineAccessChainsTest = PassTest<::testing::Test>;
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainConstant) {
27fd4e5da5Sopenharmony_ci  const std::string text = R"(
28fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
29fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
30fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
31fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
32fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]]
33fd4e5da5Sopenharmony_ciOpCapability Shader
34fd4e5da5Sopenharmony_ciOpCapability VariablePointers
35fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
36fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
37fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
38fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
39fd4e5da5Sopenharmony_ci%void = OpTypeVoid
40fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
41fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
42fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
43fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
44fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
45fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
46fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
47fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
48fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
49fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
50fd4e5da5Sopenharmony_ci%main_lab = OpLabel
51fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %var %uint_0
52fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3
53fd4e5da5Sopenharmony_ciOpReturn
54fd4e5da5Sopenharmony_ciOpFunctionEnd
55fd4e5da5Sopenharmony_ci)";
56fd4e5da5Sopenharmony_ci
57fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
58fd4e5da5Sopenharmony_ci}
59fd4e5da5Sopenharmony_ci
60fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsAccessChainConstant) {
61fd4e5da5Sopenharmony_ci  const std::string text = R"(
62fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
63fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
64fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
65fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
66fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int3]]
67fd4e5da5Sopenharmony_ciOpCapability Shader
68fd4e5da5Sopenharmony_ciOpCapability VariablePointers
69fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
70fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
71fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
72fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
73fd4e5da5Sopenharmony_ci%void = OpTypeVoid
74fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
75fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
76fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
77fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
78fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
79fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
80fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
81fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
82fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
83fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
84fd4e5da5Sopenharmony_ci%main_lab = OpLabel
85fd4e5da5Sopenharmony_ci%gep = OpInBoundsAccessChain %ptr_Workgroup_uint %var %uint_0
86fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3
87fd4e5da5Sopenharmony_ciOpReturn
88fd4e5da5Sopenharmony_ciOpFunctionEnd
89fd4e5da5Sopenharmony_ci)";
90fd4e5da5Sopenharmony_ci
91fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
92fd4e5da5Sopenharmony_ci}
93fd4e5da5Sopenharmony_ci
94fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainCombineConstant) {
95fd4e5da5Sopenharmony_ci  const std::string text = R"(
96fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
97fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
98fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
99fd4e5da5Sopenharmony_ci; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
100fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int2]]
101fd4e5da5Sopenharmony_ciOpCapability Shader
102fd4e5da5Sopenharmony_ciOpCapability VariablePointers
103fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
104fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
105fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
106fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
107fd4e5da5Sopenharmony_ci%void = OpTypeVoid
108fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
109fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
110fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
111fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
112fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
113fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
114fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
115fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
116fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
117fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
118fd4e5da5Sopenharmony_ci%main_lab = OpLabel
119fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %var %uint_1
120fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_1
121fd4e5da5Sopenharmony_ciOpReturn
122fd4e5da5Sopenharmony_ciOpFunctionEnd
123fd4e5da5Sopenharmony_ci)";
124fd4e5da5Sopenharmony_ci
125fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
126fd4e5da5Sopenharmony_ci}
127fd4e5da5Sopenharmony_ci
128fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainNonConstant) {
129fd4e5da5Sopenharmony_ci  const std::string text = R"(
130fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
131fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
132fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
133fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad
134fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad
135fd4e5da5Sopenharmony_ci; CHECK: [[add:%\w+]] = OpIAdd [[int]] [[ld1]] [[ld2]]
136fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[add]]
137fd4e5da5Sopenharmony_ciOpCapability Shader
138fd4e5da5Sopenharmony_ciOpCapability VariablePointers
139fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
140fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
141fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
142fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
143fd4e5da5Sopenharmony_ci%void = OpTypeVoid
144fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
145fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
146fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
147fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
148fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
149fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
150fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
151fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
152fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
153fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
154fd4e5da5Sopenharmony_ci%main_lab = OpLabel
155fd4e5da5Sopenharmony_ci%local_var = OpVariable %ptr_Function_uint Function
156fd4e5da5Sopenharmony_ci%ld1 = OpLoad %uint %local_var
157fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %var %ld1
158fd4e5da5Sopenharmony_ci%ld2 = OpLoad %uint %local_var
159fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld2
160fd4e5da5Sopenharmony_ciOpReturn
161fd4e5da5Sopenharmony_ciOpFunctionEnd
162fd4e5da5Sopenharmony_ci)";
163fd4e5da5Sopenharmony_ci
164fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
165fd4e5da5Sopenharmony_ci}
166fd4e5da5Sopenharmony_ci
167fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromAccessChainExtraIndices) {
168fd4e5da5Sopenharmony_ci  const std::string text = R"(
169fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
170fd4e5da5Sopenharmony_ci; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
171fd4e5da5Sopenharmony_ci; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
172fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
173fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
174fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
175fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]]
176fd4e5da5Sopenharmony_ciOpCapability Shader
177fd4e5da5Sopenharmony_ciOpCapability VariablePointers
178fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
179fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
180fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
181fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
182fd4e5da5Sopenharmony_ci%void = OpTypeVoid
183fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
184fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
185fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
186fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
187fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
188fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
189fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
190fd4e5da5Sopenharmony_ci%uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
191fd4e5da5Sopenharmony_ci%uint_array_4_array_4_array_4 = OpTypeArray %uint_array_4_array_4 %uint_4
192fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
193fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
194fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
195fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
196fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4_array_4
197fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4_array_4_array_4 Workgroup
198fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
199fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
200fd4e5da5Sopenharmony_ci%main_lab = OpLabel
201fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_0
202fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_2 %uint_3
203fd4e5da5Sopenharmony_ciOpReturn
204fd4e5da5Sopenharmony_ciOpFunctionEnd
205fd4e5da5Sopenharmony_ci)";
206fd4e5da5Sopenharmony_ci
207fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
208fd4e5da5Sopenharmony_ci}
209fd4e5da5Sopenharmony_ci
210fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest,
211fd4e5da5Sopenharmony_ci       PtrAccessChainFromPtrAccessChainCombineElementOperand) {
212fd4e5da5Sopenharmony_ci  const std::string text = R"(
213fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
214fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
215fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
216fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
217fd4e5da5Sopenharmony_ci; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
218fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int6]] [[int3]]
219fd4e5da5Sopenharmony_ciOpCapability Shader
220fd4e5da5Sopenharmony_ciOpCapability VariablePointers
221fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
222fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
223fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
224fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
225fd4e5da5Sopenharmony_ci%void = OpTypeVoid
226fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
227fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
228fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
229fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
230fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
231fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
232fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
233fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
234fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
235fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
236fd4e5da5Sopenharmony_ci%main_lab = OpLabel
237fd4e5da5Sopenharmony_ci%gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
238fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3
239fd4e5da5Sopenharmony_ciOpReturn
240fd4e5da5Sopenharmony_ciOpFunctionEnd
241fd4e5da5Sopenharmony_ci)";
242fd4e5da5Sopenharmony_ci
243fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
244fd4e5da5Sopenharmony_ci}
245fd4e5da5Sopenharmony_ci
246fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest,
247fd4e5da5Sopenharmony_ci       PtrAccessChainFromPtrAccessChainOnlyElementOperand) {
248fd4e5da5Sopenharmony_ci  const std::string text = R"(
249fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
250fd4e5da5Sopenharmony_ci; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
251fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
252fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
253fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
254fd4e5da5Sopenharmony_ci; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
255fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
256fd4e5da5Sopenharmony_ciOpCapability Shader
257fd4e5da5Sopenharmony_ciOpCapability VariablePointers
258fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
259fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
260fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
261fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
262fd4e5da5Sopenharmony_ci%void = OpTypeVoid
263fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
264fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
265fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
266fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
267fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
268fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
269fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
270fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
271fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
272fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
273fd4e5da5Sopenharmony_ci%main_lab = OpLabel
274fd4e5da5Sopenharmony_ci%gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
275fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
276fd4e5da5Sopenharmony_ciOpReturn
277fd4e5da5Sopenharmony_ciOpFunctionEnd
278fd4e5da5Sopenharmony_ci)";
279fd4e5da5Sopenharmony_ci
280fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
281fd4e5da5Sopenharmony_ci}
282fd4e5da5Sopenharmony_ci
283fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest,
284fd4e5da5Sopenharmony_ci       PtrAccessChainFromPtrAccessCombineNonElementIndex) {
285fd4e5da5Sopenharmony_ci  const std::string text = R"(
286fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
287fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
288fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
289fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
290fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]] [[int3]]
291fd4e5da5Sopenharmony_ciOpCapability Shader
292fd4e5da5Sopenharmony_ciOpCapability VariablePointers
293fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
294fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
295fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
296fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
297fd4e5da5Sopenharmony_ci%void = OpTypeVoid
298fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
299fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
300fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
301fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
302fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
303fd4e5da5Sopenharmony_ci%uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
304fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
305fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
306fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
307fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
308fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
309fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
310fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
311fd4e5da5Sopenharmony_ci%main_lab = OpLabel
312fd4e5da5Sopenharmony_ci%gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3 %uint_0
313fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %uint_3 %uint_3
314fd4e5da5Sopenharmony_ciOpReturn
315fd4e5da5Sopenharmony_ciOpFunctionEnd
316fd4e5da5Sopenharmony_ci)";
317fd4e5da5Sopenharmony_ci
318fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
319fd4e5da5Sopenharmony_ci}
320fd4e5da5Sopenharmony_ci
321fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest,
322fd4e5da5Sopenharmony_ci       AccessChainFromPtrAccessChainOnlyElementOperand) {
323fd4e5da5Sopenharmony_ci  const std::string text = R"(
324fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
325fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
326fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
327fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
328fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int3]] [[int3]]
329fd4e5da5Sopenharmony_ciOpCapability Shader
330fd4e5da5Sopenharmony_ciOpCapability VariablePointers
331fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
332fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
333fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
334fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
335fd4e5da5Sopenharmony_ci%void = OpTypeVoid
336fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
337fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
338fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
339fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
340fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
341fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
342fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
343fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
344fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
345fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
346fd4e5da5Sopenharmony_ci%main_lab = OpLabel
347fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
348fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3
349fd4e5da5Sopenharmony_ciOpReturn
350fd4e5da5Sopenharmony_ciOpFunctionEnd
351fd4e5da5Sopenharmony_ci)";
352fd4e5da5Sopenharmony_ci
353fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
354fd4e5da5Sopenharmony_ci}
355fd4e5da5Sopenharmony_ci
356fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, AccessChainFromPtrAccessChainAppend) {
357fd4e5da5Sopenharmony_ci  const std::string text = R"(
358fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
359fd4e5da5Sopenharmony_ci; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
360fd4e5da5Sopenharmony_ci; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
361fd4e5da5Sopenharmony_ci; CHECK: [[int3:%\w+]] = OpConstant [[int]] 3
362fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
363fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
364fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]] [[int3]]
365fd4e5da5Sopenharmony_ciOpCapability Shader
366fd4e5da5Sopenharmony_ciOpCapability VariablePointers
367fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
368fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
369fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
370fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
371fd4e5da5Sopenharmony_ci%void = OpTypeVoid
372fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
373fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
374fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
375fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
376fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
377fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
378fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
379fd4e5da5Sopenharmony_ci%uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
380fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
381fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
382fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
383fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
384fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
385fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
386fd4e5da5Sopenharmony_ci%main_lab = OpLabel
387fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1 %uint_2
388fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_3
389fd4e5da5Sopenharmony_ciOpReturn
390fd4e5da5Sopenharmony_ciOpFunctionEnd
391fd4e5da5Sopenharmony_ci)";
392fd4e5da5Sopenharmony_ci
393fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
394fd4e5da5Sopenharmony_ci}
395fd4e5da5Sopenharmony_ci
396fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, AccessChainFromAccessChainAppend) {
397fd4e5da5Sopenharmony_ci  const std::string text = R"(
398fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
399fd4e5da5Sopenharmony_ci; CHECK: [[int1:%\w+]] = OpConstant [[int]] 1
400fd4e5da5Sopenharmony_ci; CHECK: [[int2:%\w+]] = OpConstant [[int]] 2
401fd4e5da5Sopenharmony_ci; CHECK: [[ptr_int:%\w+]] = OpTypePointer Workgroup [[int]]
402fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
403fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain [[ptr_int]] [[var]] [[int1]] [[int2]]
404fd4e5da5Sopenharmony_ciOpCapability Shader
405fd4e5da5Sopenharmony_ciOpCapability VariablePointers
406fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
407fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
408fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
409fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
410fd4e5da5Sopenharmony_ci%void = OpTypeVoid
411fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
412fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
413fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
414fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2
415fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
416fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
417fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
418fd4e5da5Sopenharmony_ci%uint_array_4_array_4 = OpTypeArray %uint_array_4 %uint_4
419fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
420fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
421fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4_array_4 = OpTypePointer Workgroup %uint_array_4_array_4
422fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4_array_4 Workgroup
423fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
424fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
425fd4e5da5Sopenharmony_ci%main_lab = OpLabel
426fd4e5da5Sopenharmony_ci%ptr_gep = OpAccessChain %ptr_Workgroup_uint_array_4 %var %uint_1
427fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_2
428fd4e5da5Sopenharmony_ciOpReturn
429fd4e5da5Sopenharmony_ciOpFunctionEnd
430fd4e5da5Sopenharmony_ci)";
431fd4e5da5Sopenharmony_ci
432fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
433fd4e5da5Sopenharmony_ci}
434fd4e5da5Sopenharmony_ci
435fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, NonConstantStructSlide) {
436fd4e5da5Sopenharmony_ci  const std::string text = R"(
437fd4e5da5Sopenharmony_ci; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
438fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
439fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad
440fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[ld]] [[int0]]
441fd4e5da5Sopenharmony_ciOpCapability Shader
442fd4e5da5Sopenharmony_ciOpCapability VariablePointers
443fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
444fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
445fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
446fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
447fd4e5da5Sopenharmony_ci%void = OpTypeVoid
448fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
449fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
450fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint %uint
451fd4e5da5Sopenharmony_ci%ptr_Workgroup_struct = OpTypePointer Workgroup %struct
452fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
453fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
454fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_Workgroup_struct Workgroup
455fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
456fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
457fd4e5da5Sopenharmony_ci%1 = OpLabel
458fd4e5da5Sopenharmony_ci%func_var = OpVariable %ptr_Function_uint Function
459fd4e5da5Sopenharmony_ci%ld = OpLoad %uint %func_var
460fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld
461fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_uint %ptr_gep %uint_0
462fd4e5da5Sopenharmony_ciOpReturn
463fd4e5da5Sopenharmony_ciOpFunctionEnd
464fd4e5da5Sopenharmony_ci)";
465fd4e5da5Sopenharmony_ci
466fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
467fd4e5da5Sopenharmony_ci}
468fd4e5da5Sopenharmony_ci
469fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, DontCombineNonConstantStructSlide) {
470fd4e5da5Sopenharmony_ci  const std::string text = R"(
471fd4e5da5Sopenharmony_ci; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
472fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad
473fd4e5da5Sopenharmony_ci; CHECK: [[gep:%\w+]] = OpAccessChain
474fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain {{%\w+}} [[gep]] [[ld]] [[int0]]
475fd4e5da5Sopenharmony_ciOpCapability Shader
476fd4e5da5Sopenharmony_ciOpCapability VariablePointers
477fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
478fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
479fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
480fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
481fd4e5da5Sopenharmony_ci%void = OpTypeVoid
482fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
483fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
484fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
485fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint %uint
486fd4e5da5Sopenharmony_ci%struct_array_4 = OpTypeArray %struct %uint_4
487fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
488fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
489fd4e5da5Sopenharmony_ci%ptr_Workgroup_struct = OpTypePointer Workgroup %struct
490fd4e5da5Sopenharmony_ci%ptr_Workgroup_struct_array_4 = OpTypePointer Workgroup %struct_array_4
491fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_Workgroup_struct_array_4 Workgroup
492fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
493fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
494fd4e5da5Sopenharmony_ci%1 = OpLabel
495fd4e5da5Sopenharmony_ci%func_var = OpVariable %ptr_Function_uint Function
496fd4e5da5Sopenharmony_ci%ld = OpLoad %uint %func_var
497fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_Workgroup_struct %wg_var %uint_0
498fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0
499fd4e5da5Sopenharmony_ciOpReturn
500fd4e5da5Sopenharmony_ciOpFunctionEnd
501fd4e5da5Sopenharmony_ci)";
502fd4e5da5Sopenharmony_ci
503fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
504fd4e5da5Sopenharmony_ci}
505fd4e5da5Sopenharmony_ci
506fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, CombineNonConstantStructSlideElement) {
507fd4e5da5Sopenharmony_ci  const std::string text = R"(
508fd4e5da5Sopenharmony_ci; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
509fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
510fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad
511fd4e5da5Sopenharmony_ci; CHECK: [[add:%\w+]] = OpIAdd {{%\w+}} [[ld]] [[ld]]
512fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[add]] [[int0]]
513fd4e5da5Sopenharmony_ciOpCapability Shader
514fd4e5da5Sopenharmony_ciOpCapability VariablePointers
515fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
516fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
517fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
518fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
519fd4e5da5Sopenharmony_ci%void = OpTypeVoid
520fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
521fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
522fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
523fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint %uint
524fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
525fd4e5da5Sopenharmony_ci%ptr_Function_uint = OpTypePointer Function %uint
526fd4e5da5Sopenharmony_ci%ptr_Workgroup_struct = OpTypePointer Workgroup %struct
527fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_Workgroup_struct Workgroup
528fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
529fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
530fd4e5da5Sopenharmony_ci%1 = OpLabel
531fd4e5da5Sopenharmony_ci%func_var = OpVariable %ptr_Function_uint Function
532fd4e5da5Sopenharmony_ci%ld = OpLoad %uint %func_var
533fd4e5da5Sopenharmony_ci%gep = OpPtrAccessChain %ptr_Workgroup_struct %wg_var %ld
534fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint %gep %ld %uint_0
535fd4e5da5Sopenharmony_ciOpReturn
536fd4e5da5Sopenharmony_ciOpFunctionEnd
537fd4e5da5Sopenharmony_ci)";
538fd4e5da5Sopenharmony_ci
539fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
540fd4e5da5Sopenharmony_ci}
541fd4e5da5Sopenharmony_ci
542fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, PtrAccessChainFromInBoundsPtrAccessChain) {
543fd4e5da5Sopenharmony_ci  const std::string text = R"(
544fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
545fd4e5da5Sopenharmony_ci; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
546fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
547fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
548fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
549fd4e5da5Sopenharmony_ci; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
550fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
551fd4e5da5Sopenharmony_ciOpCapability Shader
552fd4e5da5Sopenharmony_ciOpCapability VariablePointers
553fd4e5da5Sopenharmony_ciOpCapability Addresses
554fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
555fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
556fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
557fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
558fd4e5da5Sopenharmony_ci%void = OpTypeVoid
559fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
560fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
561fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
562fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
563fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
564fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
565fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
566fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
567fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
568fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
569fd4e5da5Sopenharmony_ci%main_lab = OpLabel
570fd4e5da5Sopenharmony_ci%gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
571fd4e5da5Sopenharmony_ci%ptr_gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
572fd4e5da5Sopenharmony_ciOpReturn
573fd4e5da5Sopenharmony_ciOpFunctionEnd
574fd4e5da5Sopenharmony_ci)";
575fd4e5da5Sopenharmony_ci
576fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
577fd4e5da5Sopenharmony_ci}
578fd4e5da5Sopenharmony_ci
579fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, InBoundsPtrAccessChainFromPtrAccessChain) {
580fd4e5da5Sopenharmony_ci  const std::string text = R"(
581fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
582fd4e5da5Sopenharmony_ci; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
583fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
584fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
585fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
586fd4e5da5Sopenharmony_ci; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
587fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain [[ptr_array]] [[var]] [[int6]]
588fd4e5da5Sopenharmony_ciOpCapability Shader
589fd4e5da5Sopenharmony_ciOpCapability VariablePointers
590fd4e5da5Sopenharmony_ciOpCapability Addresses
591fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
592fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
593fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
594fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
595fd4e5da5Sopenharmony_ci%void = OpTypeVoid
596fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
597fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
598fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
599fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
600fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
601fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
602fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
603fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
604fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
605fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
606fd4e5da5Sopenharmony_ci%main_lab = OpLabel
607fd4e5da5Sopenharmony_ci%gep = OpPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
608fd4e5da5Sopenharmony_ci%ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
609fd4e5da5Sopenharmony_ciOpReturn
610fd4e5da5Sopenharmony_ciOpFunctionEnd
611fd4e5da5Sopenharmony_ci)";
612fd4e5da5Sopenharmony_ci
613fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
614fd4e5da5Sopenharmony_ci}
615fd4e5da5Sopenharmony_ci
616fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest,
617fd4e5da5Sopenharmony_ci       InBoundsPtrAccessChainFromInBoundsPtrAccessChain) {
618fd4e5da5Sopenharmony_ci  const std::string text = R"(
619fd4e5da5Sopenharmony_ci; CHECK: [[int:%\w+]] = OpTypeInt 32 0
620fd4e5da5Sopenharmony_ci; CHECK: [[int4:%\w+]] = OpConstant [[int]] 4
621fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[int]] [[int4]]
622fd4e5da5Sopenharmony_ci; CHECK: [[ptr_array:%\w+]] = OpTypePointer Workgroup [[array]]
623fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Workgroup
624fd4e5da5Sopenharmony_ci; CHECK: [[int6:%\w+]] = OpConstant [[int]] 6
625fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain [[ptr_array]] [[var]] [[int6]]
626fd4e5da5Sopenharmony_ciOpCapability Shader
627fd4e5da5Sopenharmony_ciOpCapability VariablePointers
628fd4e5da5Sopenharmony_ciOpCapability Addresses
629fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
630fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
631fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
632fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
633fd4e5da5Sopenharmony_ci%void = OpTypeVoid
634fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
635fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
636fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
637fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
638fd4e5da5Sopenharmony_ci%uint_array_4 = OpTypeArray %uint %uint_4
639fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
640fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint_array_4 = OpTypePointer Workgroup %uint_array_4
641fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint_array_4 Workgroup
642fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
643fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_func
644fd4e5da5Sopenharmony_ci%main_lab = OpLabel
645fd4e5da5Sopenharmony_ci%gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %var %uint_3
646fd4e5da5Sopenharmony_ci%ptr_gep = OpInBoundsPtrAccessChain %ptr_Workgroup_uint_array_4 %gep %uint_3
647fd4e5da5Sopenharmony_ciOpReturn
648fd4e5da5Sopenharmony_ciOpFunctionEnd
649fd4e5da5Sopenharmony_ci)";
650fd4e5da5Sopenharmony_ci
651fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
652fd4e5da5Sopenharmony_ci}
653fd4e5da5Sopenharmony_ci
654fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, NoIndexAccessChains) {
655fd4e5da5Sopenharmony_ci  const std::string text = R"(
656fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable
657fd4e5da5Sopenharmony_ci; CHECK-NOT: OpConstant
658fd4e5da5Sopenharmony_ci; CHECK: [[gep:%\w+]] = OpAccessChain {{%\w+}} [[var]]
659fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain {{%\w+}} [[var]]
660fd4e5da5Sopenharmony_ciOpCapability Shader
661fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
662fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
663fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
664fd4e5da5Sopenharmony_ci%void = OpTypeVoid
665fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
666fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
667fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint Workgroup
668fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
669fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_func
670fd4e5da5Sopenharmony_ci%1 = OpLabel
671fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_Workgroup_uint %var
672fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_Workgroup_uint %gep1
673fd4e5da5Sopenharmony_ciOpReturn
674fd4e5da5Sopenharmony_ciOpFunctionEnd
675fd4e5da5Sopenharmony_ci)";
676fd4e5da5Sopenharmony_ci
677fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
678fd4e5da5Sopenharmony_ci}
679fd4e5da5Sopenharmony_ci
680fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains) {
681fd4e5da5Sopenharmony_ci  const std::string text = R"(
682fd4e5da5Sopenharmony_ci; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
683fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable
684fd4e5da5Sopenharmony_ci; CHECK: [[gep:%\w+]] = OpPtrAccessChain {{%\w+}} [[var]] [[int0]]
685fd4e5da5Sopenharmony_ci; CHECK: OpCopyObject {{%\w+}} [[gep]]
686fd4e5da5Sopenharmony_ciOpCapability Shader
687fd4e5da5Sopenharmony_ciOpCapability VariablePointers
688fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
689fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
690fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
691fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
692fd4e5da5Sopenharmony_ci%void = OpTypeVoid
693fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
694fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
695fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
696fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint Workgroup
697fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
698fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_func
699fd4e5da5Sopenharmony_ci%1 = OpLabel
700fd4e5da5Sopenharmony_ci%gep1 = OpPtrAccessChain %ptr_Workgroup_uint %var %uint_0
701fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_Workgroup_uint %gep1
702fd4e5da5Sopenharmony_ciOpReturn
703fd4e5da5Sopenharmony_ciOpFunctionEnd
704fd4e5da5Sopenharmony_ci)";
705fd4e5da5Sopenharmony_ci
706fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
707fd4e5da5Sopenharmony_ci}
708fd4e5da5Sopenharmony_ci
709fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, NoIndexPtrAccessChains2) {
710fd4e5da5Sopenharmony_ci  const std::string text = R"(
711fd4e5da5Sopenharmony_ci; CHECK: [[int0:%\w+]] = OpConstant {{%\w+}} 0
712fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable
713fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain {{%\w+}} [[var]] [[int0]]
714fd4e5da5Sopenharmony_ciOpCapability Shader
715fd4e5da5Sopenharmony_ciOpCapability VariablePointers
716fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
717fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
718fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
719fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
720fd4e5da5Sopenharmony_ci%void = OpTypeVoid
721fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
722fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
723fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
724fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint Workgroup
725fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
726fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_func
727fd4e5da5Sopenharmony_ci%1 = OpLabel
728fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_Workgroup_uint %var
729fd4e5da5Sopenharmony_ci%gep2 = OpPtrAccessChain %ptr_Workgroup_uint %gep1 %uint_0
730fd4e5da5Sopenharmony_ciOpReturn
731fd4e5da5Sopenharmony_ciOpFunctionEnd
732fd4e5da5Sopenharmony_ci)";
733fd4e5da5Sopenharmony_ci
734fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
735fd4e5da5Sopenharmony_ci}
736fd4e5da5Sopenharmony_ci
737fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, CombineMixedSign) {
738fd4e5da5Sopenharmony_ci  const std::string text = R"(
739fd4e5da5Sopenharmony_ci; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
740fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable
741fd4e5da5Sopenharmony_ci; CHECK: [[uint2:%\w+]] = OpConstant [[uint]] 2
742fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain {{%\w+}} [[var]] [[uint2]]
743fd4e5da5Sopenharmony_ciOpCapability Shader
744fd4e5da5Sopenharmony_ciOpCapability VariablePointers
745fd4e5da5Sopenharmony_ciOpCapability Addresses
746fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_variable_pointers"
747fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
748fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
749fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
750fd4e5da5Sopenharmony_ci%void = OpTypeVoid
751fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
752fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
753fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
754fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
755fd4e5da5Sopenharmony_ci%ptr_Workgroup_uint = OpTypePointer Workgroup %uint
756fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_Workgroup_uint Workgroup
757fd4e5da5Sopenharmony_ci%void_func = OpTypeFunction %void
758fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_func
759fd4e5da5Sopenharmony_ci%1 = OpLabel
760fd4e5da5Sopenharmony_ci%gep1 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %var %uint_1
761fd4e5da5Sopenharmony_ci%gep2 = OpInBoundsPtrAccessChain %ptr_Workgroup_uint %gep1 %int_1
762fd4e5da5Sopenharmony_ciOpReturn
763fd4e5da5Sopenharmony_ciOpFunctionEnd
764fd4e5da5Sopenharmony_ci)";
765fd4e5da5Sopenharmony_ci
766fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<CombineAccessChains>(text, true);
767fd4e5da5Sopenharmony_ci}
768fd4e5da5Sopenharmony_ci
769fd4e5da5Sopenharmony_ciTEST_F(CombineAccessChainsTest, FunctionDeclaration) {
770fd4e5da5Sopenharmony_ci  // Make sure the pass works with a function declaration that is called.
771fd4e5da5Sopenharmony_ci  const std::string text = R"(OpCapability Addresses
772fd4e5da5Sopenharmony_ciOpCapability Linkage
773fd4e5da5Sopenharmony_ciOpCapability Kernel
774fd4e5da5Sopenharmony_ciOpCapability Int8
775fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.std"
776fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL
777fd4e5da5Sopenharmony_ciOpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool"
778fd4e5da5Sopenharmony_ciOpExecutionMode %2 ContractionOff
779fd4e5da5Sopenharmony_ciOpSource Unknown 0
780fd4e5da5Sopenharmony_ciOpDecorate %3 LinkageAttributes "julia_error_7712" Import
781fd4e5da5Sopenharmony_ci%void = OpTypeVoid
782fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void
783fd4e5da5Sopenharmony_ci%3 = OpFunction %void None %5
784fd4e5da5Sopenharmony_ciOpFunctionEnd
785fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5
786fd4e5da5Sopenharmony_ci%6 = OpLabel
787fd4e5da5Sopenharmony_ci%7 = OpFunctionCall %void %3
788fd4e5da5Sopenharmony_ciOpReturn
789fd4e5da5Sopenharmony_ciOpFunctionEnd
790fd4e5da5Sopenharmony_ci)";
791fd4e5da5Sopenharmony_ci
792fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<CombineAccessChains>(text, text, false);
793fd4e5da5Sopenharmony_ci}
794fd4e5da5Sopenharmony_ci
795fd4e5da5Sopenharmony_ci}  // namespace
796fd4e5da5Sopenharmony_ci}  // namespace opt
797fd4e5da5Sopenharmony_ci}  // namespace spvtools
798