1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc. 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 "source/opt/value_number_table.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h" 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace opt { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 28fd4e5da5Sopenharmony_ciusing ::testing::MatchesRegex; 29fd4e5da5Sopenharmony_ciusing PrivateToLocalTest = PassTest<::testing::Test>; 30fd4e5da5Sopenharmony_ci 31fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, ChangeToLocal) { 32fd4e5da5Sopenharmony_ci // Change the private variable to a local, and change the types accordingly. 33fd4e5da5Sopenharmony_ci const std::string text = R"( 34fd4e5da5Sopenharmony_ci OpCapability Shader 35fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 36fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 37fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 38fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 39fd4e5da5Sopenharmony_ci OpSource GLSL 430 40fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 41fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 42fd4e5da5Sopenharmony_ci; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32 43fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 44fd4e5da5Sopenharmony_ci; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]] 45fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %5 46fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[.+]] Private 47fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 48fd4e5da5Sopenharmony_ci; CHECK: OpFunction 49fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 50fd4e5da5Sopenharmony_ci; CHECK: OpLabel 51fd4e5da5Sopenharmony_ci %7 = OpLabel 52fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function 53fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[float]] [[newvar]] 54fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 55fd4e5da5Sopenharmony_ci OpReturn 56fd4e5da5Sopenharmony_ci OpFunctionEnd 57fd4e5da5Sopenharmony_ci )"; 58fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 59fd4e5da5Sopenharmony_ci} 60fd4e5da5Sopenharmony_ci 61fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, ReuseExistingType) { 62fd4e5da5Sopenharmony_ci // Change the private variable to a local, and change the types accordingly. 63fd4e5da5Sopenharmony_ci const std::string text = R"( 64fd4e5da5Sopenharmony_ci OpCapability Shader 65fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 66fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 67fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 68fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 69fd4e5da5Sopenharmony_ci OpSource GLSL 430 70fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 71fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 72fd4e5da5Sopenharmony_ci; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32 73fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 74fd4e5da5Sopenharmony_ci %func_ptr = OpTypePointer Function %5 75fd4e5da5Sopenharmony_ci; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]] 76fd4e5da5Sopenharmony_ci; CHECK-NOT: [[%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]] 77fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %5 78fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[.+]] Private 79fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 80fd4e5da5Sopenharmony_ci; CHECK: OpFunction 81fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 82fd4e5da5Sopenharmony_ci; CHECK: OpLabel 83fd4e5da5Sopenharmony_ci %7 = OpLabel 84fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function 85fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[float]] [[newvar]] 86fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 87fd4e5da5Sopenharmony_ci OpReturn 88fd4e5da5Sopenharmony_ci OpFunctionEnd 89fd4e5da5Sopenharmony_ci )"; 90fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 91fd4e5da5Sopenharmony_ci} 92fd4e5da5Sopenharmony_ci 93fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, UpdateAccessChain) { 94fd4e5da5Sopenharmony_ci // Change the private variable to a local, and change the AccessChain. 95fd4e5da5Sopenharmony_ci const std::string text = R"( 96fd4e5da5Sopenharmony_ci OpCapability Shader 97fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 98fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 99fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 100fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 101fd4e5da5Sopenharmony_ci OpSource GLSL 430 102fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 103fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 104fd4e5da5Sopenharmony_ci %void = OpTypeVoid 105fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %void 106fd4e5da5Sopenharmony_ci; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 107fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 108fd4e5da5Sopenharmony_ci; CHECK: [[struct:%[a-zA-Z_\d]+]] = OpTypeStruct 109fd4e5da5Sopenharmony_ci %_struct_8 = OpTypeStruct %float 110fd4e5da5Sopenharmony_ci%_ptr_Private_float = OpTypePointer Private %float 111fd4e5da5Sopenharmony_ci; CHECK: [[new_struct_type:%[a-zA-Z_\d]+]] = OpTypePointer Function [[struct]] 112fd4e5da5Sopenharmony_ci; CHECK: [[new_float_type:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]] 113fd4e5da5Sopenharmony_ci%_ptr_Private__struct_8 = OpTypePointer Private %_struct_8 114fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[.+]] Private 115fd4e5da5Sopenharmony_ci %11 = OpVariable %_ptr_Private__struct_8 Private 116fd4e5da5Sopenharmony_ci; CHECK: OpFunction 117fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %6 118fd4e5da5Sopenharmony_ci; CHECK: OpLabel 119fd4e5da5Sopenharmony_ci %12 = OpLabel 120fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[new_struct_type]] Function 121fd4e5da5Sopenharmony_ci; CHECK: [[member:%[a-zA-Z_\d]+]] = OpAccessChain [[new_float_type]] [[newvar]] 122fd4e5da5Sopenharmony_ci %13 = OpAccessChain %_ptr_Private_float %11 %uint_0 123fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[float]] [[member]] 124fd4e5da5Sopenharmony_ci %14 = OpLoad %float %13 125fd4e5da5Sopenharmony_ci OpReturn 126fd4e5da5Sopenharmony_ci OpFunctionEnd 127fd4e5da5Sopenharmony_ci )"; 128fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 129fd4e5da5Sopenharmony_ci} 130fd4e5da5Sopenharmony_ci 131fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, UseTexelPointer) { 132fd4e5da5Sopenharmony_ci // Change the private variable to a local, and change the OpImageTexelPointer. 133fd4e5da5Sopenharmony_ci const std::string text = R"( 134fd4e5da5Sopenharmony_ciOpCapability SampledBuffer 135fd4e5da5Sopenharmony_ci OpCapability StorageImageExtendedFormats 136fd4e5da5Sopenharmony_ci OpCapability ImageBuffer 137fd4e5da5Sopenharmony_ci OpCapability Shader 138fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 139fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 140fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID 141fd4e5da5Sopenharmony_ci OpExecutionMode %2 LocalSize 64 1 1 142fd4e5da5Sopenharmony_ci OpSource HLSL 600 143fd4e5da5Sopenharmony_ci OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId 144fd4e5da5Sopenharmony_ci OpDecorate %4 DescriptorSet 4 145fd4e5da5Sopenharmony_ci OpDecorate %4 Binding 70 146fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 147fd4e5da5Sopenharmony_ci %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui 148fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6 149fd4e5da5Sopenharmony_ci%_ptr_Private_6 = OpTypePointer Private %6 150fd4e5da5Sopenharmony_ci %void = OpTypeVoid 151fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %void 152fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 153fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 154fd4e5da5Sopenharmony_ci %v3uint = OpTypeVector %uint 3 155fd4e5da5Sopenharmony_ci%_ptr_Input_v3uint = OpTypePointer Input %v3uint 156fd4e5da5Sopenharmony_ci%_ptr_Image_uint = OpTypePointer Image %uint 157fd4e5da5Sopenharmony_ci %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant 158fd4e5da5Sopenharmony_ci %16 = OpVariable %_ptr_Private_6 Private 159fd4e5da5Sopenharmony_ci%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input 160fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %10 161fd4e5da5Sopenharmony_ci %17 = OpLabel 162fd4e5da5Sopenharmony_ci; Make sure the variable was moved. 163fd4e5da5Sopenharmony_ci; CHECK: OpFunction 164fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel 165fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpVariable %_ptr_Function_6 Function 166fd4e5da5Sopenharmony_ci %18 = OpLoad %6 %4 167fd4e5da5Sopenharmony_ci OpStore %16 %18 168fd4e5da5Sopenharmony_ci %19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0 169fd4e5da5Sopenharmony_ci %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1 170fd4e5da5Sopenharmony_ci OpReturn 171fd4e5da5Sopenharmony_ci OpFunctionEnd 172fd4e5da5Sopenharmony_ci )"; 173fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 174fd4e5da5Sopenharmony_ci} 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, UsedInTwoFunctions) { 177fd4e5da5Sopenharmony_ci // Should not change because it is used in multiple functions. 178fd4e5da5Sopenharmony_ci const std::string text = R"( 179fd4e5da5Sopenharmony_ci OpCapability Shader 180fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 181fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 182fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 183fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 184fd4e5da5Sopenharmony_ci OpSource GLSL 430 185fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 186fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 187fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 188fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %5 189fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 190fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 191fd4e5da5Sopenharmony_ci %7 = OpLabel 192fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 193fd4e5da5Sopenharmony_ci OpReturn 194fd4e5da5Sopenharmony_ci OpFunctionEnd 195fd4e5da5Sopenharmony_ci %10 = OpFunction %3 None %4 196fd4e5da5Sopenharmony_ci %11 = OpLabel 197fd4e5da5Sopenharmony_ci %12 = OpLoad %5 %8 198fd4e5da5Sopenharmony_ci OpReturn 199fd4e5da5Sopenharmony_ci OpFunctionEnd 200fd4e5da5Sopenharmony_ci )"; 201fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<StrengthReductionPass>( 202fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ false); 203fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 204fd4e5da5Sopenharmony_ci} 205fd4e5da5Sopenharmony_ci 206fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, UsedInFunctionCall) { 207fd4e5da5Sopenharmony_ci // Should not change because it is used in a function call. Changing the 208fd4e5da5Sopenharmony_ci // signature of the function would require cloning the function, which is not 209fd4e5da5Sopenharmony_ci // worth it. 210fd4e5da5Sopenharmony_ci const std::string text = R"( 211fd4e5da5Sopenharmony_ci OpCapability Shader 212fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 213fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 214fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 215fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 216fd4e5da5Sopenharmony_ci OpSource GLSL 430 217fd4e5da5Sopenharmony_ci %void = OpTypeVoid 218fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 219fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 220fd4e5da5Sopenharmony_ci%_ptr_Private_float = OpTypePointer Private %float 221fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void %_ptr_Private_float 222fd4e5da5Sopenharmony_ci %8 = OpVariable %_ptr_Private_float Private 223fd4e5da5Sopenharmony_ci %2 = OpFunction %void None %4 224fd4e5da5Sopenharmony_ci %9 = OpLabel 225fd4e5da5Sopenharmony_ci %10 = OpFunctionCall %void %11 %8 226fd4e5da5Sopenharmony_ci OpReturn 227fd4e5da5Sopenharmony_ci OpFunctionEnd 228fd4e5da5Sopenharmony_ci %11 = OpFunction %void None %7 229fd4e5da5Sopenharmony_ci %12 = OpFunctionParameter %_ptr_Private_float 230fd4e5da5Sopenharmony_ci %13 = OpLabel 231fd4e5da5Sopenharmony_ci %14 = OpLoad %float %12 232fd4e5da5Sopenharmony_ci OpReturn 233fd4e5da5Sopenharmony_ci OpFunctionEnd 234fd4e5da5Sopenharmony_ci )"; 235fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<StrengthReductionPass>( 236fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ false); 237fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 238fd4e5da5Sopenharmony_ci} 239fd4e5da5Sopenharmony_ci 240fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, CreatePointerToAmbiguousStruct1) { 241fd4e5da5Sopenharmony_ci // Test that the correct pointer type is picked up. 242fd4e5da5Sopenharmony_ci const std::string text = R"( 243fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%[a-zA-Z_\d]+]] = OpTypeStruct 244fd4e5da5Sopenharmony_ci; CHECK: [[struct2:%[a-zA-Z_\d]+]] = OpTypeStruct 245fd4e5da5Sopenharmony_ci; CHECK: [[priv_ptr:%[\w]+]] = OpTypePointer Private [[struct1]] 246fd4e5da5Sopenharmony_ci; CHECK: [[fuct_ptr2:%[\w]+]] = OpTypePointer Function [[struct2]] 247fd4e5da5Sopenharmony_ci; CHECK: [[fuct_ptr1:%[\w]+]] = OpTypePointer Function [[struct1]] 248fd4e5da5Sopenharmony_ci; CHECK: OpFunction 249fd4e5da5Sopenharmony_ci; CHECK: OpLabel 250fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[fuct_ptr1]] Function 251fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[struct1]] [[newvar]] 252fd4e5da5Sopenharmony_ci OpCapability Shader 253fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 254fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 255fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 256fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 257fd4e5da5Sopenharmony_ci OpSource GLSL 430 258fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 259fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 260fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 261fd4e5da5Sopenharmony_ci %struct1 = OpTypeStruct %5 262fd4e5da5Sopenharmony_ci %struct2 = OpTypeStruct %5 263fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %struct1 264fd4e5da5Sopenharmony_ci %func_ptr2 = OpTypePointer Function %struct2 265fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 266fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 267fd4e5da5Sopenharmony_ci %7 = OpLabel 268fd4e5da5Sopenharmony_ci %9 = OpLoad %struct1 %8 269fd4e5da5Sopenharmony_ci OpReturn 270fd4e5da5Sopenharmony_ci OpFunctionEnd 271fd4e5da5Sopenharmony_ci )"; 272fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 273fd4e5da5Sopenharmony_ci} 274fd4e5da5Sopenharmony_ci 275fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, CreatePointerToAmbiguousStruct2) { 276fd4e5da5Sopenharmony_ci // Test that the correct pointer type is picked up. 277fd4e5da5Sopenharmony_ci const std::string text = R"( 278fd4e5da5Sopenharmony_ci; CHECK: [[struct1:%[a-zA-Z_\d]+]] = OpTypeStruct 279fd4e5da5Sopenharmony_ci; CHECK: [[struct2:%[a-zA-Z_\d]+]] = OpTypeStruct 280fd4e5da5Sopenharmony_ci; CHECK: [[priv_ptr:%[\w]+]] = OpTypePointer Private [[struct2]] 281fd4e5da5Sopenharmony_ci; CHECK: [[fuct_ptr1:%[\w]+]] = OpTypePointer Function [[struct1]] 282fd4e5da5Sopenharmony_ci; CHECK: [[fuct_ptr2:%[\w]+]] = OpTypePointer Function [[struct2]] 283fd4e5da5Sopenharmony_ci; CHECK: OpFunction 284fd4e5da5Sopenharmony_ci; CHECK: OpLabel 285fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[fuct_ptr2]] Function 286fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[struct2]] [[newvar]] 287fd4e5da5Sopenharmony_ci OpCapability Shader 288fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 289fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 290fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 291fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 292fd4e5da5Sopenharmony_ci OpSource GLSL 430 293fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 294fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 295fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 296fd4e5da5Sopenharmony_ci %struct1 = OpTypeStruct %5 297fd4e5da5Sopenharmony_ci %struct2 = OpTypeStruct %5 298fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %struct2 299fd4e5da5Sopenharmony_ci %func_ptr2 = OpTypePointer Function %struct1 300fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 301fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 302fd4e5da5Sopenharmony_ci %7 = OpLabel 303fd4e5da5Sopenharmony_ci %9 = OpLoad %struct2 %8 304fd4e5da5Sopenharmony_ci OpReturn 305fd4e5da5Sopenharmony_ci OpFunctionEnd 306fd4e5da5Sopenharmony_ci )"; 307fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, false); 308fd4e5da5Sopenharmony_ci} 309fd4e5da5Sopenharmony_ci 310fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, SPV14RemoveFromInterface) { 311fd4e5da5Sopenharmony_ci const std::string text = R"( 312fd4e5da5Sopenharmony_ci; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv 313fd4e5da5Sopenharmony_ci; CHECK: OpEntryPoint GLCompute %foo "foo" %in 314fd4e5da5Sopenharmony_ci; CHECK: %priv = OpVariable {{%\w+}} Function 315fd4e5da5Sopenharmony_ciOpCapability Shader 316fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 317fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %foo "foo" %in %priv 318fd4e5da5Sopenharmony_ciOpExecutionMode %foo LocalSize 1 1 1 319fd4e5da5Sopenharmony_ciOpName %foo "foo" 320fd4e5da5Sopenharmony_ciOpName %in "in" 321fd4e5da5Sopenharmony_ciOpName %priv "priv" 322fd4e5da5Sopenharmony_ci%void = OpTypeVoid 323fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 324fd4e5da5Sopenharmony_ci%ptr_ssbo_int = OpTypePointer StorageBuffer %int 325fd4e5da5Sopenharmony_ci%ptr_private_int = OpTypePointer Private %int 326fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_int StorageBuffer 327fd4e5da5Sopenharmony_ci%priv = OpVariable %ptr_private_int Private 328fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 329fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 330fd4e5da5Sopenharmony_ci%entry = OpLabel 331fd4e5da5Sopenharmony_ci%ld = OpLoad %int %in 332fd4e5da5Sopenharmony_ciOpStore %priv %ld 333fd4e5da5Sopenharmony_ciOpReturn 334fd4e5da5Sopenharmony_ciOpFunctionEnd 335fd4e5da5Sopenharmony_ci)"; 336fd4e5da5Sopenharmony_ci 337fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 338fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, true); 339fd4e5da5Sopenharmony_ci} 340fd4e5da5Sopenharmony_ci 341fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, SPV14RemoveFromInterfaceMultipleEntryPoints) { 342fd4e5da5Sopenharmony_ci const std::string text = R"( 343fd4e5da5Sopenharmony_ci; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv 344fd4e5da5Sopenharmony_ci; CHECK-NOT: OpEntryPoint GLCompute %foo "bar" %in %priv 345fd4e5da5Sopenharmony_ci; CHECK: OpEntryPoint GLCompute %foo "foo" %in 346fd4e5da5Sopenharmony_ci; CHECK: OpEntryPoint GLCompute %foo "bar" %in 347fd4e5da5Sopenharmony_ci; CHECK: %priv = OpVariable {{%\w+}} Function 348fd4e5da5Sopenharmony_ciOpCapability Shader 349fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 350fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %foo "foo" %in %priv 351fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %foo "bar" %in %priv 352fd4e5da5Sopenharmony_ciOpExecutionMode %foo LocalSize 1 1 1 353fd4e5da5Sopenharmony_ciOpName %foo "foo" 354fd4e5da5Sopenharmony_ciOpName %in "in" 355fd4e5da5Sopenharmony_ciOpName %priv "priv" 356fd4e5da5Sopenharmony_ci%void = OpTypeVoid 357fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 358fd4e5da5Sopenharmony_ci%ptr_ssbo_int = OpTypePointer StorageBuffer %int 359fd4e5da5Sopenharmony_ci%ptr_private_int = OpTypePointer Private %int 360fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_int StorageBuffer 361fd4e5da5Sopenharmony_ci%priv = OpVariable %ptr_private_int Private 362fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 363fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 364fd4e5da5Sopenharmony_ci%entry = OpLabel 365fd4e5da5Sopenharmony_ci%ld = OpLoad %int %in 366fd4e5da5Sopenharmony_ciOpStore %priv %ld 367fd4e5da5Sopenharmony_ciOpReturn 368fd4e5da5Sopenharmony_ciOpFunctionEnd 369fd4e5da5Sopenharmony_ci)"; 370fd4e5da5Sopenharmony_ci 371fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 372fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, true); 373fd4e5da5Sopenharmony_ci} 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, SPV14RemoveFromInterfaceMultipleVariables) { 376fd4e5da5Sopenharmony_ci const std::string text = R"( 377fd4e5da5Sopenharmony_ci; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv1 %priv2 378fd4e5da5Sopenharmony_ci; CHECK: OpEntryPoint GLCompute %foo "foo" %in 379fd4e5da5Sopenharmony_ci; CHECK: %priv1 = OpVariable {{%\w+}} Function 380fd4e5da5Sopenharmony_ci; CHECK: %priv2 = OpVariable {{%\w+}} Function 381fd4e5da5Sopenharmony_ciOpCapability Shader 382fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 383fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %foo "foo" %in %priv1 %priv2 384fd4e5da5Sopenharmony_ciOpExecutionMode %foo LocalSize 1 1 1 385fd4e5da5Sopenharmony_ciOpName %foo "foo" 386fd4e5da5Sopenharmony_ciOpName %in "in" 387fd4e5da5Sopenharmony_ciOpName %priv1 "priv1" 388fd4e5da5Sopenharmony_ciOpName %priv2 "priv2" 389fd4e5da5Sopenharmony_ci%void = OpTypeVoid 390fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 391fd4e5da5Sopenharmony_ci%ptr_ssbo_int = OpTypePointer StorageBuffer %int 392fd4e5da5Sopenharmony_ci%ptr_private_int = OpTypePointer Private %int 393fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_int StorageBuffer 394fd4e5da5Sopenharmony_ci%priv1 = OpVariable %ptr_private_int Private 395fd4e5da5Sopenharmony_ci%priv2 = OpVariable %ptr_private_int Private 396fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 397fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 398fd4e5da5Sopenharmony_ci%entry = OpLabel 399fd4e5da5Sopenharmony_ci%1 = OpFunctionCall %void %bar1 400fd4e5da5Sopenharmony_ci%2 = OpFunctionCall %void %bar2 401fd4e5da5Sopenharmony_ciOpReturn 402fd4e5da5Sopenharmony_ciOpFunctionEnd 403fd4e5da5Sopenharmony_ci%bar1 = OpFunction %void None %void_fn 404fd4e5da5Sopenharmony_ci%3 = OpLabel 405fd4e5da5Sopenharmony_ci%ld1 = OpLoad %int %in 406fd4e5da5Sopenharmony_ciOpStore %priv1 %ld1 407fd4e5da5Sopenharmony_ciOpReturn 408fd4e5da5Sopenharmony_ciOpFunctionEnd 409fd4e5da5Sopenharmony_ci%bar2 = OpFunction %void None %void_fn 410fd4e5da5Sopenharmony_ci%4 = OpLabel 411fd4e5da5Sopenharmony_ci%ld2 = OpLoad %int %in 412fd4e5da5Sopenharmony_ciOpStore %priv2 %ld2 413fd4e5da5Sopenharmony_ciOpReturn 414fd4e5da5Sopenharmony_ciOpFunctionEnd 415fd4e5da5Sopenharmony_ci)"; 416fd4e5da5Sopenharmony_ci 417fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 418fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, true); 419fd4e5da5Sopenharmony_ci} 420fd4e5da5Sopenharmony_ci 421fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, IdBoundOverflow1) { 422fd4e5da5Sopenharmony_ci const std::string text = R"( 423fd4e5da5Sopenharmony_ci OpCapability Shader 424fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 425fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 426fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginLowerLeft 427fd4e5da5Sopenharmony_ci OpSource HLSL 84 428fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 429fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 430fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 431fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 432fd4e5da5Sopenharmony_ci %8 = OpTypeStruct %7 433fd4e5da5Sopenharmony_ci %4194302 = OpTypeStruct %8 %8 434fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %8 %8 435fd4e5da5Sopenharmony_ci %11 = OpTypePointer Private %7 436fd4e5da5Sopenharmony_ci %18 = OpTypeStruct %6 %9 437fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Private 438fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 439fd4e5da5Sopenharmony_ci %5 = OpLabel 440fd4e5da5Sopenharmony_ci %13 = OpLoad %7 %12 441fd4e5da5Sopenharmony_ci OpReturn 442fd4e5da5Sopenharmony_ci OpFunctionEnd 443fd4e5da5Sopenharmony_ci )"; 444fd4e5da5Sopenharmony_ci 445fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 446fd4e5da5Sopenharmony_ci 447fd4e5da5Sopenharmony_ci std::vector<Message> messages = { 448fd4e5da5Sopenharmony_ci {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}}; 449fd4e5da5Sopenharmony_ci SetMessageConsumer(GetTestMessageConsumer(messages)); 450fd4e5da5Sopenharmony_ci auto result = SinglePassRunToBinary<PrivateToLocalPass>(text, true); 451fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::Failure, std::get<1>(result)); 452fd4e5da5Sopenharmony_ci} 453fd4e5da5Sopenharmony_ci 454fd4e5da5Sopenharmony_ciTEST_F(PrivateToLocalTest, DebugPrivateToLocal) { 455fd4e5da5Sopenharmony_ci // Debug instructions must not have any impact on changing the private 456fd4e5da5Sopenharmony_ci // variable to a local. 457fd4e5da5Sopenharmony_ci const std::string text = R"( 458fd4e5da5Sopenharmony_ci OpCapability Shader 459fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 460fd4e5da5Sopenharmony_ci %10 = OpExtInstImport "OpenCL.DebugInfo.100" 461fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 462fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 463fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 464fd4e5da5Sopenharmony_ci %11 = OpString "test" 465fd4e5da5Sopenharmony_ci OpSource GLSL 430 466fd4e5da5Sopenharmony_ci %13 = OpTypeInt 32 0 467fd4e5da5Sopenharmony_ci %14 = OpConstant %13 32 468fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 469fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 470fd4e5da5Sopenharmony_ci; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32 471fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 472fd4e5da5Sopenharmony_ci; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]] 473fd4e5da5Sopenharmony_ci %6 = OpTypePointer Private %5 474fd4e5da5Sopenharmony_ci; CHECK-NOT: OpVariable [[.+]] Private 475fd4e5da5Sopenharmony_ci %8 = OpVariable %6 Private 476fd4e5da5Sopenharmony_ci 477fd4e5da5Sopenharmony_ci %12 = OpExtInst %3 %10 DebugTypeBasic %11 %14 Float 478fd4e5da5Sopenharmony_ci %15 = OpExtInst %3 %10 DebugSource %11 479fd4e5da5Sopenharmony_ci %16 = OpExtInst %3 %10 DebugCompilationUnit 1 4 %15 GLSL 480fd4e5da5Sopenharmony_ci; CHECK-NOT: DebugGlobalVariable 481fd4e5da5Sopenharmony_ci; CHECK: [[dbg_newvar:%[a-zA-Z_\d]+]] = OpExtInst {{%\w+}} {{%\w+}} DebugLocalVariable 482fd4e5da5Sopenharmony_ci %17 = OpExtInst %3 %10 DebugGlobalVariable %11 %12 %15 0 0 %16 %11 %8 FlagIsDefinition 483fd4e5da5Sopenharmony_ci 484fd4e5da5Sopenharmony_ci; CHECK: OpFunction 485fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 486fd4e5da5Sopenharmony_ci; CHECK: OpLabel 487fd4e5da5Sopenharmony_ci %7 = OpLabel 488fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function 489fd4e5da5Sopenharmony_ci; CHECK-NEXT: DebugDeclare [[dbg_newvar]] [[newvar]] 490fd4e5da5Sopenharmony_ci; CHECK: OpLoad [[float]] [[newvar]] 491fd4e5da5Sopenharmony_ci %9 = OpLoad %5 %8 492fd4e5da5Sopenharmony_ci OpReturn 493fd4e5da5Sopenharmony_ci OpFunctionEnd 494fd4e5da5Sopenharmony_ci )"; 495fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<PrivateToLocalPass>(text, true); 496fd4e5da5Sopenharmony_ci} 497fd4e5da5Sopenharmony_ci 498fd4e5da5Sopenharmony_ci} // namespace 499fd4e5da5Sopenharmony_ci} // namespace opt 500fd4e5da5Sopenharmony_ci} // namespace spvtools 501