1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Valve Corporation
2fd4e5da5Sopenharmony_ci// Copyright (c) 2017 LunarG Inc.
3fd4e5da5Sopenharmony_ci//
4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
7fd4e5da5Sopenharmony_ci//
8fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
9fd4e5da5Sopenharmony_ci//
10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
14fd4e5da5Sopenharmony_ci// limitations under the License.
15fd4e5da5Sopenharmony_ci
16fd4e5da5Sopenharmony_ci#include <string>
17fd4e5da5Sopenharmony_ci
18fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
19fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace opt {
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciusing DeadInsertElimTest = PassTest<::testing::Test>;
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, InsertAfterInsertElim) {
28fd4e5da5Sopenharmony_ci  // With two insertions to the same offset, the first is dead.
29fd4e5da5Sopenharmony_ci  //
30fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
31fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
32fd4e5da5Sopenharmony_ci  // reference each other.
33fd4e5da5Sopenharmony_ci  //
34fd4e5da5Sopenharmony_ci  // #version 450
35fd4e5da5Sopenharmony_ci  //
36fd4e5da5Sopenharmony_ci  // layout (location=0) in float In0;
37fd4e5da5Sopenharmony_ci  // layout (location=1) in float In1;
38fd4e5da5Sopenharmony_ci  // layout (location=2) in vec2 In2;
39fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
40fd4e5da5Sopenharmony_ci  //
41fd4e5da5Sopenharmony_ci  // void main()
42fd4e5da5Sopenharmony_ci  // {
43fd4e5da5Sopenharmony_ci  //     vec2 v = In2;
44fd4e5da5Sopenharmony_ci  //     v.x = In0 + In1; // dead
45fd4e5da5Sopenharmony_ci  //     v.x = 0.0;
46fd4e5da5Sopenharmony_ci  //     OutColor = v.xyxy;
47fd4e5da5Sopenharmony_ci  // }
48fd4e5da5Sopenharmony_ci
49fd4e5da5Sopenharmony_ci  const std::string before_predefs =
50fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
51fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
52fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
53fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
54fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
55fd4e5da5Sopenharmony_ciOpSource GLSL 450
56fd4e5da5Sopenharmony_ciOpName %main "main"
57fd4e5da5Sopenharmony_ciOpName %In2 "In2"
58fd4e5da5Sopenharmony_ciOpName %In0 "In0"
59fd4e5da5Sopenharmony_ciOpName %In1 "In1"
60fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
61fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
62fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
63fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 1 "g_n"
64fd4e5da5Sopenharmony_ciOpName %_ ""
65fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
66fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
67fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
68fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
69fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
70fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 1 Offset 4
71fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
72fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
73fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
74fd4e5da5Sopenharmony_ci%void = OpTypeVoid
75fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
76fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
77fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
78fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
79fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
80fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_v2float Input
81fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
82fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_float Input
83fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
84fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
85fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
86fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
87fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
88fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
89fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
90fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
91fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint %int
92fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
93fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
94fd4e5da5Sopenharmony_ci)";
95fd4e5da5Sopenharmony_ci
96fd4e5da5Sopenharmony_ci  const std::string after_predefs =
97fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
98fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
99fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
100fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
101fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
102fd4e5da5Sopenharmony_ciOpSource GLSL 450
103fd4e5da5Sopenharmony_ciOpName %main "main"
104fd4e5da5Sopenharmony_ciOpName %In2 "In2"
105fd4e5da5Sopenharmony_ciOpName %In0 "In0"
106fd4e5da5Sopenharmony_ciOpName %In1 "In1"
107fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
108fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
109fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
110fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 1 "g_n"
111fd4e5da5Sopenharmony_ciOpName %_ ""
112fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
113fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
114fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
115fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
116fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
117fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 1 Offset 4
118fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
119fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
120fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
121fd4e5da5Sopenharmony_ci%void = OpTypeVoid
122fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
123fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
124fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
125fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
126fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
127fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_v2float Input
128fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
129fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_float Input
130fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
131fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
132fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
133fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
134fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
135fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
136fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
137fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
138fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint %int
139fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
140fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
141fd4e5da5Sopenharmony_ci)";
142fd4e5da5Sopenharmony_ci
143fd4e5da5Sopenharmony_ci  const std::string before =
144fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %11
145fd4e5da5Sopenharmony_ci%25 = OpLabel
146fd4e5da5Sopenharmony_ci%26 = OpLoad %v2float %In2
147fd4e5da5Sopenharmony_ci%27 = OpLoad %float %In0
148fd4e5da5Sopenharmony_ci%28 = OpLoad %float %In1
149fd4e5da5Sopenharmony_ci%29 = OpFAdd %float %27 %28
150fd4e5da5Sopenharmony_ci%35 = OpCompositeInsert %v2float %29 %26 0
151fd4e5da5Sopenharmony_ci%37 = OpCompositeInsert %v2float %float_0 %35 0
152fd4e5da5Sopenharmony_ci%33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
153fd4e5da5Sopenharmony_ciOpStore %OutColor %33
154fd4e5da5Sopenharmony_ciOpReturn
155fd4e5da5Sopenharmony_ciOpFunctionEnd
156fd4e5da5Sopenharmony_ci)";
157fd4e5da5Sopenharmony_ci
158fd4e5da5Sopenharmony_ci  const std::string after =
159fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
160fd4e5da5Sopenharmony_ci%23 = OpLabel
161fd4e5da5Sopenharmony_ci%24 = OpLoad %v2float %In2
162fd4e5da5Sopenharmony_ci%29 = OpCompositeInsert %v2float %float_0 %24 0
163fd4e5da5Sopenharmony_ci%30 = OpVectorShuffle %v4float %29 %29 0 1 0 1
164fd4e5da5Sopenharmony_ciOpStore %OutColor %30
165fd4e5da5Sopenharmony_ciOpReturn
166fd4e5da5Sopenharmony_ciOpFunctionEnd
167fd4e5da5Sopenharmony_ci)";
168fd4e5da5Sopenharmony_ci
169fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
170fd4e5da5Sopenharmony_ci                                            after_predefs + after, true, true);
171fd4e5da5Sopenharmony_ci}
172fd4e5da5Sopenharmony_ci
173fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, DeadInsertForLinkage) {
174fd4e5da5Sopenharmony_ci  const std::string before =
175fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
176fd4e5da5Sopenharmony_ciOpCapability Linkage
177fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
178fd4e5da5Sopenharmony_ciOpSource HLSL 630
179fd4e5da5Sopenharmony_ciOpName %main "main"
180fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
181fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
182fd4e5da5Sopenharmony_ciOpName %v "v"
183fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export
184fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
185fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
186fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
187fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
188fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
189fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
190fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
191fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
192fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
193fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %v2float %_ptr_Function_v2float
194fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
195fd4e5da5Sopenharmony_ci%main = OpFunction %v2float None %14
196fd4e5da5Sopenharmony_ci%BaseColor = OpFunctionParameter %_ptr_Function_v2float
197fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
198fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v2float Function
199fd4e5da5Sopenharmony_ci%16 = OpLoad %v2float %v
200fd4e5da5Sopenharmony_ci%17 = OpAccessChain %_ptr_Function_float %BaseColor %int_1
201fd4e5da5Sopenharmony_ci%18 = OpLoad %float %17
202fd4e5da5Sopenharmony_ci%19 = OpCompositeInsert %v2float %18 %16 0
203fd4e5da5Sopenharmony_ci%20 = OpCompositeInsert %v2float %float_0 %19 0
204fd4e5da5Sopenharmony_ciOpReturnValue %20
205fd4e5da5Sopenharmony_ciOpFunctionEnd
206fd4e5da5Sopenharmony_ci)";
207fd4e5da5Sopenharmony_ci  const std::string after =
208fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
209fd4e5da5Sopenharmony_ciOpCapability Linkage
210fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
211fd4e5da5Sopenharmony_ciOpSource HLSL 630
212fd4e5da5Sopenharmony_ciOpName %main "main"
213fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
214fd4e5da5Sopenharmony_ciOpName %bb_entry "bb.entry"
215fd4e5da5Sopenharmony_ciOpName %v "v"
216fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export
217fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
218fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
219fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
220fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
221fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
222fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
223fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
224fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
225fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %v2float %_ptr_Function_v2float
226fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
227fd4e5da5Sopenharmony_ci%main = OpFunction %v2float None %14
228fd4e5da5Sopenharmony_ci%BaseColor = OpFunctionParameter %_ptr_Function_v2float
229fd4e5da5Sopenharmony_ci%bb_entry = OpLabel
230fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v2float Function
231fd4e5da5Sopenharmony_ci%16 = OpLoad %v2float %v
232fd4e5da5Sopenharmony_ci%20 = OpCompositeInsert %v2float %float_0 %16 0
233fd4e5da5Sopenharmony_ciOpReturnValue %20
234fd4e5da5Sopenharmony_ciOpFunctionEnd
235fd4e5da5Sopenharmony_ci)";
236fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<DeadInsertElimPass>(before, after, true, true);
237fd4e5da5Sopenharmony_ci}
238fd4e5da5Sopenharmony_ci
239fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, DeadInsertInChainWithPhi) {
240fd4e5da5Sopenharmony_ci  // Dead insert eliminated with phi in insertion chain.
241fd4e5da5Sopenharmony_ci  //
242fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
243fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
244fd4e5da5Sopenharmony_ci  // reference each other.
245fd4e5da5Sopenharmony_ci  //
246fd4e5da5Sopenharmony_ci  // #version 450
247fd4e5da5Sopenharmony_ci  //
248fd4e5da5Sopenharmony_ci  // layout (location=0) in vec4 In0;
249fd4e5da5Sopenharmony_ci  // layout (location=1) in float In1;
250fd4e5da5Sopenharmony_ci  // layout (location=2) in float In2;
251fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
252fd4e5da5Sopenharmony_ci  //
253fd4e5da5Sopenharmony_ci  // layout(std140, binding = 0 ) uniform _Globals_
254fd4e5da5Sopenharmony_ci  // {
255fd4e5da5Sopenharmony_ci  //     bool g_b;
256fd4e5da5Sopenharmony_ci  // };
257fd4e5da5Sopenharmony_ci  //
258fd4e5da5Sopenharmony_ci  // void main()
259fd4e5da5Sopenharmony_ci  // {
260fd4e5da5Sopenharmony_ci  //     vec4 v = In0;
261fd4e5da5Sopenharmony_ci  //     v.z = In1 + In2;
262fd4e5da5Sopenharmony_ci  //     if (g_b) v.w = 1.0;
263fd4e5da5Sopenharmony_ci  //     OutColor = vec4(v.x,v.y,0.0,v.w);
264fd4e5da5Sopenharmony_ci  // }
265fd4e5da5Sopenharmony_ci
266fd4e5da5Sopenharmony_ci  const std::string before_predefs =
267fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
268fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
269fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
270fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
271fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
272fd4e5da5Sopenharmony_ciOpSource GLSL 450
273fd4e5da5Sopenharmony_ciOpName %main "main"
274fd4e5da5Sopenharmony_ciOpName %In0 "In0"
275fd4e5da5Sopenharmony_ciOpName %In1 "In1"
276fd4e5da5Sopenharmony_ciOpName %In2 "In2"
277fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
278fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
279fd4e5da5Sopenharmony_ciOpName %_ ""
280fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
281fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
282fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
283fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
284fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
285fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
286fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
287fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
288fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
289fd4e5da5Sopenharmony_ci%void = OpTypeVoid
290fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
291fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
292fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
293fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
294fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
295fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_v4float Input
296fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
297fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
298fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_float Input
299fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
300fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
301fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint
302fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
303fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
304fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
305fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
306fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
307fd4e5da5Sopenharmony_ci%bool = OpTypeBool
308fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
309fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
310fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
311fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
312fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
313fd4e5da5Sopenharmony_ci)";
314fd4e5da5Sopenharmony_ci
315fd4e5da5Sopenharmony_ci  const std::string after_predefs =
316fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
317fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
318fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
319fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
320fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
321fd4e5da5Sopenharmony_ciOpSource GLSL 450
322fd4e5da5Sopenharmony_ciOpName %main "main"
323fd4e5da5Sopenharmony_ciOpName %In0 "In0"
324fd4e5da5Sopenharmony_ciOpName %In1 "In1"
325fd4e5da5Sopenharmony_ciOpName %In2 "In2"
326fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
327fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
328fd4e5da5Sopenharmony_ciOpName %_ ""
329fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
330fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
331fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
332fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
333fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
334fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
335fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
336fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
337fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
338fd4e5da5Sopenharmony_ci%void = OpTypeVoid
339fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
340fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
341fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
342fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
343fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
344fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_v4float Input
345fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
346fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
347fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_float Input
348fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
349fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
350fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint
351fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
352fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
353fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
354fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
355fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
356fd4e5da5Sopenharmony_ci%bool = OpTypeBool
357fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
358fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
359fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
360fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
361fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
362fd4e5da5Sopenharmony_ci)";
363fd4e5da5Sopenharmony_ci
364fd4e5da5Sopenharmony_ci  const std::string before =
365fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %11
366fd4e5da5Sopenharmony_ci%31 = OpLabel
367fd4e5da5Sopenharmony_ci%32 = OpLoad %v4float %In0
368fd4e5da5Sopenharmony_ci%33 = OpLoad %float %In1
369fd4e5da5Sopenharmony_ci%34 = OpLoad %float %In2
370fd4e5da5Sopenharmony_ci%35 = OpFAdd %float %33 %34
371fd4e5da5Sopenharmony_ci%51 = OpCompositeInsert %v4float %35 %32 2
372fd4e5da5Sopenharmony_ci%37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
373fd4e5da5Sopenharmony_ci%38 = OpLoad %uint %37
374fd4e5da5Sopenharmony_ci%39 = OpINotEqual %bool %38 %uint_0
375fd4e5da5Sopenharmony_ciOpSelectionMerge %40 None
376fd4e5da5Sopenharmony_ciOpBranchConditional %39 %41 %40
377fd4e5da5Sopenharmony_ci%41 = OpLabel
378fd4e5da5Sopenharmony_ci%53 = OpCompositeInsert %v4float %float_1 %51 3
379fd4e5da5Sopenharmony_ciOpBranch %40
380fd4e5da5Sopenharmony_ci%40 = OpLabel
381fd4e5da5Sopenharmony_ci%60 = OpPhi %v4float %51 %31 %53 %41
382fd4e5da5Sopenharmony_ci%55 = OpCompositeExtract %float %60 0
383fd4e5da5Sopenharmony_ci%57 = OpCompositeExtract %float %60 1
384fd4e5da5Sopenharmony_ci%59 = OpCompositeExtract %float %60 3
385fd4e5da5Sopenharmony_ci%49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
386fd4e5da5Sopenharmony_ciOpStore %OutColor %49
387fd4e5da5Sopenharmony_ciOpReturn
388fd4e5da5Sopenharmony_ciOpFunctionEnd
389fd4e5da5Sopenharmony_ci)";
390fd4e5da5Sopenharmony_ci
391fd4e5da5Sopenharmony_ci  const std::string after =
392fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
393fd4e5da5Sopenharmony_ci%27 = OpLabel
394fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %In0
395fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
396fd4e5da5Sopenharmony_ci%34 = OpLoad %uint %33
397fd4e5da5Sopenharmony_ci%35 = OpINotEqual %bool %34 %uint_0
398fd4e5da5Sopenharmony_ciOpSelectionMerge %36 None
399fd4e5da5Sopenharmony_ciOpBranchConditional %35 %37 %36
400fd4e5da5Sopenharmony_ci%37 = OpLabel
401fd4e5da5Sopenharmony_ci%38 = OpCompositeInsert %v4float %float_1 %28 3
402fd4e5da5Sopenharmony_ciOpBranch %36
403fd4e5da5Sopenharmony_ci%36 = OpLabel
404fd4e5da5Sopenharmony_ci%39 = OpPhi %v4float %28 %27 %38 %37
405fd4e5da5Sopenharmony_ci%40 = OpCompositeExtract %float %39 0
406fd4e5da5Sopenharmony_ci%41 = OpCompositeExtract %float %39 1
407fd4e5da5Sopenharmony_ci%42 = OpCompositeExtract %float %39 3
408fd4e5da5Sopenharmony_ci%43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
409fd4e5da5Sopenharmony_ciOpStore %OutColor %43
410fd4e5da5Sopenharmony_ciOpReturn
411fd4e5da5Sopenharmony_ciOpFunctionEnd
412fd4e5da5Sopenharmony_ci)";
413fd4e5da5Sopenharmony_ci
414fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
415fd4e5da5Sopenharmony_ci                                            after_predefs + after, true, true);
416fd4e5da5Sopenharmony_ci}
417fd4e5da5Sopenharmony_ci
418fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, DeadInsertTwoPasses) {
419fd4e5da5Sopenharmony_ci  // Dead insert which requires two passes to eliminate
420fd4e5da5Sopenharmony_ci  //
421fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
422fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
423fd4e5da5Sopenharmony_ci  // reference each other.
424fd4e5da5Sopenharmony_ci  //
425fd4e5da5Sopenharmony_ci  // #version 450
426fd4e5da5Sopenharmony_ci  //
427fd4e5da5Sopenharmony_ci  // layout (location=0) in vec4 In0;
428fd4e5da5Sopenharmony_ci  // layout (location=1) in float In1;
429fd4e5da5Sopenharmony_ci  // layout (location=2) in float In2;
430fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
431fd4e5da5Sopenharmony_ci  //
432fd4e5da5Sopenharmony_ci  // layout(std140, binding = 0 ) uniform _Globals_
433fd4e5da5Sopenharmony_ci  // {
434fd4e5da5Sopenharmony_ci  //     bool g_b;
435fd4e5da5Sopenharmony_ci  //     bool g_b2;
436fd4e5da5Sopenharmony_ci  // };
437fd4e5da5Sopenharmony_ci  //
438fd4e5da5Sopenharmony_ci  // void main()
439fd4e5da5Sopenharmony_ci  // {
440fd4e5da5Sopenharmony_ci  //     vec4 v1, v2;
441fd4e5da5Sopenharmony_ci  //     v1 = In0;
442fd4e5da5Sopenharmony_ci  //     v1.y = In1 + In2; // dead, second pass
443fd4e5da5Sopenharmony_ci  //     if (g_b) v1.x = 1.0;
444fd4e5da5Sopenharmony_ci  //     v2.x = v1.x;
445fd4e5da5Sopenharmony_ci  //     v2.y = v1.y; // dead, first pass
446fd4e5da5Sopenharmony_ci  //     if (g_b2) v2.x = 0.0;
447fd4e5da5Sopenharmony_ci  //     OutColor = vec4(v2.x,v2.x,0.0,1.0);
448fd4e5da5Sopenharmony_ci  // }
449fd4e5da5Sopenharmony_ci
450fd4e5da5Sopenharmony_ci  const std::string before_predefs =
451fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
452fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
453fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
454fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
455fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
456fd4e5da5Sopenharmony_ciOpSource GLSL 450
457fd4e5da5Sopenharmony_ciOpName %main "main"
458fd4e5da5Sopenharmony_ciOpName %In0 "In0"
459fd4e5da5Sopenharmony_ciOpName %In1 "In1"
460fd4e5da5Sopenharmony_ciOpName %In2 "In2"
461fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
462fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
463fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 1 "g_b2"
464fd4e5da5Sopenharmony_ciOpName %_ ""
465fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
466fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
467fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
468fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
469fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
470fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 1 Offset 4
471fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
472fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
473fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
474fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
475fd4e5da5Sopenharmony_ci%void = OpTypeVoid
476fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
477fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
478fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
479fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
480fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
481fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_v4float Input
482fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
483fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
484fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_float Input
485fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
486fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint %uint
487fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
488fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
489fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
490fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
491fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
492fd4e5da5Sopenharmony_ci%bool = OpTypeBool
493fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
494fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
495fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
496fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
497fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
498fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
499fd4e5da5Sopenharmony_ci%27 = OpUndef %v4float
500fd4e5da5Sopenharmony_ci)";
501fd4e5da5Sopenharmony_ci
502fd4e5da5Sopenharmony_ci  const std::string after_predefs =
503fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
504fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
505fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
506fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
507fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
508fd4e5da5Sopenharmony_ciOpSource GLSL 450
509fd4e5da5Sopenharmony_ciOpName %main "main"
510fd4e5da5Sopenharmony_ciOpName %In0 "In0"
511fd4e5da5Sopenharmony_ciOpName %In1 "In1"
512fd4e5da5Sopenharmony_ciOpName %In2 "In2"
513fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
514fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
515fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 1 "g_b2"
516fd4e5da5Sopenharmony_ciOpName %_ ""
517fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
518fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
519fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
520fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
521fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
522fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 1 Offset 4
523fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
524fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
525fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
526fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
527fd4e5da5Sopenharmony_ci%void = OpTypeVoid
528fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
529fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
530fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
531fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
532fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
533fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_v4float Input
534fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
535fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
536fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_float Input
537fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
538fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint %uint
539fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
540fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
541fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
542fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
543fd4e5da5Sopenharmony_ci%_ptr_Uniform_uint = OpTypePointer Uniform %uint
544fd4e5da5Sopenharmony_ci%bool = OpTypeBool
545fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
546fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
547fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
548fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
549fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
550fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
551fd4e5da5Sopenharmony_ci%27 = OpUndef %v4float
552fd4e5da5Sopenharmony_ci)";
553fd4e5da5Sopenharmony_ci
554fd4e5da5Sopenharmony_ci  const std::string before =
555fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
556fd4e5da5Sopenharmony_ci%28 = OpLabel
557fd4e5da5Sopenharmony_ci%29 = OpLoad %v4float %In0
558fd4e5da5Sopenharmony_ci%30 = OpLoad %float %In1
559fd4e5da5Sopenharmony_ci%31 = OpLoad %float %In2
560fd4e5da5Sopenharmony_ci%32 = OpFAdd %float %30 %31
561fd4e5da5Sopenharmony_ci%33 = OpCompositeInsert %v4float %32 %29 1
562fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
563fd4e5da5Sopenharmony_ci%35 = OpLoad %uint %34
564fd4e5da5Sopenharmony_ci%36 = OpINotEqual %bool %35 %uint_0
565fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None
566fd4e5da5Sopenharmony_ciOpBranchConditional %36 %38 %37
567fd4e5da5Sopenharmony_ci%38 = OpLabel
568fd4e5da5Sopenharmony_ci%39 = OpCompositeInsert %v4float %float_1 %33 0
569fd4e5da5Sopenharmony_ciOpBranch %37
570fd4e5da5Sopenharmony_ci%37 = OpLabel
571fd4e5da5Sopenharmony_ci%40 = OpPhi %v4float %33 %28 %39 %38
572fd4e5da5Sopenharmony_ci%41 = OpCompositeExtract %float %40 0
573fd4e5da5Sopenharmony_ci%42 = OpCompositeInsert %v4float %41 %27 0
574fd4e5da5Sopenharmony_ci%43 = OpCompositeExtract %float %40 1
575fd4e5da5Sopenharmony_ci%44 = OpCompositeInsert %v4float %43 %42 1
576fd4e5da5Sopenharmony_ci%45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
577fd4e5da5Sopenharmony_ci%46 = OpLoad %uint %45
578fd4e5da5Sopenharmony_ci%47 = OpINotEqual %bool %46 %uint_0
579fd4e5da5Sopenharmony_ciOpSelectionMerge %48 None
580fd4e5da5Sopenharmony_ciOpBranchConditional %47 %49 %48
581fd4e5da5Sopenharmony_ci%49 = OpLabel
582fd4e5da5Sopenharmony_ci%50 = OpCompositeInsert %v4float %float_0 %44 0
583fd4e5da5Sopenharmony_ciOpBranch %48
584fd4e5da5Sopenharmony_ci%48 = OpLabel
585fd4e5da5Sopenharmony_ci%51 = OpPhi %v4float %44 %37 %50 %49
586fd4e5da5Sopenharmony_ci%52 = OpCompositeExtract %float %51 0
587fd4e5da5Sopenharmony_ci%53 = OpCompositeExtract %float %51 0
588fd4e5da5Sopenharmony_ci%54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
589fd4e5da5Sopenharmony_ciOpStore %OutColor %54
590fd4e5da5Sopenharmony_ciOpReturn
591fd4e5da5Sopenharmony_ciOpFunctionEnd
592fd4e5da5Sopenharmony_ci)";
593fd4e5da5Sopenharmony_ci
594fd4e5da5Sopenharmony_ci  const std::string after =
595fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
596fd4e5da5Sopenharmony_ci%28 = OpLabel
597fd4e5da5Sopenharmony_ci%29 = OpLoad %v4float %In0
598fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
599fd4e5da5Sopenharmony_ci%35 = OpLoad %uint %34
600fd4e5da5Sopenharmony_ci%36 = OpINotEqual %bool %35 %uint_0
601fd4e5da5Sopenharmony_ciOpSelectionMerge %37 None
602fd4e5da5Sopenharmony_ciOpBranchConditional %36 %38 %37
603fd4e5da5Sopenharmony_ci%38 = OpLabel
604fd4e5da5Sopenharmony_ci%39 = OpCompositeInsert %v4float %float_1 %29 0
605fd4e5da5Sopenharmony_ciOpBranch %37
606fd4e5da5Sopenharmony_ci%37 = OpLabel
607fd4e5da5Sopenharmony_ci%40 = OpPhi %v4float %29 %28 %39 %38
608fd4e5da5Sopenharmony_ci%41 = OpCompositeExtract %float %40 0
609fd4e5da5Sopenharmony_ci%42 = OpCompositeInsert %v4float %41 %27 0
610fd4e5da5Sopenharmony_ci%45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
611fd4e5da5Sopenharmony_ci%46 = OpLoad %uint %45
612fd4e5da5Sopenharmony_ci%47 = OpINotEqual %bool %46 %uint_0
613fd4e5da5Sopenharmony_ciOpSelectionMerge %48 None
614fd4e5da5Sopenharmony_ciOpBranchConditional %47 %49 %48
615fd4e5da5Sopenharmony_ci%49 = OpLabel
616fd4e5da5Sopenharmony_ci%50 = OpCompositeInsert %v4float %float_0 %42 0
617fd4e5da5Sopenharmony_ciOpBranch %48
618fd4e5da5Sopenharmony_ci%48 = OpLabel
619fd4e5da5Sopenharmony_ci%51 = OpPhi %v4float %42 %37 %50 %49
620fd4e5da5Sopenharmony_ci%52 = OpCompositeExtract %float %51 0
621fd4e5da5Sopenharmony_ci%53 = OpCompositeExtract %float %51 0
622fd4e5da5Sopenharmony_ci%54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
623fd4e5da5Sopenharmony_ciOpStore %OutColor %54
624fd4e5da5Sopenharmony_ciOpReturn
625fd4e5da5Sopenharmony_ciOpFunctionEnd
626fd4e5da5Sopenharmony_ci)";
627fd4e5da5Sopenharmony_ci
628fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
629fd4e5da5Sopenharmony_ci                                            after_predefs + after, true, true);
630fd4e5da5Sopenharmony_ci}
631fd4e5da5Sopenharmony_ci
632fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, DebugInsertAfterInsertElim) {
633fd4e5da5Sopenharmony_ci  // With two insertions to the same offset, the first is dead.
634fd4e5da5Sopenharmony_ci  //
635fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
636fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
637fd4e5da5Sopenharmony_ci  // reference each other.
638fd4e5da5Sopenharmony_ci  //
639fd4e5da5Sopenharmony_ci  // #version 450
640fd4e5da5Sopenharmony_ci  //
641fd4e5da5Sopenharmony_ci  // layout (location=0) in float In0;
642fd4e5da5Sopenharmony_ci  // layout (location=1) in float In1;
643fd4e5da5Sopenharmony_ci  // layout (location=2) in vec2 In2;
644fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
645fd4e5da5Sopenharmony_ci  //
646fd4e5da5Sopenharmony_ci  // void main()
647fd4e5da5Sopenharmony_ci  // {
648fd4e5da5Sopenharmony_ci  //     vec2 v = In2;
649fd4e5da5Sopenharmony_ci  //     v.x = In0 + In1; // dead
650fd4e5da5Sopenharmony_ci  //     v.x = 0.0;
651fd4e5da5Sopenharmony_ci  //     OutColor = v.xyxy;
652fd4e5da5Sopenharmony_ci  // }
653fd4e5da5Sopenharmony_ci
654fd4e5da5Sopenharmony_ci  const std::string text =
655fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
656fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
657fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "OpenCL.DebugInfo.100"
658fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
659fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
660fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
661fd4e5da5Sopenharmony_ciOpSource GLSL 450
662fd4e5da5Sopenharmony_ci%file_name = OpString "test"
663fd4e5da5Sopenharmony_ci%float_name = OpString "float"
664fd4e5da5Sopenharmony_ci%main_name = OpString "main"
665fd4e5da5Sopenharmony_ci%f_name = OpString "f"
666fd4e5da5Sopenharmony_ciOpName %main "main"
667fd4e5da5Sopenharmony_ciOpName %In2 "In2"
668fd4e5da5Sopenharmony_ciOpName %In0 "In0"
669fd4e5da5Sopenharmony_ciOpName %In1 "In1"
670fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
671fd4e5da5Sopenharmony_ciOpName %_Globals_ "_Globals_"
672fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 0 "g_b"
673fd4e5da5Sopenharmony_ciOpMemberName %_Globals_ 1 "g_n"
674fd4e5da5Sopenharmony_ciOpName %_ ""
675fd4e5da5Sopenharmony_ciOpDecorate %In2 Location 2
676fd4e5da5Sopenharmony_ciOpDecorate %In0 Location 0
677fd4e5da5Sopenharmony_ciOpDecorate %In1 Location 1
678fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
679fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 0 Offset 0
680fd4e5da5Sopenharmony_ciOpMemberDecorate %_Globals_ 1 Offset 4
681fd4e5da5Sopenharmony_ciOpDecorate %_Globals_ Block
682fd4e5da5Sopenharmony_ciOpDecorate %_ DescriptorSet 0
683fd4e5da5Sopenharmony_ciOpDecorate %_ Binding 0
684fd4e5da5Sopenharmony_ci%void = OpTypeVoid
685fd4e5da5Sopenharmony_ci%11 = OpTypeFunction %void
686fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
687fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
688fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
689fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
690fd4e5da5Sopenharmony_ci%In2 = OpVariable %_ptr_Input_v2float Input
691fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
692fd4e5da5Sopenharmony_ci%In0 = OpVariable %_ptr_Input_float Input
693fd4e5da5Sopenharmony_ci%In1 = OpVariable %_ptr_Input_float Input
694fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
695fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
696fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
697fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
698fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
699fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
700fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
701fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
702fd4e5da5Sopenharmony_ci%_Globals_ = OpTypeStruct %uint %int
703fd4e5da5Sopenharmony_ci%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
704fd4e5da5Sopenharmony_ci%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
705fd4e5da5Sopenharmony_ci
706fd4e5da5Sopenharmony_ci%nullexpr = OpExtInst %void %ext DebugExpression
707fd4e5da5Sopenharmony_ci%src = OpExtInst %void %ext DebugSource %file_name
708fd4e5da5Sopenharmony_ci%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
709fd4e5da5Sopenharmony_ci%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
710fd4e5da5Sopenharmony_ci%dbg_v2f = OpExtInst %void %ext DebugTypeVector %dbg_tf 2
711fd4e5da5Sopenharmony_ci%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
712fd4e5da5Sopenharmony_ci%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 0 %main
713fd4e5da5Sopenharmony_ci%dbg_foo = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v2f %src 0 0 %dbg_main FlagIsLocal
714fd4e5da5Sopenharmony_ci
715fd4e5da5Sopenharmony_ci%main = OpFunction %void None %11
716fd4e5da5Sopenharmony_ci%25 = OpLabel
717fd4e5da5Sopenharmony_ci%26 = OpLoad %v2float %In2
718fd4e5da5Sopenharmony_ci%27 = OpLoad %float %In0
719fd4e5da5Sopenharmony_ci%28 = OpLoad %float %In1
720fd4e5da5Sopenharmony_ci%29 = OpFAdd %float %27 %28
721fd4e5da5Sopenharmony_ci
722fd4e5da5Sopenharmony_ci; CHECK:      [[repl:%\w+]] = OpLoad %v2float %In2
723fd4e5da5Sopenharmony_ci; CHECK-NOT:  OpCompositeInsert
724fd4e5da5Sopenharmony_ci; CHECK:      DebugValue {{%\w+}} [[repl:%\w+]]
725fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpCompositeInsert %v2float %float_0 [[repl]] 0
726fd4e5da5Sopenharmony_ci%35 = OpCompositeInsert %v2float %29 %26 0
727fd4e5da5Sopenharmony_ci%value = OpExtInst %void %ext DebugValue %dbg_foo %35 %nullexpr
728fd4e5da5Sopenharmony_ci%37 = OpCompositeInsert %v2float %float_0 %35 0
729fd4e5da5Sopenharmony_ci
730fd4e5da5Sopenharmony_ci%33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
731fd4e5da5Sopenharmony_ciOpStore %OutColor %33
732fd4e5da5Sopenharmony_ciOpReturn
733fd4e5da5Sopenharmony_ciOpFunctionEnd
734fd4e5da5Sopenharmony_ci)";
735fd4e5da5Sopenharmony_ci
736fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<DeadInsertElimPass>(text, true);
737fd4e5da5Sopenharmony_ci}
738fd4e5da5Sopenharmony_ci
739fd4e5da5Sopenharmony_ciTEST_F(DeadInsertElimTest, PhiOverEmptyStruct) {
740fd4e5da5Sopenharmony_ci  // Reproducer for nullptr access error in MarkInsertChain
741fd4e5da5Sopenharmony_ci  // that occurs when processing a phi operation with an
742fd4e5da5Sopenharmony_ci  // empty struct result type.
743fd4e5da5Sopenharmony_ci  //
744fd4e5da5Sopenharmony_ci  // Note: Disassembly created from HLSL source with
745fd4e5da5Sopenharmony_ci  // dxc -T cs_6_6 -spirv -Oconfig=
746fd4e5da5Sopenharmony_ci  //  --eliminate-dead-branches,--merge-return,--ssa-rewrite
747fd4e5da5Sopenharmony_ci  //
748fd4e5da5Sopenharmony_ci  // RWBuffer<float> buf;
749fd4e5da5Sopenharmony_ci  //
750fd4e5da5Sopenharmony_ci  // struct S { };
751fd4e5da5Sopenharmony_ci  //
752fd4e5da5Sopenharmony_ci  // S fn() {
753fd4e5da5Sopenharmony_ci  //     S s = (S)0;
754fd4e5da5Sopenharmony_ci  //     if (buf[0] > 0) {
755fd4e5da5Sopenharmony_ci  //         return s;
756fd4e5da5Sopenharmony_ci  //     }
757fd4e5da5Sopenharmony_ci  //     return s;
758fd4e5da5Sopenharmony_ci  // }
759fd4e5da5Sopenharmony_ci  //
760fd4e5da5Sopenharmony_ci  // [numthreads(1,1,1)]
761fd4e5da5Sopenharmony_ci  // void main() {
762fd4e5da5Sopenharmony_ci  //     fn();
763fd4e5da5Sopenharmony_ci  // }
764fd4e5da5Sopenharmony_ci
765fd4e5da5Sopenharmony_ci  const std::string disassembly =
766fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
767fd4e5da5Sopenharmony_ci               OpCapability SampledBuffer
768fd4e5da5Sopenharmony_ci               OpCapability ImageBuffer
769fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
770fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "main"
771fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
772fd4e5da5Sopenharmony_ci               OpSource HLSL 660
773fd4e5da5Sopenharmony_ci               OpName %S "S"
774fd4e5da5Sopenharmony_ci               OpName %type_buffer_image "type.buffer.image"
775fd4e5da5Sopenharmony_ci               OpName %buf "buf"
776fd4e5da5Sopenharmony_ci               OpName %main "main"
777fd4e5da5Sopenharmony_ci               OpName %src_main "src.main"
778fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
779fd4e5da5Sopenharmony_ci               OpName %fn "fn"
780fd4e5da5Sopenharmony_ci               OpName %bb_entry_0 "bb.entry"
781fd4e5da5Sopenharmony_ci               OpName %s "s"
782fd4e5da5Sopenharmony_ci               OpName %if_true "if.true"
783fd4e5da5Sopenharmony_ci               OpName %if_merge "if.merge"
784fd4e5da5Sopenharmony_ci               OpDecorate %buf DescriptorSet 0
785fd4e5da5Sopenharmony_ci               OpDecorate %buf Binding 0
786fd4e5da5Sopenharmony_ci          %S = OpTypeStruct
787fd4e5da5Sopenharmony_ci          %4 = OpConstantNull %S
788fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
789fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
790fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
791fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
792fd4e5da5Sopenharmony_ci%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 R32f
793fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
794fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
795fd4e5da5Sopenharmony_ci         %12 = OpTypeFunction %void
796fd4e5da5Sopenharmony_ci         %19 = OpTypeFunction %S
797fd4e5da5Sopenharmony_ci%_ptr_Function_S = OpTypePointer Function %S
798fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
799fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
800fd4e5da5Sopenharmony_ci        %buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
801fd4e5da5Sopenharmony_ci      %false = OpConstantFalse %bool
802fd4e5da5Sopenharmony_ci%_ptr_Function_bool = OpTypePointer Function %bool
803fd4e5da5Sopenharmony_ci       %true = OpConstantTrue %bool
804fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %12
805fd4e5da5Sopenharmony_ci         %13 = OpLabel
806fd4e5da5Sopenharmony_ci         %14 = OpFunctionCall %void %src_main
807fd4e5da5Sopenharmony_ci               OpReturn
808fd4e5da5Sopenharmony_ci               OpFunctionEnd
809fd4e5da5Sopenharmony_ci   %src_main = OpFunction %void None %12
810fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
811fd4e5da5Sopenharmony_ci         %17 = OpFunctionCall %S %fn
812fd4e5da5Sopenharmony_ci               OpReturn
813fd4e5da5Sopenharmony_ci               OpFunctionEnd
814fd4e5da5Sopenharmony_ci         %fn = OpFunction %S None %19
815fd4e5da5Sopenharmony_ci %bb_entry_0 = OpLabel
816fd4e5da5Sopenharmony_ci         %39 = OpVariable %_ptr_Function_bool Function %false
817fd4e5da5Sopenharmony_ci         %34 = OpVariable %_ptr_Function_S Function
818fd4e5da5Sopenharmony_ci          %s = OpVariable %_ptr_Function_S Function
819fd4e5da5Sopenharmony_ci               OpSelectionMerge %33 None
820fd4e5da5Sopenharmony_ci               OpSwitch %uint_0 %36
821fd4e5da5Sopenharmony_ci         %36 = OpLabel
822fd4e5da5Sopenharmony_ci               OpStore %s %4
823fd4e5da5Sopenharmony_ci         %23 = OpLoad %type_buffer_image %buf
824fd4e5da5Sopenharmony_ci         %25 = OpImageRead %v4float %23 %uint_0 None
825fd4e5da5Sopenharmony_ci         %26 = OpCompositeExtract %float %25 0
826fd4e5da5Sopenharmony_ci         %28 = OpFOrdGreaterThan %bool %26 %float_0
827fd4e5da5Sopenharmony_ci               OpSelectionMerge %if_merge None
828fd4e5da5Sopenharmony_ci               OpBranchConditional %28 %if_true %if_merge
829fd4e5da5Sopenharmony_ci    %if_true = OpLabel
830fd4e5da5Sopenharmony_ci               OpStore %39 %true
831fd4e5da5Sopenharmony_ci               OpStore %34 %4
832fd4e5da5Sopenharmony_ci               OpBranch %33
833fd4e5da5Sopenharmony_ci   %if_merge = OpLabel
834fd4e5da5Sopenharmony_ci               OpStore %39 %true
835fd4e5da5Sopenharmony_ci               OpStore %34 %4
836fd4e5da5Sopenharmony_ci               OpBranch %33
837fd4e5da5Sopenharmony_ci         %33 = OpLabel
838fd4e5da5Sopenharmony_ci         %41 = OpPhi %S %4 %if_true %4 %if_merge
839fd4e5da5Sopenharmony_ci               OpReturnValue %41
840fd4e5da5Sopenharmony_ci               OpFunctionEnd
841fd4e5da5Sopenharmony_ci)";
842fd4e5da5Sopenharmony_ci  // Used to crash with a nullptr access violation when processing %41
843fd4e5da5Sopenharmony_ci  SinglePassRunToBinary<DeadInsertElimPass>(disassembly, true);
844fd4e5da5Sopenharmony_ci}
845fd4e5da5Sopenharmony_ci
846fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases:
847fd4e5da5Sopenharmony_ci//
848fd4e5da5Sopenharmony_ci
849fd4e5da5Sopenharmony_ci}  // namespace
850fd4e5da5Sopenharmony_ci}  // namespace opt
851fd4e5da5Sopenharmony_ci}  // namespace spvtools
852