| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329 |
- // Copyright (c) 2019 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "assembly_builder.h"
- #include "pass_fixture.h"
- #include "pass_utils.h"
- namespace {
- using namespace spvtools;
- using EliminateDeadMemberTest = opt::PassTest<::testing::Test>;
- TEST_F(EliminateDeadMemberTest, RemoveMember1) {
- // Test that the member "y" is removed.
- // Update OpMemberName for |y| and |z|.
- // Update OpMemberDecorate for |y| and |z|.
- // Update OpAccessChain for access to |z|.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %in_var_Position "in.var.Position"
- OpName %main "main"
- OpDecorate %gl_Position BuiltIn Position
- OpDecorate %in_var_Position Location 0
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %float = OpTypeFloat 32
- %int_2 = OpConstant %int 2
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %15 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %in_var_Position = OpVariable %_ptr_Input_v4float Input
- %gl_Position = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %15
- %17 = OpLabel
- %18 = OpLoad %v4float %in_var_Position
- %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0
- %20 = OpLoad %float %19
- %21 = OpCompositeExtract %float %18 0
- %22 = OpFAdd %float %21 %20
- %23 = OpCompositeInsert %v4float %22 %18 0
- %24 = OpCompositeExtract %float %18 1
- %25 = OpCompositeInsert %v4float %24 %23 1
- %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
- %27 = OpLoad %float %26
- %28 = OpCompositeExtract %float %18 2
- %29 = OpFAdd %float %28 %27
- %30 = OpCompositeInsert %v4float %29 %25 2
- OpStore %gl_Position %30
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberWithGroupDecorations) {
- // Test that the member "y" is removed.
- // Update OpGroupMemberDecorate for %type__Globals member 1 and 2.
- // Update OpAccessChain for access to %type__Globals member 2.
- const std::string text = R"(
- ; CHECK: OpDecorate [[gr1:%\w+]] Offset 0
- ; CHECK: OpDecorate [[gr2:%\w+]] Offset 4
- ; CHECK: OpDecorate [[gr3:%\w+]] Offset 8
- ; CHECK: [[gr1]] = OpDecorationGroup
- ; CHECK: [[gr2]] = OpDecorationGroup
- ; CHECK: [[gr3]] = OpDecorationGroup
- ; CHECK: OpGroupMemberDecorate [[gr1]] %type__Globals 0
- ; CHECK-NOT: OpGroupMemberDecorate [[gr2]]
- ; CHECK: OpGroupMemberDecorate [[gr3]] %type__Globals 1
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %int_0
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpName %_Globals "$Globals"
- OpDecorate %gl_Position BuiltIn Position
- OpDecorate %in_var_Position Location 0
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpDecorate %gr1 Offset 0
- OpDecorate %gr2 Offset 4
- OpDecorate %gr3 Offset 8
- OpDecorate %type__Globals Block
- %gr1 = OpDecorationGroup
- %gr2 = OpDecorationGroup
- %gr3 = OpDecorationGroup
- OpGroupMemberDecorate %gr1 %type__Globals 0
- OpGroupMemberDecorate %gr2 %type__Globals 1
- OpGroupMemberDecorate %gr3 %type__Globals 2
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %float = OpTypeFloat 32
- %int_2 = OpConstant %int 2
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %15 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %in_var_Position = OpVariable %_ptr_Input_v4float Input
- %gl_Position = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %15
- %17 = OpLabel
- %18 = OpLoad %v4float %in_var_Position
- %19 = OpAccessChain %_ptr_Uniform_float %_Globals %int_0
- %20 = OpLoad %float %19
- %21 = OpCompositeExtract %float %18 0
- %22 = OpFAdd %float %21 %20
- %23 = OpCompositeInsert %v4float %22 %18 0
- %24 = OpCompositeExtract %float %18 1
- %25 = OpCompositeInsert %v4float %24 %23 1
- %26 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
- %27 = OpLoad %float %26
- %28 = OpCompositeExtract %float %18 2
- %29 = OpFAdd %float %28 %27
- %30 = OpCompositeInsert %v4float %29 %25 2
- OpStore %gl_Position %30
- OpReturn
- OpFunctionEnd
- )";
- // Skipping validation because of a bug in the validator. See issue #2376.
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, false);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberUpdateConstant) {
- // Test that the member "x" is removed.
- // Update the OpConstantComposite instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: OpConstantComposite %type__Globals %float_1 %float_2
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %in_var_Position "in.var.Position"
- OpName %main "main"
- OpDecorate %gl_Position BuiltIn Position
- OpDecorate %in_var_Position Location 0
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %int = OpTypeInt 32 1
- %int_1 = OpConstant %int 1
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %int_2 = OpConstant %int 2
- %type__Globals = OpTypeStruct %float %float %float
- %13 = OpConstantComposite %type__Globals %float_0 %float_1 %float_2
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %19 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %in_var_Position = OpVariable %_ptr_Input_v4float Input
- %gl_Position = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %19
- %21 = OpLabel
- %22 = OpLoad %v4float %in_var_Position
- %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1
- %24 = OpLoad %float %23
- %25 = OpCompositeExtract %float %22 0
- %26 = OpFAdd %float %25 %24
- %27 = OpCompositeInsert %v4float %26 %22 0
- %28 = OpCompositeExtract %float %22 1
- %29 = OpCompositeInsert %v4float %28 %27 1
- %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
- %31 = OpLoad %float %30
- %32 = OpCompositeExtract %float %22 2
- %33 = OpFAdd %float %32 %31
- %34 = OpCompositeInsert %v4float %33 %29 2
- OpStore %gl_Position %34
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberUpdateCompositeConstruct) {
- // Test that the member "x" is removed.
- // Update the OpConstantComposite instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: OpCompositeConstruct %type__Globals %float_1 %float_2
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_0
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals %uint_1
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %in_var_Position "in.var.Position"
- OpName %main "main"
- OpDecorate %gl_Position BuiltIn Position
- OpDecorate %in_var_Position Location 0
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %int = OpTypeInt 32 1
- %int_1 = OpConstant %int 1
- %float = OpTypeFloat 32
- %float_0 = OpConstant %float 0
- %float_1 = OpConstant %float 1
- %float_2 = OpConstant %float 2
- %int_2 = OpConstant %int 2
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %19 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %in_var_Position = OpVariable %_ptr_Input_v4float Input
- %gl_Position = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %19
- %21 = OpLabel
- %13 = OpCompositeConstruct %type__Globals %float_0 %float_1 %float_2
- %22 = OpLoad %v4float %in_var_Position
- %23 = OpAccessChain %_ptr_Uniform_float %_Globals %int_1
- %24 = OpLoad %float %23
- %25 = OpCompositeExtract %float %22 0
- %26 = OpFAdd %float %25 %24
- %27 = OpCompositeInsert %v4float %26 %22 0
- %28 = OpCompositeExtract %float %22 1
- %29 = OpCompositeInsert %v4float %28 %27 1
- %30 = OpAccessChain %_ptr_Uniform_float %_Globals %int_2
- %31 = OpLoad %float %30
- %32 = OpCompositeExtract %float %22 2
- %33 = OpFAdd %float %32 %31
- %34 = OpCompositeInsert %v4float %33 %29 2
- OpStore %gl_Position %34
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract1) {
- // Test that the members "x" and "z" are removed.
- // Update the OpCompositeExtract instruction.
- // Remove the OpCompositeInsert instruction since the member being inserted is
- // dead.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
- ; CHECK: %type__Globals = OpTypeStruct %float
- ; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
- ; CHECK: OpCompositeExtract %float [[ld]] 0
- ; CHECK-NOT: OpCompositeInsert
- ; CHECK: OpReturn
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %7
- %8 = OpLabel
- %9 = OpLoad %type__Globals %_Globals
- %10 = OpCompositeExtract %float %9 1
- %11 = OpCompositeInsert %type__Globals %10 %9 2
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract2) {
- // Test that the members "x" and "z" are removed.
- // Update the OpCompositeExtract instruction.
- // Update the OpCompositeInsert instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
- ; CHECK: %type__Globals = OpTypeStruct %float
- ; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
- ; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0
- ; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0
- ; CHECK: OpReturn
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %7
- %8 = OpLabel
- %9 = OpLoad %type__Globals %_Globals
- %10 = OpCompositeExtract %float %9 1
- %11 = OpCompositeInsert %type__Globals %10 %9 1
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract3) {
- // Test that the members "x" and "z" are removed, and one member from the
- // substruct. Update the OpCompositeExtract instruction. Update the
- // OpCompositeInsert instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
- ; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
- ; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
- ; CHECK: [[struct:%\w+]] = OpTypeStruct %float
- ; CHECK: %type__Globals = OpTypeStruct [[struct]]
- ; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
- ; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 0
- ; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 0
- ; CHECK: OpReturn
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 16
- OpMemberDecorate %type__Globals 2 Offset 24
- OpMemberDecorate %_struct_6 0 Offset 0
- OpMemberDecorate %_struct_6 1 Offset 4
- OpDecorate %type__Globals Block
- %float = OpTypeFloat 32
- %_struct_6 = OpTypeStruct %float %float
- %type__Globals = OpTypeStruct %float %_struct_6 %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %7
- %8 = OpLabel
- %9 = OpLoad %type__Globals %_Globals
- %10 = OpCompositeExtract %float %9 1 1
- %11 = OpCompositeInsert %type__Globals %10 %9 1 1
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMembersUpdateInserExtract4) {
- // Test that the members "x" and "z" are removed, and one member from the
- // substruct. Update the OpCompositeExtract instruction. Update the
- // OpCompositeInsert instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
- ; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
- ; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
- ; CHECK: [[struct:%\w+]] = OpTypeStruct %float
- ; CHECK: [[array:%\w+]] = OpTypeArray [[struct]]
- ; CHECK: %type__Globals = OpTypeStruct [[array]]
- ; CHECK: [[ld:%\w+]] = OpLoad %type__Globals %_Globals
- ; CHECK: [[ex:%\w+]] = OpCompositeExtract %float [[ld]] 0 1 0
- ; CHECK: OpCompositeInsert %type__Globals [[ex]] [[ld]] 0 1 0
- ; CHECK: OpReturn
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 16
- OpMemberDecorate %type__Globals 2 Offset 80
- OpMemberDecorate %_struct_6 0 Offset 0
- OpMemberDecorate %_struct_6 1 Offset 4
- OpDecorate %array ArrayStride 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0 ; 32-bit int, sign-less
- %uint_4 = OpConstant %uint 4
- %float = OpTypeFloat 32
- %_struct_6 = OpTypeStruct %float %float
- %array = OpTypeArray %_struct_6 %uint_4
- %type__Globals = OpTypeStruct %float %array %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %7 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %7
- %8 = OpLabel
- %9 = OpLoad %type__Globals %_Globals
- %10 = OpCompositeExtract %float %9 1 1 1
- %11 = OpCompositeInsert %type__Globals %10 %9 1 1 1
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMembersUpdateArrayLength) {
- // Test that the members "x" and "y" are removed.
- // Member "z" is live because of the OpArrayLength instruction.
- // Update the OpArrayLength instruction.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
- ; CHECK-NOT: OpMemberDecorate %type__Globals 1 Offset
- ; CHECK: %type__Globals = OpTypeStruct %_runtimearr_float
- ; CHECK: OpArrayLength %uint %_Globals 0
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpDecorate %_runtimearr_float ArrayStride 16
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %_runtimearr_float = OpTypeRuntimeArray %float
- %type__Globals = OpTypeStruct %float %float %_runtimearr_float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %9
- %10 = OpLabel
- %12 = OpArrayLength %uint %_Globals 2
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, KeepMembersOpStore) {
- // Test that all members are kept because of an OpStore.
- // No change expected.
- const std::string text = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %_Globals "$Globals2"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %9
- %10 = OpLabel
- %11 = OpLoad %type__Globals %_Globals
- OpStore %_Globals2 %11
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, KeepStorageBufferMembers) {
- // Test that all members of the storage buffer struct %S are kept.
- // No change expected.
- const std::string text = R"(
- OpCapability Shader
- OpExtension "SPV_GOOGLE_hlsl_functionality1"
- OpExtension "SPV_GOOGLE_user_type"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %PSMain "PSMain" %out_var_SV_TARGET
- OpExecutionMode %PSMain OriginUpperLeft
- OpSource HLSL 600
- OpName %type_StructuredBuffer_S "type.StructuredBuffer.S"
- OpName %S "S"
- OpMemberName %S 0 "A"
- OpMemberName %S 1 "B"
- OpName %Buf "Buf"
- OpName %out_var_SV_TARGET "out.var.SV_TARGET"
- OpName %PSMain "PSMain"
- OpDecorateString %out_var_SV_TARGET UserSemantic "SV_TARGET"
- OpDecorate %out_var_SV_TARGET Location 0
- OpDecorate %Buf DescriptorSet 0
- OpDecorate %Buf Binding 0
- OpMemberDecorate %S 0 Offset 0
- OpMemberDecorate %S 1 Offset 16
- OpDecorate %_runtimearr_S ArrayStride 32
- OpMemberDecorate %type_StructuredBuffer_S 0 Offset 0
- OpMemberDecorate %type_StructuredBuffer_S 0 NonWritable
- OpDecorate %type_StructuredBuffer_S BufferBlock
- OpDecorateString %Buf UserTypeGOOGLE "structuredbuffer"
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %int_1 = OpConstant %int 1
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %S = OpTypeStruct %v4float %v4float
- %_runtimearr_S = OpTypeRuntimeArray %S
- %type_StructuredBuffer_S = OpTypeStruct %_runtimearr_S
- %_ptr_Uniform_type_StructuredBuffer_S = OpTypePointer Uniform %type_StructuredBuffer_S
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %18 = OpTypeFunction %void
- %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
- %Buf = OpVariable %_ptr_Uniform_type_StructuredBuffer_S Uniform
- %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
- %PSMain = OpFunction %void None %18
- %20 = OpLabel
- %21 = OpAccessChain %_ptr_Uniform_v4float %Buf %int_0 %uint_0 %int_1
- %22 = OpLoad %v4float %21
- OpStore %out_var_SV_TARGET %22
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemory) {
- // Test that all members are kept because of an OpCopyMemory.
- // No change expected.
- const std::string text = R"(
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %_Globals "$Globals2"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %9
- %10 = OpLabel
- OpCopyMemory %_Globals2 %_Globals
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, KeepMembersOpCopyMemorySized) {
- // Test that all members are kept because of an OpCopyMemorySized.
- // No change expected.
- const std::string text = R"(
- OpCapability Shader
- OpCapability Addresses
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %_Globals "$Globals2"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %uint_20 = OpConstant %uint 20
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %9 = OpTypeFunction %void
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %void None %9
- %10 = OpLabel
- OpCopyMemorySized %_Globals2 %_Globals %uint_20
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, KeepMembersOpReturnValue) {
- // Test that all members are kept because of an OpCopyMemorySized.
- // No change expected.
- const std::string text = R"(
- OpCapability Shader
- OpCapability Linkage
- OpMemoryModel Logical GLSL450
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %_Globals "$Globals2"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %uint_20 = OpConstant %uint 20
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %void = OpTypeVoid
- %9 = OpTypeFunction %type__Globals
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %_Globals2 = OpVariable %_ptr_Uniform_type__Globals Uniform
- %main = OpFunction %type__Globals None %9
- %10 = OpLabel
- %11 = OpLoad %type__Globals %_Globals
- OpReturnValue %11
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberAccessChainWithArrays) {
- // Leave only 1 member in each of the structs.
- // Update OpMemberName, OpMemberDecorate, and OpAccessChain.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 16
- ; CHECK: OpMemberDecorate [[struct:%\w+]] 0 Offset 4
- ; CHECK: [[struct]] = OpTypeStruct %float
- ; CHECK: [[array:%\w+]] = OpTypeArray [[struct]]
- ; CHECK: %type__Globals = OpTypeStruct [[array]]
- ; CHECK: [[undef:%\w+]] = OpUndef %uint
- ; CHECK: OpAccessChain %_ptr_Uniform_float %_Globals [[undef]] %uint_0 [[undef]] %uint_0
- OpCapability Shader
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 16
- OpMemberDecorate %type__Globals 2 Offset 48
- OpMemberDecorate %_struct_4 0 Offset 0
- OpMemberDecorate %_struct_4 1 Offset 4
- OpDecorate %_arr__struct_4_uint_2 ArrayStride 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %float = OpTypeFloat 32
- %_struct_4 = OpTypeStruct %float %float
- %_arr__struct_4_uint_2 = OpTypeArray %_struct_4 %uint_2
- %type__Globals = OpTypeStruct %float %_arr__struct_4_uint_2 %float
- %_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
- %_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
- %void = OpTypeVoid
- %15 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
- %main = OpFunction %void None %15
- %17 = OpLabel
- %18 = OpUndef %uint
- %19 = OpAccessChain %_ptr_Uniform_float %_Globals %18 %uint_1 %18 %uint_1
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberInboundsAccessChain) {
- // Test that the member "y" is removed.
- // Update OpMemberName for |y| and |z|.
- // Update OpMemberDecorate for |y| and |z|.
- // Update OpInboundsAccessChain for access to |z|.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 8
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0
- ; CHECK: OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %uint_1
- OpCapability Shader
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %in_var_Position %gl_Position
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %in_var_Position "in.var.Position"
- OpName %main "main"
- OpDecorate %gl_Position BuiltIn Position
- OpDecorate %in_var_Position Location 0
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 8
- OpDecorate %type__Globals Block
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %float = OpTypeFloat 32
- %int_2 = OpConstant %int 2
- %type__Globals = OpTypeStruct %float %float %float
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %v4float = OpTypeVector %float 4
- %_ptr_Input_v4float = OpTypePointer Input %v4float
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %void = OpTypeVoid
- %15 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform_type__Globals Uniform
- %in_var_Position = OpVariable %_ptr_Input_v4float Input
- %gl_Position = OpVariable %_ptr_Output_v4float Output
- %main = OpFunction %void None %15
- %17 = OpLabel
- %18 = OpLoad %v4float %in_var_Position
- %19 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_0
- %20 = OpLoad %float %19
- %21 = OpCompositeExtract %float %18 0
- %22 = OpFAdd %float %21 %20
- %23 = OpCompositeInsert %v4float %22 %18 0
- %24 = OpCompositeExtract %float %18 1
- %25 = OpCompositeInsert %v4float %24 %23 1
- %26 = OpInBoundsAccessChain %_ptr_Uniform_float %_Globals %int_2
- %27 = OpLoad %float %26
- %28 = OpCompositeExtract %float %18 2
- %29 = OpFAdd %float %28 %27
- %30 = OpCompositeInsert %v4float %29 %25 2
- OpStore %gl_Position %30
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberPtrAccessChain) {
- // Test that the member "y" is removed.
- // Update OpMemberName for |y| and |z|.
- // Update OpMemberDecorate for |y| and |z|.
- // Update OpInboundsAccessChain for access to |z|.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 16
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
- ; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0
- ; CHECK: OpPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1
- OpCapability Shader
- OpCapability VariablePointersStorageBuffer
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- OpDecorate %_ptr_Uniform_type__Globals ArrayStride 8
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
- %void = OpTypeVoid
- %14 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
- %main = OpFunction %void None %14
- %16 = OpLabel
- %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
- %18 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0
- %19 = OpPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, RemoveMemberInBoundsPtrAccessChain) {
- // Test that the member "y" is removed.
- // Update OpMemberName for |y| and |z|.
- // Update OpMemberDecorate for |y| and |z|.
- // Update OpInboundsAccessChain for access to |z|.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "x"
- ; CHECK-NEXT: OpMemberName %type__Globals 1 "z"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 0
- ; CHECK: OpMemberDecorate %type__Globals 1 Offset 16
- ; CHECK: %type__Globals = OpTypeStruct %float %float
- ; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
- ; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_1 %uint_0
- ; CHECK: OpInBoundsPtrAccessChain %_ptr_Uniform_float [[ac]] %uint_0 %uint_1
- OpCapability Shader
- OpCapability Addresses
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %_Globals "$Globals"
- OpName %main "main"
- OpDecorate %_Globals DescriptorSet 0
- OpDecorate %_Globals Binding 0
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- OpDecorate %type__Globals Block
- %uint = OpTypeInt 32 0
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %float = OpTypeFloat 32
- %type__Globals = OpTypeStruct %float %float %float
- %_arr_type__Globals_uint_3 = OpTypeArray %type__Globals %uint_3
- %_ptr_Uniform_type__Globals = OpTypePointer Uniform %type__Globals
- %_ptr_Uniform__arr_type__Globals_uint_3 = OpTypePointer Uniform %_arr_type__Globals_uint_3
- %void = OpTypeVoid
- %14 = OpTypeFunction %void
- %_ptr_Uniform_float = OpTypePointer Uniform %float
- %_Globals = OpVariable %_ptr_Uniform__arr_type__Globals_uint_3 Uniform
- %main = OpFunction %void None %14
- %16 = OpLabel
- %17 = OpAccessChain %_ptr_Uniform_type__Globals %_Globals %uint_0
- %18 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_1 %uint_0
- %19 = OpInBoundsPtrAccessChain %_ptr_Uniform_float %17 %uint_0 %uint_2
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, DontRemoveModfStructResultTypeMembers) {
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main"
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 600
- %float = OpTypeFloat 32
- %void = OpTypeVoid
- %21 = OpTypeFunction %void
- %ModfStructType = OpTypeStruct %float %float
- %main = OpFunction %void None %21
- %22 = OpLabel
- %23 = OpUndef %float
- %24 = OpExtInst %ModfStructType %1 ModfStruct %23
- %25 = OpCompositeExtract %float %24 1
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, DontChangeInputStructs) {
- // The input for a shader has to match the type of the output from the
- // previous shader in the pipeline. Because of that, we cannot change the
- // types of input variables.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %input_var
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 600
- %float = OpTypeFloat 32
- %void = OpTypeVoid
- %21 = OpTypeFunction %void
- %in_var_type = OpTypeStruct %float %float
- %in_ptr_type = OpTypePointer Input %in_var_type
- %input_var = OpVariable %in_ptr_type Input
- %main = OpFunction %void None %21
- %22 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, DontChangeOutputStructs) {
- // The output for a shader has to match the type of the output from the
- // previous shader in the pipeline. Because of that, we cannot change the
- // types of output variables.
- const std::string text = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %output_var
- OpExecutionMode %main OriginUpperLeft
- OpSource HLSL 600
- %float = OpTypeFloat 32
- %void = OpTypeVoid
- %21 = OpTypeFunction %void
- %out_var_type = OpTypeStruct %float %float
- %out_ptr_type = OpTypePointer Output %out_var_type
- %output_var = OpVariable %out_ptr_type Output
- %main = OpFunction %void None %21
- %22 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, UpdateSpecConstOpExtract) {
- // Test that an extract in an OpSpecConstantOp is correctly updated.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK: %type__Globals = OpTypeStruct %uint
- ; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]]
- ; CHECK: OpSpecConstantOp %uint CompositeExtract [[struct]] 0
- OpCapability Shader
- OpCapability Addresses
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %main "main"
- OpDecorate %c_0 SpecId 0
- OpDecorate %c_1 SpecId 1
- OpDecorate %c_2 SpecId 2
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- %uint = OpTypeInt 32 0
- %c_0 = OpSpecConstant %uint 0
- %c_1 = OpSpecConstant %uint 1
- %c_2 = OpSpecConstant %uint 2
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %type__Globals = OpTypeStruct %uint %uint %uint
- %spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2
- %extract = OpSpecConstantOp %uint CompositeExtract %spec_const_global 1
- %void = OpTypeVoid
- %14 = OpTypeFunction %void
- %main = OpFunction %void None %14
- %16 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, UpdateSpecConstOpInsert) {
- // Test that an insert in an OpSpecConstantOp is correctly updated.
- const std::string text = R"(
- ; CHECK: OpName
- ; CHECK-NEXT: OpMemberName %type__Globals 0 "y"
- ; CHECK-NOT: OpMemberName
- ; CHECK: OpDecorate [[spec_const:%\w+]] SpecId 1
- ; CHECK: OpMemberDecorate %type__Globals 0 Offset 4
- ; CHECK: %type__Globals = OpTypeStruct %uint
- ; CHECK: [[struct:%\w+]] = OpSpecConstantComposite %type__Globals [[spec_const]]
- ; CHECK: OpSpecConstantOp %type__Globals CompositeInsert %uint_3 [[struct]] 0
- OpCapability Shader
- OpCapability Addresses
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main"
- OpSource HLSL 600
- OpName %type__Globals "type.$Globals"
- OpMemberName %type__Globals 0 "x"
- OpMemberName %type__Globals 1 "y"
- OpMemberName %type__Globals 2 "z"
- OpName %main "main"
- OpDecorate %c_0 SpecId 0
- OpDecorate %c_1 SpecId 1
- OpDecorate %c_2 SpecId 2
- OpMemberDecorate %type__Globals 0 Offset 0
- OpMemberDecorate %type__Globals 1 Offset 4
- OpMemberDecorate %type__Globals 2 Offset 16
- %uint = OpTypeInt 32 0
- %c_0 = OpSpecConstant %uint 0
- %c_1 = OpSpecConstant %uint 1
- %c_2 = OpSpecConstant %uint 2
- %uint_0 = OpConstant %uint 0
- %uint_1 = OpConstant %uint 1
- %uint_2 = OpConstant %uint 2
- %uint_3 = OpConstant %uint 3
- %type__Globals = OpTypeStruct %uint %uint %uint
- %spec_const_global = OpSpecConstantComposite %type__Globals %c_0 %c_1 %c_2
- %insert = OpSpecConstantOp %type__Globals CompositeInsert %uint_3 %spec_const_global 1
- %extract = OpSpecConstantOp %uint CompositeExtract %insert 1
- %void = OpTypeVoid
- %14 = OpTypeFunction %void
- %main = OpFunction %void None %14
- %16 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- TEST_F(EliminateDeadMemberTest, 8BitIndexNoChange) {
- // Test that the pass does not crash when an 8 bit index is used in an
- // OpAccessChain. No change is expected.
- const std::string text = R"(
- OpCapability ImageQuery
- OpCapability Int8
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "OpnSeman/" %2
- OpExecutionMode %1 OriginUpperLeft
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_struct_7 = OpTypeStruct %v4float
- %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %10 = OpTypeFunction %v4float %_ptr_Function__struct_7
- %char = OpTypeInt 8 1
- %char_0 = OpConstant %char 0
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %2 = OpVariable %_ptr_Output_v4float Output
- %1 = OpFunction %void None %4
- %14 = OpLabel
- %15 = OpVariable %_ptr_Function__struct_7 Function
- %16 = OpFunctionCall %v4float %17 %15
- OpReturn
- OpFunctionEnd
- %17 = OpFunction %v4float DontInline %10
- %18 = OpFunctionParameter %_ptr_Function__struct_7
- %19 = OpLabel
- %20 = OpAccessChain %_ptr_Function_v4float %18 %char_0
- %21 = OpLoad %v4float %20
- OpReturnValue %21
- OpFunctionEnd
- )";
- auto result = SinglePassRunAndDisassemble<opt::EliminateDeadMembersPass>(
- text, /* skip_nop = */ true, /* do_validation = */ true);
- EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
- }
- TEST_F(EliminateDeadMemberTest, 8BitIndexWithChange) {
- // Test that the pass does not crash when an 8 bit index is used in an
- // OpAccessChain. The index in the access change should be changed to 0.
- const std::string text = R"(
- OpCapability ImageQuery
- OpCapability Int8
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %1 "OpnSeman/" %2
- OpExecutionMode %1 OriginUpperLeft
- %void = OpTypeVoid
- %4 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_struct_7 = OpTypeStruct %v4float %v4float
- %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %10 = OpTypeFunction %v4float %_ptr_Function__struct_7
- %char = OpTypeInt 8 1
- %char_1 = OpConstant %char 1
- %_ptr_Function_v4float = OpTypePointer Function %v4float
- %2 = OpVariable %_ptr_Output_v4float Output
- %1 = OpFunction %void None %4
- %14 = OpLabel
- %15 = OpVariable %_ptr_Function__struct_7 Function
- %16 = OpFunctionCall %v4float %17 %15
- OpReturn
- OpFunctionEnd
- %17 = OpFunction %v4float DontInline %10
- ; CHECK: [[param:%\w+]] = OpFunctionParameter
- %18 = OpFunctionParameter %_ptr_Function__struct_7
- %19 = OpLabel
- ; CHECK: OpAccessChain %_ptr_Function_v4float [[param]] %uint_0
- %20 = OpAccessChain %_ptr_Function_v4float %18 %char_1
- %21 = OpLoad %v4float %20
- OpReturnValue %21
- OpFunctionEnd
- )";
- SinglePassRunAndMatch<opt::EliminateDeadMembersPass>(text, true);
- }
- } // namespace
|