1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Valve Corporation 2fd4e5da5Sopenharmony_ci// Copyright (c) 2017 LunarG Inc. 3fd4e5da5Sopenharmony_ci// 4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 7fd4e5da5Sopenharmony_ci// 8fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 9fd4e5da5Sopenharmony_ci// 10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 14fd4e5da5Sopenharmony_ci// limitations under the License. 15fd4e5da5Sopenharmony_ci 16fd4e5da5Sopenharmony_ci#include <string> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace opt { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciusing LocalAccessChainConvertTest = PassTest<::testing::Test>; 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, StructOfVecsOfFloatConverted) { 28fd4e5da5Sopenharmony_ci // #version 140 29fd4e5da5Sopenharmony_ci // 30fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 31fd4e5da5Sopenharmony_ci // 32fd4e5da5Sopenharmony_ci // struct S_t { 33fd4e5da5Sopenharmony_ci // vec4 v0; 34fd4e5da5Sopenharmony_ci // vec4 v1; 35fd4e5da5Sopenharmony_ci // }; 36fd4e5da5Sopenharmony_ci // 37fd4e5da5Sopenharmony_ci // void main() 38fd4e5da5Sopenharmony_ci // { 39fd4e5da5Sopenharmony_ci // S_t s0; 40fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 41fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 42fd4e5da5Sopenharmony_ci // } 43fd4e5da5Sopenharmony_ci 44fd4e5da5Sopenharmony_ci const std::string predefs_before = 45fd4e5da5Sopenharmony_ci R"(OpCapability Shader 46fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 47fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 48fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 49fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 50fd4e5da5Sopenharmony_ciOpSource GLSL 140 51fd4e5da5Sopenharmony_ciOpName %main "main" 52fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 53fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 54fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 55fd4e5da5Sopenharmony_ciOpName %s0 "s0" 56fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 57fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 58fd4e5da5Sopenharmony_ci%void = OpTypeVoid 59fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 60fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 61fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 62fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 63fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 64fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 65fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 66fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 67fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 68fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 69fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 70fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 71fd4e5da5Sopenharmony_ci)"; 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ci const std::string before = 74fd4e5da5Sopenharmony_ci R"( 75fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 76fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0 77fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 78fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ex1]] 79fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0 80fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 81fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 82fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 83fd4e5da5Sopenharmony_ci%17 = OpLabel 84fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 85fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 86fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 87fd4e5da5Sopenharmony_ciOpStore %19 %18 88fd4e5da5Sopenharmony_ci%20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 89fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %20 90fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 91fd4e5da5Sopenharmony_ciOpReturn 92fd4e5da5Sopenharmony_ciOpFunctionEnd 93fd4e5da5Sopenharmony_ci)"; 94fd4e5da5Sopenharmony_ci 95fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 96fd4e5da5Sopenharmony_ci true); 97fd4e5da5Sopenharmony_ci} 98fd4e5da5Sopenharmony_ci 99fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, DebugScopeAndLineInfoForNewInstructions) { 100fd4e5da5Sopenharmony_ci // #version 140 101fd4e5da5Sopenharmony_ci // 102fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 103fd4e5da5Sopenharmony_ci // 104fd4e5da5Sopenharmony_ci // struct S_t { 105fd4e5da5Sopenharmony_ci // vec4 v0; 106fd4e5da5Sopenharmony_ci // vec4 v1; 107fd4e5da5Sopenharmony_ci // }; 108fd4e5da5Sopenharmony_ci // 109fd4e5da5Sopenharmony_ci // void main() 110fd4e5da5Sopenharmony_ci // { 111fd4e5da5Sopenharmony_ci // S_t s0; 112fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 113fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 114fd4e5da5Sopenharmony_ci // } 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci const std::string predefs_before = 117fd4e5da5Sopenharmony_ci R"(OpCapability Shader 118fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 119fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 120fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 121fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 122fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 123fd4e5da5Sopenharmony_ciOpSource GLSL 140 124fd4e5da5Sopenharmony_ciOpName %main "main" 125fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 126fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 127fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 128fd4e5da5Sopenharmony_ciOpName %s0 "s0" 129fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 130fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 131fd4e5da5Sopenharmony_ci%5 = OpString "ps.hlsl" 132fd4e5da5Sopenharmony_ci%6 = OpString "float" 133fd4e5da5Sopenharmony_ci%var_name = OpString "s0" 134fd4e5da5Sopenharmony_ci%main_name = OpString "main" 135fd4e5da5Sopenharmony_ci%void = OpTypeVoid 136fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 137fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 138fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 139fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 140fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 141fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 142fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 143fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32 144fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 145fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 146fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 147fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 148fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 149fd4e5da5Sopenharmony_ci%20 = OpExtInst %void %ext DebugSource %5 150fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %ext DebugCompilationUnit 1 4 %20 HLSL 151fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %ext DebugTypeBasic %6 %int_32 Float 152fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %ext DebugTypeVector %22 4 153fd4e5da5Sopenharmony_ci%24 = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 154fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %24 %20 4 1 %21 %main_name FlagIsProtected|FlagIsPrivate 4 %main 155fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %ext DebugLocalVariable %var_name %23 %20 0 0 %dbg_main FlagIsLocal 156fd4e5da5Sopenharmony_ci)"; 157fd4e5da5Sopenharmony_ci 158fd4e5da5Sopenharmony_ci const std::string before = 159fd4e5da5Sopenharmony_ci R"( 160fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 161fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 1 0 162fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0 163fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 164fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ex1]] 165fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 3 0 166fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0 167fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 168fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 4 0 169fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 170fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 171fd4e5da5Sopenharmony_ci%17 = OpLabel 172fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %ext DebugScope %dbg_main 173fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 174fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 175fd4e5da5Sopenharmony_ciOpLine %5 0 0 176fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 177fd4e5da5Sopenharmony_ciOpLine %5 1 0 178fd4e5da5Sopenharmony_ciOpStore %19 %18 179fd4e5da5Sopenharmony_ciOpLine %5 2 0 180fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 181fd4e5da5Sopenharmony_ciOpLine %5 3 0 182fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %27 183fd4e5da5Sopenharmony_ciOpLine %5 4 0 184fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %28 185fd4e5da5Sopenharmony_ciOpReturn 186fd4e5da5Sopenharmony_ciOpFunctionEnd 187fd4e5da5Sopenharmony_ci)"; 188fd4e5da5Sopenharmony_ci 189fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 190fd4e5da5Sopenharmony_ci true); 191fd4e5da5Sopenharmony_ci} 192fd4e5da5Sopenharmony_ci 193fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, TestTargetsReferencedByDebugValue) { 194fd4e5da5Sopenharmony_ci // #version 140 195fd4e5da5Sopenharmony_ci // 196fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 197fd4e5da5Sopenharmony_ci // 198fd4e5da5Sopenharmony_ci // struct S_t { 199fd4e5da5Sopenharmony_ci // vec4 v0; 200fd4e5da5Sopenharmony_ci // vec4 v1; 201fd4e5da5Sopenharmony_ci // }; 202fd4e5da5Sopenharmony_ci // 203fd4e5da5Sopenharmony_ci // void main() 204fd4e5da5Sopenharmony_ci // { 205fd4e5da5Sopenharmony_ci // S_t s0; 206fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 207fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 208fd4e5da5Sopenharmony_ci // } 209fd4e5da5Sopenharmony_ci 210fd4e5da5Sopenharmony_ci const std::string predefs_before = 211fd4e5da5Sopenharmony_ci R"(OpCapability Shader 212fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 213fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100" 214fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 215fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 216fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 217fd4e5da5Sopenharmony_ciOpSource GLSL 140 218fd4e5da5Sopenharmony_ciOpName %main "main" 219fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 220fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 221fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 222fd4e5da5Sopenharmony_ciOpName %s0 "s0" 223fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 224fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 225fd4e5da5Sopenharmony_ci%5 = OpString "ps.hlsl" 226fd4e5da5Sopenharmony_ci%6 = OpString "float" 227fd4e5da5Sopenharmony_ci%var_name = OpString "s0" 228fd4e5da5Sopenharmony_ci%main_name = OpString "main" 229fd4e5da5Sopenharmony_ci%void = OpTypeVoid 230fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 231fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 232fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 233fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 234fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 235fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 236fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 237fd4e5da5Sopenharmony_ci%int_32 = OpConstant %int 32 238fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 239fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 240fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 241fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 242fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 243fd4e5da5Sopenharmony_ci%deref = OpExtInst %void %ext DebugOperation Deref 244fd4e5da5Sopenharmony_ci%deref_expr = OpExtInst %void %ext DebugExpression %deref 245fd4e5da5Sopenharmony_ci%null_expr = OpExtInst %void %ext DebugExpression 246fd4e5da5Sopenharmony_ci%20 = OpExtInst %void %ext DebugSource %5 247fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %ext DebugCompilationUnit 1 4 %20 HLSL 248fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %ext DebugTypeBasic %6 %int_32 Float 249fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %ext DebugTypeVector %22 4 250fd4e5da5Sopenharmony_ci%24 = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 251fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %24 %20 4 1 %21 %main_name FlagIsProtected|FlagIsPrivate 4 %main 252fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %ext DebugLocalVariable %var_name %23 %20 0 0 %dbg_main FlagIsLocal 253fd4e5da5Sopenharmony_ci)"; 254fd4e5da5Sopenharmony_ci 255fd4e5da5Sopenharmony_ci const std::string before = 256fd4e5da5Sopenharmony_ci R"( 257fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 258fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 0 0 259fd4e5da5Sopenharmony_ci; CHECK: [[s0_1_ptr:%\w+]] = OpAccessChain %_ptr_Function_v4float %s0 %int_1 260fd4e5da5Sopenharmony_ci; CHECK: DebugValue [[dbg_s0:%\w+]] [[s0_1_ptr]] 261fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 1 0 262fd4e5da5Sopenharmony_ci; CHECK: [[s0:%\w+]] = OpLoad %S_t %s0 263fd4e5da5Sopenharmony_ci; CHECK: [[comp:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[s0]] 1 264fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[comp]] 265fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 2 0 266fd4e5da5Sopenharmony_ci; CHECK: [[s0_2_ptr:%\w+]] = OpAccessChain %_ptr_Function_v4float %s0 %int_1 267fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 3 0 268fd4e5da5Sopenharmony_ci; CHECK: [[s0:%\w+]] = OpLoad %S_t %s0 269fd4e5da5Sopenharmony_ci; CHECK: [[s0_2_val:%\w+]] = OpCompositeExtract %v4float [[s0]] 1 270fd4e5da5Sopenharmony_ci; CHECK: DebugValue [[dbg_s0]] [[s0_2_val]] 271fd4e5da5Sopenharmony_ci; CHECK: OpLine {{%\w+}} 4 0 272fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[s0_2_val]] 273fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 274fd4e5da5Sopenharmony_ci%17 = OpLabel 275fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %ext DebugScope %dbg_main 276fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 277fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 278fd4e5da5Sopenharmony_ciOpLine %5 0 0 279fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 280fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %ext DebugValue %25 %19 %deref_expr %int_1 281fd4e5da5Sopenharmony_ciOpLine %5 1 0 282fd4e5da5Sopenharmony_ciOpStore %19 %18 283fd4e5da5Sopenharmony_ciOpLine %5 2 0 284fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 285fd4e5da5Sopenharmony_ciOpLine %5 3 0 286fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %27 287fd4e5da5Sopenharmony_ci%30 = OpExtInst %void %ext DebugValue %25 %28 %null_expr %int_1 288fd4e5da5Sopenharmony_ciOpLine %5 4 0 289fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %28 290fd4e5da5Sopenharmony_ciOpReturn 291fd4e5da5Sopenharmony_ciOpFunctionEnd 292fd4e5da5Sopenharmony_ci)"; 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 295fd4e5da5Sopenharmony_ci true); 296fd4e5da5Sopenharmony_ci} 297fd4e5da5Sopenharmony_ci 298fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, InBoundsAccessChainsConverted) { 299fd4e5da5Sopenharmony_ci // #version 140 300fd4e5da5Sopenharmony_ci // 301fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 302fd4e5da5Sopenharmony_ci // 303fd4e5da5Sopenharmony_ci // struct S_t { 304fd4e5da5Sopenharmony_ci // vec4 v0; 305fd4e5da5Sopenharmony_ci // vec4 v1; 306fd4e5da5Sopenharmony_ci // }; 307fd4e5da5Sopenharmony_ci // 308fd4e5da5Sopenharmony_ci // void main() 309fd4e5da5Sopenharmony_ci // { 310fd4e5da5Sopenharmony_ci // S_t s0; 311fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 312fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 313fd4e5da5Sopenharmony_ci // } 314fd4e5da5Sopenharmony_ci 315fd4e5da5Sopenharmony_ci const std::string predefs_before = 316fd4e5da5Sopenharmony_ci R"(OpCapability Shader 317fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 318fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 319fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 320fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 321fd4e5da5Sopenharmony_ciOpSource GLSL 140 322fd4e5da5Sopenharmony_ciOpName %main "main" 323fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 324fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 325fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 326fd4e5da5Sopenharmony_ciOpName %s0 "s0" 327fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 328fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 329fd4e5da5Sopenharmony_ci%void = OpTypeVoid 330fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 331fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 332fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 333fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 334fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 335fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 336fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 337fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 338fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 339fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 340fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 341fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 342fd4e5da5Sopenharmony_ci)"; 343fd4e5da5Sopenharmony_ci 344fd4e5da5Sopenharmony_ci const std::string before = 345fd4e5da5Sopenharmony_ci R"( 346fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 347fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0 348fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 349fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ex1]] 350fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0 351fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 352fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 353fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 354fd4e5da5Sopenharmony_ci%17 = OpLabel 355fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 356fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 357fd4e5da5Sopenharmony_ci%19 = OpInBoundsAccessChain %_ptr_Function_v4float %s0 %int_1 358fd4e5da5Sopenharmony_ciOpStore %19 %18 359fd4e5da5Sopenharmony_ci%20 = OpInBoundsAccessChain %_ptr_Function_v4float %s0 %int_1 360fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %20 361fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 362fd4e5da5Sopenharmony_ciOpReturn 363fd4e5da5Sopenharmony_ciOpFunctionEnd 364fd4e5da5Sopenharmony_ci)"; 365fd4e5da5Sopenharmony_ci 366fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 367fd4e5da5Sopenharmony_ci true); 368fd4e5da5Sopenharmony_ci} 369fd4e5da5Sopenharmony_ci 370fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, TwoUsesofSingleChainConverted) { 371fd4e5da5Sopenharmony_ci // #version 140 372fd4e5da5Sopenharmony_ci // 373fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 374fd4e5da5Sopenharmony_ci // 375fd4e5da5Sopenharmony_ci // struct S_t { 376fd4e5da5Sopenharmony_ci // vec4 v0; 377fd4e5da5Sopenharmony_ci // vec4 v1; 378fd4e5da5Sopenharmony_ci // }; 379fd4e5da5Sopenharmony_ci // 380fd4e5da5Sopenharmony_ci // void main() 381fd4e5da5Sopenharmony_ci // { 382fd4e5da5Sopenharmony_ci // S_t s0; 383fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 384fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 385fd4e5da5Sopenharmony_ci // } 386fd4e5da5Sopenharmony_ci 387fd4e5da5Sopenharmony_ci const std::string predefs_before = 388fd4e5da5Sopenharmony_ci R"(OpCapability Shader 389fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 390fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 391fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 392fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 393fd4e5da5Sopenharmony_ciOpSource GLSL 140 394fd4e5da5Sopenharmony_ciOpName %main "main" 395fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 396fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 397fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 398fd4e5da5Sopenharmony_ciOpName %s0 "s0" 399fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 400fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 401fd4e5da5Sopenharmony_ci%void = OpTypeVoid 402fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 403fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 404fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 405fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 406fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 407fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 408fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 409fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 410fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 411fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 412fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 413fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 414fd4e5da5Sopenharmony_ci)"; 415fd4e5da5Sopenharmony_ci 416fd4e5da5Sopenharmony_ci const std::string before = 417fd4e5da5Sopenharmony_ci R"( 418fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 419fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0 420fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 421fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ex1]] 422fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0 423fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 424fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 425fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 426fd4e5da5Sopenharmony_ci%17 = OpLabel 427fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 428fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 429fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 430fd4e5da5Sopenharmony_ciOpStore %19 %18 431fd4e5da5Sopenharmony_ci%20 = OpLoad %v4float %19 432fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %20 433fd4e5da5Sopenharmony_ciOpReturn 434fd4e5da5Sopenharmony_ciOpFunctionEnd 435fd4e5da5Sopenharmony_ci)"; 436fd4e5da5Sopenharmony_ci 437fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 438fd4e5da5Sopenharmony_ci true); 439fd4e5da5Sopenharmony_ci} 440fd4e5da5Sopenharmony_ci 441fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, OpaqueConverted) { 442fd4e5da5Sopenharmony_ci // SPIR-V not representable in GLSL; not generatable from HLSL 443fd4e5da5Sopenharmony_ci // at the moment 444fd4e5da5Sopenharmony_ci 445fd4e5da5Sopenharmony_ci const std::string predefs = 446fd4e5da5Sopenharmony_ci R"( 447fd4e5da5Sopenharmony_ciOpCapability Shader 448fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 449fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 450fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %outColor %texCoords 451fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 452fd4e5da5Sopenharmony_ciOpSource GLSL 140 453fd4e5da5Sopenharmony_ciOpName %main "main" 454fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 455fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 456fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 457fd4e5da5Sopenharmony_ciOpMemberName %S_t 2 "smp" 458fd4e5da5Sopenharmony_ciOpName %foo_struct_S_t_vf2_vf21_ "foo(struct-S_t-vf2-vf21;" 459fd4e5da5Sopenharmony_ciOpName %s "s" 460fd4e5da5Sopenharmony_ciOpName %outColor "outColor" 461fd4e5da5Sopenharmony_ciOpName %sampler15 "sampler15" 462fd4e5da5Sopenharmony_ciOpName %s0 "s0" 463fd4e5da5Sopenharmony_ciOpName %texCoords "texCoords" 464fd4e5da5Sopenharmony_ciOpName %param "param" 465fd4e5da5Sopenharmony_ciOpDecorate %sampler15 DescriptorSet 0 466fd4e5da5Sopenharmony_ci%void = OpTypeVoid 467fd4e5da5Sopenharmony_ci%12 = OpTypeFunction %void 468fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 469fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2 470fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 471fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 472fd4e5da5Sopenharmony_ci%outColor = OpVariable %_ptr_Output_v4float Output 473fd4e5da5Sopenharmony_ci%17 = OpTypeImage %float 2D 0 0 0 1 Unknown 474fd4e5da5Sopenharmony_ci%18 = OpTypeSampledImage %17 475fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v2float %v2float %18 476fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 477fd4e5da5Sopenharmony_ci%20 = OpTypeFunction %void %_ptr_Function_S_t 478fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18 479fd4e5da5Sopenharmony_ci%_ptr_Function_18 = OpTypePointer Function %18 480fd4e5da5Sopenharmony_ci%sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant 481fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 482fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 483fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 484fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float 485fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float 486fd4e5da5Sopenharmony_ci%texCoords = OpVariable %_ptr_Input_v2float Input 487fd4e5da5Sopenharmony_ci)"; 488fd4e5da5Sopenharmony_ci 489fd4e5da5Sopenharmony_ci const std::string before = 490fd4e5da5Sopenharmony_ci R"( 491fd4e5da5Sopenharmony_ci; CHECK: [[l1:%\w+]] = OpLoad %S_t %param 492fd4e5da5Sopenharmony_ci; CHECK: [[e1:%\w+]] = OpCompositeExtract {{%\w+}} [[l1]] 2 493fd4e5da5Sopenharmony_ci; CHECK: [[l2:%\w+]] = OpLoad %S_t %param 494fd4e5da5Sopenharmony_ci; CHECK: [[e2:%\w+]] = OpCompositeExtract {{%\w+}} [[l2]] 0 495fd4e5da5Sopenharmony_ci; CHECK: OpImageSampleImplicitLod {{%\w+}} [[e1]] [[e2]] 496fd4e5da5Sopenharmony_ci%main = OpFunction %void None %12 497fd4e5da5Sopenharmony_ci%28 = OpLabel 498fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 499fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_S_t Function 500fd4e5da5Sopenharmony_ci%29 = OpLoad %v2float %texCoords 501fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Function_v2float %s0 %int_0 502fd4e5da5Sopenharmony_ciOpStore %30 %29 503fd4e5da5Sopenharmony_ci%31 = OpLoad %18 %sampler15 504fd4e5da5Sopenharmony_ci%32 = OpAccessChain %_ptr_Function_18 %s0 %int_2 505fd4e5da5Sopenharmony_ciOpStore %32 %31 506fd4e5da5Sopenharmony_ci%33 = OpLoad %S_t %s0 507fd4e5da5Sopenharmony_ciOpStore %param %33 508fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Function_18 %param %int_2 509fd4e5da5Sopenharmony_ci%35 = OpLoad %18 %34 510fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_Function_v2float %param %int_0 511fd4e5da5Sopenharmony_ci%37 = OpLoad %v2float %36 512fd4e5da5Sopenharmony_ci%38 = OpImageSampleImplicitLod %v4float %35 %37 513fd4e5da5Sopenharmony_ciOpStore %outColor %38 514fd4e5da5Sopenharmony_ciOpReturn 515fd4e5da5Sopenharmony_ciOpFunctionEnd 516fd4e5da5Sopenharmony_ci)"; 517fd4e5da5Sopenharmony_ci 518fd4e5da5Sopenharmony_ci const std::string remain = 519fd4e5da5Sopenharmony_ci R"(%foo_struct_S_t_vf2_vf21_ = OpFunction %void None %20 520fd4e5da5Sopenharmony_ci%s = OpFunctionParameter %_ptr_Function_S_t 521fd4e5da5Sopenharmony_ci%39 = OpLabel 522fd4e5da5Sopenharmony_ci%40 = OpAccessChain %_ptr_Function_18 %s %int_2 523fd4e5da5Sopenharmony_ci%41 = OpLoad %18 %40 524fd4e5da5Sopenharmony_ci%42 = OpAccessChain %_ptr_Function_v2float %s %int_0 525fd4e5da5Sopenharmony_ci%43 = OpLoad %v2float %42 526fd4e5da5Sopenharmony_ci%44 = OpImageSampleImplicitLod %v4float %41 %43 527fd4e5da5Sopenharmony_ciOpStore %outColor %44 528fd4e5da5Sopenharmony_ciOpReturn 529fd4e5da5Sopenharmony_ciOpFunctionEnd 530fd4e5da5Sopenharmony_ci)"; 531fd4e5da5Sopenharmony_ci 532fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs + before + remain, 533fd4e5da5Sopenharmony_ci true); 534fd4e5da5Sopenharmony_ci} 535fd4e5da5Sopenharmony_ci 536fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, NestedStructsConverted) { 537fd4e5da5Sopenharmony_ci // #version 140 538fd4e5da5Sopenharmony_ci // 539fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 540fd4e5da5Sopenharmony_ci // 541fd4e5da5Sopenharmony_ci // struct S1_t { 542fd4e5da5Sopenharmony_ci // vec4 v1; 543fd4e5da5Sopenharmony_ci // }; 544fd4e5da5Sopenharmony_ci // 545fd4e5da5Sopenharmony_ci // struct S2_t { 546fd4e5da5Sopenharmony_ci // vec4 v2; 547fd4e5da5Sopenharmony_ci // S1_t s1; 548fd4e5da5Sopenharmony_ci // }; 549fd4e5da5Sopenharmony_ci // 550fd4e5da5Sopenharmony_ci // void main() 551fd4e5da5Sopenharmony_ci // { 552fd4e5da5Sopenharmony_ci // S2_t s2; 553fd4e5da5Sopenharmony_ci // s2.s1.v1 = BaseColor; 554fd4e5da5Sopenharmony_ci // gl_FragColor = s2.s1.v1; 555fd4e5da5Sopenharmony_ci // } 556fd4e5da5Sopenharmony_ci 557fd4e5da5Sopenharmony_ci const std::string predefs_before = 558fd4e5da5Sopenharmony_ci R"(OpCapability Shader 559fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 560fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 561fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 562fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 563fd4e5da5Sopenharmony_ciOpSource GLSL 140 564fd4e5da5Sopenharmony_ciOpName %main "main" 565fd4e5da5Sopenharmony_ciOpName %S1_t "S1_t" 566fd4e5da5Sopenharmony_ciOpMemberName %S1_t 0 "v1" 567fd4e5da5Sopenharmony_ciOpName %S2_t "S2_t" 568fd4e5da5Sopenharmony_ciOpMemberName %S2_t 0 "v2" 569fd4e5da5Sopenharmony_ciOpMemberName %S2_t 1 "s1" 570fd4e5da5Sopenharmony_ciOpName %s2 "s2" 571fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 572fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 573fd4e5da5Sopenharmony_ci%void = OpTypeVoid 574fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %void 575fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 576fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 577fd4e5da5Sopenharmony_ci%S1_t = OpTypeStruct %v4float 578fd4e5da5Sopenharmony_ci%S2_t = OpTypeStruct %v4float %S1_t 579fd4e5da5Sopenharmony_ci%_ptr_Function_S2_t = OpTypePointer Function %S2_t 580fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 581fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 582fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 583fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 584fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 585fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 586fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 587fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 588fd4e5da5Sopenharmony_ci)"; 589fd4e5da5Sopenharmony_ci 590fd4e5da5Sopenharmony_ci const std::string before = 591fd4e5da5Sopenharmony_ci R"( 592fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 593fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S2_t %s2 594fd4e5da5Sopenharmony_ci; CHECK: [[ex1:%\w+]] = OpCompositeInsert %S2_t [[st_id]] [[ld1]] 1 0 595fd4e5da5Sopenharmony_ci; CHECK: OpStore %s2 [[ex1]] 596fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S2_t %s2 597fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 0 598fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 599fd4e5da5Sopenharmony_ci%main = OpFunction %void None %9 600fd4e5da5Sopenharmony_ci%19 = OpLabel 601fd4e5da5Sopenharmony_ci%s2 = OpVariable %_ptr_Function_S2_t Function 602fd4e5da5Sopenharmony_ci%20 = OpLoad %v4float %BaseColor 603fd4e5da5Sopenharmony_ci%21 = OpAccessChain %_ptr_Function_v4float %s2 %int_1 %int_0 604fd4e5da5Sopenharmony_ciOpStore %21 %20 605fd4e5da5Sopenharmony_ci%22 = OpAccessChain %_ptr_Function_v4float %s2 %int_1 %int_0 606fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %22 607fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23 608fd4e5da5Sopenharmony_ciOpReturn 609fd4e5da5Sopenharmony_ciOpFunctionEnd 610fd4e5da5Sopenharmony_ci)"; 611fd4e5da5Sopenharmony_ci 612fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 613fd4e5da5Sopenharmony_ci true); 614fd4e5da5Sopenharmony_ci} 615fd4e5da5Sopenharmony_ci 616fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, SomeAccessChainsHaveNoUse) { 617fd4e5da5Sopenharmony_ci // Based on HLSL source code: 618fd4e5da5Sopenharmony_ci // struct S { 619fd4e5da5Sopenharmony_ci // float f; 620fd4e5da5Sopenharmony_ci // }; 621fd4e5da5Sopenharmony_ci 622fd4e5da5Sopenharmony_ci // float main(float input : A) : B { 623fd4e5da5Sopenharmony_ci // S local = { input }; 624fd4e5da5Sopenharmony_ci // return local.f; 625fd4e5da5Sopenharmony_ci // } 626fd4e5da5Sopenharmony_ci 627fd4e5da5Sopenharmony_ci const std::string predefs = R"(OpCapability Shader 628fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 629fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %in_var_A %out_var_B 630fd4e5da5Sopenharmony_ciOpName %main "main" 631fd4e5da5Sopenharmony_ciOpName %in_var_A "in.var.A" 632fd4e5da5Sopenharmony_ciOpName %out_var_B "out.var.B" 633fd4e5da5Sopenharmony_ciOpName %S "S" 634fd4e5da5Sopenharmony_ciOpName %local "local" 635fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 636fd4e5da5Sopenharmony_ci%void = OpTypeVoid 637fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 638fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 639fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 640fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float 641fd4e5da5Sopenharmony_ci%_ptr_Output_float = OpTypePointer Output %float 642fd4e5da5Sopenharmony_ci%S = OpTypeStruct %float 643fd4e5da5Sopenharmony_ci%_ptr_Function_S = OpTypePointer Function %S 644fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 645fd4e5da5Sopenharmony_ci%in_var_A = OpVariable %_ptr_Input_float Input 646fd4e5da5Sopenharmony_ci%out_var_B = OpVariable %_ptr_Output_float Output 647fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 648fd4e5da5Sopenharmony_ci%15 = OpLabel 649fd4e5da5Sopenharmony_ci%local = OpVariable %_ptr_Function_S Function 650fd4e5da5Sopenharmony_ci%16 = OpLoad %float %in_var_A 651fd4e5da5Sopenharmony_ci%17 = OpCompositeConstruct %S %16 652fd4e5da5Sopenharmony_ciOpStore %local %17 653fd4e5da5Sopenharmony_ci)"; 654fd4e5da5Sopenharmony_ci 655fd4e5da5Sopenharmony_ci const std::string before = 656fd4e5da5Sopenharmony_ci R"( 657fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %S %local 658fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 659fd4e5da5Sopenharmony_ci; CHECK: OpStore %out_var_B [[ex]] 660fd4e5da5Sopenharmony_ci%18 = OpAccessChain %_ptr_Function_float %local %int_0 661fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_float %local %int_0 662fd4e5da5Sopenharmony_ci%20 = OpLoad %float %18 663fd4e5da5Sopenharmony_ciOpStore %out_var_B %20 664fd4e5da5Sopenharmony_ciOpReturn 665fd4e5da5Sopenharmony_ciOpFunctionEnd 666fd4e5da5Sopenharmony_ci)"; 667fd4e5da5Sopenharmony_ci 668fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs + before, true); 669fd4e5da5Sopenharmony_ci} 670fd4e5da5Sopenharmony_ci 671fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, 672fd4e5da5Sopenharmony_ci StructOfVecsOfFloatConvertedWithDecorationOnLoad) { 673fd4e5da5Sopenharmony_ci // #version 140 674fd4e5da5Sopenharmony_ci // 675fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 676fd4e5da5Sopenharmony_ci // 677fd4e5da5Sopenharmony_ci // struct S_t { 678fd4e5da5Sopenharmony_ci // vec4 v0; 679fd4e5da5Sopenharmony_ci // vec4 v1; 680fd4e5da5Sopenharmony_ci // }; 681fd4e5da5Sopenharmony_ci // 682fd4e5da5Sopenharmony_ci // void main() 683fd4e5da5Sopenharmony_ci // { 684fd4e5da5Sopenharmony_ci // S_t s0; 685fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 686fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 687fd4e5da5Sopenharmony_ci // } 688fd4e5da5Sopenharmony_ci 689fd4e5da5Sopenharmony_ci const std::string predefs_before = 690fd4e5da5Sopenharmony_ci R"(OpCapability Shader 691fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 692fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 693fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 694fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 695fd4e5da5Sopenharmony_ciOpSource GLSL 140 696fd4e5da5Sopenharmony_ciOpName %main "main" 697fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 698fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 699fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 700fd4e5da5Sopenharmony_ciOpName %s0 "s0" 701fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 702fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 703fd4e5da5Sopenharmony_ciOpDecorate %21 RelaxedPrecision 704fd4e5da5Sopenharmony_ci%void = OpTypeVoid 705fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 706fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 707fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 708fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 709fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 710fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 711fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 712fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 713fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 714fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 715fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 716fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 717fd4e5da5Sopenharmony_ci)"; 718fd4e5da5Sopenharmony_ci 719fd4e5da5Sopenharmony_ci const std::string before = 720fd4e5da5Sopenharmony_ci R"( 721fd4e5da5Sopenharmony_ci; CHECK: OpDecorate 722fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[ld2:%\w+]] RelaxedPrecision 723fd4e5da5Sopenharmony_ci; CHECK-NOT: OpDecorate 724fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 725fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %S_t %s0 726fd4e5da5Sopenharmony_ci; CHECK: [[ins:%\w+]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 727fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ins]] 728fd4e5da5Sopenharmony_ci; CHECK: [[ld2]] = OpLoad %S_t %s0 729fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 730fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 731fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 732fd4e5da5Sopenharmony_ci%17 = OpLabel 733fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 734fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 735fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 736fd4e5da5Sopenharmony_ciOpStore %19 %18 737fd4e5da5Sopenharmony_ci%20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 738fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %20 739fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 740fd4e5da5Sopenharmony_ciOpReturn 741fd4e5da5Sopenharmony_ciOpFunctionEnd 742fd4e5da5Sopenharmony_ci)"; 743fd4e5da5Sopenharmony_ci 744fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 745fd4e5da5Sopenharmony_ci true); 746fd4e5da5Sopenharmony_ci} 747fd4e5da5Sopenharmony_ci 748fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, 749fd4e5da5Sopenharmony_ci StructOfVecsOfFloatConvertedWithDecorationOnStore) { 750fd4e5da5Sopenharmony_ci // #version 140 751fd4e5da5Sopenharmony_ci // 752fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 753fd4e5da5Sopenharmony_ci // 754fd4e5da5Sopenharmony_ci // struct S_t { 755fd4e5da5Sopenharmony_ci // vec4 v0; 756fd4e5da5Sopenharmony_ci // vec4 v1; 757fd4e5da5Sopenharmony_ci // }; 758fd4e5da5Sopenharmony_ci // 759fd4e5da5Sopenharmony_ci // void main() 760fd4e5da5Sopenharmony_ci // { 761fd4e5da5Sopenharmony_ci // S_t s0; 762fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 763fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 764fd4e5da5Sopenharmony_ci // } 765fd4e5da5Sopenharmony_ci 766fd4e5da5Sopenharmony_ci const std::string predefs_before = 767fd4e5da5Sopenharmony_ci R"(OpCapability Shader 768fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 769fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 770fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor 771fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 772fd4e5da5Sopenharmony_ciOpSource GLSL 140 773fd4e5da5Sopenharmony_ciOpName %main "main" 774fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 775fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 776fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 777fd4e5da5Sopenharmony_ciOpName %s0 "s0" 778fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 779fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 780fd4e5da5Sopenharmony_ciOpDecorate %s0 RelaxedPrecision 781fd4e5da5Sopenharmony_ci%void = OpTypeVoid 782fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 783fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 784fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 785fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 786fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 787fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 788fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 789fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 790fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 791fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 792fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 793fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 794fd4e5da5Sopenharmony_ci)"; 795fd4e5da5Sopenharmony_ci 796fd4e5da5Sopenharmony_ci const std::string before = 797fd4e5da5Sopenharmony_ci R"( 798fd4e5da5Sopenharmony_ci; CHECK: OpDecorate 799fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[ld1:%\w+]] RelaxedPrecision 800fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[ins:%\w+]] RelaxedPrecision 801fd4e5da5Sopenharmony_ci; CHECK-NOT: OpDecorate 802fd4e5da5Sopenharmony_ci; CHECK: [[st_id:%\w+]] = OpLoad %v4float %BaseColor 803fd4e5da5Sopenharmony_ci; CHECK: [[ld1]] = OpLoad %S_t %s0 804fd4e5da5Sopenharmony_ci; CHECK: [[ins]] = OpCompositeInsert %S_t [[st_id]] [[ld1]] 1 805fd4e5da5Sopenharmony_ci; CHECK: OpStore %s0 [[ins]] 806fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad %S_t %s0 807fd4e5da5Sopenharmony_ci; CHECK: [[ex2:%\w+]] = OpCompositeExtract %v4float [[ld2]] 1 808fd4e5da5Sopenharmony_ci; CHECK: OpStore %gl_FragColor [[ex2]] 809fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8 810fd4e5da5Sopenharmony_ci%17 = OpLabel 811fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 812fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor 813fd4e5da5Sopenharmony_ci%19 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 814fd4e5da5Sopenharmony_ciOpStore %19 %18 815fd4e5da5Sopenharmony_ci%20 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 816fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %20 817fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21 818fd4e5da5Sopenharmony_ciOpReturn 819fd4e5da5Sopenharmony_ciOpFunctionEnd 820fd4e5da5Sopenharmony_ci)"; 821fd4e5da5Sopenharmony_ci 822fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(predefs_before + before, 823fd4e5da5Sopenharmony_ci true); 824fd4e5da5Sopenharmony_ci} 825fd4e5da5Sopenharmony_ci 826fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, DynamicallyIndexedVarNotConverted) { 827fd4e5da5Sopenharmony_ci // #version 140 828fd4e5da5Sopenharmony_ci // 829fd4e5da5Sopenharmony_ci // in vec4 BaseColor; 830fd4e5da5Sopenharmony_ci // flat in int Idx; 831fd4e5da5Sopenharmony_ci // in float Bi; 832fd4e5da5Sopenharmony_ci // 833fd4e5da5Sopenharmony_ci // struct S_t { 834fd4e5da5Sopenharmony_ci // vec4 v0; 835fd4e5da5Sopenharmony_ci // vec4 v1; 836fd4e5da5Sopenharmony_ci // }; 837fd4e5da5Sopenharmony_ci // 838fd4e5da5Sopenharmony_ci // void main() 839fd4e5da5Sopenharmony_ci // { 840fd4e5da5Sopenharmony_ci // S_t s0; 841fd4e5da5Sopenharmony_ci // s0.v1 = BaseColor; 842fd4e5da5Sopenharmony_ci // s0.v1[Idx] = Bi; 843fd4e5da5Sopenharmony_ci // gl_FragColor = s0.v1; 844fd4e5da5Sopenharmony_ci // } 845fd4e5da5Sopenharmony_ci 846fd4e5da5Sopenharmony_ci const std::string assembly = 847fd4e5da5Sopenharmony_ci R"(OpCapability Shader 848fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 849fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 850fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %Idx %Bi %gl_FragColor 851fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 852fd4e5da5Sopenharmony_ciOpSource GLSL 140 853fd4e5da5Sopenharmony_ciOpName %main "main" 854fd4e5da5Sopenharmony_ciOpName %S_t "S_t" 855fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0" 856fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1" 857fd4e5da5Sopenharmony_ciOpName %s0 "s0" 858fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor" 859fd4e5da5Sopenharmony_ciOpName %Idx "Idx" 860fd4e5da5Sopenharmony_ciOpName %Bi "Bi" 861fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor" 862fd4e5da5Sopenharmony_ciOpDecorate %Idx Flat 863fd4e5da5Sopenharmony_ci%void = OpTypeVoid 864fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 865fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 866fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 867fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float 868fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t 869fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 870fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 871fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 872fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input 873fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 874fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int 875fd4e5da5Sopenharmony_ci%Idx = OpVariable %_ptr_Input_int Input 876fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float 877fd4e5da5Sopenharmony_ci%Bi = OpVariable %_ptr_Input_float Input 878fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 879fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 880fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output 881fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 882fd4e5da5Sopenharmony_ci%22 = OpLabel 883fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function 884fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor 885fd4e5da5Sopenharmony_ci%24 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 886fd4e5da5Sopenharmony_ciOpStore %24 %23 887fd4e5da5Sopenharmony_ci%25 = OpLoad %int %Idx 888fd4e5da5Sopenharmony_ci%26 = OpLoad %float %Bi 889fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_float %s0 %int_1 %25 890fd4e5da5Sopenharmony_ciOpStore %27 %26 891fd4e5da5Sopenharmony_ci%28 = OpAccessChain %_ptr_Function_v4float %s0 %int_1 892fd4e5da5Sopenharmony_ci%29 = OpLoad %v4float %28 893fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %29 894fd4e5da5Sopenharmony_ciOpReturn 895fd4e5da5Sopenharmony_ciOpFunctionEnd 896fd4e5da5Sopenharmony_ci)"; 897fd4e5da5Sopenharmony_ci 898fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(assembly, assembly, false, 899fd4e5da5Sopenharmony_ci true); 900fd4e5da5Sopenharmony_ci} 901fd4e5da5Sopenharmony_ci 902fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, VariablePointersStorageBuffer) { 903fd4e5da5Sopenharmony_ci // A case with a storage buffer variable pointer. We should still convert 904fd4e5da5Sopenharmony_ci // the access chain on the function scope symbol. 905fd4e5da5Sopenharmony_ci const std::string test = 906fd4e5da5Sopenharmony_ci R"( 907fd4e5da5Sopenharmony_ci; CHECK: OpFunction 908fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable {{%\w+}} Function 909fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad {{%\w+}} [[var]] 910fd4e5da5Sopenharmony_ci; CHECK: OpCompositeExtract {{%\w+}} [[ld]] 0 0 911fd4e5da5Sopenharmony_ci OpCapability Shader 912fd4e5da5Sopenharmony_ci OpCapability VariablePointersStorageBuffer 913fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 914fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 915fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %2 "main" 916fd4e5da5Sopenharmony_ci OpExecutionMode %2 LocalSize 1 1 1 917fd4e5da5Sopenharmony_ci OpSource GLSL 450 918fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_3 0 Offset 0 919fd4e5da5Sopenharmony_ci OpDecorate %_struct_3 Block 920fd4e5da5Sopenharmony_ci OpDecorate %4 DescriptorSet 0 921fd4e5da5Sopenharmony_ci OpDecorate %4 Binding 0 922fd4e5da5Sopenharmony_ci OpDecorate %_ptr_StorageBuffer_int ArrayStride 4 923fd4e5da5Sopenharmony_ci OpDecorate %_arr_int_int_128 ArrayStride 4 924fd4e5da5Sopenharmony_ci %void = OpTypeVoid 925fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %void 926fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 927fd4e5da5Sopenharmony_ci %int_128 = OpConstant %int 128 928fd4e5da5Sopenharmony_ci%_arr_int_int_128 = OpTypeArray %int %int_128 929fd4e5da5Sopenharmony_ci %_struct_3 = OpTypeStruct %_arr_int_int_128 930fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3 931fd4e5da5Sopenharmony_ci%_ptr_Function__struct_3 = OpTypePointer Function %_struct_3 932fd4e5da5Sopenharmony_ci %4 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer 933fd4e5da5Sopenharmony_ci %bool = OpTypeBool 934fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 935fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 936fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 937fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int 938fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 939fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %8 940fd4e5da5Sopenharmony_ci %18 = OpLabel 941fd4e5da5Sopenharmony_ci %19 = OpVariable %_ptr_Function__struct_3 Function 942fd4e5da5Sopenharmony_ci %20 = OpAccessChain %_ptr_StorageBuffer_int %4 %int_0 %int_0 943fd4e5da5Sopenharmony_ci OpBranch %21 944fd4e5da5Sopenharmony_ci %21 = OpLabel 945fd4e5da5Sopenharmony_ci %22 = OpPhi %_ptr_StorageBuffer_int %20 %18 %23 %24 946fd4e5da5Sopenharmony_ci OpLoopMerge %25 %24 None 947fd4e5da5Sopenharmony_ci OpBranchConditional %true %26 %25 948fd4e5da5Sopenharmony_ci %26 = OpLabel 949fd4e5da5Sopenharmony_ci OpStore %22 %int_0 950fd4e5da5Sopenharmony_ci OpBranch %24 951fd4e5da5Sopenharmony_ci %24 = OpLabel 952fd4e5da5Sopenharmony_ci %23 = OpPtrAccessChain %_ptr_StorageBuffer_int %22 %int_1 953fd4e5da5Sopenharmony_ci OpBranch %21 954fd4e5da5Sopenharmony_ci %25 = OpLabel 955fd4e5da5Sopenharmony_ci %27 = OpAccessChain %_ptr_Function_int %19 %int_0 %int_0 956fd4e5da5Sopenharmony_ci %28 = OpLoad %int %27 957fd4e5da5Sopenharmony_ci OpReturn 958fd4e5da5Sopenharmony_ci OpFunctionEnd 959fd4e5da5Sopenharmony_ci)"; 960fd4e5da5Sopenharmony_ci 961fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(test, true); 962fd4e5da5Sopenharmony_ci} 963fd4e5da5Sopenharmony_ci 964fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, VariablePointers) { 965fd4e5da5Sopenharmony_ci // A case with variable pointer capability. We should not convert 966fd4e5da5Sopenharmony_ci // the access chain on the function scope symbol because the variable pointer 967fd4e5da5Sopenharmony_ci // could the analysis to miss references to function scope symbols. 968fd4e5da5Sopenharmony_ci const std::string test = 969fd4e5da5Sopenharmony_ci R"(OpCapability Shader 970fd4e5da5Sopenharmony_ciOpCapability VariablePointers 971fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 972fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 973fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %2 "main" 974fd4e5da5Sopenharmony_ciOpExecutionMode %2 LocalSize 1 1 1 975fd4e5da5Sopenharmony_ciOpSource GLSL 450 976fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_3 0 Offset 0 977fd4e5da5Sopenharmony_ciOpDecorate %_struct_3 Block 978fd4e5da5Sopenharmony_ciOpDecorate %4 DescriptorSet 0 979fd4e5da5Sopenharmony_ciOpDecorate %4 Binding 0 980fd4e5da5Sopenharmony_ciOpDecorate %_ptr_StorageBuffer_int ArrayStride 4 981fd4e5da5Sopenharmony_ciOpDecorate %_arr_int_int_128 ArrayStride 4 982fd4e5da5Sopenharmony_ci%void = OpTypeVoid 983fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void 984fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 985fd4e5da5Sopenharmony_ci%int_128 = OpConstant %int 128 986fd4e5da5Sopenharmony_ci%_arr_int_int_128 = OpTypeArray %int %int_128 987fd4e5da5Sopenharmony_ci%_struct_3 = OpTypeStruct %_arr_int_int_128 988fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3 989fd4e5da5Sopenharmony_ci%_ptr_Function__struct_3 = OpTypePointer Function %_struct_3 990fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer 991fd4e5da5Sopenharmony_ci%bool = OpTypeBool 992fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool 993fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 994fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 995fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int 996fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 997fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %8 998fd4e5da5Sopenharmony_ci%18 = OpLabel 999fd4e5da5Sopenharmony_ci%19 = OpVariable %_ptr_Function__struct_3 Function 1000fd4e5da5Sopenharmony_ci%20 = OpAccessChain %_ptr_StorageBuffer_int %4 %int_0 %int_0 1001fd4e5da5Sopenharmony_ciOpBranch %21 1002fd4e5da5Sopenharmony_ci%21 = OpLabel 1003fd4e5da5Sopenharmony_ci%22 = OpPhi %_ptr_StorageBuffer_int %20 %18 %23 %24 1004fd4e5da5Sopenharmony_ciOpLoopMerge %25 %24 None 1005fd4e5da5Sopenharmony_ciOpBranchConditional %true %26 %25 1006fd4e5da5Sopenharmony_ci%26 = OpLabel 1007fd4e5da5Sopenharmony_ciOpStore %22 %int_0 1008fd4e5da5Sopenharmony_ciOpBranch %24 1009fd4e5da5Sopenharmony_ci%24 = OpLabel 1010fd4e5da5Sopenharmony_ci%23 = OpPtrAccessChain %_ptr_StorageBuffer_int %22 %int_1 1011fd4e5da5Sopenharmony_ciOpBranch %21 1012fd4e5da5Sopenharmony_ci%25 = OpLabel 1013fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Function_int %19 %int_0 %int_0 1014fd4e5da5Sopenharmony_ci%28 = OpLoad %int %27 1015fd4e5da5Sopenharmony_ciOpReturn 1016fd4e5da5Sopenharmony_ciOpFunctionEnd 1017fd4e5da5Sopenharmony_ci)"; 1018fd4e5da5Sopenharmony_ci 1019fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(test, test, false, true); 1020fd4e5da5Sopenharmony_ci} 1021fd4e5da5Sopenharmony_ci 1022fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, IdOverflowReplacingLoad) { 1023fd4e5da5Sopenharmony_ci const std::string text = 1024fd4e5da5Sopenharmony_ci R"( 1025fd4e5da5Sopenharmony_ci OpCapability Shader 1026fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1027fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "PSMain" 1028fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1029fd4e5da5Sopenharmony_ci OpDecorate %10 Location 47360 1030fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1031fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1032fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1033fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1034fd4e5da5Sopenharmony_ci %_struct_8 = OpTypeStruct %v4float 1035fd4e5da5Sopenharmony_ci%_ptr_Function__struct_8 = OpTypePointer Function %_struct_8 1036fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 1037fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 1038fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1039fd4e5da5Sopenharmony_ci %4 = OpFunction %void None %3 1040fd4e5da5Sopenharmony_ci %5 = OpLabel 1041fd4e5da5Sopenharmony_ci %10 = OpVariable %_ptr_Function__struct_8 Function 1042fd4e5da5Sopenharmony_ci %4194301 = OpAccessChain %_ptr_Function_v4float %10 %int_0 1043fd4e5da5Sopenharmony_ci %4194302 = OpLoad %v4float %4194301 1044fd4e5da5Sopenharmony_ci OpReturn 1045fd4e5da5Sopenharmony_ci OpFunctionEnd 1046fd4e5da5Sopenharmony_ci)"; 1047fd4e5da5Sopenharmony_ci 1048fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1049fd4e5da5Sopenharmony_ci 1050fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1051fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1052fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1053fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<LocalAccessChainConvertPass>(text, true); 1054fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1055fd4e5da5Sopenharmony_ci} 1056fd4e5da5Sopenharmony_ci 1057fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, IdOverflowReplacingStore1) { 1058fd4e5da5Sopenharmony_ci const std::string text = 1059fd4e5da5Sopenharmony_ci R"( 1060fd4e5da5Sopenharmony_ci OpCapability Shader 1061fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1062fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "PSMain" 1063fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1064fd4e5da5Sopenharmony_ci OpDecorate %10 Location 47360 1065fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1066fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1067fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1068fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1069fd4e5da5Sopenharmony_ci %_struct_7 = OpTypeStruct %v4float 1070fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 1071fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 1072fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 1073fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1074fd4e5da5Sopenharmony_ci %13 = OpConstantNull %v4float 1075fd4e5da5Sopenharmony_ci %4 = OpFunction %void None %3 1076fd4e5da5Sopenharmony_ci %5 = OpLabel 1077fd4e5da5Sopenharmony_ci %10 = OpVariable %_ptr_Function__struct_7 Function 1078fd4e5da5Sopenharmony_ci %4194302 = OpAccessChain %_ptr_Function_v4float %10 %int_0 1079fd4e5da5Sopenharmony_ci OpStore %4194302 %13 1080fd4e5da5Sopenharmony_ci OpReturn 1081fd4e5da5Sopenharmony_ci OpFunctionEnd 1082fd4e5da5Sopenharmony_ci)"; 1083fd4e5da5Sopenharmony_ci 1084fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1085fd4e5da5Sopenharmony_ci 1086fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1087fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1088fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1089fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<LocalAccessChainConvertPass>(text, true); 1090fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1091fd4e5da5Sopenharmony_ci} 1092fd4e5da5Sopenharmony_ci 1093fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, IdOverflowReplacingStore2) { 1094fd4e5da5Sopenharmony_ci const std::string text = 1095fd4e5da5Sopenharmony_ci R"( 1096fd4e5da5Sopenharmony_ci OpCapability Shader 1097fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1098fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "PSMain" 1099fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1100fd4e5da5Sopenharmony_ci OpDecorate %10 Location 47360 1101fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1102fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1103fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1104fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1105fd4e5da5Sopenharmony_ci %_struct_7 = OpTypeStruct %v4float 1106fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 1107fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 1108fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 1109fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1110fd4e5da5Sopenharmony_ci %13 = OpConstantNull %v4float 1111fd4e5da5Sopenharmony_ci %4 = OpFunction %void None %3 1112fd4e5da5Sopenharmony_ci %5 = OpLabel 1113fd4e5da5Sopenharmony_ci %10 = OpVariable %_ptr_Function__struct_7 Function 1114fd4e5da5Sopenharmony_ci %4194301 = OpAccessChain %_ptr_Function_v4float %10 %int_0 1115fd4e5da5Sopenharmony_ci OpStore %4194301 %13 1116fd4e5da5Sopenharmony_ci OpReturn 1117fd4e5da5Sopenharmony_ci OpFunctionEnd 1118fd4e5da5Sopenharmony_ci)"; 1119fd4e5da5Sopenharmony_ci 1120fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 1121fd4e5da5Sopenharmony_ci 1122fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 1123fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 1124fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 1125fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<LocalAccessChainConvertPass>(text, true); 1126fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 1127fd4e5da5Sopenharmony_ci} 1128fd4e5da5Sopenharmony_ci 1129fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, AccessChainWithNoIndex) { 1130fd4e5da5Sopenharmony_ci const std::string before = 1131fd4e5da5Sopenharmony_ci R"( 1132fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1133fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 1134fd4e5da5Sopenharmony_ci; CHECK: OpStore [[var]] %true 1135fd4e5da5Sopenharmony_ci; CHECK: OpLoad %bool [[var]] 1136fd4e5da5Sopenharmony_ci OpCapability Shader 1137fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1138fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1139fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 1140fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1141fd4e5da5Sopenharmony_ci OpSource ESSL 310 1142fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1143fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 1144fd4e5da5Sopenharmony_ci %bool = OpTypeBool 1145fd4e5da5Sopenharmony_ci %true = OpConstantTrue %bool 1146fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool 1147fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 1148fd4e5da5Sopenharmony_ci %8 = OpLabel 1149fd4e5da5Sopenharmony_ci %9 = OpVariable %_ptr_Function_bool Function 1150fd4e5da5Sopenharmony_ci %10 = OpAccessChain %_ptr_Function_bool %9 1151fd4e5da5Sopenharmony_ci OpStore %10 %true 1152fd4e5da5Sopenharmony_ci %11 = OpLoad %bool %10 1153fd4e5da5Sopenharmony_ci OpReturn 1154fd4e5da5Sopenharmony_ci OpFunctionEnd 1155fd4e5da5Sopenharmony_ci)"; 1156fd4e5da5Sopenharmony_ci 1157fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(before, true); 1158fd4e5da5Sopenharmony_ci} 1159fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, AccessChainWithLongIndex) { 1160fd4e5da5Sopenharmony_ci // The access chain take a value that is larger than 32-bit. The index cannot 1161fd4e5da5Sopenharmony_ci // be encoded in an OpCompositeExtract, so nothing should be done. 1162fd4e5da5Sopenharmony_ci const std::string before = 1163fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1164fd4e5da5Sopenharmony_ciOpCapability Int64 1165fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1166fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1167fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main_0004f4d4_85b2f584" 1168fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 1169fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 1170fd4e5da5Sopenharmony_ci%ulong_8589934592 = OpConstant %ulong 8589934592 1171fd4e5da5Sopenharmony_ci%ulong_8589934591 = OpConstant %ulong 8589934591 1172fd4e5da5Sopenharmony_ci%_arr_ulong_ulong_8589934592 = OpTypeArray %ulong %ulong_8589934592 1173fd4e5da5Sopenharmony_ci%_ptr_Function__arr_ulong_ulong_8589934592 = OpTypePointer Function %_arr_ulong_ulong_8589934592 1174fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 1175fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1176fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 1177fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %10 1178fd4e5da5Sopenharmony_ci%11 = OpLabel 1179fd4e5da5Sopenharmony_ci%12 = OpVariable %_ptr_Function__arr_ulong_ulong_8589934592 Function 1180fd4e5da5Sopenharmony_ci%13 = OpAccessChain %_ptr_Function_ulong %12 %ulong_8589934591 1181fd4e5da5Sopenharmony_ci%14 = OpLoad %ulong %13 1182fd4e5da5Sopenharmony_ciOpReturn 1183fd4e5da5Sopenharmony_ciOpFunctionEnd 1184fd4e5da5Sopenharmony_ci)"; 1185fd4e5da5Sopenharmony_ci 1186fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(before, before, false, 1187fd4e5da5Sopenharmony_ci true); 1188fd4e5da5Sopenharmony_ci} 1189fd4e5da5Sopenharmony_ci 1190fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, AccessChainWith32BitIndexInLong) { 1191fd4e5da5Sopenharmony_ci // The access chain has a value that is 32-bits, but it is stored in a 64-bit 1192fd4e5da5Sopenharmony_ci // variable. This access change can be converted to an extract. 1193fd4e5da5Sopenharmony_ci const std::string before = 1194fd4e5da5Sopenharmony_ci R"( 1195fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1196fd4e5da5Sopenharmony_ci; CHECK: [[var:%\w+]] = OpVariable 1197fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad {{%\w+}} [[var]] 1198fd4e5da5Sopenharmony_ci; CHECK: OpCompositeExtract %ulong [[ld]] 3 1199fd4e5da5Sopenharmony_ci OpCapability Shader 1200fd4e5da5Sopenharmony_ci OpCapability Int64 1201fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1202fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1203fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main_0004f4d4_85b2f584" 1204fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1205fd4e5da5Sopenharmony_ci %ulong = OpTypeInt 64 0 1206fd4e5da5Sopenharmony_ci%ulong_8589934592 = OpConstant %ulong 8589934592 1207fd4e5da5Sopenharmony_ci%ulong_3 = OpConstant %ulong 3 1208fd4e5da5Sopenharmony_ci%_arr_ulong_ulong_8589934592 = OpTypeArray %ulong %ulong_8589934592 1209fd4e5da5Sopenharmony_ci%_ptr_Function__arr_ulong_ulong_8589934592 = OpTypePointer Function %_arr_ulong_ulong_8589934592 1210fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 1211fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1212fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %void 1213fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %10 1214fd4e5da5Sopenharmony_ci %11 = OpLabel 1215fd4e5da5Sopenharmony_ci %12 = OpVariable %_ptr_Function__arr_ulong_ulong_8589934592 Function 1216fd4e5da5Sopenharmony_ci %13 = OpAccessChain %_ptr_Function_ulong %12 %ulong_3 1217fd4e5da5Sopenharmony_ci %14 = OpLoad %ulong %13 1218fd4e5da5Sopenharmony_ci OpReturn 1219fd4e5da5Sopenharmony_ci OpFunctionEnd 1220fd4e5da5Sopenharmony_ci)"; 1221fd4e5da5Sopenharmony_ci 1222fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(before, true); 1223fd4e5da5Sopenharmony_ci} 1224fd4e5da5Sopenharmony_ci 1225fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, AccessChainWithVarIndex) { 1226fd4e5da5Sopenharmony_ci // The access chain has a value that is not constant, so there should not be 1227fd4e5da5Sopenharmony_ci // any changes. 1228fd4e5da5Sopenharmony_ci const std::string before = 1229fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1230fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1231fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1232fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main_0004f4d4_85b2f584" 1233fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 1234fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1235fd4e5da5Sopenharmony_ci%uint_5 = OpConstant %uint 5 1236fd4e5da5Sopenharmony_ci%_arr_uint_uint_5 = OpTypeArray %uint %uint_5 1237fd4e5da5Sopenharmony_ci%_ptr_Function__arr_uint_uint_5 = OpTypePointer Function %_arr_uint_uint_5 1238fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint 1239fd4e5da5Sopenharmony_ci%8 = OpUndef %uint 1240fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1241fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 1242fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %10 1243fd4e5da5Sopenharmony_ci%11 = OpLabel 1244fd4e5da5Sopenharmony_ci%12 = OpVariable %_ptr_Function__arr_uint_uint_5 Function 1245fd4e5da5Sopenharmony_ci%13 = OpAccessChain %_ptr_Function_uint %12 %8 1246fd4e5da5Sopenharmony_ci%14 = OpLoad %uint %13 1247fd4e5da5Sopenharmony_ciOpReturn 1248fd4e5da5Sopenharmony_ciOpFunctionEnd 1249fd4e5da5Sopenharmony_ci)"; 1250fd4e5da5Sopenharmony_ci 1251fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(before, before, false, 1252fd4e5da5Sopenharmony_ci true); 1253fd4e5da5Sopenharmony_ci} 1254fd4e5da5Sopenharmony_ci 1255fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, OutOfBoundsAccess) { 1256fd4e5da5Sopenharmony_ci // The access chain indexes element 12 in an array of size 10. Nothing should 1257fd4e5da5Sopenharmony_ci // be done. 1258fd4e5da5Sopenharmony_ci const std::string assembly = 1259fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1260fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1261fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1262fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" %3 1263fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 1264fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1265fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 1266fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1267fd4e5da5Sopenharmony_ci%int_10 = OpConstant %int 10 1268fd4e5da5Sopenharmony_ci%_arr_int_int_10 = OpTypeArray %int %int_10 1269fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1270fd4e5da5Sopenharmony_ci%int_12 = OpConstant %int 12 1271fd4e5da5Sopenharmony_ci%_ptr_Output_int = OpTypePointer Output %int 1272fd4e5da5Sopenharmony_ci%3 = OpVariable %_ptr_Output_int Output 1273fd4e5da5Sopenharmony_ci%_ptr_Function__arr_int_int_10 = OpTypePointer Function %_arr_int_int_10 1274fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 1275fd4e5da5Sopenharmony_ci%13 = OpLabel 1276fd4e5da5Sopenharmony_ci%14 = OpVariable %_ptr_Function__arr_int_int_10 Function 1277fd4e5da5Sopenharmony_ci%15 = OpAccessChain %_ptr_Function_int %14 %int_12 1278fd4e5da5Sopenharmony_ci%16 = OpLoad %int %15 1279fd4e5da5Sopenharmony_ciOpStore %3 %16 1280fd4e5da5Sopenharmony_ciOpReturn 1281fd4e5da5Sopenharmony_ciOpFunctionEnd 1282fd4e5da5Sopenharmony_ci)"; 1283fd4e5da5Sopenharmony_ci 1284fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(assembly, assembly, false, 1285fd4e5da5Sopenharmony_ci true); 1286fd4e5da5Sopenharmony_ci} 1287fd4e5da5Sopenharmony_ci 1288fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, OutOfBoundsAccessAtBoundary) { 1289fd4e5da5Sopenharmony_ci // The access chain indexes element 10 in an array of size 10. Nothing should 1290fd4e5da5Sopenharmony_ci // be done. 1291fd4e5da5Sopenharmony_ci const std::string assembly = 1292fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1293fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1294fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1295fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" %3 1296fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 1297fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1298fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %void 1299fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1300fd4e5da5Sopenharmony_ci%int_10 = OpConstant %int 10 1301fd4e5da5Sopenharmony_ci%_arr_int_int_10 = OpTypeArray %int %int_10 1302fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1303fd4e5da5Sopenharmony_ci%_ptr_Output_int = OpTypePointer Output %int 1304fd4e5da5Sopenharmony_ci%3 = OpVariable %_ptr_Output_int Output 1305fd4e5da5Sopenharmony_ci%_ptr_Function__arr_int_int_10 = OpTypePointer Function %_arr_int_int_10 1306fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %5 1307fd4e5da5Sopenharmony_ci%12 = OpLabel 1308fd4e5da5Sopenharmony_ci%13 = OpVariable %_ptr_Function__arr_int_int_10 Function 1309fd4e5da5Sopenharmony_ci%14 = OpAccessChain %_ptr_Function_int %13 %int_10 1310fd4e5da5Sopenharmony_ci%15 = OpLoad %int %14 1311fd4e5da5Sopenharmony_ciOpStore %3 %15 1312fd4e5da5Sopenharmony_ciOpReturn 1313fd4e5da5Sopenharmony_ciOpFunctionEnd 1314fd4e5da5Sopenharmony_ci)"; 1315fd4e5da5Sopenharmony_ci 1316fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(assembly, assembly, false, 1317fd4e5da5Sopenharmony_ci true); 1318fd4e5da5Sopenharmony_ci} 1319fd4e5da5Sopenharmony_ci 1320fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, NegativeIndex) { 1321fd4e5da5Sopenharmony_ci // The access chain has a negative index and should not be converted because 1322fd4e5da5Sopenharmony_ci // the extract instruction cannot hold a negative number. 1323fd4e5da5Sopenharmony_ci const std::string assembly = 1324fd4e5da5Sopenharmony_ci R"(OpCapability Shader 1325fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 1326fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1327fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" 1328fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 1329fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1330fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void 1331fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1332fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1333fd4e5da5Sopenharmony_ci%uint_3808428041 = OpConstant %uint 3808428041 1334fd4e5da5Sopenharmony_ci%_arr_int_uint_3808428041 = OpTypeArray %int %uint_3808428041 1335fd4e5da5Sopenharmony_ci%_ptr_Function__arr_int_uint_3808428041 = OpTypePointer Function %_arr_int_uint_3808428041 1336fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 1337fd4e5da5Sopenharmony_ci%int_n1272971256 = OpConstant %int -1272971256 1338fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %4 1339fd4e5da5Sopenharmony_ci%12 = OpLabel 1340fd4e5da5Sopenharmony_ci%13 = OpVariable %_ptr_Function__arr_int_uint_3808428041 Function 1341fd4e5da5Sopenharmony_ci%14 = OpAccessChain %_ptr_Function_int %13 %int_n1272971256 1342fd4e5da5Sopenharmony_ci%15 = OpLoad %int %14 1343fd4e5da5Sopenharmony_ciOpReturn 1344fd4e5da5Sopenharmony_ciOpFunctionEnd 1345fd4e5da5Sopenharmony_ci)"; 1346fd4e5da5Sopenharmony_ci 1347fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<LocalAccessChainConvertPass>(assembly, assembly, false, 1348fd4e5da5Sopenharmony_ci true); 1349fd4e5da5Sopenharmony_ci} 1350fd4e5da5Sopenharmony_ci 1351fd4e5da5Sopenharmony_ciTEST_F(LocalAccessChainConvertTest, VkMemoryModelTest) { 1352fd4e5da5Sopenharmony_ci const std::string text = 1353fd4e5da5Sopenharmony_ci R"( 1354fd4e5da5Sopenharmony_ci; CHECK: OpCapability Shader 1355fd4e5da5Sopenharmony_ci; CHECK: OpCapability VulkanMemoryModel 1356fd4e5da5Sopenharmony_ci; CHECK: OpExtension "SPV_KHR_vulkan_memory_model" 1357fd4e5da5Sopenharmony_ci OpCapability Shader 1358fd4e5da5Sopenharmony_ci OpCapability VulkanMemoryModel 1359fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_vulkan_memory_model" 1360fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1361fd4e5da5Sopenharmony_ci OpMemoryModel Logical Vulkan 1362fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %main "main" 1363fd4e5da5Sopenharmony_ci OpExecutionMode %main LocalSize 1 1 1 1364fd4e5da5Sopenharmony_ci OpSource GLSL 450 1365fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" 1366fd4e5da5Sopenharmony_ci OpSourceExtension "GL_GOOGLE_include_directive" 1367fd4e5da5Sopenharmony_ci OpName %main "main" 1368fd4e5da5Sopenharmony_ci OpName %a "a" 1369fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1370fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %void 1371fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1372fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1373fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1374fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1375fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 1376fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 1377fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 1378fd4e5da5Sopenharmony_ci; CHECK: OpFunction 1379fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 1380fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[a:%\w+]] = OpVariable 1381fd4e5da5Sopenharmony_ci; Make sure the access chains were removed. 1382fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad {{%\w+}} [[a]] 1383fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract {{%\w+}} [[ld]] 0 1384fd4e5da5Sopenharmony_ci; CHECK: [[ld2:%\w+]] = OpLoad {{%\w+}} [[a]] 1385fd4e5da5Sopenharmony_ci; CHECK: [[v:%\w+]] = OpCompositeInsert {{%\w+}} [[ex]] [[ld2]] 0 1386fd4e5da5Sopenharmony_ci; CHECK: OpStore [[a]] [[v]] 1387fd4e5da5Sopenharmony_ci %main = OpFunction %void None %3 1388fd4e5da5Sopenharmony_ci %5 = OpLabel 1389fd4e5da5Sopenharmony_ci %a = OpVariable %_ptr_Function_v4float Function 1390fd4e5da5Sopenharmony_ci %13 = OpAccessChain %_ptr_Function_float %a %uint_0 1391fd4e5da5Sopenharmony_ci %14 = OpLoad %float %13 1392fd4e5da5Sopenharmony_ci %17 = OpAccessChain %_ptr_Function_float %a %uint_0 1393fd4e5da5Sopenharmony_ci OpStore %17 %14 1394fd4e5da5Sopenharmony_ci OpReturn 1395fd4e5da5Sopenharmony_ci OpFunctionEnd 1396fd4e5da5Sopenharmony_ci)"; 1397fd4e5da5Sopenharmony_ci 1398fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<LocalAccessChainConvertPass>(text, false); 1399fd4e5da5Sopenharmony_ci} 1400fd4e5da5Sopenharmony_ci 1401fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases: 1402fd4e5da5Sopenharmony_ci// 1403fd4e5da5Sopenharmony_ci// Assorted vector and matrix types 1404fd4e5da5Sopenharmony_ci// Assorted struct array types 1405fd4e5da5Sopenharmony_ci// Assorted scalar types 1406fd4e5da5Sopenharmony_ci// Assorted non-target types 1407fd4e5da5Sopenharmony_ci// OpInBoundsAccessChain 1408fd4e5da5Sopenharmony_ci// Others? 1409fd4e5da5Sopenharmony_ci 1410fd4e5da5Sopenharmony_ci} // namespace 1411fd4e5da5Sopenharmony_ci} // namespace opt 1412fd4e5da5Sopenharmony_ci} // namespace spvtools 1413