1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include <sstream>
16fd4e5da5Sopenharmony_ci#include <string>
17fd4e5da5Sopenharmony_ci#include <vector>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "pass_fixture.h"
20fd4e5da5Sopenharmony_ci#include "pass_utils.h"
21fd4e5da5Sopenharmony_ci#include "source/opt/graphics_robust_access_pass.h"
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciusing namespace spvtools;
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing opt::GraphicsRobustAccessPass;
28fd4e5da5Sopenharmony_ciusing GraphicsRobustAccessTest = opt::PassTest<::testing::Test>;
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ci// Test incompatible module, determined at module-level.
31fd4e5da5Sopenharmony_ci
32fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailNotShader) {
33fd4e5da5Sopenharmony_ci  const std::string text = R"(
34fd4e5da5Sopenharmony_ci; CHECK: Can only process Shader modules
35fd4e5da5Sopenharmony_ciOpCapability Kernel
36fd4e5da5Sopenharmony_ci)";
37fd4e5da5Sopenharmony_ci
38fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
39fd4e5da5Sopenharmony_ci}
40fd4e5da5Sopenharmony_ci
41fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailCantProcessVariablePointers) {
42fd4e5da5Sopenharmony_ci  const std::string text = R"(
43fd4e5da5Sopenharmony_ci; CHECK: Can't process modules with VariablePointers capability
44fd4e5da5Sopenharmony_ciOpCapability VariablePointers
45fd4e5da5Sopenharmony_ci)";
46fd4e5da5Sopenharmony_ci
47fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
48fd4e5da5Sopenharmony_ci}
49fd4e5da5Sopenharmony_ci
50fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailCantProcessVariablePointersStorageBuffer) {
51fd4e5da5Sopenharmony_ci  const std::string text = R"(
52fd4e5da5Sopenharmony_ci; CHECK: Can't process modules with VariablePointersStorageBuffer capability
53fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
54fd4e5da5Sopenharmony_ci)";
55fd4e5da5Sopenharmony_ci
56fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
57fd4e5da5Sopenharmony_ci}
58fd4e5da5Sopenharmony_ci
59fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailCantProcessRuntimeDescriptorArrayEXT) {
60fd4e5da5Sopenharmony_ci  const std::string text = R"(
61fd4e5da5Sopenharmony_ci; CHECK: Can't process modules with RuntimeDescriptorArrayEXT capability
62fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
63fd4e5da5Sopenharmony_ci)";
64fd4e5da5Sopenharmony_ci
65fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
66fd4e5da5Sopenharmony_ci}
67fd4e5da5Sopenharmony_ci
68fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailCantProcessPhysical32AddressingModel) {
69fd4e5da5Sopenharmony_ci  const std::string text = R"(
70fd4e5da5Sopenharmony_ci; CHECK: Addressing model must be Logical.  Found OpMemoryModel Physical32 OpenCL
71fd4e5da5Sopenharmony_ciOpCapability Shader
72fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL
73fd4e5da5Sopenharmony_ci)";
74fd4e5da5Sopenharmony_ci
75fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
76fd4e5da5Sopenharmony_ci}
77fd4e5da5Sopenharmony_ci
78fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, FailCantProcessPhysical64AddressingModel) {
79fd4e5da5Sopenharmony_ci  const std::string text = R"(
80fd4e5da5Sopenharmony_ci; CHECK: Addressing model must be Logical.  Found OpMemoryModel Physical64 OpenCL
81fd4e5da5Sopenharmony_ciOpCapability Shader
82fd4e5da5Sopenharmony_ciOpMemoryModel Physical64 OpenCL
83fd4e5da5Sopenharmony_ci)";
84fd4e5da5Sopenharmony_ci
85fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
86fd4e5da5Sopenharmony_ci}
87fd4e5da5Sopenharmony_ci
88fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest,
89fd4e5da5Sopenharmony_ci       FailCantProcessPhysicalStorageBuffer64EXTAddressingModel) {
90fd4e5da5Sopenharmony_ci  const std::string text = R"(
91fd4e5da5Sopenharmony_ci; CHECK: Addressing model must be Logical.  Found OpMemoryModel PhysicalStorageBuffer64 GLSL450
92fd4e5da5Sopenharmony_ciOpCapability Shader
93fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64EXT GLSL450
94fd4e5da5Sopenharmony_ci)";
95fd4e5da5Sopenharmony_ci
96fd4e5da5Sopenharmony_ci  SinglePassRunAndFail<GraphicsRobustAccessPass>(text);
97fd4e5da5Sopenharmony_ci}
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_ci// Test access chains
100fd4e5da5Sopenharmony_ci
101fd4e5da5Sopenharmony_ci// Returns the names of access chain instructions handled by the pass.
102fd4e5da5Sopenharmony_ci// For the purposes of this pass, regular and in-bounds access chains are the
103fd4e5da5Sopenharmony_ci// same.)
104fd4e5da5Sopenharmony_cistd::vector<const char*> AccessChains() {
105fd4e5da5Sopenharmony_ci  return {"OpAccessChain", "OpInBoundsAccessChain"};
106fd4e5da5Sopenharmony_ci}
107fd4e5da5Sopenharmony_ci
108fd4e5da5Sopenharmony_cistd::string ShaderPreamble() {
109fd4e5da5Sopenharmony_ci  return R"(
110fd4e5da5Sopenharmony_ci  OpCapability Shader
111fd4e5da5Sopenharmony_ci  OpMemoryModel Logical Simple
112fd4e5da5Sopenharmony_ci  OpEntryPoint GLCompute %main "main"
113fd4e5da5Sopenharmony_ci)";
114fd4e5da5Sopenharmony_ci}
115fd4e5da5Sopenharmony_ci
116fd4e5da5Sopenharmony_cistd::string ShaderPreamble(const std::vector<std::string>& names) {
117fd4e5da5Sopenharmony_ci  std::ostringstream os;
118fd4e5da5Sopenharmony_ci  os << ShaderPreamble();
119fd4e5da5Sopenharmony_ci  for (auto& name : names) {
120fd4e5da5Sopenharmony_ci    os << "  OpName %" << name << " \"" << name << "\"\n";
121fd4e5da5Sopenharmony_ci  }
122fd4e5da5Sopenharmony_ci  return os.str();
123fd4e5da5Sopenharmony_ci}
124fd4e5da5Sopenharmony_ci
125fd4e5da5Sopenharmony_cistd::string ShaderPreambleAC() {
126fd4e5da5Sopenharmony_ci  return ShaderPreamble({"ac", "ptr_ty", "var"});
127fd4e5da5Sopenharmony_ci}
128fd4e5da5Sopenharmony_ci
129fd4e5da5Sopenharmony_cistd::string ShaderPreambleAC(const std::vector<std::string>& names) {
130fd4e5da5Sopenharmony_ci  auto names2 = names;
131fd4e5da5Sopenharmony_ci  names2.push_back("ac");
132fd4e5da5Sopenharmony_ci  names2.push_back("ptr_ty");
133fd4e5da5Sopenharmony_ci  names2.push_back("var");
134fd4e5da5Sopenharmony_ci  return ShaderPreamble(names2);
135fd4e5da5Sopenharmony_ci}
136fd4e5da5Sopenharmony_ci
137fd4e5da5Sopenharmony_cistd::string DecoSSBO() {
138fd4e5da5Sopenharmony_ci  return R"(
139fd4e5da5Sopenharmony_ci  OpDecorate %ssbo_s BufferBlock
140fd4e5da5Sopenharmony_ci  OpMemberDecorate %ssbo_s 0 Offset 0
141fd4e5da5Sopenharmony_ci  OpMemberDecorate %ssbo_s 1 Offset 4
142fd4e5da5Sopenharmony_ci  OpMemberDecorate %ssbo_s 2 Offset 16
143fd4e5da5Sopenharmony_ci  OpDecorate %var DescriptorSet 0
144fd4e5da5Sopenharmony_ci  OpDecorate %var Binding 0
145fd4e5da5Sopenharmony_ci)";
146fd4e5da5Sopenharmony_ci}
147fd4e5da5Sopenharmony_ci
148fd4e5da5Sopenharmony_cistd::string TypesVoid() {
149fd4e5da5Sopenharmony_ci  return R"(
150fd4e5da5Sopenharmony_ci  %void = OpTypeVoid
151fd4e5da5Sopenharmony_ci  %void_fn = OpTypeFunction %void
152fd4e5da5Sopenharmony_ci)";
153fd4e5da5Sopenharmony_ci}
154fd4e5da5Sopenharmony_ci
155fd4e5da5Sopenharmony_cistd::string TypesInt() {
156fd4e5da5Sopenharmony_ci  return R"(
157fd4e5da5Sopenharmony_ci  %uint = OpTypeInt 32 0
158fd4e5da5Sopenharmony_ci  %int = OpTypeInt 32 1
159fd4e5da5Sopenharmony_ci)";
160fd4e5da5Sopenharmony_ci}
161fd4e5da5Sopenharmony_ci
162fd4e5da5Sopenharmony_cistd::string TypesFloat() {
163fd4e5da5Sopenharmony_ci  return R"(
164fd4e5da5Sopenharmony_ci  %float = OpTypeFloat 32
165fd4e5da5Sopenharmony_ci)";
166fd4e5da5Sopenharmony_ci}
167fd4e5da5Sopenharmony_ci
168fd4e5da5Sopenharmony_cistd::string TypesShort() {
169fd4e5da5Sopenharmony_ci  return R"(
170fd4e5da5Sopenharmony_ci  %ushort = OpTypeInt 16 0
171fd4e5da5Sopenharmony_ci  %short = OpTypeInt 16 1
172fd4e5da5Sopenharmony_ci)";
173fd4e5da5Sopenharmony_ci}
174fd4e5da5Sopenharmony_ci
175fd4e5da5Sopenharmony_cistd::string TypesLong() {
176fd4e5da5Sopenharmony_ci  return R"(
177fd4e5da5Sopenharmony_ci  %ulong = OpTypeInt 64 0
178fd4e5da5Sopenharmony_ci  %long = OpTypeInt 64 1
179fd4e5da5Sopenharmony_ci)";
180fd4e5da5Sopenharmony_ci}
181fd4e5da5Sopenharmony_ci
182fd4e5da5Sopenharmony_cistd::string MainPrefix() {
183fd4e5da5Sopenharmony_ci  return R"(
184fd4e5da5Sopenharmony_ci  %main = OpFunction %void None %void_fn
185fd4e5da5Sopenharmony_ci  %entry = OpLabel
186fd4e5da5Sopenharmony_ci)";
187fd4e5da5Sopenharmony_ci}
188fd4e5da5Sopenharmony_ci
189fd4e5da5Sopenharmony_cistd::string MainSuffix() {
190fd4e5da5Sopenharmony_ci  return R"(
191fd4e5da5Sopenharmony_ci  OpReturn
192fd4e5da5Sopenharmony_ci  OpFunctionEnd
193fd4e5da5Sopenharmony_ci)";
194fd4e5da5Sopenharmony_ci}
195fd4e5da5Sopenharmony_ci
196fd4e5da5Sopenharmony_cistd::string ACCheck(const std::string& access_chain_inst,
197fd4e5da5Sopenharmony_ci                    const std::string& original,
198fd4e5da5Sopenharmony_ci                    const std::string& transformed) {
199fd4e5da5Sopenharmony_ci  return "\n ; CHECK: %ac = " + access_chain_inst + " %ptr_ty %var" +
200fd4e5da5Sopenharmony_ci         (transformed.empty() ? "" : " ") + transformed +
201fd4e5da5Sopenharmony_ci         "\n ; CHECK-NOT: " + access_chain_inst +
202fd4e5da5Sopenharmony_ci         "\n ; CHECK-NEXT: OpReturn"
203fd4e5da5Sopenharmony_ci         "\n %ac = " +
204fd4e5da5Sopenharmony_ci         access_chain_inst + " %ptr_ty %var " + (original.empty() ? "" : " ") +
205fd4e5da5Sopenharmony_ci         original + "\n";
206fd4e5da5Sopenharmony_ci}
207fd4e5da5Sopenharmony_ci
208fd4e5da5Sopenharmony_cistd::string ACCheckFail(const std::string& access_chain_inst,
209fd4e5da5Sopenharmony_ci                        const std::string& original,
210fd4e5da5Sopenharmony_ci                        const std::string& transformed) {
211fd4e5da5Sopenharmony_ci  return "\n ; CHECK: %ac = " + access_chain_inst + " %ptr_ty %var" +
212fd4e5da5Sopenharmony_ci         (transformed.empty() ? "" : " ") + transformed +
213fd4e5da5Sopenharmony_ci         "\n ; CHECK-NOT: " + access_chain_inst +
214fd4e5da5Sopenharmony_ci         "\n ; CHECK-NOT: OpReturn"
215fd4e5da5Sopenharmony_ci         "\n %ac = " +
216fd4e5da5Sopenharmony_ci         access_chain_inst + " %ptr_ty %var " + (original.empty() ? "" : " ") +
217fd4e5da5Sopenharmony_ci         original + "\n";
218fd4e5da5Sopenharmony_ci}
219fd4e5da5Sopenharmony_ci
220fd4e5da5Sopenharmony_ci// Access chain into:
221fd4e5da5Sopenharmony_ci//   Vector
222fd4e5da5Sopenharmony_ci//     Vector sizes 2, 3, 4
223fd4e5da5Sopenharmony_ci//   Matrix
224fd4e5da5Sopenharmony_ci//     Matrix columns 2, 4
225fd4e5da5Sopenharmony_ci//     Component is vector 2, 4
226fd4e5da5Sopenharmony_ci//   Array
227fd4e5da5Sopenharmony_ci//   Struct
228fd4e5da5Sopenharmony_ci//   TODO(dneto): RuntimeArray
229fd4e5da5Sopenharmony_ci
230fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorLeastInboundConstantUntouched) {
231fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
232fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
233fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt() << R"(
234fd4e5da5Sopenharmony_ci       %uvec2 = OpTypeVector %uint 2
235fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %uvec2
236fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
237fd4e5da5Sopenharmony_ci       %uint_0 = OpConstant %uint 0
238fd4e5da5Sopenharmony_ci       )"
239fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
240fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%uint_0", "%uint_0")
241fd4e5da5Sopenharmony_ci            << MainSuffix();
242fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
243fd4e5da5Sopenharmony_ci  }
244fd4e5da5Sopenharmony_ci}
245fd4e5da5Sopenharmony_ci
246fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorMostInboundConstantUntouched) {
247fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
248fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
249fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt() << R"(
250fd4e5da5Sopenharmony_ci       %v4uint = OpTypeVector %uint 4
251fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4uint
252fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
253fd4e5da5Sopenharmony_ci       %uint_3 = OpConstant %uint 3
254fd4e5da5Sopenharmony_ci       )"
255fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
256fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%uint_3", "%uint_3")
257fd4e5da5Sopenharmony_ci            << MainSuffix();
258fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
259fd4e5da5Sopenharmony_ci  }
260fd4e5da5Sopenharmony_ci}
261fd4e5da5Sopenharmony_ci
262fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorExcessConstantClamped) {
263fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
264fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
265fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt() << R"(
266fd4e5da5Sopenharmony_ci       %v4uint = OpTypeVector %uint 4
267fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4uint
268fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
269fd4e5da5Sopenharmony_ci       %uint_4 = OpConstant %uint 4
270fd4e5da5Sopenharmony_ci       )"
271fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
272fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%uint_4", "%int_3")
273fd4e5da5Sopenharmony_ci            << MainSuffix();
274fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
275fd4e5da5Sopenharmony_ci  }
276fd4e5da5Sopenharmony_ci}
277fd4e5da5Sopenharmony_ci
278fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorNegativeConstantClamped) {
279fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
280fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
281fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt() << R"(
282fd4e5da5Sopenharmony_ci       %v4uint = OpTypeVector %uint 4
283fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4uint
284fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
285fd4e5da5Sopenharmony_ci       %int_n1 = OpConstant %int -1
286fd4e5da5Sopenharmony_ci       )"
287fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
288fd4e5da5Sopenharmony_ci       ; CHECK: %int_0 = OpConstant %int 0
289fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%int_n1", "%int_0")
290fd4e5da5Sopenharmony_ci            << MainSuffix();
291fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
292fd4e5da5Sopenharmony_ci  }
293fd4e5da5Sopenharmony_ci}
294fd4e5da5Sopenharmony_ci
295fd4e5da5Sopenharmony_ci// Like the previous test, but ensures the pass knows how to modify an index
296fd4e5da5Sopenharmony_ci// which does not come first in the access chain.
297fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorInArrayNegativeConstantClamped) {
298fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
299fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
300fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt() << R"(
301fd4e5da5Sopenharmony_ci       %v4uint = OpTypeVector %uint 4
302fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
303fd4e5da5Sopenharmony_ci       %uint_2 = OpConstant %uint 2
304fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %v4uint %uint_2
305fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
306fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
307fd4e5da5Sopenharmony_ci       %int_n1 = OpConstant %int -1
308fd4e5da5Sopenharmony_ci       )"
309fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
310fd4e5da5Sopenharmony_ci       ; CHECK: %int_0 = OpConstant %int 0
311fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
312fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%uint_1 %int_n1", "%uint_1 %int_0") << MainSuffix();
313fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
314fd4e5da5Sopenharmony_ci  }
315fd4e5da5Sopenharmony_ci}
316fd4e5da5Sopenharmony_ci
317fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorGeneralClamped) {
318fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
319fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
320fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt() << R"(
321fd4e5da5Sopenharmony_ci       %v4uint = OpTypeVector %uint 4
322fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4uint
323fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %uint
324fd4e5da5Sopenharmony_ci       %i = OpUndef %int)"
325fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
326fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
327fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
328fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_3 = OpConstant %int 3
329fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
330fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_3
331fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
332fd4e5da5Sopenharmony_ci            << MainSuffix();
333fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
334fd4e5da5Sopenharmony_ci  }
335fd4e5da5Sopenharmony_ci}
336fd4e5da5Sopenharmony_ci
337fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorGeneralShortClamped) {
338fd4e5da5Sopenharmony_ci  // Show that signed 16 bit integers are clamped as well.
339fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
340fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
341fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
342fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesShort() <<
343fd4e5da5Sopenharmony_ci        R"(
344fd4e5da5Sopenharmony_ci       %v4short = OpTypeVector %short 4
345fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4short
346fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %short
347fd4e5da5Sopenharmony_ci       %i = OpUndef %short)"
348fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
349fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
350fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
351fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %short_0 = OpConstant %short 0
352fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %short_3 = OpConstant %short 3
353fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
354fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
355fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %short %[[GLSLSTD450]] SClamp %i %short_0 %short_3
356fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
357fd4e5da5Sopenharmony_ci            << MainSuffix();
358fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
359fd4e5da5Sopenharmony_ci  }
360fd4e5da5Sopenharmony_ci}
361fd4e5da5Sopenharmony_ci
362fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorGeneralUShortClamped) {
363fd4e5da5Sopenharmony_ci  // Show that unsigned 16 bit integers are clamped as well.
364fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
365fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
366fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
367fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesShort() <<
368fd4e5da5Sopenharmony_ci        R"(
369fd4e5da5Sopenharmony_ci       %v4ushort = OpTypeVector %ushort 4
370fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4ushort
371fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %ushort
372fd4e5da5Sopenharmony_ci       %i = OpUndef %ushort)"
373fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
374fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
375fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
376fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %short_0 = OpConstant %short 0
377fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %short_3 = OpConstant %short 3
378fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
379fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
380fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ushort %[[GLSLSTD450]] SClamp %i %short_0 %short_3
381fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
382fd4e5da5Sopenharmony_ci            << MainSuffix();
383fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
384fd4e5da5Sopenharmony_ci  }
385fd4e5da5Sopenharmony_ci}
386fd4e5da5Sopenharmony_ci
387fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorGeneralLongClamped) {
388fd4e5da5Sopenharmony_ci  // Show that signed 64 bit integers are clamped as well.
389fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
390fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
391fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64\n"
392fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesLong() <<
393fd4e5da5Sopenharmony_ci        R"(
394fd4e5da5Sopenharmony_ci       %v4long = OpTypeVector %long 4
395fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4long
396fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %long
397fd4e5da5Sopenharmony_ci       %i = OpUndef %long)"
398fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
399fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
400fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
401fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
402fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_3 = OpConstant %long 3
403fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
404fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
405fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %long %[[GLSLSTD450]] SClamp %i %long_0 %long_3
406fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
407fd4e5da5Sopenharmony_ci            << MainSuffix();
408fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
409fd4e5da5Sopenharmony_ci  }
410fd4e5da5Sopenharmony_ci}
411fd4e5da5Sopenharmony_ci
412fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACVectorGeneralULongClamped) {
413fd4e5da5Sopenharmony_ci  // Show that unsigned 64 bit integers are clamped as well.
414fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
415fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
416fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64\n"
417fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesLong() <<
418fd4e5da5Sopenharmony_ci        R"(
419fd4e5da5Sopenharmony_ci       %v4ulong = OpTypeVector %ulong 4
420fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %v4ulong
421fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %ulong
422fd4e5da5Sopenharmony_ci       %i = OpUndef %ulong)"
423fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
424fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
425fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
426fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
427fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_3 = OpConstant %long 3
428fd4e5da5Sopenharmony_ci       ; CHECK-NOT: = OpTypeInt 32
429fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
430fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ulong %[[GLSLSTD450]] SClamp %i %long_0 %long_3
431fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
432fd4e5da5Sopenharmony_ci            << MainSuffix();
433fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
434fd4e5da5Sopenharmony_ci  }
435fd4e5da5Sopenharmony_ci}
436fd4e5da5Sopenharmony_ci
437fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACMatrixLeastInboundConstantUntouched) {
438fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
439fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
440fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
441fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
442fd4e5da5Sopenharmony_ci       %v2float = OpTypeVector %float 2
443fd4e5da5Sopenharmony_ci       %mat4v2float = OpTypeMatrix %v2float 4
444fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %mat4v2float
445fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
446fd4e5da5Sopenharmony_ci       %uint_0 = OpConstant %uint 0
447fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
448fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
449fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
450fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%uint_0 %uint_1", "%uint_0 %uint_1")
451fd4e5da5Sopenharmony_ci            << MainSuffix();
452fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
453fd4e5da5Sopenharmony_ci  }
454fd4e5da5Sopenharmony_ci}
455fd4e5da5Sopenharmony_ci
456fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACMatrixMostInboundConstantUntouched) {
457fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
458fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
459fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
460fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
461fd4e5da5Sopenharmony_ci       %v2float = OpTypeVector %float 2
462fd4e5da5Sopenharmony_ci       %mat4v2float = OpTypeMatrix %v2float 4
463fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %mat4v2float
464fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
465fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
466fd4e5da5Sopenharmony_ci       %uint_3 = OpConstant %uint 3
467fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
468fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
469fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%uint_3 %uint_1", "%uint_3 %uint_1")
470fd4e5da5Sopenharmony_ci            << MainSuffix();
471fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
472fd4e5da5Sopenharmony_ci  }
473fd4e5da5Sopenharmony_ci}
474fd4e5da5Sopenharmony_ci
475fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACMatrixExcessConstantClamped) {
476fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
477fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
478fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
479fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
480fd4e5da5Sopenharmony_ci       %v2float = OpTypeVector %float 2
481fd4e5da5Sopenharmony_ci       %mat4v2float = OpTypeMatrix %v2float 4
482fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %mat4v2float
483fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
484fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
485fd4e5da5Sopenharmony_ci       %uint_4 = OpConstant %uint 4
486fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
487fd4e5da5Sopenharmony_ci       ; CHECK: %int_3 = OpConstant %int 3
488fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
489fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%uint_4 %uint_1", "%int_3 %uint_1") << MainSuffix();
490fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
491fd4e5da5Sopenharmony_ci  }
492fd4e5da5Sopenharmony_ci}
493fd4e5da5Sopenharmony_ci
494fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACMatrixNegativeConstantClamped) {
495fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
496fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
497fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
498fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
499fd4e5da5Sopenharmony_ci       %v2float = OpTypeVector %float 2
500fd4e5da5Sopenharmony_ci       %mat4v2float = OpTypeMatrix %v2float 4
501fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %mat4v2float
502fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
503fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
504fd4e5da5Sopenharmony_ci       %int_n1 = OpConstant %int -1
505fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
506fd4e5da5Sopenharmony_ci       ; CHECK: %int_0 = OpConstant %int 0
507fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
508fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_n1 %uint_1", "%int_0 %uint_1") << MainSuffix();
509fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
510fd4e5da5Sopenharmony_ci  }
511fd4e5da5Sopenharmony_ci}
512fd4e5da5Sopenharmony_ci
513fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACMatrixGeneralClamped) {
514fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
515fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
516fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
517fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
518fd4e5da5Sopenharmony_ci       %v2float = OpTypeVector %float 2
519fd4e5da5Sopenharmony_ci       %mat4v2float = OpTypeMatrix %v2float 4
520fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %mat4v2float
521fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
522fd4e5da5Sopenharmony_ci       %uint_1 = OpConstant %uint 1
523fd4e5da5Sopenharmony_ci       %i = OpUndef %int
524fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
525fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
526fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
527fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_3 = OpConstant %int 3
528fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
529fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_3
530fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
531fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i %uint_1", "%[[clamp]] %uint_1") << MainSuffix();
532fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
533fd4e5da5Sopenharmony_ci  }
534fd4e5da5Sopenharmony_ci}
535fd4e5da5Sopenharmony_ci
536fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayLeastInboundConstantUntouched) {
537fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
538fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
539fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
540fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
541fd4e5da5Sopenharmony_ci       %uint_200 = OpConstant %uint 200
542fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_200
543fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
544fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
545fd4e5da5Sopenharmony_ci       %int_0 = OpConstant %int 0
546fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
547fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
548fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_0", "%int_0") << MainSuffix();
549fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
550fd4e5da5Sopenharmony_ci  }
551fd4e5da5Sopenharmony_ci}
552fd4e5da5Sopenharmony_ci
553fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayMostInboundConstantUntouched) {
554fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
555fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
556fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
557fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
558fd4e5da5Sopenharmony_ci       %uint_200 = OpConstant %uint 200
559fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_200
560fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
561fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
562fd4e5da5Sopenharmony_ci       %int_199 = OpConstant %int 199
563fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
564fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
565fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_199", "%int_199") << MainSuffix();
566fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
567fd4e5da5Sopenharmony_ci  }
568fd4e5da5Sopenharmony_ci}
569fd4e5da5Sopenharmony_ci
570fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralClamped) {
571fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
572fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
573fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
574fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
575fd4e5da5Sopenharmony_ci       %uint_200 = OpConstant %uint 200
576fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_200
577fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
578fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
579fd4e5da5Sopenharmony_ci       %i = OpUndef %int
580fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
581fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
582fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
583fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_199 = OpConstant %int 199
584fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
585fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_199
586fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
587fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
588fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
589fd4e5da5Sopenharmony_ci  }
590fd4e5da5Sopenharmony_ci}
591fd4e5da5Sopenharmony_ci
592fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralShortIndexUIntBoundsClamped) {
593fd4e5da5Sopenharmony_ci  // Index is signed short, array bounds overflows the index type.
594fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
595fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
596fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
597fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
598fd4e5da5Sopenharmony_ci            << TypesShort() << TypesFloat() << R"(
599fd4e5da5Sopenharmony_ci       %uint_70000 = OpConstant %uint 70000 ; overflows 16bits
600fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_70000
601fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
602fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
603fd4e5da5Sopenharmony_ci       %i = OpUndef %short
604fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
605fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
606fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
607fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_69999 = OpConstant %int 69999
608fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
609fd4e5da5Sopenharmony_ci       ; CHECK: %[[i_ext:\w+]] = OpSConvert %uint %i
610fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %[[i_ext]] %int_0 %int_69999
611fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
612fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
613fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
614fd4e5da5Sopenharmony_ci  }
615fd4e5da5Sopenharmony_ci}
616fd4e5da5Sopenharmony_ci
617fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralUShortIndexIntBoundsClamped) {
618fd4e5da5Sopenharmony_ci  // Index is unsigned short, array bounds overflows the index type.
619fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
620fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
621fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
622fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
623fd4e5da5Sopenharmony_ci            << TypesShort() << TypesFloat() << R"(
624fd4e5da5Sopenharmony_ci       %int_70000 = OpConstant %int 70000 ; overflows 16bits
625fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %int_70000
626fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
627fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
628fd4e5da5Sopenharmony_ci       %i = OpUndef %ushort
629fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
630fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
631fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
632fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_69999 = OpConstant %int 69999
633fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
634fd4e5da5Sopenharmony_ci       ; CHECK: %[[i_ext:\w+]] = OpUConvert %uint %i
635fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %[[i_ext]] %int_0 %int_69999
636fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
637fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
638fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
639fd4e5da5Sopenharmony_ci  }
640fd4e5da5Sopenharmony_ci}
641fd4e5da5Sopenharmony_ci
642fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralUIntIndexShortBoundsClamped) {
643fd4e5da5Sopenharmony_ci  // Signed int index i is wider than the array bounds type.
644fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
645fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
646fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
647fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
648fd4e5da5Sopenharmony_ci            << TypesShort() << TypesFloat() << R"(
649fd4e5da5Sopenharmony_ci       %short_200 = OpConstant %short 200
650fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %short_200
651fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
652fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
653fd4e5da5Sopenharmony_ci       %i = OpUndef %uint
654fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
655fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
656fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
657fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_199 = OpConstant %int 199
658fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
659fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %i %int_0 %int_199
660fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
661fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
662fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
663fd4e5da5Sopenharmony_ci  }
664fd4e5da5Sopenharmony_ci}
665fd4e5da5Sopenharmony_ci
666fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralIntIndexUShortBoundsClamped) {
667fd4e5da5Sopenharmony_ci  // Unsigned int index i is wider than the array bounds type.
668fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
669fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
670fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
671fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
672fd4e5da5Sopenharmony_ci            << TypesShort() << TypesFloat() << R"(
673fd4e5da5Sopenharmony_ci       %ushort_200 = OpConstant %ushort 200
674fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %ushort_200
675fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
676fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
677fd4e5da5Sopenharmony_ci       %i = OpUndef %int
678fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
679fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
680fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
681fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_199 = OpConstant %int 199
682fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
683fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_199
684fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
685fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
686fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
687fd4e5da5Sopenharmony_ci  }
688fd4e5da5Sopenharmony_ci}
689fd4e5da5Sopenharmony_ci
690fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralLongIndexUIntBoundsClamped) {
691fd4e5da5Sopenharmony_ci  // Signed long index i is wider than the array bounds type.
692fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
693fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
694fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64\n"
695fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
696fd4e5da5Sopenharmony_ci            << TypesLong() << TypesFloat() << R"(
697fd4e5da5Sopenharmony_ci       %uint_200 = OpConstant %uint 200
698fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_200
699fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
700fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
701fd4e5da5Sopenharmony_ci       %i = OpUndef %long
702fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
703fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
704fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
705fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_199 = OpConstant %long 199
706fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
707fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %long %[[GLSLSTD450]] SClamp %i %long_0 %long_199
708fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
709fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
710fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
711fd4e5da5Sopenharmony_ci  }
712fd4e5da5Sopenharmony_ci}
713fd4e5da5Sopenharmony_ci
714fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayGeneralULongIndexIntBoundsClamped) {
715fd4e5da5Sopenharmony_ci  // Unsigned long index i is wider than the array bounds type.
716fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
717fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
718fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64\n"
719fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
720fd4e5da5Sopenharmony_ci            << TypesLong() << TypesFloat() << R"(
721fd4e5da5Sopenharmony_ci       %int_200 = OpConstant %int 200
722fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %int_200
723fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
724fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
725fd4e5da5Sopenharmony_ci       %i = OpUndef %ulong
726fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
727fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
728fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
729fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_199 = OpConstant %long 199
730fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
731fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ulong %[[GLSLSTD450]] SClamp %i %long_0 %long_199
732fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
733fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
734fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
735fd4e5da5Sopenharmony_ci  }
736fd4e5da5Sopenharmony_ci}
737fd4e5da5Sopenharmony_ci
738fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest,
739fd4e5da5Sopenharmony_ci       ACArrayGeneralShortIndeArrayBiggerThanShortMaxClipsToShortIntMax) {
740fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
741fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
742fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
743fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesShort()
744fd4e5da5Sopenharmony_ci            << TypesInt() << TypesFloat() << R"(
745fd4e5da5Sopenharmony_ci       %uint_50000 = OpConstant %uint 50000
746fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_50000
747fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
748fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
749fd4e5da5Sopenharmony_ci       %i = OpUndef %ushort
750fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
751fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
752fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %short_0 = OpConstant %short 0
753fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %short 32767
754fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
755fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ushort %[[GLSLSTD450]] SClamp %i %short_0 %[[intmax]]
756fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
757fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
758fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
759fd4e5da5Sopenharmony_ci  }
760fd4e5da5Sopenharmony_ci}
761fd4e5da5Sopenharmony_ci
762fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest,
763fd4e5da5Sopenharmony_ci       ACArrayGeneralIntIndexArrayBiggerThanIntMaxClipsToSignedIntMax) {
764fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
765fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
766fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
767fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
768fd4e5da5Sopenharmony_ci       %uint_3000000000 = OpConstant %uint 3000000000
769fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %uint_3000000000
770fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
771fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
772fd4e5da5Sopenharmony_ci       %i = OpUndef %uint
773fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
774fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
775fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
776fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
777fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
778fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %i %int_0 %[[intmax]]
779fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
780fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%i", "%[[clamp]]") << MainSuffix();
781fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
782fd4e5da5Sopenharmony_ci  }
783fd4e5da5Sopenharmony_ci}
784fd4e5da5Sopenharmony_ci
785fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest,
786fd4e5da5Sopenharmony_ci       ACArrayGeneralLongIndexArrayBiggerThanLongMaxClipsToSignedLongMax) {
787fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
788fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
789fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64\n"
790fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << TypesVoid() << TypesInt()
791fd4e5da5Sopenharmony_ci            << TypesLong()
792fd4e5da5Sopenharmony_ci            << TypesFloat()
793fd4e5da5Sopenharmony_ci            // 2^63 == 9,223,372,036,854,775,807
794fd4e5da5Sopenharmony_ci            << R"(
795fd4e5da5Sopenharmony_ci       %ulong_9223372036854775999 = OpConstant %ulong 9223372036854775999
796fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %ulong_9223372036854775999
797fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
798fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
799fd4e5da5Sopenharmony_ci       %i = OpUndef %ulong
800fd4e5da5Sopenharmony_ci       )"
801fd4e5da5Sopenharmony_ci            << MainPrefix() << R"(
802fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
803fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
804fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %long 9223372036854775807
805fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
806fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ulong %[[GLSLSTD450]] SClamp %i %long_0 %[[intmax]]
807fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)" << ACCheck(ac, "%i", "%[[clamp]]")
808fd4e5da5Sopenharmony_ci            << MainSuffix();
809fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
810fd4e5da5Sopenharmony_ci  }
811fd4e5da5Sopenharmony_ci}
812fd4e5da5Sopenharmony_ci
813fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArraySpecIdSizedAlwaysClamped) {
814fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
815fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
816fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"spec200"}) << R"(
817fd4e5da5Sopenharmony_ci       OpDecorate %spec200 SpecId 0 )" << TypesVoid() << TypesInt()
818fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
819fd4e5da5Sopenharmony_ci       %spec200 = OpSpecConstant %int 200
820fd4e5da5Sopenharmony_ci       %arr = OpTypeArray %float %spec200
821fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %arr
822fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
823fd4e5da5Sopenharmony_ci       %uint_5 = OpConstant %uint 5
824fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
825fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
826fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_0 = OpConstant %uint 0
827fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_1 = OpConstant %uint 1
828fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[uint_intmax:\w+]] = OpConstant %uint 2147483647
829fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
830fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %uint %spec200 %uint_1
831fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %uint %[[GLSLSTD450]] UMin %[[max]] %[[uint_intmax]]
832fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %uint_5 %uint_0 %[[smin]]
833fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
834fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%uint_5", "%[[clamp]]") << MainSuffix();
835fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
836fd4e5da5Sopenharmony_ci  }
837fd4e5da5Sopenharmony_ci}
838fd4e5da5Sopenharmony_ci
839fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructLeastUntouched) {
840fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
841fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
842fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
843fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
844fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
845fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
846fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
847fd4e5da5Sopenharmony_ci       %int_0 = OpConstant %int 0
848fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
849fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
850fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_0", "%int_0") << MainSuffix();
851fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
852fd4e5da5Sopenharmony_ci  }
853fd4e5da5Sopenharmony_ci}
854fd4e5da5Sopenharmony_ci
855fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructMostUntouched) {
856fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
857fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
858fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << TypesVoid() << TypesInt()
859fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
860fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
861fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
862fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
863fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
864fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
865fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function)"
866fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_2", "%int_2") << MainSuffix();
867fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
868fd4e5da5Sopenharmony_ci  }
869fd4e5da5Sopenharmony_ci}
870fd4e5da5Sopenharmony_ci
871fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructSpecConstantFail) {
872fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
873fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
874fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"struct", "spec200"})
875fd4e5da5Sopenharmony_ci            << "OpDecorate %spec200 SpecId 0\n"
876fd4e5da5Sopenharmony_ci            <<
877fd4e5da5Sopenharmony_ci
878fd4e5da5Sopenharmony_ci        TypesVoid() << TypesInt() << TypesFloat() << R"(
879fd4e5da5Sopenharmony_ci       %spec200 = OpSpecConstant %int 200
880fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
881fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
882fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
883fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
884fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function
885fd4e5da5Sopenharmony_ci       ; CHECK: Member index into struct is not a constant integer
886fd4e5da5Sopenharmony_ci       ; CHECK-SAME: %spec200 = OpSpecConstant %int 200
887fd4e5da5Sopenharmony_ci       )"
888fd4e5da5Sopenharmony_ci            << ACCheckFail(ac, "%spec200", "%spec200") << MainSuffix();
889fd4e5da5Sopenharmony_ci    SinglePassRunAndFail<GraphicsRobustAccessPass>(shaders.str());
890fd4e5da5Sopenharmony_ci  }
891fd4e5da5Sopenharmony_ci}
892fd4e5da5Sopenharmony_ci
893fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructFloatConstantFail) {
894fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
895fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
896fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"struct"}) <<
897fd4e5da5Sopenharmony_ci
898fd4e5da5Sopenharmony_ci        TypesVoid() << TypesInt() << TypesFloat() << R"(
899fd4e5da5Sopenharmony_ci       %float_2 = OpConstant %float 2
900fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
901fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
902fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
903fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
904fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function
905fd4e5da5Sopenharmony_ci       ; CHECK: Member index into struct is not a constant integer
906fd4e5da5Sopenharmony_ci       ; CHECK-SAME: %float_2 = OpConstant %float 2
907fd4e5da5Sopenharmony_ci       )"
908fd4e5da5Sopenharmony_ci            << ACCheckFail(ac, "%float_2", "%float_2") << MainSuffix();
909fd4e5da5Sopenharmony_ci    SinglePassRunAndFail<GraphicsRobustAccessPass>(shaders.str());
910fd4e5da5Sopenharmony_ci  }
911fd4e5da5Sopenharmony_ci}
912fd4e5da5Sopenharmony_ci
913fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructNonConstantFail) {
914fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
915fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
916fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"struct", "i"}) <<
917fd4e5da5Sopenharmony_ci
918fd4e5da5Sopenharmony_ci        TypesVoid() << TypesInt() << TypesFloat() << R"(
919fd4e5da5Sopenharmony_ci       %float_2 = OpConstant %float 2
920fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
921fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
922fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
923fd4e5da5Sopenharmony_ci       %i = OpUndef %int
924fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
925fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function
926fd4e5da5Sopenharmony_ci       ; CHECK: Member index into struct is not a constant integer
927fd4e5da5Sopenharmony_ci       ; CHECK-SAME: %i = OpUndef %int
928fd4e5da5Sopenharmony_ci       )"
929fd4e5da5Sopenharmony_ci            << ACCheckFail(ac, "%i", "%i") << MainSuffix();
930fd4e5da5Sopenharmony_ci    SinglePassRunAndFail<GraphicsRobustAccessPass>(shaders.str());
931fd4e5da5Sopenharmony_ci  }
932fd4e5da5Sopenharmony_ci}
933fd4e5da5Sopenharmony_ci
934fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructExcessFail) {
935fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
936fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
937fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"struct", "i"}) << TypesVoid() << TypesInt()
938fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
939fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
940fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
941fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
942fd4e5da5Sopenharmony_ci       %i = OpConstant %int 4
943fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
944fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function
945fd4e5da5Sopenharmony_ci       ; CHECK: Member index 4 is out of bounds for struct type:
946fd4e5da5Sopenharmony_ci       ; CHECK-SAME: %struct = OpTypeStruct %float %float %float
947fd4e5da5Sopenharmony_ci       )"
948fd4e5da5Sopenharmony_ci            << ACCheckFail(ac, "%i", "%i") << MainSuffix();
949fd4e5da5Sopenharmony_ci    SinglePassRunAndFail<GraphicsRobustAccessPass>(shaders.str());
950fd4e5da5Sopenharmony_ci  }
951fd4e5da5Sopenharmony_ci}
952fd4e5da5Sopenharmony_ci
953fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACStructNegativeFail) {
954fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
955fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
956fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"struct", "i"}) << TypesVoid() << TypesInt()
957fd4e5da5Sopenharmony_ci            << TypesFloat() << R"(
958fd4e5da5Sopenharmony_ci       %struct = OpTypeStruct %float %float %float
959fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Function %struct
960fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Function %float
961fd4e5da5Sopenharmony_ci       %i = OpConstant %int -1
962fd4e5da5Sopenharmony_ci       )" << MainPrefix() << R"(
963fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Function
964fd4e5da5Sopenharmony_ci       ; CHECK: Member index -1 is out of bounds for struct type:
965fd4e5da5Sopenharmony_ci       ; CHECK-SAME: %struct = OpTypeStruct %float %float %float
966fd4e5da5Sopenharmony_ci       )"
967fd4e5da5Sopenharmony_ci            << ACCheckFail(ac, "%i", "%i") << MainSuffix();
968fd4e5da5Sopenharmony_ci    SinglePassRunAndFail<GraphicsRobustAccessPass>(shaders.str());
969fd4e5da5Sopenharmony_ci  }
970fd4e5da5Sopenharmony_ci}
971fd4e5da5Sopenharmony_ci
972fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayLeastInboundClamped) {
973fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
974fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
975fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC() << "OpDecorate %rtarr ArrayStride 4 "
976fd4e5da5Sopenharmony_ci            << DecoSSBO() << TypesVoid() << TypesInt() << TypesFloat() << R"(
977fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
978fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %uint %uint %rtarr
979fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
980fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
981fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
982fd4e5da5Sopenharmony_ci       %int_0 = OpConstant %int 0
983fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
984fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
985fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_1 = OpConstant %int 1
986fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
987fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
988fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
989fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
990fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
991fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %int_0 %int_0 %[[smin]]
992fd4e5da5Sopenharmony_ci       )"
993fd4e5da5Sopenharmony_ci            << MainPrefix() << ACCheck(ac, "%int_2 %int_0", "%int_2 %[[clamp]]")
994fd4e5da5Sopenharmony_ci            << MainSuffix();
995fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
996fd4e5da5Sopenharmony_ci  }
997fd4e5da5Sopenharmony_ci}
998fd4e5da5Sopenharmony_ci
999fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralShortIndexClamped) {
1000fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1001fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1002fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
1003fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << "OpDecorate %rtarr ArrayStride 4 "
1004fd4e5da5Sopenharmony_ci            << DecoSSBO() << TypesVoid() << TypesShort() << TypesFloat() << R"(
1005fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1006fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %short %short %rtarr
1007fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1008fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1009fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1010fd4e5da5Sopenharmony_ci       %short_2 = OpConstant %short 2
1011fd4e5da5Sopenharmony_ci       %i = OpUndef %short
1012fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1013fd4e5da5Sopenharmony_ci       ; CHECK: %uint = OpTypeInt 32 0
1014fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_1 = OpConstant %uint 1
1015fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_0 = OpConstant %uint 0
1016fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %uint 2147483647
1017fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1018fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1019fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[max:\w+]] = OpISub %uint %[[arrlen]] %uint_1
1020fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[i_ext:\w+]] = OpSConvert %uint %i
1021fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %uint %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1022fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %[[i_ext]] %uint_0 %[[smin]]
1023fd4e5da5Sopenharmony_ci       )"
1024fd4e5da5Sopenharmony_ci            << MainPrefix() << ACCheck(ac, "%short_2 %i", "%short_2 %[[clamp]]")
1025fd4e5da5Sopenharmony_ci            << MainSuffix();
1026fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1027fd4e5da5Sopenharmony_ci  }
1028fd4e5da5Sopenharmony_ci}
1029fd4e5da5Sopenharmony_ci
1030fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralUShortIndexClamped) {
1031fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1032fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1033fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int16\n"
1034fd4e5da5Sopenharmony_ci            << ShaderPreambleAC({"i"}) << "OpDecorate %rtarr ArrayStride 4 "
1035fd4e5da5Sopenharmony_ci            << DecoSSBO() << TypesVoid() << TypesShort() << TypesFloat() << R"(
1036fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1037fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %short %short %rtarr
1038fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1039fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1040fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1041fd4e5da5Sopenharmony_ci       %short_2 = OpConstant %short 2
1042fd4e5da5Sopenharmony_ci       %i = OpUndef %ushort
1043fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1044fd4e5da5Sopenharmony_ci       ; CHECK: %uint = OpTypeInt 32 0
1045fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_1 = OpConstant %uint 1
1046fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_0 = OpConstant %uint 0
1047fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %uint 2147483647
1048fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1049fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1050fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[max:\w+]] = OpISub %uint %[[arrlen]] %uint_1
1051fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[i_ext:\w+]] = OpSConvert %uint %i
1052fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %uint %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1053fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %[[i_ext]] %uint_0 %[[smin]]
1054fd4e5da5Sopenharmony_ci       )"
1055fd4e5da5Sopenharmony_ci            << MainPrefix() << ACCheck(ac, "%short_2 %i", "%short_2 %[[clamp]]")
1056fd4e5da5Sopenharmony_ci            << MainSuffix();
1057fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1058fd4e5da5Sopenharmony_ci  }
1059fd4e5da5Sopenharmony_ci}
1060fd4e5da5Sopenharmony_ci
1061fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralIntIndexClamped) {
1062fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1063fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1064fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << "OpDecorate %rtarr ArrayStride 4 "
1065fd4e5da5Sopenharmony_ci            << DecoSSBO() << TypesVoid() << TypesInt() << TypesFloat() << R"(
1066fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1067fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1068fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1069fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1070fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1071fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1072fd4e5da5Sopenharmony_ci       %i = OpUndef %int
1073fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1074fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_1 = OpConstant %int 1
1075fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
1076fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
1077fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1078fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1079fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
1080fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1081fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %[[smin]]
1082fd4e5da5Sopenharmony_ci       )"
1083fd4e5da5Sopenharmony_ci            << MainPrefix() << ACCheck(ac, "%int_2 %i", "%int_2 %[[clamp]]")
1084fd4e5da5Sopenharmony_ci            << MainSuffix();
1085fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1086fd4e5da5Sopenharmony_ci  }
1087fd4e5da5Sopenharmony_ci}
1088fd4e5da5Sopenharmony_ci
1089fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralUIntIndexClamped) {
1090fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1091fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1092fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i"}) << "OpDecorate %rtarr ArrayStride 4 "
1093fd4e5da5Sopenharmony_ci            << DecoSSBO() << TypesVoid() << TypesInt() << TypesFloat() << R"(
1094fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1095fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1096fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1097fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1098fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1099fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1100fd4e5da5Sopenharmony_ci       %i = OpUndef %uint
1101fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1102fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_1 = OpConstant %uint 1
1103fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %uint_0 = OpConstant %uint 0
1104fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %uint 2147483647
1105fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1106fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1107fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %uint %[[arrlen]] %uint_1
1108fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %uint %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1109fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %uint %[[GLSLSTD450]] SClamp %i %uint_0 %[[smin]]
1110fd4e5da5Sopenharmony_ci       )"
1111fd4e5da5Sopenharmony_ci            << MainPrefix() << ACCheck(ac, "%int_2 %i", "%int_2 %[[clamp]]")
1112fd4e5da5Sopenharmony_ci            << MainSuffix();
1113fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1114fd4e5da5Sopenharmony_ci  }
1115fd4e5da5Sopenharmony_ci}
1116fd4e5da5Sopenharmony_ci
1117fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralLongIndexClamped) {
1118fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1119fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1120fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64" << ShaderPreambleAC({"i"})
1121fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 4 " << DecoSSBO() << TypesVoid()
1122fd4e5da5Sopenharmony_ci            << TypesInt() << TypesLong() << TypesFloat() << R"(
1123fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1124fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1125fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1126fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1127fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1128fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1129fd4e5da5Sopenharmony_ci       %i = OpUndef %long
1130fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1131fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_0 = OpConstant %long 0
1132fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %long_1 = OpConstant %long 1
1133fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[longmax:\w+]] = OpConstant %long 9223372036854775807
1134fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1135fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1136fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen_ext:\w+]] = OpUConvert %ulong %[[arrlen]]
1137fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %long %[[arrlen_ext]] %long_1
1138fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %long %[[GLSLSTD450]] UMin %[[max]] %[[longmax]]
1139fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %long %[[GLSLSTD450]] SClamp %i %long_0 %[[smin]]
1140fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1141fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_2 %i", "%int_2 %[[clamp]]") << MainSuffix();
1142fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1143fd4e5da5Sopenharmony_ci  }
1144fd4e5da5Sopenharmony_ci}
1145fd4e5da5Sopenharmony_ci
1146fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayGeneralULongIndexClamped) {
1147fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1148fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1149fd4e5da5Sopenharmony_ci    shaders << "OpCapability Int64" << ShaderPreambleAC({"i"})
1150fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 4 " << DecoSSBO() << TypesVoid()
1151fd4e5da5Sopenharmony_ci            << TypesInt() << TypesLong() << TypesFloat() << R"(
1152fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %float
1153fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1154fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1155fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1156fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1157fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1158fd4e5da5Sopenharmony_ci       %i = OpUndef %ulong
1159fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1160fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %ulong_0 = OpConstant %ulong 0
1161fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %ulong_1 = OpConstant %ulong 1
1162fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[longmax:\w+]] = OpConstant %ulong 9223372036854775807
1163fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1164fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1165fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen_ext:\w+]] = OpUConvert %ulong %[[arrlen]]
1166fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %ulong %[[arrlen_ext]] %ulong_1
1167fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %ulong %[[GLSLSTD450]] UMin %[[max]] %[[longmax]]
1168fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp:\w+]] = OpExtInst %ulong %[[GLSLSTD450]] SClamp %i %ulong_0 %[[smin]]
1169fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1170fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_2 %i", "%int_2 %[[clamp]]") << MainSuffix();
1171fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1172fd4e5da5Sopenharmony_ci  }
1173fd4e5da5Sopenharmony_ci}
1174fd4e5da5Sopenharmony_ci
1175fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACRTArrayStructVectorElem) {
1176fd4e5da5Sopenharmony_ci  // The point of this test is that the access chain can have indices past the
1177fd4e5da5Sopenharmony_ci  // index into the runtime array.  For good measure, the index into the final
1178fd4e5da5Sopenharmony_ci  // struct is out of bounds.  We have to clamp that index too.
1179fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1180fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1181fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i", "j"})
1182fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 32\n"
1183fd4e5da5Sopenharmony_ci            << DecoSSBO() << "OpMemberDecorate %rtelem 0 Offset 0\n"
1184fd4e5da5Sopenharmony_ci            << "OpMemberDecorate %rtelem 1 Offset 16\n"
1185fd4e5da5Sopenharmony_ci            << TypesVoid() << TypesInt() << TypesFloat() << R"(
1186fd4e5da5Sopenharmony_ci       %v4float = OpTypeVector %float 4
1187fd4e5da5Sopenharmony_ci       %rtelem = OpTypeStruct %v4float %v4float
1188fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %rtelem
1189fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1190fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %ssbo_s
1191fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1192fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1193fd4e5da5Sopenharmony_ci       %int_1 = OpConstant %int 1
1194fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1195fd4e5da5Sopenharmony_ci       %i = OpUndef %int
1196fd4e5da5Sopenharmony_ci       %j = OpUndef %int
1197fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1198fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
1199fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_3 = OpConstant %int 3
1200fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
1201fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1202fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %var 2
1203fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
1204fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1205fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_i:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %[[smin]]
1206fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_j:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %j %int_0 %int_3
1207fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1208fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_2 %i %int_1 %j",
1209fd4e5da5Sopenharmony_ci                       "%int_2 %[[clamp_i]] %int_1 %[[clamp_j]]")
1210fd4e5da5Sopenharmony_ci            << MainSuffix();
1211fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1212fd4e5da5Sopenharmony_ci  }
1213fd4e5da5Sopenharmony_ci}
1214fd4e5da5Sopenharmony_ci
1215fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACArrayRTArrayStructVectorElem) {
1216fd4e5da5Sopenharmony_ci  // Now add an additional level of arrays around the Block-decorated struct.
1217fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1218fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1219fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i", "ssbo_s"})
1220fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 32\n"
1221fd4e5da5Sopenharmony_ci            << DecoSSBO() << "OpMemberDecorate %rtelem 0 Offset 0\n"
1222fd4e5da5Sopenharmony_ci            << "OpMemberDecorate %rtelem 1 Offset 16\n"
1223fd4e5da5Sopenharmony_ci            << TypesVoid() << TypesInt() << TypesFloat() << R"(
1224fd4e5da5Sopenharmony_ci       %v4float = OpTypeVector %float 4
1225fd4e5da5Sopenharmony_ci       %rtelem = OpTypeStruct %v4float %v4float
1226fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %rtelem
1227fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1228fd4e5da5Sopenharmony_ci       %arr_size = OpConstant %int 10
1229fd4e5da5Sopenharmony_ci       %arr_ssbo = OpTypeArray %ssbo_s %arr_size
1230fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %arr_ssbo
1231fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1232fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1233fd4e5da5Sopenharmony_ci       %int_1 = OpConstant %int 1
1234fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1235fd4e5da5Sopenharmony_ci       %int_17 = OpConstant %int 17
1236fd4e5da5Sopenharmony_ci       %i = OpUndef %int
1237fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1238fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[ssbo_p:\w+]] = OpTypePointer Uniform %ssbo_s
1239fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
1240fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_9 = OpConstant %int 9
1241fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
1242fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1243fd4e5da5Sopenharmony_ci       ; This access chain is manufactured only so we can compute the array length.
1244fd4e5da5Sopenharmony_ci       ; Note that the %int_9 is already clamped
1245fd4e5da5Sopenharmony_ci       ; CHECK: %[[ssbo_base:\w+]] = )" << ac
1246fd4e5da5Sopenharmony_ci            << R"( %[[ssbo_p]] %var %int_9
1247fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %[[ssbo_base]] 2
1248fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
1249fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1250fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_i:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %[[smin]]
1251fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1252fd4e5da5Sopenharmony_ci            << ACCheck(ac, "%int_17 %int_2 %i %int_1 %int_2",
1253fd4e5da5Sopenharmony_ci                       "%int_9 %int_2 %[[clamp_i]] %int_1 %int_2")
1254fd4e5da5Sopenharmony_ci            << MainSuffix();
1255fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1256fd4e5da5Sopenharmony_ci  }
1257fd4e5da5Sopenharmony_ci}
1258fd4e5da5Sopenharmony_ci
1259fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ACSplitACArrayRTArrayStructVectorElem) {
1260fd4e5da5Sopenharmony_ci  // Split the address calculation across two access chains.  Force
1261fd4e5da5Sopenharmony_ci  // the transform to walk up the access chains to find the base variable.
1262fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1263fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1264fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i", "j", "k", "ssbo_s", "ssbo_pty",
1265fd4e5da5Sopenharmony_ci                                 "rtarr_pty", "ac_ssbo", "ac_rtarr"})
1266fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 32\n"
1267fd4e5da5Sopenharmony_ci            << DecoSSBO() << "OpMemberDecorate %rtelem 0 Offset 0\n"
1268fd4e5da5Sopenharmony_ci            << "OpMemberDecorate %rtelem 1 Offset 16\n"
1269fd4e5da5Sopenharmony_ci            << TypesVoid() << TypesInt() << TypesFloat() << R"(
1270fd4e5da5Sopenharmony_ci       %v4float = OpTypeVector %float 4
1271fd4e5da5Sopenharmony_ci       %rtelem = OpTypeStruct %v4float %v4float
1272fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %rtelem
1273fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1274fd4e5da5Sopenharmony_ci       %arr_size = OpConstant %int 10
1275fd4e5da5Sopenharmony_ci       %arr_ssbo = OpTypeArray %ssbo_s %arr_size
1276fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %arr_ssbo
1277fd4e5da5Sopenharmony_ci       %ssbo_pty = OpTypePointer Uniform %ssbo_s
1278fd4e5da5Sopenharmony_ci       %rtarr_pty = OpTypePointer Uniform %rtarr
1279fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1280fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1281fd4e5da5Sopenharmony_ci       %int_1 = OpConstant %int 1
1282fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1283fd4e5da5Sopenharmony_ci       %i = OpUndef %int
1284fd4e5da5Sopenharmony_ci       %j = OpUndef %int
1285fd4e5da5Sopenharmony_ci       %k = OpUndef %int
1286fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1287fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
1288fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_9 = OpConstant %int 9
1289fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_3 = OpConstant %int 3
1290fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
1291fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1292fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_i:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_9
1293fd4e5da5Sopenharmony_ci       ; CHECK: %ac_ssbo = )" << ac
1294fd4e5da5Sopenharmony_ci            << R"( %ssbo_pty %var %[[clamp_i]]
1295fd4e5da5Sopenharmony_ci       ; CHECK: %ac_rtarr = )"
1296fd4e5da5Sopenharmony_ci            << ac << R"( %rtarr_pty %ac_ssbo %int_2
1297fd4e5da5Sopenharmony_ci
1298fd4e5da5Sopenharmony_ci       ; This is the interesting bit.  This array length is needed for an OpAccessChain
1299fd4e5da5Sopenharmony_ci       ; computing %ac, but the algorithm had to track back through %ac_rtarr's
1300fd4e5da5Sopenharmony_ci       ; definition to find the base pointer %ac_ssbo.
1301fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %ac_ssbo 2
1302fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
1303fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1304fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_j:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %j %int_0 %[[smin]]
1305fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_k:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %k %int_0 %int_3
1306fd4e5da5Sopenharmony_ci       ; CHECK: %ac = )" << ac
1307fd4e5da5Sopenharmony_ci            << R"( %ptr_ty %ac_rtarr %[[clamp_j]] %int_1 %[[clamp_k]]
1308fd4e5da5Sopenharmony_ci       ; CHECK-NOT: AccessChain
1309fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1310fd4e5da5Sopenharmony_ci            << "%ac_ssbo = " << ac << " %ssbo_pty %var %i\n"
1311fd4e5da5Sopenharmony_ci            << "%ac_rtarr = " << ac << " %rtarr_pty %ac_ssbo %int_2\n"
1312fd4e5da5Sopenharmony_ci            << "%ac = " << ac << " %ptr_ty %ac_rtarr %j %int_1 %k\n"
1313fd4e5da5Sopenharmony_ci
1314fd4e5da5Sopenharmony_ci            << MainSuffix();
1315fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1316fd4e5da5Sopenharmony_ci  }
1317fd4e5da5Sopenharmony_ci}
1318fd4e5da5Sopenharmony_ci
1319fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest,
1320fd4e5da5Sopenharmony_ci       ACSplitACArrayRTArrayStructVectorElemAcrossBasicBlocks) {
1321fd4e5da5Sopenharmony_ci  // Split the address calculation across two access chains.  Force
1322fd4e5da5Sopenharmony_ci  // the transform to walk up the access chains to find the base variable.
1323fd4e5da5Sopenharmony_ci  // This time, put the different access chains in different basic blocks.
1324fd4e5da5Sopenharmony_ci  // This is an integrity check to ensure that we keep the instruction-to-block
1325fd4e5da5Sopenharmony_ci  // mapping consistent.
1326fd4e5da5Sopenharmony_ci  for (auto* ac : AccessChains()) {
1327fd4e5da5Sopenharmony_ci    std::ostringstream shaders;
1328fd4e5da5Sopenharmony_ci    shaders << ShaderPreambleAC({"i", "j", "k", "bb1", "bb2", "ssbo_s",
1329fd4e5da5Sopenharmony_ci                                 "ssbo_pty", "rtarr_pty", "ac_ssbo",
1330fd4e5da5Sopenharmony_ci                                 "ac_rtarr"})
1331fd4e5da5Sopenharmony_ci            << "OpDecorate %rtarr ArrayStride 32\n"
1332fd4e5da5Sopenharmony_ci            << DecoSSBO() << "OpMemberDecorate %rtelem 0 Offset 0\n"
1333fd4e5da5Sopenharmony_ci            << "OpMemberDecorate %rtelem 1 Offset 16\n"
1334fd4e5da5Sopenharmony_ci            << TypesVoid() << TypesInt() << TypesFloat() << R"(
1335fd4e5da5Sopenharmony_ci       %v4float = OpTypeVector %float 4
1336fd4e5da5Sopenharmony_ci       %rtelem = OpTypeStruct %v4float %v4float
1337fd4e5da5Sopenharmony_ci       %rtarr = OpTypeRuntimeArray %rtelem
1338fd4e5da5Sopenharmony_ci       %ssbo_s = OpTypeStruct %int %int %rtarr
1339fd4e5da5Sopenharmony_ci       %arr_size = OpConstant %int 10
1340fd4e5da5Sopenharmony_ci       %arr_ssbo = OpTypeArray %ssbo_s %arr_size
1341fd4e5da5Sopenharmony_ci       %var_ty = OpTypePointer Uniform %arr_ssbo
1342fd4e5da5Sopenharmony_ci       %ssbo_pty = OpTypePointer Uniform %ssbo_s
1343fd4e5da5Sopenharmony_ci       %rtarr_pty = OpTypePointer Uniform %rtarr
1344fd4e5da5Sopenharmony_ci       %ptr_ty = OpTypePointer Uniform %float
1345fd4e5da5Sopenharmony_ci       %var = OpVariable %var_ty Uniform
1346fd4e5da5Sopenharmony_ci       %int_1 = OpConstant %int 1
1347fd4e5da5Sopenharmony_ci       %int_2 = OpConstant %int 2
1348fd4e5da5Sopenharmony_ci       %i = OpUndef %int
1349fd4e5da5Sopenharmony_ci       %j = OpUndef %int
1350fd4e5da5Sopenharmony_ci       %k = OpUndef %int
1351fd4e5da5Sopenharmony_ci       ; CHECK: %[[GLSLSTD450:\w+]] = OpExtInstImport "GLSL.std.450"
1352fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_0 = OpConstant %int 0
1353fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_9 = OpConstant %int 9
1354fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %int_3 = OpConstant %int 3
1355fd4e5da5Sopenharmony_ci       ; CHECK-DAG: %[[intmax:\w+]] = OpConstant %int 2147483647
1356fd4e5da5Sopenharmony_ci       ; CHECK: OpLabel
1357fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_i:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %i %int_0 %int_9
1358fd4e5da5Sopenharmony_ci       ; CHECK: %ac_ssbo = )" << ac
1359fd4e5da5Sopenharmony_ci            << R"( %ssbo_pty %var %[[clamp_i]]
1360fd4e5da5Sopenharmony_ci       ; CHECK: %bb1 = OpLabel
1361fd4e5da5Sopenharmony_ci       ; CHECK: %ac_rtarr = )"
1362fd4e5da5Sopenharmony_ci            << ac << R"( %rtarr_pty %ac_ssbo %int_2
1363fd4e5da5Sopenharmony_ci       ; CHECK: %bb2 = OpLabel
1364fd4e5da5Sopenharmony_ci
1365fd4e5da5Sopenharmony_ci       ; This is the interesting bit.  This array length is needed for an OpAccessChain
1366fd4e5da5Sopenharmony_ci       ; computing %ac, but the algorithm had to track back through %ac_rtarr's
1367fd4e5da5Sopenharmony_ci       ; definition to find the base pointer %ac_ssbo.
1368fd4e5da5Sopenharmony_ci       ; CHECK: %[[arrlen:\w+]] = OpArrayLength %uint %ac_ssbo 2
1369fd4e5da5Sopenharmony_ci       ; CHECK: %[[max:\w+]] = OpISub %int %[[arrlen]] %int_1
1370fd4e5da5Sopenharmony_ci       ; CHECK: %[[smin:\w+]] = OpExtInst %int %[[GLSLSTD450]] UMin %[[max]] %[[intmax]]
1371fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_j:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %j %int_0 %[[smin]]
1372fd4e5da5Sopenharmony_ci       ; CHECK: %[[clamp_k:\w+]] = OpExtInst %int %[[GLSLSTD450]] SClamp %k %int_0 %int_3
1373fd4e5da5Sopenharmony_ci       ; CHECK: %ac = )" << ac
1374fd4e5da5Sopenharmony_ci            << R"( %ptr_ty %ac_rtarr %[[clamp_j]] %int_1 %[[clamp_k]]
1375fd4e5da5Sopenharmony_ci       ; CHECK-NOT: AccessChain
1376fd4e5da5Sopenharmony_ci       )" << MainPrefix()
1377fd4e5da5Sopenharmony_ci            << "%ac_ssbo = " << ac << " %ssbo_pty %var %i\n"
1378fd4e5da5Sopenharmony_ci            << "OpBranch %bb1\n%bb1 = OpLabel\n"
1379fd4e5da5Sopenharmony_ci            << "%ac_rtarr = " << ac << " %rtarr_pty %ac_ssbo %int_2\n"
1380fd4e5da5Sopenharmony_ci            << "OpBranch %bb2\n%bb2 = OpLabel\n"
1381fd4e5da5Sopenharmony_ci            << "%ac = " << ac << " %ptr_ty %ac_rtarr %j %int_1 %k\n"
1382fd4e5da5Sopenharmony_ci
1383fd4e5da5Sopenharmony_ci            << MainSuffix();
1384fd4e5da5Sopenharmony_ci    SinglePassRunAndMatch<GraphicsRobustAccessPass>(shaders.str(), true);
1385fd4e5da5Sopenharmony_ci  }
1386fd4e5da5Sopenharmony_ci}
1387fd4e5da5Sopenharmony_ci
1388fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, bug3813) {
1389fd4e5da5Sopenharmony_ci  // This shader comes from Dawn's
1390fd4e5da5Sopenharmony_ci  // TextureViewSamplingTest.TextureCubeMapOnWholeTexture, converted from GLSL
1391fd4e5da5Sopenharmony_ci  // by glslang.
1392fd4e5da5Sopenharmony_ci  // The pass was inserting a signed 32-bit int type, but not correctly marking
1393fd4e5da5Sopenharmony_ci  // the shader as changed.
1394fd4e5da5Sopenharmony_ci  std::string shader = R"(
1395fd4e5da5Sopenharmony_ci; SPIR-V
1396fd4e5da5Sopenharmony_ci; Version: 1.0
1397fd4e5da5Sopenharmony_ci; Generator: Google Shaderc over Glslang; 10
1398fd4e5da5Sopenharmony_ci; Bound: 46
1399fd4e5da5Sopenharmony_ci; Schema: 0
1400fd4e5da5Sopenharmony_ci       OpCapability Shader
1401fd4e5da5Sopenharmony_ci  %1 = OpExtInstImport "GLSL.std.450"
1402fd4e5da5Sopenharmony_ci       OpMemoryModel Logical GLSL450
1403fd4e5da5Sopenharmony_ci       OpEntryPoint Fragment %4 "main" %12 %29
1404fd4e5da5Sopenharmony_ci       OpExecutionMode %4 OriginUpperLeft
1405fd4e5da5Sopenharmony_ci       OpSource GLSL 450
1406fd4e5da5Sopenharmony_ci       OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
1407fd4e5da5Sopenharmony_ci       OpSourceExtension "GL_GOOGLE_include_directive"
1408fd4e5da5Sopenharmony_ci       OpName %4 "main"
1409fd4e5da5Sopenharmony_ci       OpName %8 "sc"
1410fd4e5da5Sopenharmony_ci       OpName %12 "texCoord"
1411fd4e5da5Sopenharmony_ci       OpName %21 "tc"
1412fd4e5da5Sopenharmony_ci       OpName %29 "fragColor"
1413fd4e5da5Sopenharmony_ci       OpName %32 "texture0"
1414fd4e5da5Sopenharmony_ci       OpName %36 "sampler0"
1415fd4e5da5Sopenharmony_ci       OpDecorate %12 Location 0
1416fd4e5da5Sopenharmony_ci       OpDecorate %29 Location 0
1417fd4e5da5Sopenharmony_ci       OpDecorate %32 DescriptorSet 0
1418fd4e5da5Sopenharmony_ci       OpDecorate %32 Binding 1
1419fd4e5da5Sopenharmony_ci       OpDecorate %36 DescriptorSet 0
1420fd4e5da5Sopenharmony_ci       OpDecorate %36 Binding 0
1421fd4e5da5Sopenharmony_ci  %2 = OpTypeVoid
1422fd4e5da5Sopenharmony_ci  %3 = OpTypeFunction %2
1423fd4e5da5Sopenharmony_ci  %6 = OpTypeFloat 32
1424fd4e5da5Sopenharmony_ci  %7 = OpTypePointer Function %6
1425fd4e5da5Sopenharmony_ci  %9 = OpConstant %6 2
1426fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2
1427fd4e5da5Sopenharmony_ci %11 = OpTypePointer Input %10
1428fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Input
1429fd4e5da5Sopenharmony_ci %13 = OpTypeInt 32 0
1430fd4e5da5Sopenharmony_ci %14 = OpConstant %13 0
1431fd4e5da5Sopenharmony_ci %15 = OpTypePointer Input %6
1432fd4e5da5Sopenharmony_ci %19 = OpConstant %6 1
1433fd4e5da5Sopenharmony_ci %22 = OpConstant %13 1
1434fd4e5da5Sopenharmony_ci %27 = OpTypeVector %6 4
1435fd4e5da5Sopenharmony_ci %28 = OpTypePointer Output %27
1436fd4e5da5Sopenharmony_ci %29 = OpVariable %28 Output
1437fd4e5da5Sopenharmony_ci %30 = OpTypeImage %6 Cube 0 0 0 1 Unknown
1438fd4e5da5Sopenharmony_ci %31 = OpTypePointer UniformConstant %30
1439fd4e5da5Sopenharmony_ci %32 = OpVariable %31 UniformConstant
1440fd4e5da5Sopenharmony_ci %34 = OpTypeSampler
1441fd4e5da5Sopenharmony_ci %35 = OpTypePointer UniformConstant %34
1442fd4e5da5Sopenharmony_ci %36 = OpVariable %35 UniformConstant
1443fd4e5da5Sopenharmony_ci %38 = OpTypeSampledImage %30
1444fd4e5da5Sopenharmony_ci %43 = OpTypeVector %6 3
1445fd4e5da5Sopenharmony_ci  %4 = OpFunction %2 None %3
1446fd4e5da5Sopenharmony_ci  %5 = OpLabel
1447fd4e5da5Sopenharmony_ci  %8 = OpVariable %7 Function
1448fd4e5da5Sopenharmony_ci %21 = OpVariable %7 Function
1449fd4e5da5Sopenharmony_ci %16 = OpAccessChain %15 %12 %14
1450fd4e5da5Sopenharmony_ci %17 = OpLoad %6 %16
1451fd4e5da5Sopenharmony_ci %18 = OpFMul %6 %9 %17
1452fd4e5da5Sopenharmony_ci %20 = OpFSub %6 %18 %19
1453fd4e5da5Sopenharmony_ci       OpStore %8 %20
1454fd4e5da5Sopenharmony_ci %23 = OpAccessChain %15 %12 %22
1455fd4e5da5Sopenharmony_ci %24 = OpLoad %6 %23
1456fd4e5da5Sopenharmony_ci %25 = OpFMul %6 %9 %24
1457fd4e5da5Sopenharmony_ci %26 = OpFSub %6 %25 %19
1458fd4e5da5Sopenharmony_ci       OpStore %21 %26
1459fd4e5da5Sopenharmony_ci %33 = OpLoad %30 %32
1460fd4e5da5Sopenharmony_ci %37 = OpLoad %34 %36
1461fd4e5da5Sopenharmony_ci %39 = OpSampledImage %38 %33 %37
1462fd4e5da5Sopenharmony_ci %40 = OpLoad %6 %21
1463fd4e5da5Sopenharmony_ci %41 = OpLoad %6 %8
1464fd4e5da5Sopenharmony_ci %42 = OpFNegate %6 %41
1465fd4e5da5Sopenharmony_ci %44 = OpCompositeConstruct %43 %19 %40 %42
1466fd4e5da5Sopenharmony_ci %45 = OpImageSampleImplicitLod %27 %39 %44
1467fd4e5da5Sopenharmony_ci       OpStore %29 %45
1468fd4e5da5Sopenharmony_ci       OpReturn
1469fd4e5da5Sopenharmony_ci       OpFunctionEnd
1470fd4e5da5Sopenharmony_ci)";
1471fd4e5da5Sopenharmony_ci
1472fd4e5da5Sopenharmony_ci  std::string expected = R"(OpCapability Shader
1473fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1474fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1475fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %texCoord %fragColor
1476fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1477fd4e5da5Sopenharmony_ciOpSource GLSL 450
1478fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
1479fd4e5da5Sopenharmony_ciOpSourceExtension "GL_GOOGLE_include_directive"
1480fd4e5da5Sopenharmony_ciOpName %main "main"
1481fd4e5da5Sopenharmony_ciOpName %sc "sc"
1482fd4e5da5Sopenharmony_ciOpName %texCoord "texCoord"
1483fd4e5da5Sopenharmony_ciOpName %tc "tc"
1484fd4e5da5Sopenharmony_ciOpName %fragColor "fragColor"
1485fd4e5da5Sopenharmony_ciOpName %texture0 "texture0"
1486fd4e5da5Sopenharmony_ciOpName %sampler0 "sampler0"
1487fd4e5da5Sopenharmony_ciOpDecorate %texCoord Location 0
1488fd4e5da5Sopenharmony_ciOpDecorate %fragColor Location 0
1489fd4e5da5Sopenharmony_ciOpDecorate %texture0 DescriptorSet 0
1490fd4e5da5Sopenharmony_ciOpDecorate %texture0 Binding 1
1491fd4e5da5Sopenharmony_ciOpDecorate %sampler0 DescriptorSet 0
1492fd4e5da5Sopenharmony_ciOpDecorate %sampler0 Binding 0
1493fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1494fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
1495fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1496fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
1497fd4e5da5Sopenharmony_ci%float_2 = OpConstant %float 2
1498fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
1499fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
1500fd4e5da5Sopenharmony_ci%texCoord = OpVariable %_ptr_Input_v2float Input
1501fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1502fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
1503fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
1504fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
1505fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
1506fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1507fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1508fd4e5da5Sopenharmony_ci%fragColor = OpVariable %_ptr_Output_v4float Output
1509fd4e5da5Sopenharmony_ci%23 = OpTypeImage %float Cube 0 0 0 1 Unknown
1510fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
1511fd4e5da5Sopenharmony_ci%texture0 = OpVariable %_ptr_UniformConstant_23 UniformConstant
1512fd4e5da5Sopenharmony_ci%25 = OpTypeSampler
1513fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
1514fd4e5da5Sopenharmony_ci%sampler0 = OpVariable %_ptr_UniformConstant_25 UniformConstant
1515fd4e5da5Sopenharmony_ci%27 = OpTypeSampledImage %23
1516fd4e5da5Sopenharmony_ci%v3float = OpTypeVector %float 3
1517fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1518fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10
1519fd4e5da5Sopenharmony_ci%29 = OpLabel
1520fd4e5da5Sopenharmony_ci%sc = OpVariable %_ptr_Function_float Function
1521fd4e5da5Sopenharmony_ci%tc = OpVariable %_ptr_Function_float Function
1522fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Input_float %texCoord %uint_0
1523fd4e5da5Sopenharmony_ci%31 = OpLoad %float %30
1524fd4e5da5Sopenharmony_ci%32 = OpFMul %float %float_2 %31
1525fd4e5da5Sopenharmony_ci%33 = OpFSub %float %32 %float_1
1526fd4e5da5Sopenharmony_ciOpStore %sc %33
1527fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Input_float %texCoord %uint_1
1528fd4e5da5Sopenharmony_ci%35 = OpLoad %float %34
1529fd4e5da5Sopenharmony_ci%36 = OpFMul %float %float_2 %35
1530fd4e5da5Sopenharmony_ci%37 = OpFSub %float %36 %float_1
1531fd4e5da5Sopenharmony_ciOpStore %tc %37
1532fd4e5da5Sopenharmony_ci%38 = OpLoad %23 %texture0
1533fd4e5da5Sopenharmony_ci%39 = OpLoad %25 %sampler0
1534fd4e5da5Sopenharmony_ci%40 = OpSampledImage %27 %38 %39
1535fd4e5da5Sopenharmony_ci%41 = OpLoad %float %tc
1536fd4e5da5Sopenharmony_ci%42 = OpLoad %float %sc
1537fd4e5da5Sopenharmony_ci%43 = OpFNegate %float %42
1538fd4e5da5Sopenharmony_ci%44 = OpCompositeConstruct %v3float %float_1 %41 %43
1539fd4e5da5Sopenharmony_ci%45 = OpImageSampleImplicitLod %v4float %40 %44
1540fd4e5da5Sopenharmony_ciOpStore %fragColor %45
1541fd4e5da5Sopenharmony_ciOpReturn
1542fd4e5da5Sopenharmony_ciOpFunctionEnd
1543fd4e5da5Sopenharmony_ci)";
1544fd4e5da5Sopenharmony_ci
1545fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<GraphicsRobustAccessPass>(shader, expected, false,
1546fd4e5da5Sopenharmony_ci                                                  true);
1547fd4e5da5Sopenharmony_ci}
1548fd4e5da5Sopenharmony_ci
1549fd4e5da5Sopenharmony_ciTEST_F(GraphicsRobustAccessTest, ReplaceIndexReportsChanged) {
1550fd4e5da5Sopenharmony_ci  // A ClusterFuzz generated shader that triggered a
1551fd4e5da5Sopenharmony_ci  // "Binary size unexpectedly changed despite the optimizer saying there was no
1552fd4e5da5Sopenharmony_ci  // change" assertion.
1553fd4e5da5Sopenharmony_ci  // See https://github.com/KhronosGroup/SPIRV-Tools/issues/4166.
1554fd4e5da5Sopenharmony_ci  std::string shader = R"(
1555fd4e5da5Sopenharmony_ci; SPIR-V
1556fd4e5da5Sopenharmony_ci; Version: 1.0
1557fd4e5da5Sopenharmony_ci; Generator: Google Shaderc over Glslang; 245
1558fd4e5da5Sopenharmony_ci; Bound: 41
1559fd4e5da5Sopenharmony_ci; Schema: 0
1560fd4e5da5Sopenharmony_ci               OpCapability Shader
1561fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1562fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1563fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "else" %gl_GlobalInvocationID
1564fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 3338665985
1565fd4e5da5Sopenharmony_ci               OpSource GLSL 450
1566fd4e5da5Sopenharmony_ci               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
1567fd4e5da5Sopenharmony_ci               OpSourceExtension "GL_GOOGLE_include_directive"
1568fd4e5da5Sopenharmony_ci               OpName %main "main"
1569fd4e5da5Sopenharmony_ci               OpName %index "index"
1570fd4e5da5Sopenharmony_ci               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
1571fd4e5da5Sopenharmony_ci               OpName %S "S"
1572fd4e5da5Sopenharmony_ci               OpMemberName %_struct_24 0 ""
1573fd4e5da5Sopenharmony_ci               OpMemberName %_struct_24 1 ""
1574fd4e5da5Sopenharmony_ci               OpName %Dst "Dst"
1575fd4e5da5Sopenharmony_ci               OpMemberName %Dst 0 "s"
1576fd4e5da5Sopenharmony_ci               OpName %dst "dst"
1577fd4e5da5Sopenharmony_ci               OpName %Src "Src"
1578fd4e5da5Sopenharmony_ci               OpMemberName %Src 0 "s"
1579fd4e5da5Sopenharmony_ci               OpName %src "src"
1580fd4e5da5Sopenharmony_ci               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
1581fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_24 0 Offset 64
1582fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_24 1 Offset 8
1583fd4e5da5Sopenharmony_ci               OpDecorate %_arr__struct_24_uint_1 ArrayStride 16
1584fd4e5da5Sopenharmony_ci               OpMemberDecorate %Dst 0 Offset 0
1585fd4e5da5Sopenharmony_ci               OpDecorate %Dst BufferBlock
1586fd4e5da5Sopenharmony_ci               OpDecorate %dst DescriptorSet 0
1587fd4e5da5Sopenharmony_ci               OpDecorate %dst Binding 1
1588fd4e5da5Sopenharmony_ci               OpDecorate %_arr__struct_24_uint_1_0 ArrayStride 16
1589fd4e5da5Sopenharmony_ci               OpMemberDecorate %Src 0 Offset 0
1590fd4e5da5Sopenharmony_ci               OpDecorate %Src Block
1591fd4e5da5Sopenharmony_ci               OpDecorate %src DescriptorSet 0
1592fd4e5da5Sopenharmony_ci               OpDecorate %src Binding 0
1593fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1594fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
1595fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1596fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
1597fd4e5da5Sopenharmony_ci     %v3uint = OpTypeVector %uint 3
1598fd4e5da5Sopenharmony_ci%_ptr_Input_v3uint = OpTypePointer Input %v3uint
1599fd4e5da5Sopenharmony_ci%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
1600fd4e5da5Sopenharmony_ci  %uint_4864 = OpConstant %uint 4864
1601fd4e5da5Sopenharmony_ci%_ptr_Input_uint = OpTypePointer Input %uint
1602fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
1603fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
1604fd4e5da5Sopenharmony_ci     %v2uint = OpTypeVector %uint 2
1605fd4e5da5Sopenharmony_ci %_struct_24 = OpTypeStruct %_ptr_Input_uint %v2uint
1606fd4e5da5Sopenharmony_ci%_arr__struct_24_uint_1 = OpTypeArray %_struct_24 %uint_1
1607fd4e5da5Sopenharmony_ci        %Dst = OpTypeStruct %_arr__struct_24_uint_1
1608fd4e5da5Sopenharmony_ci%_ptr_Uniform_Dst = OpTypePointer Uniform %Dst
1609fd4e5da5Sopenharmony_ci        %dst = OpVariable %_ptr_Uniform_Dst Uniform
1610fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
1611fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
1612fd4e5da5Sopenharmony_ci%_arr__struct_24_uint_1_0 = OpTypeArray %_struct_24 %uint_1
1613fd4e5da5Sopenharmony_ci        %Src = OpTypeStruct %_arr__struct_24_uint_1_0
1614fd4e5da5Sopenharmony_ci%_ptr_Uniform_Src = OpTypePointer Uniform %Src
1615fd4e5da5Sopenharmony_ci        %src = OpVariable %_ptr_Uniform_Src Uniform
1616fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_24 = OpTypePointer Uniform %_struct_24
1617fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
1618fd4e5da5Sopenharmony_ci          %5 = OpLabel
1619fd4e5da5Sopenharmony_ci      %index = OpVariable %_ptr_Function_uint Function
1620fd4e5da5Sopenharmony_ci         %14 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_4864
1621fd4e5da5Sopenharmony_ci         %15 = OpLoad %uint %14
1622fd4e5da5Sopenharmony_ci               OpStore %index %15
1623fd4e5da5Sopenharmony_ci         %16 = OpLoad %uint %index
1624fd4e5da5Sopenharmony_ci          %S = OpUGreaterThanEqual %bool %16 %uint_1
1625fd4e5da5Sopenharmony_ci               OpSelectionMerge %21 None
1626fd4e5da5Sopenharmony_ci               OpBranchConditional %S %20 %21
1627fd4e5da5Sopenharmony_ci         %20 = OpLabel
1628fd4e5da5Sopenharmony_ci               OpReturn
1629fd4e5da5Sopenharmony_ci         %21 = OpLabel
1630fd4e5da5Sopenharmony_ci         %31 = OpLoad %uint %index
1631fd4e5da5Sopenharmony_ci         %36 = OpLoad %uint %index
1632fd4e5da5Sopenharmony_ci         %38 = OpAccessChain %_ptr_Uniform__struct_24 %src %int_0 %36
1633fd4e5da5Sopenharmony_ci         %39 = OpLoad %_struct_24 %38
1634fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %_ptr_Uniform__struct_24 %dst %int_0 %31
1635fd4e5da5Sopenharmony_ci               OpStore %40 %39
1636fd4e5da5Sopenharmony_ci               OpReturn
1637fd4e5da5Sopenharmony_ci               OpFunctionEnd
1638fd4e5da5Sopenharmony_ci)";
1639fd4e5da5Sopenharmony_ci
1640fd4e5da5Sopenharmony_ci  std::vector<uint32_t> optimized_bin;
1641fd4e5da5Sopenharmony_ci  auto status = spvtools::opt::Pass::Status::Failure;
1642fd4e5da5Sopenharmony_ci  std::tie(optimized_bin, status) =
1643fd4e5da5Sopenharmony_ci      SinglePassRunToBinary<GraphicsRobustAccessPass>(shader, false);
1644fd4e5da5Sopenharmony_ci  // Check whether the pass returns the correct modification indication.
1645fd4e5da5Sopenharmony_ci  EXPECT_EQ(status, spvtools::opt::Pass::Status::SuccessWithChange);
1646fd4e5da5Sopenharmony_ci}
1647fd4e5da5Sopenharmony_ci
1648fd4e5da5Sopenharmony_ci// TODO(dneto): Test access chain index wider than 64 bits?
1649fd4e5da5Sopenharmony_ci// TODO(dneto): Test struct access chain index wider than 64 bits?
1650fd4e5da5Sopenharmony_ci// TODO(dneto): OpImageTexelPointer
1651fd4e5da5Sopenharmony_ci//   - all Dim types: 1D 2D Cube 3D Rect Buffer
1652fd4e5da5Sopenharmony_ci//   - all Dim types that can be arrayed: 1D 2D 3D
1653fd4e5da5Sopenharmony_ci//   - sample index: set to 0 if not multisampled
1654fd4e5da5Sopenharmony_ci//   - Dim (2D, Cube Rect} with multisampling
1655fd4e5da5Sopenharmony_ci//      -1 0 max excess
1656fd4e5da5Sopenharmony_ci// TODO(dneto): Test OpImageTexelPointer with coordinate component index other
1657fd4e5da5Sopenharmony_ci// than 32 bits.
1658fd4e5da5Sopenharmony_ci
1659fd4e5da5Sopenharmony_ci}  // namespace
1660