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