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