1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include "assembly_builder.h" 16fd4e5da5Sopenharmony_ci#include "pass_fixture.h" 17fd4e5da5Sopenharmony_ci#include "pass_utils.h" 18fd4e5da5Sopenharmony_ci 19fd4e5da5Sopenharmony_cinamespace { 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_ciusing namespace spvtools; 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_ciusing EliminateDeadMemberTest = opt::PassTest<::testing::Test>; 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMember1) { 26fd4e5da5Sopenharmony_ci // Test that the member "y" is removed. 27fd4e5da5Sopenharmony_ci // Update OpMemberName for |y| and |z|. 28fd4e5da5Sopenharmony_ci // Update OpMemberDecorate for |y| and |z|. 29fd4e5da5Sopenharmony_ci // Update OpAccessChain for access to |z|. 30fd4e5da5Sopenharmony_ci const std::string text = R"( 31fd4e5da5Sopenharmony_ci; CHECK: OpName 32fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x" 33fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 34fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 35fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0 36fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8 37fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 38fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0 39fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1 40fd4e5da5Sopenharmony_ci OpCapability Shader 41fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 42fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position 43fd4e5da5Sopenharmony_ci OpSource HLSL 600 44fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 45fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 46fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 47fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 48fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 49fd4e5da5Sopenharmony_ci OpName %in_var_Position "in.var.Position" 50fd4e5da5Sopenharmony_ci OpName %main "main" 51fd4e5da5Sopenharmony_ci OpDecorate %gl_Position BuiltIn Position 52fd4e5da5Sopenharmony_ci OpDecorate %in_var_Position Location 0 53fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 54fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 55fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 56fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 57fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 58fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 59fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 60fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 61fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 62fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 63fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 64fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 65fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 66fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 67fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 68fd4e5da5Sopenharmony_ci %void = OpTypeVoid 69fd4e5da5Sopenharmony_ci %15 = OpTypeFunction %void 70fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 71fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 72fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input 73fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output 74fd4e5da5Sopenharmony_ci %main = OpFunction %void None %15 75fd4e5da5Sopenharmony_ci %17 = OpLabel 76fd4e5da5Sopenharmony_ci %18 = OpLoad %v4float %in_var_Position 77fd4e5da5Sopenharmony_ci %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0 78fd4e5da5Sopenharmony_ci %20 = OpLoad %float %19 79fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %float %18 0 80fd4e5da5Sopenharmony_ci %22 = OpFAdd %float %21 %20 81fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %v4float %22 %18 0 82fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %float %18 1 83fd4e5da5Sopenharmony_ci %25 = OpCompositeInsert %v4float %24 %23 1 84fd4e5da5Sopenharmony_ci %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2 85fd4e5da5Sopenharmony_ci %27 = OpLoad %float %26 86fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %float %18 2 87fd4e5da5Sopenharmony_ci %29 = OpFAdd %float %28 %27 88fd4e5da5Sopenharmony_ci %30 = OpCompositeInsert %v4float %29 %25 2 89fd4e5da5Sopenharmony_ci OpStore %gl_Position %30 90fd4e5da5Sopenharmony_ci OpReturn 91fd4e5da5Sopenharmony_ci OpFunctionEnd 92fd4e5da5Sopenharmony_ci)"; 93fd4e5da5Sopenharmony_ci 94fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 95fd4e5da5Sopenharmony_ci} 96fd4e5da5Sopenharmony_ci 97fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberWithGroupDecorations) { 98fd4e5da5Sopenharmony_ci // Test that the member "y" is removed. 99fd4e5da5Sopenharmony_ci // Update OpGroupMemberDecorate for %type__Globals member 1 and 2. 100fd4e5da5Sopenharmony_ci // Update OpAccessChain for access to %type__Globals member 2. 101fd4e5da5Sopenharmony_ci const std::string text = R"( 102fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr1:%\w+]] Offset 0 103fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr2:%\w+]] Offset 4 104fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[gr3:%\w+]] Offset 8 105fd4e5da5Sopenharmony_ci; CHECK: [[gr1]] = OpDecorationGroup 106fd4e5da5Sopenharmony_ci; CHECK: [[gr2]] = OpDecorationGroup 107fd4e5da5Sopenharmony_ci; CHECK: [[gr3]] = OpDecorationGroup 108fd4e5da5Sopenharmony_ci; CHECK: OpGroupMemberDecorate [[gr1]] %type__Globals 0 109fd4e5da5Sopenharmony_ci; CHECK-NOT: OpGroupMemberDecorate [[gr2]] 110fd4e5da5Sopenharmony_ci; CHECK: OpGroupMemberDecorate [[gr3]] %type__Globals 1 111fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 112fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0 113fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1 114fd4e5da5Sopenharmony_ci OpCapability Shader 115fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 116fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position 117fd4e5da5Sopenharmony_ci OpSource HLSL 600 118fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 119fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 120fd4e5da5Sopenharmony_ci OpDecorate %gl_Position BuiltIn Position 121fd4e5da5Sopenharmony_ci OpDecorate %in_var_Position Location 0 122fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 123fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 124fd4e5da5Sopenharmony_ci OpDecorate %gr1 Offset 0 125fd4e5da5Sopenharmony_ci OpDecorate %gr2 Offset 4 126fd4e5da5Sopenharmony_ci OpDecorate %gr3 Offset 8 127fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 128fd4e5da5Sopenharmony_ci %gr1 = OpDecorationGroup 129fd4e5da5Sopenharmony_ci %gr2 = OpDecorationGroup 130fd4e5da5Sopenharmony_ci %gr3 = OpDecorationGroup 131fd4e5da5Sopenharmony_ci OpGroupMemberDecorate %gr1 %type__Globals 0 132fd4e5da5Sopenharmony_ci OpGroupMemberDecorate %gr2 %type__Globals 1 133fd4e5da5Sopenharmony_ci OpGroupMemberDecorate %gr3 %type__Globals 2 134fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 135fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 136fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 137fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 138fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 139fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 140fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 141fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 142fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 143fd4e5da5Sopenharmony_ci %void = OpTypeVoid 144fd4e5da5Sopenharmony_ci %15 = OpTypeFunction %void 145fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 146fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 147fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input 148fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output 149fd4e5da5Sopenharmony_ci %main = OpFunction %void None %15 150fd4e5da5Sopenharmony_ci %17 = OpLabel 151fd4e5da5Sopenharmony_ci %18 = OpLoad %v4float %in_var_Position 152fd4e5da5Sopenharmony_ci %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0 153fd4e5da5Sopenharmony_ci %20 = OpLoad %float %19 154fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %float %18 0 155fd4e5da5Sopenharmony_ci %22 = OpFAdd %float %21 %20 156fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %v4float %22 %18 0 157fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %float %18 1 158fd4e5da5Sopenharmony_ci %25 = OpCompositeInsert %v4float %24 %23 1 159fd4e5da5Sopenharmony_ci %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2 160fd4e5da5Sopenharmony_ci %27 = OpLoad %float %26 161fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %float %18 2 162fd4e5da5Sopenharmony_ci %29 = OpFAdd %float %28 %27 163fd4e5da5Sopenharmony_ci %30 = OpCompositeInsert %v4float %29 %25 2 164fd4e5da5Sopenharmony_ci OpStore %gl_Position %30 165fd4e5da5Sopenharmony_ci OpReturn 166fd4e5da5Sopenharmony_ci OpFunctionEnd 167fd4e5da5Sopenharmony_ci)"; 168fd4e5da5Sopenharmony_ci 169fd4e5da5Sopenharmony_ci // Skipping validation because of a bug in the validator. See issue #2376. 170fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, false); 171fd4e5da5Sopenharmony_ci} 172fd4e5da5Sopenharmony_ci 173fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberUpdateConstant) { 174fd4e5da5Sopenharmony_ci // Test that the member "x" is removed. 175fd4e5da5Sopenharmony_ci // Update the OpConstantComposite instruction. 176fd4e5da5Sopenharmony_ci const std::string text = R"( 177fd4e5da5Sopenharmony_ci; CHECK: OpName 178fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 179fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 180fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 181fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 182fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8 183fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 184fd4e5da5Sopenharmony_ci; CHECK: OpConstantComposite %type__Globals %float_1 %float_2 185fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0 186fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1 187fd4e5da5Sopenharmony_ci OpCapability Shader 188fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 189fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position 190fd4e5da5Sopenharmony_ci OpSource HLSL 600 191fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 192fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 193fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 194fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 195fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 196fd4e5da5Sopenharmony_ci OpName %in_var_Position "in.var.Position" 197fd4e5da5Sopenharmony_ci OpName %main "main" 198fd4e5da5Sopenharmony_ci OpDecorate %gl_Position BuiltIn Position 199fd4e5da5Sopenharmony_ci OpDecorate %in_var_Position Location 0 200fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 201fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 202fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 203fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 204fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 205fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 206fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 207fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 208fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 209fd4e5da5Sopenharmony_ci %float_0 = OpConstant %float 0 210fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 211fd4e5da5Sopenharmony_ci %float_2 = OpConstant %float 2 212fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 213fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 214fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %type__Globals %float_0 %float_1 %float_2 215fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 216fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 217fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 218fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 219fd4e5da5Sopenharmony_ci %void = OpTypeVoid 220fd4e5da5Sopenharmony_ci %19 = OpTypeFunction %void 221fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 222fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 223fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input 224fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output 225fd4e5da5Sopenharmony_ci %main = OpFunction %void None %19 226fd4e5da5Sopenharmony_ci %21 = OpLabel 227fd4e5da5Sopenharmony_ci %22 = OpLoad %v4float %in_var_Position 228fd4e5da5Sopenharmony_ci %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1 229fd4e5da5Sopenharmony_ci %24 = OpLoad %float %23 230fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %float %22 0 231fd4e5da5Sopenharmony_ci %26 = OpFAdd %float %25 %24 232fd4e5da5Sopenharmony_ci %27 = OpCompositeInsert %v4float %26 %22 0 233fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %float %22 1 234fd4e5da5Sopenharmony_ci %29 = OpCompositeInsert %v4float %28 %27 1 235fd4e5da5Sopenharmony_ci %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2 236fd4e5da5Sopenharmony_ci %31 = OpLoad %float %30 237fd4e5da5Sopenharmony_ci %32 = OpCompositeExtract %float %22 2 238fd4e5da5Sopenharmony_ci %33 = OpFAdd %float %32 %31 239fd4e5da5Sopenharmony_ci %34 = OpCompositeInsert %v4float %33 %29 2 240fd4e5da5Sopenharmony_ci OpStore %gl_Position %34 241fd4e5da5Sopenharmony_ci OpReturn 242fd4e5da5Sopenharmony_ci OpFunctionEnd 243fd4e5da5Sopenharmony_ci)"; 244fd4e5da5Sopenharmony_ci 245fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 246fd4e5da5Sopenharmony_ci} 247fd4e5da5Sopenharmony_ci 248fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberUpdateCompositeConstruct) { 249fd4e5da5Sopenharmony_ci // Test that the member "x" is removed. 250fd4e5da5Sopenharmony_ci // Update the OpConstantComposite instruction. 251fd4e5da5Sopenharmony_ci const std::string text = R"( 252fd4e5da5Sopenharmony_ci; CHECK: OpName 253fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 254fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 255fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 256fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 257fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8 258fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 259fd4e5da5Sopenharmony_ci; CHECK: OpCompositeConstruct %type__Globals %float_1 %float_2 260fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0 261fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1 262fd4e5da5Sopenharmony_ci OpCapability Shader 263fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 264fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position 265fd4e5da5Sopenharmony_ci OpSource HLSL 600 266fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 267fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 268fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 269fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 270fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 271fd4e5da5Sopenharmony_ci OpName %in_var_Position "in.var.Position" 272fd4e5da5Sopenharmony_ci OpName %main "main" 273fd4e5da5Sopenharmony_ci OpDecorate %gl_Position BuiltIn Position 274fd4e5da5Sopenharmony_ci OpDecorate %in_var_Position Location 0 275fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 276fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 277fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 278fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 279fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 280fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 281fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 282fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 283fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 284fd4e5da5Sopenharmony_ci %float_0 = OpConstant %float 0 285fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 286fd4e5da5Sopenharmony_ci %float_2 = OpConstant %float 2 287fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 288fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 289fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 290fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 291fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 292fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 293fd4e5da5Sopenharmony_ci %void = OpTypeVoid 294fd4e5da5Sopenharmony_ci %19 = OpTypeFunction %void 295fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 296fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 297fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input 298fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output 299fd4e5da5Sopenharmony_ci %main = OpFunction %void None %19 300fd4e5da5Sopenharmony_ci %21 = OpLabel 301fd4e5da5Sopenharmony_ci %13 = OpCompositeConstruct %type__Globals %float_0 %float_1 %float_2 302fd4e5da5Sopenharmony_ci %22 = OpLoad %v4float %in_var_Position 303fd4e5da5Sopenharmony_ci %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1 304fd4e5da5Sopenharmony_ci %24 = OpLoad %float %23 305fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %float %22 0 306fd4e5da5Sopenharmony_ci %26 = OpFAdd %float %25 %24 307fd4e5da5Sopenharmony_ci %27 = OpCompositeInsert %v4float %26 %22 0 308fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %float %22 1 309fd4e5da5Sopenharmony_ci %29 = OpCompositeInsert %v4float %28 %27 1 310fd4e5da5Sopenharmony_ci %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2 311fd4e5da5Sopenharmony_ci %31 = OpLoad %float %30 312fd4e5da5Sopenharmony_ci %32 = OpCompositeExtract %float %22 2 313fd4e5da5Sopenharmony_ci %33 = OpFAdd %float %32 %31 314fd4e5da5Sopenharmony_ci %34 = OpCompositeInsert %v4float %33 %29 2 315fd4e5da5Sopenharmony_ci OpStore %gl_Position %34 316fd4e5da5Sopenharmony_ci OpReturn 317fd4e5da5Sopenharmony_ci OpFunctionEnd 318fd4e5da5Sopenharmony_ci)"; 319fd4e5da5Sopenharmony_ci 320fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 321fd4e5da5Sopenharmony_ci} 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract1) { 324fd4e5da5Sopenharmony_ci // Test that the members "x" and "z" are removed. 325fd4e5da5Sopenharmony_ci // Update the OpCompositeExtract instruction. 326fd4e5da5Sopenharmony_ci // Remove the OpCompositeInsert instruction since the member being inserted is 327fd4e5da5Sopenharmony_ci // dead. 328fd4e5da5Sopenharmony_ci const std::string text = R"( 329fd4e5da5Sopenharmony_ci; CHECK: OpName 330fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 331fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 332fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 333fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset 334fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float 335fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals 336fd4e5da5Sopenharmony_ci; CHECK: OpCompositeExtract %float [[ld]] 0 337fd4e5da5Sopenharmony_ci; CHECK-NOT: OpCompositeInsert 338fd4e5da5Sopenharmony_ci; CHECK: OpReturn 339fd4e5da5Sopenharmony_ci OpCapability Shader 340fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 341fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 342fd4e5da5Sopenharmony_ci OpSource HLSL 600 343fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 344fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 345fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 346fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 347fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 348fd4e5da5Sopenharmony_ci OpName %main "main" 349fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 350fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 351fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 352fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 353fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 354fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 355fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 356fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 357fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 358fd4e5da5Sopenharmony_ci %void = OpTypeVoid 359fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void 360fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 361fd4e5da5Sopenharmony_ci %main = OpFunction %void None %7 362fd4e5da5Sopenharmony_ci %8 = OpLabel 363fd4e5da5Sopenharmony_ci %9 = OpLoad %type__Globals %_Globals 364fd4e5da5Sopenharmony_ci %10 = OpCompositeExtract %float %9 1 365fd4e5da5Sopenharmony_ci %11 = OpCompositeInsert %type__Globals %10 %9 2 366fd4e5da5Sopenharmony_ci OpReturn 367fd4e5da5Sopenharmony_ci OpFunctionEnd 368fd4e5da5Sopenharmony_ci 369fd4e5da5Sopenharmony_ci)"; 370fd4e5da5Sopenharmony_ci 371fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 372fd4e5da5Sopenharmony_ci} 373fd4e5da5Sopenharmony_ci 374fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract2) { 375fd4e5da5Sopenharmony_ci // Test that the members "x" and "z" are removed. 376fd4e5da5Sopenharmony_ci // Update the OpCompositeExtract instruction. 377fd4e5da5Sopenharmony_ci // Update the OpCompositeInsert instruction. 378fd4e5da5Sopenharmony_ci const std::string text = R"( 379fd4e5da5Sopenharmony_ci; CHECK: OpName 380fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 381fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 382fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 383fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset 384fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float 385fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals 386fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 387fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 388fd4e5da5Sopenharmony_ci; CHECK: OpReturn 389fd4e5da5Sopenharmony_ci OpCapability Shader 390fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 391fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 392fd4e5da5Sopenharmony_ci OpSource HLSL 600 393fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 394fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 395fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 396fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 397fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 398fd4e5da5Sopenharmony_ci OpName %main "main" 399fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 400fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 401fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 402fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 403fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 404fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 405fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 406fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 407fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 408fd4e5da5Sopenharmony_ci %void = OpTypeVoid 409fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void 410fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 411fd4e5da5Sopenharmony_ci %main = OpFunction %void None %7 412fd4e5da5Sopenharmony_ci %8 = OpLabel 413fd4e5da5Sopenharmony_ci %9 = OpLoad %type__Globals %_Globals 414fd4e5da5Sopenharmony_ci %10 = OpCompositeExtract %float %9 1 415fd4e5da5Sopenharmony_ci %11 = OpCompositeInsert %type__Globals %10 %9 1 416fd4e5da5Sopenharmony_ci OpReturn 417fd4e5da5Sopenharmony_ci OpFunctionEnd 418fd4e5da5Sopenharmony_ci 419fd4e5da5Sopenharmony_ci)"; 420fd4e5da5Sopenharmony_ci 421fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 422fd4e5da5Sopenharmony_ci} 423fd4e5da5Sopenharmony_ci 424fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract3) { 425fd4e5da5Sopenharmony_ci // Test that the members "x" and "z" are removed, and one member from the 426fd4e5da5Sopenharmony_ci // substruct. Update the OpCompositeExtract instruction. Update the 427fd4e5da5Sopenharmony_ci // OpCompositeInsert instruction. 428fd4e5da5Sopenharmony_ci const std::string text = R"( 429fd4e5da5Sopenharmony_ci; CHECK: OpName 430fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 431fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 432fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16 433fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset 434fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4 435fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct %float 436fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[struct]] 437fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals 438fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 0 439fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 0 440fd4e5da5Sopenharmony_ci; CHECK: OpReturn 441fd4e5da5Sopenharmony_ci OpCapability Shader 442fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 443fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 444fd4e5da5Sopenharmony_ci OpSource HLSL 600 445fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 446fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 447fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 448fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 449fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 450fd4e5da5Sopenharmony_ci OpName %main "main" 451fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 452fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 453fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 454fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 16 455fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 24 456fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_6 0 Offset 0 457fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_6 1 Offset 4 458fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 459fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 460fd4e5da5Sopenharmony_ci %_struct_6 = OpTypeStruct %float %float 461fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %_struct_6 %float 462fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 463fd4e5da5Sopenharmony_ci %void = OpTypeVoid 464fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void 465fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 466fd4e5da5Sopenharmony_ci %main = OpFunction %void None %7 467fd4e5da5Sopenharmony_ci %8 = OpLabel 468fd4e5da5Sopenharmony_ci %9 = OpLoad %type__Globals %_Globals 469fd4e5da5Sopenharmony_ci %10 = OpCompositeExtract %float %9 1 1 470fd4e5da5Sopenharmony_ci %11 = OpCompositeInsert %type__Globals %10 %9 1 1 471fd4e5da5Sopenharmony_ci OpReturn 472fd4e5da5Sopenharmony_ci OpFunctionEnd 473fd4e5da5Sopenharmony_ci 474fd4e5da5Sopenharmony_ci)"; 475fd4e5da5Sopenharmony_ci 476fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 477fd4e5da5Sopenharmony_ci} 478fd4e5da5Sopenharmony_ci 479fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract4) { 480fd4e5da5Sopenharmony_ci // Test that the members "x" and "z" are removed, and one member from the 481fd4e5da5Sopenharmony_ci // substruct. Update the OpCompositeExtract instruction. Update the 482fd4e5da5Sopenharmony_ci // OpCompositeInsert instruction. 483fd4e5da5Sopenharmony_ci const std::string text = R"( 484fd4e5da5Sopenharmony_ci; CHECK: OpName 485fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 486fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 487fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16 488fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset 489fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4 490fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpTypeStruct %float 491fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[struct]] 492fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[array]] 493fd4e5da5Sopenharmony_ci; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals 494fd4e5da5Sopenharmony_ci; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 1 0 495fd4e5da5Sopenharmony_ci; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 1 0 496fd4e5da5Sopenharmony_ci; CHECK: OpReturn 497fd4e5da5Sopenharmony_ci OpCapability Shader 498fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 499fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 500fd4e5da5Sopenharmony_ci OpSource HLSL 600 501fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 502fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 503fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 504fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 505fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 506fd4e5da5Sopenharmony_ci OpName %main "main" 507fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 508fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 509fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 510fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 16 511fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 80 512fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_6 0 Offset 0 513fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_6 1 Offset 4 514fd4e5da5Sopenharmony_ci OpDecorate %array ArrayStride 16 515fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 516fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 ; 32-bit int, sign-less 517fd4e5da5Sopenharmony_ci %uint_4 = OpConstant %uint 4 518fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 519fd4e5da5Sopenharmony_ci %_struct_6 = OpTypeStruct %float %float 520fd4e5da5Sopenharmony_ci %array = OpTypeArray %_struct_6 %uint_4 521fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %array %float 522fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 523fd4e5da5Sopenharmony_ci %void = OpTypeVoid 524fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %void 525fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 526fd4e5da5Sopenharmony_ci %main = OpFunction %void None %7 527fd4e5da5Sopenharmony_ci %8 = OpLabel 528fd4e5da5Sopenharmony_ci %9 = OpLoad %type__Globals %_Globals 529fd4e5da5Sopenharmony_ci %10 = OpCompositeExtract %float %9 1 1 1 530fd4e5da5Sopenharmony_ci %11 = OpCompositeInsert %type__Globals %10 %9 1 1 1 531fd4e5da5Sopenharmony_ci OpReturn 532fd4e5da5Sopenharmony_ci OpFunctionEnd 533fd4e5da5Sopenharmony_ci 534fd4e5da5Sopenharmony_ci)"; 535fd4e5da5Sopenharmony_ci 536fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 537fd4e5da5Sopenharmony_ci} 538fd4e5da5Sopenharmony_ci 539fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMembersUpdateArrayLength) { 540fd4e5da5Sopenharmony_ci // Test that the members "x" and "y" are removed. 541fd4e5da5Sopenharmony_ci // Member "z" is live because of the OpArrayLength instruction. 542fd4e5da5Sopenharmony_ci // Update the OpArrayLength instruction. 543fd4e5da5Sopenharmony_ci const std::string text = R"( 544fd4e5da5Sopenharmony_ci; CHECK: OpName 545fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "z" 546fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 547fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16 548fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset 549fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %_runtimearr_float 550fd4e5da5Sopenharmony_ci; CHECK: OpArrayLength %uint %_Globals 0 551fd4e5da5Sopenharmony_ci OpCapability Shader 552fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 553fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 554fd4e5da5Sopenharmony_ci OpSource HLSL 600 555fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 556fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 557fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 558fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 559fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 560fd4e5da5Sopenharmony_ci OpName %main "main" 561fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 562fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 563fd4e5da5Sopenharmony_ci OpDecorate %_runtimearr_float ArrayStride 16 564fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 565fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 566fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 567fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 568fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 569fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 570fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float 571fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %_runtimearr_float 572fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 573fd4e5da5Sopenharmony_ci %void = OpTypeVoid 574fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %void 575fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 576fd4e5da5Sopenharmony_ci %main = OpFunction %void None %9 577fd4e5da5Sopenharmony_ci %10 = OpLabel 578fd4e5da5Sopenharmony_ci %12 = OpArrayLength %uint %_Globals 2 579fd4e5da5Sopenharmony_ci OpReturn 580fd4e5da5Sopenharmony_ci OpFunctionEnd 581fd4e5da5Sopenharmony_ci)"; 582fd4e5da5Sopenharmony_ci 583fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 584fd4e5da5Sopenharmony_ci} 585fd4e5da5Sopenharmony_ci 586fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpStore) { 587fd4e5da5Sopenharmony_ci // Test that all members are kept because of an OpStore. 588fd4e5da5Sopenharmony_ci // No change expected. 589fd4e5da5Sopenharmony_ci const std::string text = R"( 590fd4e5da5Sopenharmony_ci OpCapability Shader 591fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 592fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 593fd4e5da5Sopenharmony_ci OpSource HLSL 600 594fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 595fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 596fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 597fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 598fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 599fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals2" 600fd4e5da5Sopenharmony_ci OpName %main "main" 601fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 602fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 603fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 604fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 605fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 606fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 607fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 608fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 609fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 610fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 611fd4e5da5Sopenharmony_ci %void = OpTypeVoid 612fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %void 613fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 614fd4e5da5Sopenharmony_ci %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform 615fd4e5da5Sopenharmony_ci %main = OpFunction %void None %9 616fd4e5da5Sopenharmony_ci %10 = OpLabel 617fd4e5da5Sopenharmony_ci %11 = OpLoad %type__Globals %_Globals 618fd4e5da5Sopenharmony_ci OpStore %_Globals2 %11 619fd4e5da5Sopenharmony_ci OpReturn 620fd4e5da5Sopenharmony_ci OpFunctionEnd 621fd4e5da5Sopenharmony_ci)"; 622fd4e5da5Sopenharmony_ci 623fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 624fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 625fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 626fd4e5da5Sopenharmony_ci} 627fd4e5da5Sopenharmony_ci 628fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepStorageBufferMembers) { 629fd4e5da5Sopenharmony_ci // Test that all members of the storage buffer struct %S are kept. 630fd4e5da5Sopenharmony_ci // No change expected. 631fd4e5da5Sopenharmony_ci const std::string text = R"( 632fd4e5da5Sopenharmony_ci OpCapability Shader 633fd4e5da5Sopenharmony_ci OpExtension "SPV_GOOGLE_hlsl_functionality1" 634fd4e5da5Sopenharmony_ci OpExtension "SPV_GOOGLE_user_type" 635fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 636fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 637fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %PSMain "PSMain" %out_var_SV_TARGET 638fd4e5da5Sopenharmony_ci OpExecutionMode %PSMain OriginUpperLeft 639fd4e5da5Sopenharmony_ci OpSource HLSL 600 640fd4e5da5Sopenharmony_ci OpName %type_StructuredBuffer_S "type.StructuredBuffer.S" 641fd4e5da5Sopenharmony_ci OpName %S "S" 642fd4e5da5Sopenharmony_ci OpMemberName %S 0 "A" 643fd4e5da5Sopenharmony_ci OpMemberName %S 1 "B" 644fd4e5da5Sopenharmony_ci OpName %Buf "Buf" 645fd4e5da5Sopenharmony_ci OpName %out_var_SV_TARGET "out.var.SV_TARGET" 646fd4e5da5Sopenharmony_ci OpName %PSMain "PSMain" 647fd4e5da5Sopenharmony_ci OpDecorateString %out_var_SV_TARGET UserSemantic "SV_TARGET" 648fd4e5da5Sopenharmony_ci OpDecorate %out_var_SV_TARGET Location 0 649fd4e5da5Sopenharmony_ci OpDecorate %Buf DescriptorSet 0 650fd4e5da5Sopenharmony_ci OpDecorate %Buf Binding 0 651fd4e5da5Sopenharmony_ci OpMemberDecorate %S 0 Offset 0 652fd4e5da5Sopenharmony_ci OpMemberDecorate %S 1 Offset 16 653fd4e5da5Sopenharmony_ci OpDecorate %_runtimearr_S ArrayStride 32 654fd4e5da5Sopenharmony_ci OpMemberDecorate %type_StructuredBuffer_S 0 Offset 0 655fd4e5da5Sopenharmony_ci OpMemberDecorate %type_StructuredBuffer_S 0 NonWritable 656fd4e5da5Sopenharmony_ci OpDecorate %type_StructuredBuffer_S BufferBlock 657fd4e5da5Sopenharmony_ci OpDecorateString %Buf UserTypeGOOGLE "structuredbuffer" 658fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 659fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 660fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 661fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 662fd4e5da5Sopenharmony_ci %int_1 = OpConstant %int 1 663fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 664fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 665fd4e5da5Sopenharmony_ci %S = OpTypeStruct %v4float %v4float 666fd4e5da5Sopenharmony_ci%_runtimearr_S = OpTypeRuntimeArray %S 667fd4e5da5Sopenharmony_ci%type_StructuredBuffer_S = OpTypeStruct %_runtimearr_S 668fd4e5da5Sopenharmony_ci%_ptr_Uniform_type_StructuredBuffer_S = OpTypePointer Uniform %type_StructuredBuffer_S 669fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 670fd4e5da5Sopenharmony_ci %void = OpTypeVoid 671fd4e5da5Sopenharmony_ci %18 = OpTypeFunction %void 672fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float 673fd4e5da5Sopenharmony_ci %Buf = OpVariable %_ptr_Uniform_type_StructuredBuffer_S Uniform 674fd4e5da5Sopenharmony_ci%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output 675fd4e5da5Sopenharmony_ci %PSMain = OpFunction %void None %18 676fd4e5da5Sopenharmony_ci %20 = OpLabel 677fd4e5da5Sopenharmony_ci %21 = OpAccessChain %_ptr_Uniform_v4float %Buf %int_0 %uint_0 %int_1 678fd4e5da5Sopenharmony_ci %22 = OpLoad %v4float %21 679fd4e5da5Sopenharmony_ci OpStore %out_var_SV_TARGET %22 680fd4e5da5Sopenharmony_ci OpReturn 681fd4e5da5Sopenharmony_ci OpFunctionEnd 682fd4e5da5Sopenharmony_ci)"; 683fd4e5da5Sopenharmony_ci 684fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 685fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 686fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 687fd4e5da5Sopenharmony_ci} 688fd4e5da5Sopenharmony_ci 689fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemory) { 690fd4e5da5Sopenharmony_ci // Test that all members are kept because of an OpCopyMemory. 691fd4e5da5Sopenharmony_ci // No change expected. 692fd4e5da5Sopenharmony_ci const std::string text = R"( 693fd4e5da5Sopenharmony_ci OpCapability Shader 694fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 695fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 696fd4e5da5Sopenharmony_ci OpSource HLSL 600 697fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 698fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 699fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 700fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 701fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 702fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals2" 703fd4e5da5Sopenharmony_ci OpName %main "main" 704fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 705fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 706fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 707fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 708fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 709fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 710fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 711fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 712fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 713fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 714fd4e5da5Sopenharmony_ci %void = OpTypeVoid 715fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %void 716fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 717fd4e5da5Sopenharmony_ci %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform 718fd4e5da5Sopenharmony_ci %main = OpFunction %void None %9 719fd4e5da5Sopenharmony_ci %10 = OpLabel 720fd4e5da5Sopenharmony_ci OpCopyMemory %_Globals2 %_Globals 721fd4e5da5Sopenharmony_ci OpReturn 722fd4e5da5Sopenharmony_ci OpFunctionEnd 723fd4e5da5Sopenharmony_ci)"; 724fd4e5da5Sopenharmony_ci 725fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 726fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 727fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 728fd4e5da5Sopenharmony_ci} 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemorySized) { 731fd4e5da5Sopenharmony_ci // Test that all members are kept because of an OpCopyMemorySized. 732fd4e5da5Sopenharmony_ci // No change expected. 733fd4e5da5Sopenharmony_ci const std::string text = R"( 734fd4e5da5Sopenharmony_ci OpCapability Shader 735fd4e5da5Sopenharmony_ci OpCapability Addresses 736fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 737fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 738fd4e5da5Sopenharmony_ci OpSource HLSL 600 739fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 740fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 741fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 742fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 743fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 744fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals2" 745fd4e5da5Sopenharmony_ci OpName %main "main" 746fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 747fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 748fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 749fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 750fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 751fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 752fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 753fd4e5da5Sopenharmony_ci %uint_20 = OpConstant %uint 20 754fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 755fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 756fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 757fd4e5da5Sopenharmony_ci %void = OpTypeVoid 758fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %void 759fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 760fd4e5da5Sopenharmony_ci %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform 761fd4e5da5Sopenharmony_ci %main = OpFunction %void None %9 762fd4e5da5Sopenharmony_ci %10 = OpLabel 763fd4e5da5Sopenharmony_ci OpCopyMemorySized %_Globals2 %_Globals %uint_20 764fd4e5da5Sopenharmony_ci OpReturn 765fd4e5da5Sopenharmony_ci OpFunctionEnd 766fd4e5da5Sopenharmony_ci)"; 767fd4e5da5Sopenharmony_ci 768fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 769fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 770fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 771fd4e5da5Sopenharmony_ci} 772fd4e5da5Sopenharmony_ci 773fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, KeepMembersOpReturnValue) { 774fd4e5da5Sopenharmony_ci // Test that all members are kept because of an OpCopyMemorySized. 775fd4e5da5Sopenharmony_ci // No change expected. 776fd4e5da5Sopenharmony_ci const std::string text = R"( 777fd4e5da5Sopenharmony_ci OpCapability Shader 778fd4e5da5Sopenharmony_ci OpCapability Linkage 779fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 780fd4e5da5Sopenharmony_ci OpSource HLSL 600 781fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 782fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 783fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 784fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 785fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 786fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals2" 787fd4e5da5Sopenharmony_ci OpName %main "main" 788fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 789fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 790fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 791fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 792fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 793fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 794fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 795fd4e5da5Sopenharmony_ci %uint_20 = OpConstant %uint 20 796fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 797fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 798fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 799fd4e5da5Sopenharmony_ci %void = OpTypeVoid 800fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %type__Globals 801fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 802fd4e5da5Sopenharmony_ci %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform 803fd4e5da5Sopenharmony_ci %main = OpFunction %type__Globals None %9 804fd4e5da5Sopenharmony_ci %10 = OpLabel 805fd4e5da5Sopenharmony_ci %11 = OpLoad %type__Globals %_Globals 806fd4e5da5Sopenharmony_ci OpReturnValue %11 807fd4e5da5Sopenharmony_ci OpFunctionEnd 808fd4e5da5Sopenharmony_ci)"; 809fd4e5da5Sopenharmony_ci 810fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 811fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 812fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 813fd4e5da5Sopenharmony_ci} 814fd4e5da5Sopenharmony_ci 815fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberAccessChainWithArrays) { 816fd4e5da5Sopenharmony_ci // Leave only 1 member in each of the structs. 817fd4e5da5Sopenharmony_ci // Update OpMemberName, OpMemberDecorate, and OpAccessChain. 818fd4e5da5Sopenharmony_ci const std::string text = R"( 819fd4e5da5Sopenharmony_ci; CHECK: OpName 820fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 821fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 822fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 16 823fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4 824fd4e5da5Sopenharmony_ci; CHECK: [[struct]] = OpTypeStruct %float 825fd4e5da5Sopenharmony_ci; CHECK: [[array:%\w+]] = OpTypeArray [[struct]] 826fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct [[array]] 827fd4e5da5Sopenharmony_ci; CHECK: [[undef:%\w+]] = OpUndef %uint 828fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals [[undef]] %uint_0 [[undef]] %uint_0 829fd4e5da5Sopenharmony_ci OpCapability Shader 830fd4e5da5Sopenharmony_ci OpCapability VariablePointersStorageBuffer 831fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 832fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 833fd4e5da5Sopenharmony_ci OpSource HLSL 600 834fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 835fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 836fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 837fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 838fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 839fd4e5da5Sopenharmony_ci OpName %main "main" 840fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 841fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 842fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 843fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 16 844fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 48 845fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_4 0 Offset 0 846fd4e5da5Sopenharmony_ci OpMemberDecorate %_struct_4 1 Offset 4 847fd4e5da5Sopenharmony_ci OpDecorate %_arr__struct_4_uint_2 ArrayStride 16 848fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 849fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 850fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 851fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 852fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 853fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 854fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 855fd4e5da5Sopenharmony_ci %_struct_4 = OpTypeStruct %float %float 856fd4e5da5Sopenharmony_ci%_arr__struct_4_uint_2 = OpTypeArray %_struct_4 %uint_2 857fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %_arr__struct_4_uint_2 %float 858fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3 859fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3 860fd4e5da5Sopenharmony_ci %void = OpTypeVoid 861fd4e5da5Sopenharmony_ci %15 = OpTypeFunction %void 862fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 863fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform 864fd4e5da5Sopenharmony_ci %main = OpFunction %void None %15 865fd4e5da5Sopenharmony_ci %17 = OpLabel 866fd4e5da5Sopenharmony_ci %18 = OpUndef %uint 867fd4e5da5Sopenharmony_ci %19 = OpAccessChain %_ptr_Uniform_float %_Globals %18 %uint_1 %18 %uint_1 868fd4e5da5Sopenharmony_ci OpReturn 869fd4e5da5Sopenharmony_ci OpFunctionEnd 870fd4e5da5Sopenharmony_ci)"; 871fd4e5da5Sopenharmony_ci 872fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 873fd4e5da5Sopenharmony_ci} 874fd4e5da5Sopenharmony_ci 875fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberInboundsAccessChain) { 876fd4e5da5Sopenharmony_ci // Test that the member "y" is removed. 877fd4e5da5Sopenharmony_ci // Update OpMemberName for |y| and |z|. 878fd4e5da5Sopenharmony_ci // Update OpMemberDecorate for |y| and |z|. 879fd4e5da5Sopenharmony_ci // Update OpInboundsAccessChain for access to |z|. 880fd4e5da5Sopenharmony_ci const std::string text = R"( 881fd4e5da5Sopenharmony_ci; CHECK: OpName 882fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x" 883fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 884fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 885fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0 886fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 8 887fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 888fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0 889fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %uint_1 890fd4e5da5Sopenharmony_ci OpCapability Shader 891fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 892fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position 893fd4e5da5Sopenharmony_ci OpSource HLSL 600 894fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 895fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 896fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 897fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 898fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 899fd4e5da5Sopenharmony_ci OpName %in_var_Position "in.var.Position" 900fd4e5da5Sopenharmony_ci OpName %main "main" 901fd4e5da5Sopenharmony_ci OpDecorate %gl_Position BuiltIn Position 902fd4e5da5Sopenharmony_ci OpDecorate %in_var_Position Location 0 903fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 904fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 905fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 906fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 907fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 8 908fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 909fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 910fd4e5da5Sopenharmony_ci %int_0 = OpConstant %int 0 911fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 912fd4e5da5Sopenharmony_ci %int_2 = OpConstant %int 2 913fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 914fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 915fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 916fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 917fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 918fd4e5da5Sopenharmony_ci %void = OpTypeVoid 919fd4e5da5Sopenharmony_ci %15 = OpTypeFunction %void 920fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 921fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform 922fd4e5da5Sopenharmony_ci%in_var_Position = OpVariable %_ptr_Input_v4float Input 923fd4e5da5Sopenharmony_ci%gl_Position = OpVariable %_ptr_Output_v4float Output 924fd4e5da5Sopenharmony_ci %main = OpFunction %void None %15 925fd4e5da5Sopenharmony_ci %17 = OpLabel 926fd4e5da5Sopenharmony_ci %18 = OpLoad %v4float %in_var_Position 927fd4e5da5Sopenharmony_ci %19 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0 928fd4e5da5Sopenharmony_ci %20 = OpLoad %float %19 929fd4e5da5Sopenharmony_ci %21 = OpCompositeExtract %float %18 0 930fd4e5da5Sopenharmony_ci %22 = OpFAdd %float %21 %20 931fd4e5da5Sopenharmony_ci %23 = OpCompositeInsert %v4float %22 %18 0 932fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %float %18 1 933fd4e5da5Sopenharmony_ci %25 = OpCompositeInsert %v4float %24 %23 1 934fd4e5da5Sopenharmony_ci %26 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_2 935fd4e5da5Sopenharmony_ci %27 = OpLoad %float %26 936fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %float %18 2 937fd4e5da5Sopenharmony_ci %29 = OpFAdd %float %28 %27 938fd4e5da5Sopenharmony_ci %30 = OpCompositeInsert %v4float %29 %25 2 939fd4e5da5Sopenharmony_ci OpStore %gl_Position %30 940fd4e5da5Sopenharmony_ci OpReturn 941fd4e5da5Sopenharmony_ci OpFunctionEnd 942fd4e5da5Sopenharmony_ci)"; 943fd4e5da5Sopenharmony_ci 944fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 945fd4e5da5Sopenharmony_ci} 946fd4e5da5Sopenharmony_ci 947fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberPtrAccessChain) { 948fd4e5da5Sopenharmony_ci // Test that the member "y" is removed. 949fd4e5da5Sopenharmony_ci // Update OpMemberName for |y| and |z|. 950fd4e5da5Sopenharmony_ci // Update OpMemberDecorate for |y| and |z|. 951fd4e5da5Sopenharmony_ci // Update OpInboundsAccessChain for access to |z|. 952fd4e5da5Sopenharmony_ci const std::string text = R"( 953fd4e5da5Sopenharmony_ci; CHECK: OpName 954fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x" 955fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 956fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 957fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0 958fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 16 959fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 960fd4e5da5Sopenharmony_ci; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0 961fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0 962fd4e5da5Sopenharmony_ci; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1 963fd4e5da5Sopenharmony_ci OpCapability Shader 964fd4e5da5Sopenharmony_ci OpCapability VariablePointersStorageBuffer 965fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 966fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 967fd4e5da5Sopenharmony_ci OpSource HLSL 600 968fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 969fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 970fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 971fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 972fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 973fd4e5da5Sopenharmony_ci OpName %main "main" 974fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 975fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 976fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 977fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 978fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 979fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 980fd4e5da5Sopenharmony_ci OpDecorate %_ptr_Uniform_type__Globals ArrayStride 8 981fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 982fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 983fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 984fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 985fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 986fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 987fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 988fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3 989fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 990fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3 991fd4e5da5Sopenharmony_ci %void = OpTypeVoid 992fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %void 993fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 994fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform 995fd4e5da5Sopenharmony_ci %main = OpFunction %void None %14 996fd4e5da5Sopenharmony_ci %16 = OpLabel 997fd4e5da5Sopenharmony_ci %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0 998fd4e5da5Sopenharmony_ci %18 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0 999fd4e5da5Sopenharmony_ci %19 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2 1000fd4e5da5Sopenharmony_ci OpReturn 1001fd4e5da5Sopenharmony_ci OpFunctionEnd 1002fd4e5da5Sopenharmony_ci)"; 1003fd4e5da5Sopenharmony_ci 1004fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 1005fd4e5da5Sopenharmony_ci} 1006fd4e5da5Sopenharmony_ci 1007fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, RemoveMemberInBoundsPtrAccessChain) { 1008fd4e5da5Sopenharmony_ci // Test that the member "y" is removed. 1009fd4e5da5Sopenharmony_ci // Update OpMemberName for |y| and |z|. 1010fd4e5da5Sopenharmony_ci // Update OpMemberDecorate for |y| and |z|. 1011fd4e5da5Sopenharmony_ci // Update OpInboundsAccessChain for access to |z|. 1012fd4e5da5Sopenharmony_ci const std::string text = R"( 1013fd4e5da5Sopenharmony_ci; CHECK: OpName 1014fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "x" 1015fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 1 "z" 1016fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 1017fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 0 1018fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 1 Offset 16 1019fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %float %float 1020fd4e5da5Sopenharmony_ci; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0 1021fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0 1022fd4e5da5Sopenharmony_ci; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1 1023fd4e5da5Sopenharmony_ci OpCapability Shader 1024fd4e5da5Sopenharmony_ci OpCapability Addresses 1025fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1026fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 1027fd4e5da5Sopenharmony_ci OpSource HLSL 600 1028fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 1029fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 1030fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 1031fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 1032fd4e5da5Sopenharmony_ci OpName %_Globals "$Globals" 1033fd4e5da5Sopenharmony_ci OpName %main "main" 1034fd4e5da5Sopenharmony_ci OpDecorate %_Globals DescriptorSet 0 1035fd4e5da5Sopenharmony_ci OpDecorate %_Globals Binding 0 1036fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 1037fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 1038fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 1039fd4e5da5Sopenharmony_ci OpDecorate %type__Globals Block 1040fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1041fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 1042fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 1043fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 1044fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 1045fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1046fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %float %float %float 1047fd4e5da5Sopenharmony_ci%_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3 1048fd4e5da5Sopenharmony_ci%_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals 1049fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3 1050fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1051fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %void 1052fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 1053fd4e5da5Sopenharmony_ci %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform 1054fd4e5da5Sopenharmony_ci %main = OpFunction %void None %14 1055fd4e5da5Sopenharmony_ci %16 = OpLabel 1056fd4e5da5Sopenharmony_ci %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0 1057fd4e5da5Sopenharmony_ci %18 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0 1058fd4e5da5Sopenharmony_ci %19 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2 1059fd4e5da5Sopenharmony_ci OpReturn 1060fd4e5da5Sopenharmony_ci OpFunctionEnd 1061fd4e5da5Sopenharmony_ci)"; 1062fd4e5da5Sopenharmony_ci 1063fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 1064fd4e5da5Sopenharmony_ci} 1065fd4e5da5Sopenharmony_ci 1066fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontRemoveModfStructResultTypeMembers) { 1067fd4e5da5Sopenharmony_ci const std::string text = R"( 1068fd4e5da5Sopenharmony_ci OpCapability Shader 1069fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1070fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1071fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" 1072fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 1073fd4e5da5Sopenharmony_ci OpSource HLSL 600 1074fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1075fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1076fd4e5da5Sopenharmony_ci %21 = OpTypeFunction %void 1077fd4e5da5Sopenharmony_ci%ModfStructType = OpTypeStruct %float %float 1078fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21 1079fd4e5da5Sopenharmony_ci %22 = OpLabel 1080fd4e5da5Sopenharmony_ci %23 = OpUndef %float 1081fd4e5da5Sopenharmony_ci %24 = OpExtInst %ModfStructType %1 ModfStruct %23 1082fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %float %24 1 1083fd4e5da5Sopenharmony_ci OpReturn 1084fd4e5da5Sopenharmony_ci OpFunctionEnd 1085fd4e5da5Sopenharmony_ci)"; 1086fd4e5da5Sopenharmony_ci 1087fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 1088fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1089fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1090fd4e5da5Sopenharmony_ci} 1091fd4e5da5Sopenharmony_ci 1092fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontChangeInputStructs) { 1093fd4e5da5Sopenharmony_ci // The input for a shader has to match the type of the output from the 1094fd4e5da5Sopenharmony_ci // previous shader in the pipeline. Because of that, we cannot change the 1095fd4e5da5Sopenharmony_ci // types of input variables. 1096fd4e5da5Sopenharmony_ci const std::string text = R"( 1097fd4e5da5Sopenharmony_ci OpCapability Shader 1098fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1099fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1100fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %input_var 1101fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 1102fd4e5da5Sopenharmony_ci OpSource HLSL 600 1103fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1104fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1105fd4e5da5Sopenharmony_ci %21 = OpTypeFunction %void 1106fd4e5da5Sopenharmony_ci%in_var_type = OpTypeStruct %float %float 1107fd4e5da5Sopenharmony_ci%in_ptr_type = OpTypePointer Input %in_var_type 1108fd4e5da5Sopenharmony_ci%input_var = OpVariable %in_ptr_type Input 1109fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21 1110fd4e5da5Sopenharmony_ci %22 = OpLabel 1111fd4e5da5Sopenharmony_ci OpReturn 1112fd4e5da5Sopenharmony_ci OpFunctionEnd 1113fd4e5da5Sopenharmony_ci)"; 1114fd4e5da5Sopenharmony_ci 1115fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 1116fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1117fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1118fd4e5da5Sopenharmony_ci} 1119fd4e5da5Sopenharmony_ci 1120fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, DontChangeOutputStructs) { 1121fd4e5da5Sopenharmony_ci // The output for a shader has to match the type of the output from the 1122fd4e5da5Sopenharmony_ci // previous shader in the pipeline. Because of that, we cannot change the 1123fd4e5da5Sopenharmony_ci // types of output variables. 1124fd4e5da5Sopenharmony_ci const std::string text = R"( 1125fd4e5da5Sopenharmony_ci OpCapability Shader 1126fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1127fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1128fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %main "main" %output_var 1129fd4e5da5Sopenharmony_ci OpExecutionMode %main OriginUpperLeft 1130fd4e5da5Sopenharmony_ci OpSource HLSL 600 1131fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1132fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1133fd4e5da5Sopenharmony_ci %21 = OpTypeFunction %void 1134fd4e5da5Sopenharmony_ci%out_var_type = OpTypeStruct %float %float 1135fd4e5da5Sopenharmony_ci%out_ptr_type = OpTypePointer Output %out_var_type 1136fd4e5da5Sopenharmony_ci%output_var = OpVariable %out_ptr_type Output 1137fd4e5da5Sopenharmony_ci%main = OpFunction %void None %21 1138fd4e5da5Sopenharmony_ci %22 = OpLabel 1139fd4e5da5Sopenharmony_ci OpReturn 1140fd4e5da5Sopenharmony_ci OpFunctionEnd 1141fd4e5da5Sopenharmony_ci)"; 1142fd4e5da5Sopenharmony_ci 1143fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 1144fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1145fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1146fd4e5da5Sopenharmony_ci} 1147fd4e5da5Sopenharmony_ci 1148fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, UpdateSpecConstOpExtract) { 1149fd4e5da5Sopenharmony_ci // Test that an extract in an OpSpecConstantOp is correctly updated. 1150fd4e5da5Sopenharmony_ci const std::string text = R"( 1151fd4e5da5Sopenharmony_ci; CHECK: OpName 1152fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 1153fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 1154fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1 1155fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 1156fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %uint 1157fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]] 1158fd4e5da5Sopenharmony_ci; CHECK: OpSpecConstantOp %uint CompositeExtract [[struct]] 0 1159fd4e5da5Sopenharmony_ci OpCapability Shader 1160fd4e5da5Sopenharmony_ci OpCapability Addresses 1161fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1162fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 1163fd4e5da5Sopenharmony_ci OpSource HLSL 600 1164fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 1165fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 1166fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 1167fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 1168fd4e5da5Sopenharmony_ci OpName %main "main" 1169fd4e5da5Sopenharmony_ci OpDecorate %c_0 SpecId 0 1170fd4e5da5Sopenharmony_ci OpDecorate %c_1 SpecId 1 1171fd4e5da5Sopenharmony_ci OpDecorate %c_2 SpecId 2 1172fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 1173fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 1174fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 1175fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1176fd4e5da5Sopenharmony_ci %c_0 = OpSpecConstant %uint 0 1177fd4e5da5Sopenharmony_ci %c_1 = OpSpecConstant %uint 1 1178fd4e5da5Sopenharmony_ci %c_2 = OpSpecConstant %uint 2 1179fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 1180fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 1181fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 1182fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 1183fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %uint %uint %uint 1184fd4e5da5Sopenharmony_ci%spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2 1185fd4e5da5Sopenharmony_ci%extract = OpSpecConstantOp %uint CompositeExtract %spec_const_global 1 1186fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1187fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %void 1188fd4e5da5Sopenharmony_ci %main = OpFunction %void None %14 1189fd4e5da5Sopenharmony_ci %16 = OpLabel 1190fd4e5da5Sopenharmony_ci OpReturn 1191fd4e5da5Sopenharmony_ci OpFunctionEnd 1192fd4e5da5Sopenharmony_ci)"; 1193fd4e5da5Sopenharmony_ci 1194fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 1195fd4e5da5Sopenharmony_ci} 1196fd4e5da5Sopenharmony_ci 1197fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, UpdateSpecConstOpInsert) { 1198fd4e5da5Sopenharmony_ci // Test that an insert in an OpSpecConstantOp is correctly updated. 1199fd4e5da5Sopenharmony_ci const std::string text = R"( 1200fd4e5da5Sopenharmony_ci; CHECK: OpName 1201fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpMemberName %type__Globals 0 "y" 1202fd4e5da5Sopenharmony_ci; CHECK-NOT: OpMemberName 1203fd4e5da5Sopenharmony_ci; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1 1204fd4e5da5Sopenharmony_ci; CHECK: OpMemberDecorate %type__Globals 0 Offset 4 1205fd4e5da5Sopenharmony_ci; CHECK: %type__Globals = OpTypeStruct %uint 1206fd4e5da5Sopenharmony_ci; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]] 1207fd4e5da5Sopenharmony_ci; CHECK: OpSpecConstantOp %type__Globals CompositeInsert %uint_3 [[struct]] 0 1208fd4e5da5Sopenharmony_ci OpCapability Shader 1209fd4e5da5Sopenharmony_ci OpCapability Addresses 1210fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1211fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 1212fd4e5da5Sopenharmony_ci OpSource HLSL 600 1213fd4e5da5Sopenharmony_ci OpName %type__Globals "type.$Globals" 1214fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 0 "x" 1215fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 1 "y" 1216fd4e5da5Sopenharmony_ci OpMemberName %type__Globals 2 "z" 1217fd4e5da5Sopenharmony_ci OpName %main "main" 1218fd4e5da5Sopenharmony_ci OpDecorate %c_0 SpecId 0 1219fd4e5da5Sopenharmony_ci OpDecorate %c_1 SpecId 1 1220fd4e5da5Sopenharmony_ci OpDecorate %c_2 SpecId 2 1221fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 0 Offset 0 1222fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 1 Offset 4 1223fd4e5da5Sopenharmony_ci OpMemberDecorate %type__Globals 2 Offset 16 1224fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 1225fd4e5da5Sopenharmony_ci %c_0 = OpSpecConstant %uint 0 1226fd4e5da5Sopenharmony_ci %c_1 = OpSpecConstant %uint 1 1227fd4e5da5Sopenharmony_ci %c_2 = OpSpecConstant %uint 2 1228fd4e5da5Sopenharmony_ci %uint_0 = OpConstant %uint 0 1229fd4e5da5Sopenharmony_ci %uint_1 = OpConstant %uint 1 1230fd4e5da5Sopenharmony_ci %uint_2 = OpConstant %uint 2 1231fd4e5da5Sopenharmony_ci %uint_3 = OpConstant %uint 3 1232fd4e5da5Sopenharmony_ci%type__Globals = OpTypeStruct %uint %uint %uint 1233fd4e5da5Sopenharmony_ci%spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2 1234fd4e5da5Sopenharmony_ci%insert = OpSpecConstantOp %type__Globals CompositeInsert %uint_3 %spec_const_global 1 1235fd4e5da5Sopenharmony_ci%extract = OpSpecConstantOp %uint CompositeExtract %insert 1 1236fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1237fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %void 1238fd4e5da5Sopenharmony_ci %main = OpFunction %void None %14 1239fd4e5da5Sopenharmony_ci %16 = OpLabel 1240fd4e5da5Sopenharmony_ci OpReturn 1241fd4e5da5Sopenharmony_ci OpFunctionEnd 1242fd4e5da5Sopenharmony_ci)"; 1243fd4e5da5Sopenharmony_ci 1244fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 1245fd4e5da5Sopenharmony_ci} 1246fd4e5da5Sopenharmony_ci 1247fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, 8BitIndexNoChange) { 1248fd4e5da5Sopenharmony_ci // Test that the pass does not crash when an 8 bit index is used in an 1249fd4e5da5Sopenharmony_ci // OpAccessChain. No change is expected. 1250fd4e5da5Sopenharmony_ci const std::string text = R"( 1251fd4e5da5Sopenharmony_ci OpCapability ImageQuery 1252fd4e5da5Sopenharmony_ci OpCapability Int8 1253fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1254fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %1 "OpnSeman/" %2 1255fd4e5da5Sopenharmony_ci OpExecutionMode %1 OriginUpperLeft 1256fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1257fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 1258fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1259fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1260fd4e5da5Sopenharmony_ci %_struct_7 = OpTypeStruct %v4float 1261fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 1262fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1263fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %v4float %_ptr_Function__struct_7 1264fd4e5da5Sopenharmony_ci %char = OpTypeInt 8 1 1265fd4e5da5Sopenharmony_ci %char_0 = OpConstant %char 0 1266fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1267fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Output_v4float Output 1268fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %4 1269fd4e5da5Sopenharmony_ci %14 = OpLabel 1270fd4e5da5Sopenharmony_ci %15 = OpVariable %_ptr_Function__struct_7 Function 1271fd4e5da5Sopenharmony_ci %16 = OpFunctionCall %v4float %17 %15 1272fd4e5da5Sopenharmony_ci OpReturn 1273fd4e5da5Sopenharmony_ci OpFunctionEnd 1274fd4e5da5Sopenharmony_ci %17 = OpFunction %v4float DontInline %10 1275fd4e5da5Sopenharmony_ci %18 = OpFunctionParameter %_ptr_Function__struct_7 1276fd4e5da5Sopenharmony_ci %19 = OpLabel 1277fd4e5da5Sopenharmony_ci %20 = OpAccessChain %_ptr_Function_v4float %18 %char_0 1278fd4e5da5Sopenharmony_ci %21 = OpLoad %v4float %20 1279fd4e5da5Sopenharmony_ci OpReturnValue %21 1280fd4e5da5Sopenharmony_ci OpFunctionEnd 1281fd4e5da5Sopenharmony_ci)"; 1282fd4e5da5Sopenharmony_ci 1283fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>( 1284fd4e5da5Sopenharmony_ci text, /* skip_nop = */ true, /* do_validation = */ true); 1285fd4e5da5Sopenharmony_ci EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result)); 1286fd4e5da5Sopenharmony_ci} 1287fd4e5da5Sopenharmony_ci 1288fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadMemberTest, 8BitIndexWithChange) { 1289fd4e5da5Sopenharmony_ci // Test that the pass does not crash when an 8 bit index is used in an 1290fd4e5da5Sopenharmony_ci // OpAccessChain. The index in the access change should be changed to 0. 1291fd4e5da5Sopenharmony_ci const std::string text = R"( 1292fd4e5da5Sopenharmony_ci OpCapability ImageQuery 1293fd4e5da5Sopenharmony_ci OpCapability Int8 1294fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1295fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %1 "OpnSeman/" %2 1296fd4e5da5Sopenharmony_ci OpExecutionMode %1 OriginUpperLeft 1297fd4e5da5Sopenharmony_ci %void = OpTypeVoid 1298fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %void 1299fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 1300fd4e5da5Sopenharmony_ci %v4float = OpTypeVector %float 4 1301fd4e5da5Sopenharmony_ci %_struct_7 = OpTypeStruct %v4float %v4float 1302fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7 1303fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 1304fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %v4float %_ptr_Function__struct_7 1305fd4e5da5Sopenharmony_ci %char = OpTypeInt 8 1 1306fd4e5da5Sopenharmony_ci %char_1 = OpConstant %char 1 1307fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 1308fd4e5da5Sopenharmony_ci %2 = OpVariable %_ptr_Output_v4float Output 1309fd4e5da5Sopenharmony_ci %1 = OpFunction %void None %4 1310fd4e5da5Sopenharmony_ci %14 = OpLabel 1311fd4e5da5Sopenharmony_ci %15 = OpVariable %_ptr_Function__struct_7 Function 1312fd4e5da5Sopenharmony_ci %16 = OpFunctionCall %v4float %17 %15 1313fd4e5da5Sopenharmony_ci OpReturn 1314fd4e5da5Sopenharmony_ci OpFunctionEnd 1315fd4e5da5Sopenharmony_ci %17 = OpFunction %v4float DontInline %10 1316fd4e5da5Sopenharmony_ci; CHECK: [[param:%\w+]] = OpFunctionParameter 1317fd4e5da5Sopenharmony_ci %18 = OpFunctionParameter %_ptr_Function__struct_7 1318fd4e5da5Sopenharmony_ci %19 = OpLabel 1319fd4e5da5Sopenharmony_ci; CHECK: OpAccessChain %_ptr_Function_v4float [[param]] %uint_0 1320fd4e5da5Sopenharmony_ci %20 = OpAccessChain %_ptr_Function_v4float %18 %char_1 1321fd4e5da5Sopenharmony_ci %21 = OpLoad %v4float %20 1322fd4e5da5Sopenharmony_ci OpReturnValue %21 1323fd4e5da5Sopenharmony_ci OpFunctionEnd 1324fd4e5da5Sopenharmony_ci)"; 1325fd4e5da5Sopenharmony_ci 1326fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true); 1327fd4e5da5Sopenharmony_ci} 1328fd4e5da5Sopenharmony_ci 1329fd4e5da5Sopenharmony_ci} // namespace 1330