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 LocalSingleBlockLoadStoreElimTest = PassTest<::testing::Test>;
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, SimpleStoreLoadElim) {
28fd4e5da5Sopenharmony_ci  // #version 140
29fd4e5da5Sopenharmony_ci  //
30fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
31fd4e5da5Sopenharmony_ci  //
32fd4e5da5Sopenharmony_ci  // void main()
33fd4e5da5Sopenharmony_ci  // {
34fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor;
35fd4e5da5Sopenharmony_ci  //     gl_FragColor = v;
36fd4e5da5Sopenharmony_ci  // }
37fd4e5da5Sopenharmony_ci
38fd4e5da5Sopenharmony_ci  const std::string predefs_before =
39fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
40fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
41fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
42fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
43fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
44fd4e5da5Sopenharmony_ciOpSource GLSL 140
45fd4e5da5Sopenharmony_ciOpName %main "main"
46fd4e5da5Sopenharmony_ciOpName %v "v"
47fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
48fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
49fd4e5da5Sopenharmony_ci%void = OpTypeVoid
50fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
51fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
52fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
53fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
54fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
55fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
56fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
57fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
58fd4e5da5Sopenharmony_ci)";
59fd4e5da5Sopenharmony_ci
60fd4e5da5Sopenharmony_ci  const std::string before =
61fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
62fd4e5da5Sopenharmony_ci%13 = OpLabel
63fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
64fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
65fd4e5da5Sopenharmony_ciOpStore %v %14
66fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
67fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %15
68fd4e5da5Sopenharmony_ciOpReturn
69fd4e5da5Sopenharmony_ciOpFunctionEnd
70fd4e5da5Sopenharmony_ci)";
71fd4e5da5Sopenharmony_ci
72fd4e5da5Sopenharmony_ci  const std::string after =
73fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
74fd4e5da5Sopenharmony_ci%13 = OpLabel
75fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
76fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
77fd4e5da5Sopenharmony_ciOpStore %v %14
78fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %14
79fd4e5da5Sopenharmony_ciOpReturn
80fd4e5da5Sopenharmony_ciOpFunctionEnd
81fd4e5da5Sopenharmony_ci)";
82fd4e5da5Sopenharmony_ci
83fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
84fd4e5da5Sopenharmony_ci      predefs_before + before, predefs_before + after, true, true);
85fd4e5da5Sopenharmony_ci}
86fd4e5da5Sopenharmony_ci
87fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, LSBElimForLinkage) {
88fd4e5da5Sopenharmony_ci  const std::string predefs_before =
89fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
90fd4e5da5Sopenharmony_ciOpCapability Linkage
91fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
92fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
93fd4e5da5Sopenharmony_ciOpSource HLSL 630
94fd4e5da5Sopenharmony_ciOpName %main "main"
95fd4e5da5Sopenharmony_ciOpName %v "v"
96fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
97fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
98fd4e5da5Sopenharmony_ciOpDecorate %main LinkageAttributes "main" Export
99fd4e5da5Sopenharmony_ci%void = OpTypeVoid
100fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
101fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
102fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
103fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
104fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
105fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
106fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
107fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
108fd4e5da5Sopenharmony_ci)";
109fd4e5da5Sopenharmony_ci
110fd4e5da5Sopenharmony_ci  const std::string before =
111fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
112fd4e5da5Sopenharmony_ci%13 = OpLabel
113fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
114fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
115fd4e5da5Sopenharmony_ciOpStore %v %14
116fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
117fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %15
118fd4e5da5Sopenharmony_ciOpReturn
119fd4e5da5Sopenharmony_ciOpFunctionEnd
120fd4e5da5Sopenharmony_ci)";
121fd4e5da5Sopenharmony_ci
122fd4e5da5Sopenharmony_ci  const std::string after =
123fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
124fd4e5da5Sopenharmony_ci%13 = OpLabel
125fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
126fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
127fd4e5da5Sopenharmony_ciOpStore %v %14
128fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %14
129fd4e5da5Sopenharmony_ciOpReturn
130fd4e5da5Sopenharmony_ciOpFunctionEnd
131fd4e5da5Sopenharmony_ci)";
132fd4e5da5Sopenharmony_ci
133fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
134fd4e5da5Sopenharmony_ci      predefs_before + before, predefs_before + after, true, true);
135fd4e5da5Sopenharmony_ci}
136fd4e5da5Sopenharmony_ci
137fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, SimpleLoadLoadElim) {
138fd4e5da5Sopenharmony_ci  // #version 140
139fd4e5da5Sopenharmony_ci  //
140fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
141fd4e5da5Sopenharmony_ci  // in float fi;
142fd4e5da5Sopenharmony_ci  //
143fd4e5da5Sopenharmony_ci  // void main()
144fd4e5da5Sopenharmony_ci  // {
145fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor;
146fd4e5da5Sopenharmony_ci  //     if (fi < 0)
147fd4e5da5Sopenharmony_ci  //         v = vec4(0.0);
148fd4e5da5Sopenharmony_ci  //     gl_FragData[0] = v;
149fd4e5da5Sopenharmony_ci  //     gl_FragData[1] = v;
150fd4e5da5Sopenharmony_ci  // }
151fd4e5da5Sopenharmony_ci
152fd4e5da5Sopenharmony_ci  const std::string predefs =
153fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
154fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
155fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
156fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %fi %gl_FragData
157fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
158fd4e5da5Sopenharmony_ciOpSource GLSL 140
159fd4e5da5Sopenharmony_ciOpName %main "main"
160fd4e5da5Sopenharmony_ciOpName %v "v"
161fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
162fd4e5da5Sopenharmony_ciOpName %fi "fi"
163fd4e5da5Sopenharmony_ciOpName %gl_FragData "gl_FragData"
164fd4e5da5Sopenharmony_ci%void = OpTypeVoid
165fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
166fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
167fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
168fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
169fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
170fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
171fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
172fd4e5da5Sopenharmony_ci%fi = OpVariable %_ptr_Input_float Input
173fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
174fd4e5da5Sopenharmony_ci%bool = OpTypeBool
175fd4e5da5Sopenharmony_ci%16 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
176fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
177fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
178fd4e5da5Sopenharmony_ci%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
179fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
180fd4e5da5Sopenharmony_ci%gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
181fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
182fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
183fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
184fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
185fd4e5da5Sopenharmony_ci)";
186fd4e5da5Sopenharmony_ci
187fd4e5da5Sopenharmony_ci  const std::string before =
188fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
189fd4e5da5Sopenharmony_ci%25 = OpLabel
190fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
191fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor
192fd4e5da5Sopenharmony_ciOpStore %v %26
193fd4e5da5Sopenharmony_ci%27 = OpLoad %float %fi
194fd4e5da5Sopenharmony_ci%28 = OpFOrdLessThan %bool %27 %float_0
195fd4e5da5Sopenharmony_ciOpSelectionMerge %29 None
196fd4e5da5Sopenharmony_ciOpBranchConditional %28 %30 %29
197fd4e5da5Sopenharmony_ci%30 = OpLabel
198fd4e5da5Sopenharmony_ciOpStore %v %16
199fd4e5da5Sopenharmony_ciOpBranch %29
200fd4e5da5Sopenharmony_ci%29 = OpLabel
201fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %v
202fd4e5da5Sopenharmony_ci%32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
203fd4e5da5Sopenharmony_ciOpStore %32 %31
204fd4e5da5Sopenharmony_ci%33 = OpLoad %v4float %v
205fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
206fd4e5da5Sopenharmony_ciOpStore %34 %33
207fd4e5da5Sopenharmony_ciOpReturn
208fd4e5da5Sopenharmony_ciOpFunctionEnd
209fd4e5da5Sopenharmony_ci)";
210fd4e5da5Sopenharmony_ci
211fd4e5da5Sopenharmony_ci  const std::string after =
212fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
213fd4e5da5Sopenharmony_ci%25 = OpLabel
214fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
215fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor
216fd4e5da5Sopenharmony_ciOpStore %v %26
217fd4e5da5Sopenharmony_ci%27 = OpLoad %float %fi
218fd4e5da5Sopenharmony_ci%28 = OpFOrdLessThan %bool %27 %float_0
219fd4e5da5Sopenharmony_ciOpSelectionMerge %29 None
220fd4e5da5Sopenharmony_ciOpBranchConditional %28 %30 %29
221fd4e5da5Sopenharmony_ci%30 = OpLabel
222fd4e5da5Sopenharmony_ciOpStore %v %16
223fd4e5da5Sopenharmony_ciOpBranch %29
224fd4e5da5Sopenharmony_ci%29 = OpLabel
225fd4e5da5Sopenharmony_ci%31 = OpLoad %v4float %v
226fd4e5da5Sopenharmony_ci%32 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
227fd4e5da5Sopenharmony_ciOpStore %32 %31
228fd4e5da5Sopenharmony_ci%34 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
229fd4e5da5Sopenharmony_ciOpStore %34 %31
230fd4e5da5Sopenharmony_ciOpReturn
231fd4e5da5Sopenharmony_ciOpFunctionEnd
232fd4e5da5Sopenharmony_ci)";
233fd4e5da5Sopenharmony_ci
234fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
235fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
236fd4e5da5Sopenharmony_ci}
237fd4e5da5Sopenharmony_ci
238fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, StoreStoreElim) {
239fd4e5da5Sopenharmony_ci  //
240fd4e5da5Sopenharmony_ci  // Note first store to v is eliminated
241fd4e5da5Sopenharmony_ci  //
242fd4e5da5Sopenharmony_ci  // #version 450
243fd4e5da5Sopenharmony_ci  //
244fd4e5da5Sopenharmony_ci  // layout(location = 0) in vec4 BaseColor;
245fd4e5da5Sopenharmony_ci  // layout(location = 0) out vec4 OutColor;
246fd4e5da5Sopenharmony_ci  //
247fd4e5da5Sopenharmony_ci  // void main()
248fd4e5da5Sopenharmony_ci  // {
249fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor;
250fd4e5da5Sopenharmony_ci  //     v = v * 0.5;
251fd4e5da5Sopenharmony_ci  //     OutColor = v;
252fd4e5da5Sopenharmony_ci  // }
253fd4e5da5Sopenharmony_ci
254fd4e5da5Sopenharmony_ci  const std::string predefs_before =
255fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
256fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
257fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
258fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %OutColor
259fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
260fd4e5da5Sopenharmony_ciOpSource GLSL 450
261fd4e5da5Sopenharmony_ciOpName %main "main"
262fd4e5da5Sopenharmony_ciOpName %v "v"
263fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
264fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
265fd4e5da5Sopenharmony_ciOpDecorate %BaseColor Location 0
266fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
267fd4e5da5Sopenharmony_ci%void = OpTypeVoid
268fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
269fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
270fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
271fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
272fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
273fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
274fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5
275fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
276fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
277fd4e5da5Sopenharmony_ci)";
278fd4e5da5Sopenharmony_ci
279fd4e5da5Sopenharmony_ci  const std::string before =
280fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
281fd4e5da5Sopenharmony_ci%14 = OpLabel
282fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
283fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %BaseColor
284fd4e5da5Sopenharmony_ciOpStore %v %15
285fd4e5da5Sopenharmony_ci%16 = OpLoad %v4float %v
286fd4e5da5Sopenharmony_ci%17 = OpVectorTimesScalar %v4float %16 %float_0_5
287fd4e5da5Sopenharmony_ciOpStore %v %17
288fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %v
289fd4e5da5Sopenharmony_ciOpStore %OutColor %18
290fd4e5da5Sopenharmony_ciOpReturn
291fd4e5da5Sopenharmony_ciOpFunctionEnd
292fd4e5da5Sopenharmony_ci)";
293fd4e5da5Sopenharmony_ci
294fd4e5da5Sopenharmony_ci  const std::string after =
295fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
296fd4e5da5Sopenharmony_ci%14 = OpLabel
297fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
298fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %BaseColor
299fd4e5da5Sopenharmony_ci%17 = OpVectorTimesScalar %v4float %15 %float_0_5
300fd4e5da5Sopenharmony_ciOpStore %v %17
301fd4e5da5Sopenharmony_ciOpStore %OutColor %17
302fd4e5da5Sopenharmony_ciOpReturn
303fd4e5da5Sopenharmony_ciOpFunctionEnd
304fd4e5da5Sopenharmony_ci)";
305fd4e5da5Sopenharmony_ci
306fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
307fd4e5da5Sopenharmony_ci      predefs_before + before, predefs_before + after, true, true);
308fd4e5da5Sopenharmony_ci}
309fd4e5da5Sopenharmony_ci
310fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest,
311fd4e5da5Sopenharmony_ci       NoStoreElimIfInterveningAccessChainLoad) {
312fd4e5da5Sopenharmony_ci  //
313fd4e5da5Sopenharmony_ci  // Note the first Store to %v is not eliminated due to the following access
314fd4e5da5Sopenharmony_ci  // chain reference.
315fd4e5da5Sopenharmony_ci  //
316fd4e5da5Sopenharmony_ci  // #version 450
317fd4e5da5Sopenharmony_ci  //
318fd4e5da5Sopenharmony_ci  // layout(location = 0) in vec4 BaseColor0;
319fd4e5da5Sopenharmony_ci  // layout(location = 1) in vec4 BaseColor1;
320fd4e5da5Sopenharmony_ci  // layout(location = 2) flat in int Idx;
321fd4e5da5Sopenharmony_ci  // layout(location = 0) out vec4 OutColor;
322fd4e5da5Sopenharmony_ci  //
323fd4e5da5Sopenharmony_ci  // void main()
324fd4e5da5Sopenharmony_ci  // {
325fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor0;
326fd4e5da5Sopenharmony_ci  //     float f = v[Idx];
327fd4e5da5Sopenharmony_ci  //     v = BaseColor1 + vec4(0.1);
328fd4e5da5Sopenharmony_ci  //     OutColor = v/f;
329fd4e5da5Sopenharmony_ci  // }
330fd4e5da5Sopenharmony_ci
331fd4e5da5Sopenharmony_ci  const std::string predefs =
332fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
333fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
334fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
335fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
336fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
337fd4e5da5Sopenharmony_ciOpSource GLSL 450
338fd4e5da5Sopenharmony_ciOpName %main "main"
339fd4e5da5Sopenharmony_ciOpName %v "v"
340fd4e5da5Sopenharmony_ciOpName %BaseColor0 "BaseColor0"
341fd4e5da5Sopenharmony_ciOpName %f "f"
342fd4e5da5Sopenharmony_ciOpName %Idx "Idx"
343fd4e5da5Sopenharmony_ciOpName %BaseColor1 "BaseColor1"
344fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
345fd4e5da5Sopenharmony_ciOpDecorate %BaseColor0 Location 0
346fd4e5da5Sopenharmony_ciOpDecorate %Idx Flat
347fd4e5da5Sopenharmony_ciOpDecorate %Idx Location 2
348fd4e5da5Sopenharmony_ciOpDecorate %BaseColor1 Location 1
349fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
350fd4e5da5Sopenharmony_ci%void = OpTypeVoid
351fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
352fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
353fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
354fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
355fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
356fd4e5da5Sopenharmony_ci%BaseColor0 = OpVariable %_ptr_Input_v4float Input
357fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
358fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
359fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
360fd4e5da5Sopenharmony_ci%Idx = OpVariable %_ptr_Input_int Input
361fd4e5da5Sopenharmony_ci%BaseColor1 = OpVariable %_ptr_Input_v4float Input
362fd4e5da5Sopenharmony_ci%float_0_100000001 = OpConstant %float 0.100000001
363fd4e5da5Sopenharmony_ci%19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
364fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
365fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
366fd4e5da5Sopenharmony_ci)";
367fd4e5da5Sopenharmony_ci
368fd4e5da5Sopenharmony_ci  const std::string before =
369fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
370fd4e5da5Sopenharmony_ci%21 = OpLabel
371fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
372fd4e5da5Sopenharmony_ci%f = OpVariable %_ptr_Function_float Function
373fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor0
374fd4e5da5Sopenharmony_ciOpStore %v %22
375fd4e5da5Sopenharmony_ci%23 = OpLoad %int %Idx
376fd4e5da5Sopenharmony_ci%24 = OpAccessChain %_ptr_Function_float %v %23
377fd4e5da5Sopenharmony_ci%25 = OpLoad %float %24
378fd4e5da5Sopenharmony_ciOpStore %f %25
379fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor1
380fd4e5da5Sopenharmony_ci%27 = OpFAdd %v4float %26 %19
381fd4e5da5Sopenharmony_ciOpStore %v %27
382fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %v
383fd4e5da5Sopenharmony_ci%29 = OpLoad %float %f
384fd4e5da5Sopenharmony_ci%30 = OpCompositeConstruct %v4float %29 %29 %29 %29
385fd4e5da5Sopenharmony_ci%31 = OpFDiv %v4float %28 %30
386fd4e5da5Sopenharmony_ciOpStore %OutColor %31
387fd4e5da5Sopenharmony_ciOpReturn
388fd4e5da5Sopenharmony_ciOpFunctionEnd
389fd4e5da5Sopenharmony_ci)";
390fd4e5da5Sopenharmony_ci
391fd4e5da5Sopenharmony_ci  const std::string after =
392fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
393fd4e5da5Sopenharmony_ci%21 = OpLabel
394fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
395fd4e5da5Sopenharmony_ci%f = OpVariable %_ptr_Function_float Function
396fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor0
397fd4e5da5Sopenharmony_ciOpStore %v %22
398fd4e5da5Sopenharmony_ci%23 = OpLoad %int %Idx
399fd4e5da5Sopenharmony_ci%24 = OpAccessChain %_ptr_Function_float %v %23
400fd4e5da5Sopenharmony_ci%25 = OpLoad %float %24
401fd4e5da5Sopenharmony_ciOpStore %f %25
402fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor1
403fd4e5da5Sopenharmony_ci%27 = OpFAdd %v4float %26 %19
404fd4e5da5Sopenharmony_ciOpStore %v %27
405fd4e5da5Sopenharmony_ci%30 = OpCompositeConstruct %v4float %25 %25 %25 %25
406fd4e5da5Sopenharmony_ci%31 = OpFDiv %v4float %27 %30
407fd4e5da5Sopenharmony_ciOpStore %OutColor %31
408fd4e5da5Sopenharmony_ciOpReturn
409fd4e5da5Sopenharmony_ciOpFunctionEnd
410fd4e5da5Sopenharmony_ci)";
411fd4e5da5Sopenharmony_ci
412fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
413fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
414fd4e5da5Sopenharmony_ci}
415fd4e5da5Sopenharmony_ci
416fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningAccessChainStore) {
417fd4e5da5Sopenharmony_ci  // #version 140
418fd4e5da5Sopenharmony_ci  //
419fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
420fd4e5da5Sopenharmony_ci  // flat in int Idx;
421fd4e5da5Sopenharmony_ci  //
422fd4e5da5Sopenharmony_ci  // void main()
423fd4e5da5Sopenharmony_ci  // {
424fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor;
425fd4e5da5Sopenharmony_ci  //     v[Idx] = 0;
426fd4e5da5Sopenharmony_ci  //     gl_FragColor = v;
427fd4e5da5Sopenharmony_ci  // }
428fd4e5da5Sopenharmony_ci
429fd4e5da5Sopenharmony_ci  const std::string assembly =
430fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
431fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
432fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
433fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %Idx %gl_FragColor
434fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
435fd4e5da5Sopenharmony_ciOpSource GLSL 140
436fd4e5da5Sopenharmony_ciOpName %main "main"
437fd4e5da5Sopenharmony_ciOpName %v "v"
438fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
439fd4e5da5Sopenharmony_ciOpName %Idx "Idx"
440fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
441fd4e5da5Sopenharmony_ciOpDecorate %Idx Flat
442fd4e5da5Sopenharmony_ci%void = OpTypeVoid
443fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
444fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
445fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
446fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
447fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
448fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
449fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
450fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
451fd4e5da5Sopenharmony_ci%Idx = OpVariable %_ptr_Input_int Input
452fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
453fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
454fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
455fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
456fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8
457fd4e5da5Sopenharmony_ci%18 = OpLabel
458fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
459fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor
460fd4e5da5Sopenharmony_ciOpStore %v %19
461fd4e5da5Sopenharmony_ci%20 = OpLoad %int %Idx
462fd4e5da5Sopenharmony_ci%21 = OpAccessChain %_ptr_Function_float %v %20
463fd4e5da5Sopenharmony_ciOpStore %21 %float_0
464fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %v
465fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %22
466fd4e5da5Sopenharmony_ciOpReturn
467fd4e5da5Sopenharmony_ciOpFunctionEnd
468fd4e5da5Sopenharmony_ci)";
469fd4e5da5Sopenharmony_ci
470fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
471fd4e5da5Sopenharmony_ci                                                           false, true);
472fd4e5da5Sopenharmony_ci}
473fd4e5da5Sopenharmony_ci
474fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningFunctionCall) {
475fd4e5da5Sopenharmony_ci  // #version 140
476fd4e5da5Sopenharmony_ci  //
477fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
478fd4e5da5Sopenharmony_ci  //
479fd4e5da5Sopenharmony_ci  // void foo() {
480fd4e5da5Sopenharmony_ci  // }
481fd4e5da5Sopenharmony_ci  //
482fd4e5da5Sopenharmony_ci  // void main()
483fd4e5da5Sopenharmony_ci  // {
484fd4e5da5Sopenharmony_ci  //     vec4 v = BaseColor;
485fd4e5da5Sopenharmony_ci  //     foo();
486fd4e5da5Sopenharmony_ci  //     gl_FragColor = v;
487fd4e5da5Sopenharmony_ci  // }
488fd4e5da5Sopenharmony_ci
489fd4e5da5Sopenharmony_ci  const std::string assembly =
490fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
491fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
492fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
493fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
494fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
495fd4e5da5Sopenharmony_ciOpSource GLSL 140
496fd4e5da5Sopenharmony_ciOpName %main "main"
497fd4e5da5Sopenharmony_ciOpName %foo_ "foo("
498fd4e5da5Sopenharmony_ciOpName %v "v"
499fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
500fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
501fd4e5da5Sopenharmony_ci%void = OpTypeVoid
502fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
503fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
504fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
505fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
506fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
507fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
508fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
509fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
510fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8
511fd4e5da5Sopenharmony_ci%14 = OpLabel
512fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
513fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %BaseColor
514fd4e5da5Sopenharmony_ciOpStore %v %15
515fd4e5da5Sopenharmony_ci%16 = OpFunctionCall %void %foo_
516fd4e5da5Sopenharmony_ci%17 = OpLoad %v4float %v
517fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %17
518fd4e5da5Sopenharmony_ciOpReturn
519fd4e5da5Sopenharmony_ciOpFunctionEnd
520fd4e5da5Sopenharmony_ci%foo_ = OpFunction %void None %8
521fd4e5da5Sopenharmony_ci%18 = OpLabel
522fd4e5da5Sopenharmony_ciOpReturn
523fd4e5da5Sopenharmony_ciOpFunctionEnd
524fd4e5da5Sopenharmony_ci)";
525fd4e5da5Sopenharmony_ci
526fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(assembly, assembly,
527fd4e5da5Sopenharmony_ci                                                           false, true);
528fd4e5da5Sopenharmony_ci}
529fd4e5da5Sopenharmony_ci
530fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, ElimIfCopyObjectInFunction) {
531fd4e5da5Sopenharmony_ci  // Note: SPIR-V hand edited to insert CopyObject
532fd4e5da5Sopenharmony_ci  //
533fd4e5da5Sopenharmony_ci  // #version 140
534fd4e5da5Sopenharmony_ci  //
535fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
536fd4e5da5Sopenharmony_ci  //
537fd4e5da5Sopenharmony_ci  // void main()
538fd4e5da5Sopenharmony_ci  // {
539fd4e5da5Sopenharmony_ci  //   vec4 v1 = BaseColor;
540fd4e5da5Sopenharmony_ci  //   gl_FragData[0] = v1;
541fd4e5da5Sopenharmony_ci  //   vec4 v2 = BaseColor * 0.5;
542fd4e5da5Sopenharmony_ci  //   gl_FragData[1] = v2;
543fd4e5da5Sopenharmony_ci  // }
544fd4e5da5Sopenharmony_ci
545fd4e5da5Sopenharmony_ci  const std::string predefs =
546fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
547fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
548fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
549fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragData
550fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
551fd4e5da5Sopenharmony_ciOpSource GLSL 140
552fd4e5da5Sopenharmony_ciOpName %main "main"
553fd4e5da5Sopenharmony_ciOpName %v1 "v1"
554fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
555fd4e5da5Sopenharmony_ciOpName %gl_FragData "gl_FragData"
556fd4e5da5Sopenharmony_ciOpName %v2 "v2"
557fd4e5da5Sopenharmony_ci%void = OpTypeVoid
558fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
559fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
560fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
561fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
562fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
563fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
564fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
565fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32
566fd4e5da5Sopenharmony_ci%_arr_v4float_uint_32 = OpTypeArray %v4float %uint_32
567fd4e5da5Sopenharmony_ci%_ptr_Output__arr_v4float_uint_32 = OpTypePointer Output %_arr_v4float_uint_32
568fd4e5da5Sopenharmony_ci%gl_FragData = OpVariable %_ptr_Output__arr_v4float_uint_32 Output
569fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
570fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
571fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
572fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5
573fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
574fd4e5da5Sopenharmony_ci)";
575fd4e5da5Sopenharmony_ci
576fd4e5da5Sopenharmony_ci  const std::string before =
577fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
578fd4e5da5Sopenharmony_ci%22 = OpLabel
579fd4e5da5Sopenharmony_ci%v1 = OpVariable %_ptr_Function_v4float Function
580fd4e5da5Sopenharmony_ci%v2 = OpVariable %_ptr_Function_v4float Function
581fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
582fd4e5da5Sopenharmony_ciOpStore %v1 %23
583fd4e5da5Sopenharmony_ci%24 = OpLoad %v4float %v1
584fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
585fd4e5da5Sopenharmony_ciOpStore %25 %24
586fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor
587fd4e5da5Sopenharmony_ci%27 = OpVectorTimesScalar %v4float %26 %float_0_5
588fd4e5da5Sopenharmony_ci%28 = OpCopyObject %_ptr_Function_v4float %v2
589fd4e5da5Sopenharmony_ciOpStore %28 %27
590fd4e5da5Sopenharmony_ci%29 = OpLoad %v4float %28
591fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
592fd4e5da5Sopenharmony_ciOpStore %30 %29
593fd4e5da5Sopenharmony_ciOpReturn
594fd4e5da5Sopenharmony_ciOpFunctionEnd
595fd4e5da5Sopenharmony_ci)";
596fd4e5da5Sopenharmony_ci
597fd4e5da5Sopenharmony_ci  const std::string after =
598fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
599fd4e5da5Sopenharmony_ci%22 = OpLabel
600fd4e5da5Sopenharmony_ci%v1 = OpVariable %_ptr_Function_v4float Function
601fd4e5da5Sopenharmony_ci%v2 = OpVariable %_ptr_Function_v4float Function
602fd4e5da5Sopenharmony_ci%23 = OpLoad %v4float %BaseColor
603fd4e5da5Sopenharmony_ciOpStore %v1 %23
604fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_0
605fd4e5da5Sopenharmony_ciOpStore %25 %23
606fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor
607fd4e5da5Sopenharmony_ci%27 = OpVectorTimesScalar %v4float %26 %float_0_5
608fd4e5da5Sopenharmony_ci%28 = OpCopyObject %_ptr_Function_v4float %v2
609fd4e5da5Sopenharmony_ciOpStore %28 %27
610fd4e5da5Sopenharmony_ci%30 = OpAccessChain %_ptr_Output_v4float %gl_FragData %int_1
611fd4e5da5Sopenharmony_ciOpStore %30 %27
612fd4e5da5Sopenharmony_ciOpReturn
613fd4e5da5Sopenharmony_ciOpFunctionEnd
614fd4e5da5Sopenharmony_ci)";
615fd4e5da5Sopenharmony_ci
616fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
617fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
618fd4e5da5Sopenharmony_ci}
619fd4e5da5Sopenharmony_ci
620fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, ElimOpaque) {
621fd4e5da5Sopenharmony_ci  // SPIR-V not representable in GLSL; not generatable from HLSL
622fd4e5da5Sopenharmony_ci  // at the moment
623fd4e5da5Sopenharmony_ci
624fd4e5da5Sopenharmony_ci  const std::string predefs =
625fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
626fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
627fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
628fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %outColor %texCoords
629fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
630fd4e5da5Sopenharmony_ciOpSource GLSL 140
631fd4e5da5Sopenharmony_ciOpName %main "main"
632fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
633fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
634fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
635fd4e5da5Sopenharmony_ciOpMemberName %S_t 2 "smp"
636fd4e5da5Sopenharmony_ciOpName %outColor "outColor"
637fd4e5da5Sopenharmony_ciOpName %sampler15 "sampler15"
638fd4e5da5Sopenharmony_ciOpName %s0 "s0"
639fd4e5da5Sopenharmony_ciOpName %texCoords "texCoords"
640fd4e5da5Sopenharmony_ciOpName %param "param"
641fd4e5da5Sopenharmony_ciOpDecorate %sampler15 DescriptorSet 0
642fd4e5da5Sopenharmony_ci%void = OpTypeVoid
643fd4e5da5Sopenharmony_ci%12 = OpTypeFunction %void
644fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
645fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
646fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
647fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
648fd4e5da5Sopenharmony_ci%outColor = OpVariable %_ptr_Output_v4float Output
649fd4e5da5Sopenharmony_ci%17 = OpTypeImage %float 2D 0 0 0 1 Unknown
650fd4e5da5Sopenharmony_ci%18 = OpTypeSampledImage %17
651fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v2float %v2float %18
652fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
653fd4e5da5Sopenharmony_ci%20 = OpTypeFunction %void %_ptr_Function_S_t
654fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
655fd4e5da5Sopenharmony_ci%_ptr_Function_18 = OpTypePointer Function %18
656fd4e5da5Sopenharmony_ci%sampler15 = OpVariable %_ptr_UniformConstant_18 UniformConstant
657fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
658fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
659fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2
660fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
661fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
662fd4e5da5Sopenharmony_ci%texCoords = OpVariable %_ptr_Input_v2float Input
663fd4e5da5Sopenharmony_ci)";
664fd4e5da5Sopenharmony_ci
665fd4e5da5Sopenharmony_ci  const std::string before =
666fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %12
667fd4e5da5Sopenharmony_ci%28 = OpLabel
668fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
669fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_S_t Function
670fd4e5da5Sopenharmony_ci%29 = OpLoad %v2float %texCoords
671fd4e5da5Sopenharmony_ci%30 = OpLoad %S_t %s0
672fd4e5da5Sopenharmony_ci%31 = OpCompositeInsert %S_t %29 %30 0
673fd4e5da5Sopenharmony_ciOpStore %s0 %31
674fd4e5da5Sopenharmony_ci%32 = OpLoad %18 %sampler15
675fd4e5da5Sopenharmony_ci%33 = OpLoad %S_t %s0
676fd4e5da5Sopenharmony_ci%34 = OpCompositeInsert %S_t %32 %33 2
677fd4e5da5Sopenharmony_ciOpStore %s0 %34
678fd4e5da5Sopenharmony_ci%35 = OpLoad %S_t %s0
679fd4e5da5Sopenharmony_ciOpStore %param %35
680fd4e5da5Sopenharmony_ci%36 = OpLoad %S_t %param
681fd4e5da5Sopenharmony_ci%37 = OpCompositeExtract %18 %36 2
682fd4e5da5Sopenharmony_ci%38 = OpLoad %S_t %param
683fd4e5da5Sopenharmony_ci%39 = OpCompositeExtract %v2float %38 0
684fd4e5da5Sopenharmony_ci%40 = OpImageSampleImplicitLod %v4float %37 %39
685fd4e5da5Sopenharmony_ciOpStore %outColor %40
686fd4e5da5Sopenharmony_ciOpReturn
687fd4e5da5Sopenharmony_ciOpFunctionEnd
688fd4e5da5Sopenharmony_ci)";
689fd4e5da5Sopenharmony_ci
690fd4e5da5Sopenharmony_ci  const std::string after =
691fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %12
692fd4e5da5Sopenharmony_ci%28 = OpLabel
693fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
694fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_S_t Function
695fd4e5da5Sopenharmony_ci%29 = OpLoad %v2float %texCoords
696fd4e5da5Sopenharmony_ci%30 = OpLoad %S_t %s0
697fd4e5da5Sopenharmony_ci%31 = OpCompositeInsert %S_t %29 %30 0
698fd4e5da5Sopenharmony_ci%32 = OpLoad %18 %sampler15
699fd4e5da5Sopenharmony_ci%34 = OpCompositeInsert %S_t %32 %31 2
700fd4e5da5Sopenharmony_ciOpStore %s0 %34
701fd4e5da5Sopenharmony_ciOpStore %param %34
702fd4e5da5Sopenharmony_ci%37 = OpCompositeExtract %18 %34 2
703fd4e5da5Sopenharmony_ci%39 = OpCompositeExtract %v2float %34 0
704fd4e5da5Sopenharmony_ci%40 = OpImageSampleImplicitLod %v4float %37 %39
705fd4e5da5Sopenharmony_ciOpStore %outColor %40
706fd4e5da5Sopenharmony_ciOpReturn
707fd4e5da5Sopenharmony_ciOpFunctionEnd
708fd4e5da5Sopenharmony_ci)";
709fd4e5da5Sopenharmony_ci
710fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
711fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
712fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
713fd4e5da5Sopenharmony_ci}
714fd4e5da5Sopenharmony_ci
715fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, PositiveAndNegativeCallTree) {
716fd4e5da5Sopenharmony_ci  // Note that the call tree function bar is optimized, but foo is not
717fd4e5da5Sopenharmony_ci  //
718fd4e5da5Sopenharmony_ci  // #version 140
719fd4e5da5Sopenharmony_ci  //
720fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
721fd4e5da5Sopenharmony_ci  //
722fd4e5da5Sopenharmony_ci  // vec4 foo(vec4 v1)
723fd4e5da5Sopenharmony_ci  // {
724fd4e5da5Sopenharmony_ci  //     vec4 t = v1;
725fd4e5da5Sopenharmony_ci  //     return t;
726fd4e5da5Sopenharmony_ci  // }
727fd4e5da5Sopenharmony_ci  //
728fd4e5da5Sopenharmony_ci  // vec4 bar(vec4 v1)
729fd4e5da5Sopenharmony_ci  // {
730fd4e5da5Sopenharmony_ci  //     vec4 t = v1;
731fd4e5da5Sopenharmony_ci  //     return t;
732fd4e5da5Sopenharmony_ci  // }
733fd4e5da5Sopenharmony_ci  //
734fd4e5da5Sopenharmony_ci  // void main()
735fd4e5da5Sopenharmony_ci  // {
736fd4e5da5Sopenharmony_ci  //     gl_FragColor = bar(BaseColor);
737fd4e5da5Sopenharmony_ci  // }
738fd4e5da5Sopenharmony_ci
739fd4e5da5Sopenharmony_ci  const std::string predefs =
740fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
741fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
742fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
743fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %gl_FragColor %BaseColor
744fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
745fd4e5da5Sopenharmony_ciOpSource GLSL 140
746fd4e5da5Sopenharmony_ciOpName %main "main"
747fd4e5da5Sopenharmony_ciOpName %foo_vf4_ "foo(vf4;"
748fd4e5da5Sopenharmony_ciOpName %v1 "v1"
749fd4e5da5Sopenharmony_ciOpName %bar_vf4_ "bar(vf4;"
750fd4e5da5Sopenharmony_ciOpName %v1_0 "v1"
751fd4e5da5Sopenharmony_ciOpName %t "t"
752fd4e5da5Sopenharmony_ciOpName %t_0 "t"
753fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
754fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
755fd4e5da5Sopenharmony_ciOpName %param "param"
756fd4e5da5Sopenharmony_ci%void = OpTypeVoid
757fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %void
758fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
759fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
760fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
761fd4e5da5Sopenharmony_ci%17 = OpTypeFunction %v4float %_ptr_Function_v4float
762fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
763fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
764fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
765fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
766fd4e5da5Sopenharmony_ci%main = OpFunction %void None %13
767fd4e5da5Sopenharmony_ci%20 = OpLabel
768fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_v4float Function
769fd4e5da5Sopenharmony_ci%21 = OpLoad %v4float %BaseColor
770fd4e5da5Sopenharmony_ciOpStore %param %21
771fd4e5da5Sopenharmony_ci%22 = OpFunctionCall %v4float %bar_vf4_ %param
772fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %22
773fd4e5da5Sopenharmony_ciOpReturn
774fd4e5da5Sopenharmony_ciOpFunctionEnd
775fd4e5da5Sopenharmony_ci)";
776fd4e5da5Sopenharmony_ci
777fd4e5da5Sopenharmony_ci  const std::string before =
778fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %v4float None %17
779fd4e5da5Sopenharmony_ci%v1 = OpFunctionParameter %_ptr_Function_v4float
780fd4e5da5Sopenharmony_ci%23 = OpLabel
781fd4e5da5Sopenharmony_ci%t = OpVariable %_ptr_Function_v4float Function
782fd4e5da5Sopenharmony_ci%24 = OpLoad %v4float %v1
783fd4e5da5Sopenharmony_ciOpStore %t %24
784fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %t
785fd4e5da5Sopenharmony_ciOpReturnValue %25
786fd4e5da5Sopenharmony_ciOpFunctionEnd
787fd4e5da5Sopenharmony_ci%bar_vf4_ = OpFunction %v4float None %17
788fd4e5da5Sopenharmony_ci%v1_0 = OpFunctionParameter %_ptr_Function_v4float
789fd4e5da5Sopenharmony_ci%26 = OpLabel
790fd4e5da5Sopenharmony_ci%t_0 = OpVariable %_ptr_Function_v4float Function
791fd4e5da5Sopenharmony_ci%27 = OpLoad %v4float %v1_0
792fd4e5da5Sopenharmony_ciOpStore %t_0 %27
793fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %t_0
794fd4e5da5Sopenharmony_ciOpReturnValue %28
795fd4e5da5Sopenharmony_ciOpFunctionEnd
796fd4e5da5Sopenharmony_ci)";
797fd4e5da5Sopenharmony_ci
798fd4e5da5Sopenharmony_ci  const std::string after =
799fd4e5da5Sopenharmony_ci      R"(%foo_vf4_ = OpFunction %v4float None %17
800fd4e5da5Sopenharmony_ci%v1 = OpFunctionParameter %_ptr_Function_v4float
801fd4e5da5Sopenharmony_ci%23 = OpLabel
802fd4e5da5Sopenharmony_ci%t = OpVariable %_ptr_Function_v4float Function
803fd4e5da5Sopenharmony_ci%24 = OpLoad %v4float %v1
804fd4e5da5Sopenharmony_ciOpStore %t %24
805fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %t
806fd4e5da5Sopenharmony_ciOpReturnValue %25
807fd4e5da5Sopenharmony_ciOpFunctionEnd
808fd4e5da5Sopenharmony_ci%bar_vf4_ = OpFunction %v4float None %17
809fd4e5da5Sopenharmony_ci%v1_0 = OpFunctionParameter %_ptr_Function_v4float
810fd4e5da5Sopenharmony_ci%26 = OpLabel
811fd4e5da5Sopenharmony_ci%t_0 = OpVariable %_ptr_Function_v4float Function
812fd4e5da5Sopenharmony_ci%27 = OpLoad %v4float %v1_0
813fd4e5da5Sopenharmony_ciOpStore %t_0 %27
814fd4e5da5Sopenharmony_ciOpReturnValue %27
815fd4e5da5Sopenharmony_ciOpFunctionEnd
816fd4e5da5Sopenharmony_ci)";
817fd4e5da5Sopenharmony_ci
818fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
819fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
820fd4e5da5Sopenharmony_ci}
821fd4e5da5Sopenharmony_ci
822fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, PointerVariable) {
823fd4e5da5Sopenharmony_ci  // Test that checks if a pointer variable is removed.
824fd4e5da5Sopenharmony_ci
825fd4e5da5Sopenharmony_ci  const std::string before =
826fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
827fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
828fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" %2
829fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft
830fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_3 0 Offset 0
831fd4e5da5Sopenharmony_ciOpDecorate %_runtimearr__struct_3 ArrayStride 16
832fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_5 0 Offset 0
833fd4e5da5Sopenharmony_ciOpDecorate %_struct_5 BufferBlock
834fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_6 0 Offset 0
835fd4e5da5Sopenharmony_ciOpDecorate %_struct_6 BufferBlock
836fd4e5da5Sopenharmony_ciOpDecorate %2 Location 0
837fd4e5da5Sopenharmony_ciOpDecorate %7 DescriptorSet 0
838fd4e5da5Sopenharmony_ciOpDecorate %7 Binding 0
839fd4e5da5Sopenharmony_ci%void = OpTypeVoid
840fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
841fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
842fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
843fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
844fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
845fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
846fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
847fd4e5da5Sopenharmony_ci%_struct_3 = OpTypeStruct %v4float
848fd4e5da5Sopenharmony_ci%_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
849fd4e5da5Sopenharmony_ci%_struct_5 = OpTypeStruct %_runtimearr__struct_3
850fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
851fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %int
852fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
853fd4e5da5Sopenharmony_ci%_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
854fd4e5da5Sopenharmony_ci%_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
855fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
856fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
857fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_v4float Output
858fd4e5da5Sopenharmony_ci%7 = OpVariable %_ptr_Uniform__struct_5 Uniform
859fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %10
860fd4e5da5Sopenharmony_ci%23 = OpLabel
861fd4e5da5Sopenharmony_ci%24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
862fd4e5da5Sopenharmony_ciOpStore %24 %7
863fd4e5da5Sopenharmony_ci%26 = OpLoad %_ptr_Uniform__struct_5 %24
864fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
865fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %27
866fd4e5da5Sopenharmony_ci%29 = OpCopyObject %v4float %28
867fd4e5da5Sopenharmony_ciOpStore %2 %28
868fd4e5da5Sopenharmony_ciOpReturn
869fd4e5da5Sopenharmony_ciOpFunctionEnd
870fd4e5da5Sopenharmony_ci)";
871fd4e5da5Sopenharmony_ci
872fd4e5da5Sopenharmony_ci  const std::string after =
873fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
874fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
875fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "main" %2
876fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft
877fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_3 0 Offset 0
878fd4e5da5Sopenharmony_ciOpDecorate %_runtimearr__struct_3 ArrayStride 16
879fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_5 0 Offset 0
880fd4e5da5Sopenharmony_ciOpDecorate %_struct_5 BufferBlock
881fd4e5da5Sopenharmony_ciOpMemberDecorate %_struct_6 0 Offset 0
882fd4e5da5Sopenharmony_ciOpDecorate %_struct_6 BufferBlock
883fd4e5da5Sopenharmony_ciOpDecorate %2 Location 0
884fd4e5da5Sopenharmony_ciOpDecorate %7 DescriptorSet 0
885fd4e5da5Sopenharmony_ciOpDecorate %7 Binding 0
886fd4e5da5Sopenharmony_ci%void = OpTypeVoid
887fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
888fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
889fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
890fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
891fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
892fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
893fd4e5da5Sopenharmony_ci%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
894fd4e5da5Sopenharmony_ci%_struct_3 = OpTypeStruct %v4float
895fd4e5da5Sopenharmony_ci%_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
896fd4e5da5Sopenharmony_ci%_struct_5 = OpTypeStruct %_runtimearr__struct_3
897fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
898fd4e5da5Sopenharmony_ci%_struct_6 = OpTypeStruct %int
899fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
900fd4e5da5Sopenharmony_ci%_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
901fd4e5da5Sopenharmony_ci%_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
902fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
903fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
904fd4e5da5Sopenharmony_ci%2 = OpVariable %_ptr_Output_v4float Output
905fd4e5da5Sopenharmony_ci%7 = OpVariable %_ptr_Uniform__struct_5 Uniform
906fd4e5da5Sopenharmony_ci%1 = OpFunction %void None %10
907fd4e5da5Sopenharmony_ci%23 = OpLabel
908fd4e5da5Sopenharmony_ci%24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
909fd4e5da5Sopenharmony_ciOpStore %24 %7
910fd4e5da5Sopenharmony_ci%27 = OpAccessChain %_ptr_Uniform_v4float %7 %int_0 %uint_0 %int_0
911fd4e5da5Sopenharmony_ci%28 = OpLoad %v4float %27
912fd4e5da5Sopenharmony_ci%29 = OpCopyObject %v4float %28
913fd4e5da5Sopenharmony_ciOpStore %2 %28
914fd4e5da5Sopenharmony_ciOpReturn
915fd4e5da5Sopenharmony_ciOpFunctionEnd
916fd4e5da5Sopenharmony_ci)";
917fd4e5da5Sopenharmony_ci
918fd4e5da5Sopenharmony_ci  // Relax logical pointers to allow pointer allocations.
919fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
920fd4e5da5Sopenharmony_ci  ValidatorOptions()->relax_logical_pointer = true;
921fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(before, after, true,
922fd4e5da5Sopenharmony_ci                                                           true);
923fd4e5da5Sopenharmony_ci}
924fd4e5da5Sopenharmony_ci
925fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore) {
926fd4e5da5Sopenharmony_ci  // Test that checks if a pointer variable is removed.
927fd4e5da5Sopenharmony_ci  const std::string predefs_before =
928fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
929fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
930fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
931fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
932fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
933fd4e5da5Sopenharmony_ciOpSource GLSL 140
934fd4e5da5Sopenharmony_ciOpName %main "main"
935fd4e5da5Sopenharmony_ciOpName %v "v"
936fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
937fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
938fd4e5da5Sopenharmony_ci%void = OpTypeVoid
939fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
940fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
941fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
942fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
943fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
944fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
945fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
946fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
947fd4e5da5Sopenharmony_ci)";
948fd4e5da5Sopenharmony_ci
949fd4e5da5Sopenharmony_ci  const std::string before =
950fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
951fd4e5da5Sopenharmony_ci%13 = OpLabel
952fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
953fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
954fd4e5da5Sopenharmony_ciOpStore %v %14
955fd4e5da5Sopenharmony_ciOpBranch %16
956fd4e5da5Sopenharmony_ci%16 = OpLabel
957fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
958fd4e5da5Sopenharmony_ciOpStore %v %15
959fd4e5da5Sopenharmony_ciOpReturn
960fd4e5da5Sopenharmony_ciOpFunctionEnd
961fd4e5da5Sopenharmony_ci)";
962fd4e5da5Sopenharmony_ci
963fd4e5da5Sopenharmony_ci  const std::string after =
964fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
965fd4e5da5Sopenharmony_ci%13 = OpLabel
966fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
967fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
968fd4e5da5Sopenharmony_ciOpStore %v %14
969fd4e5da5Sopenharmony_ciOpBranch %16
970fd4e5da5Sopenharmony_ci%16 = OpLabel
971fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
972fd4e5da5Sopenharmony_ciOpReturn
973fd4e5da5Sopenharmony_ciOpFunctionEnd
974fd4e5da5Sopenharmony_ci)";
975fd4e5da5Sopenharmony_ci
976fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
977fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
978fd4e5da5Sopenharmony_ci      predefs_before + before, predefs_before + after, true, true);
979fd4e5da5Sopenharmony_ci}
980fd4e5da5Sopenharmony_ci
981fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, RedundantStore2) {
982fd4e5da5Sopenharmony_ci  // Test that checks if a pointer variable is removed.
983fd4e5da5Sopenharmony_ci  const std::string predefs_before =
984fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
985fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
986fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
987fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
988fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
989fd4e5da5Sopenharmony_ciOpSource GLSL 140
990fd4e5da5Sopenharmony_ciOpName %main "main"
991fd4e5da5Sopenharmony_ciOpName %v "v"
992fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
993fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
994fd4e5da5Sopenharmony_ci%void = OpTypeVoid
995fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
996fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
997fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
998fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
999fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1000fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
1001fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1002fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
1003fd4e5da5Sopenharmony_ci)";
1004fd4e5da5Sopenharmony_ci
1005fd4e5da5Sopenharmony_ci  const std::string before =
1006fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
1007fd4e5da5Sopenharmony_ci%13 = OpLabel
1008fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
1009fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
1010fd4e5da5Sopenharmony_ciOpStore %v %14
1011fd4e5da5Sopenharmony_ciOpBranch %16
1012fd4e5da5Sopenharmony_ci%16 = OpLabel
1013fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
1014fd4e5da5Sopenharmony_ciOpStore %v %15
1015fd4e5da5Sopenharmony_ci%17 = OpLoad %v4float %v
1016fd4e5da5Sopenharmony_ciOpStore %v %17
1017fd4e5da5Sopenharmony_ciOpReturn
1018fd4e5da5Sopenharmony_ciOpFunctionEnd
1019fd4e5da5Sopenharmony_ci)";
1020fd4e5da5Sopenharmony_ci
1021fd4e5da5Sopenharmony_ci  const std::string after =
1022fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
1023fd4e5da5Sopenharmony_ci%13 = OpLabel
1024fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
1025fd4e5da5Sopenharmony_ci%14 = OpLoad %v4float %BaseColor
1026fd4e5da5Sopenharmony_ciOpStore %v %14
1027fd4e5da5Sopenharmony_ciOpBranch %16
1028fd4e5da5Sopenharmony_ci%16 = OpLabel
1029fd4e5da5Sopenharmony_ci%15 = OpLoad %v4float %v
1030fd4e5da5Sopenharmony_ciOpReturn
1031fd4e5da5Sopenharmony_ciOpFunctionEnd
1032fd4e5da5Sopenharmony_ci)";
1033fd4e5da5Sopenharmony_ci
1034fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1035fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
1036fd4e5da5Sopenharmony_ci      predefs_before + before, predefs_before + after, true, true);
1037fd4e5da5Sopenharmony_ci}
1038fd4e5da5Sopenharmony_ci
1039fd4e5da5Sopenharmony_ci// Test that that an unused OpAccessChain between two store does does not
1040fd4e5da5Sopenharmony_ci// hinders the removal of the first store.  We need to check this because
1041fd4e5da5Sopenharmony_ci// local-access-chain-convert does always remove the OpAccessChain instructions
1042fd4e5da5Sopenharmony_ci// that become dead.
1043fd4e5da5Sopenharmony_ci
1044fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest,
1045fd4e5da5Sopenharmony_ci       StoreElimIfInterveningUnusedAccessChain) {
1046fd4e5da5Sopenharmony_ci  const std::string predefs =
1047fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
1048fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1049fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1050fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor0 %Idx %BaseColor1 %OutColor
1051fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1052fd4e5da5Sopenharmony_ciOpSource GLSL 450
1053fd4e5da5Sopenharmony_ciOpName %main "main"
1054fd4e5da5Sopenharmony_ciOpName %v "v"
1055fd4e5da5Sopenharmony_ciOpName %BaseColor0 "BaseColor0"
1056fd4e5da5Sopenharmony_ciOpName %Idx "Idx"
1057fd4e5da5Sopenharmony_ciOpName %BaseColor1 "BaseColor1"
1058fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
1059fd4e5da5Sopenharmony_ciOpDecorate %BaseColor0 Location 0
1060fd4e5da5Sopenharmony_ciOpDecorate %Idx Flat
1061fd4e5da5Sopenharmony_ciOpDecorate %Idx Location 2
1062fd4e5da5Sopenharmony_ciOpDecorate %BaseColor1 Location 1
1063fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
1064fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1065fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
1066fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1067fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1068fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1069fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1070fd4e5da5Sopenharmony_ci%BaseColor0 = OpVariable %_ptr_Input_v4float Input
1071fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
1072fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
1073fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
1074fd4e5da5Sopenharmony_ci%Idx = OpVariable %_ptr_Input_int Input
1075fd4e5da5Sopenharmony_ci%BaseColor1 = OpVariable %_ptr_Input_v4float Input
1076fd4e5da5Sopenharmony_ci%float_0_100000001 = OpConstant %float 0.100000001
1077fd4e5da5Sopenharmony_ci%19 = OpConstantComposite %v4float %float_0_100000001 %float_0_100000001 %float_0_100000001 %float_0_100000001
1078fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1079fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
1080fd4e5da5Sopenharmony_ci)";
1081fd4e5da5Sopenharmony_ci
1082fd4e5da5Sopenharmony_ci  const std::string before =
1083fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
1084fd4e5da5Sopenharmony_ci%21 = OpLabel
1085fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
1086fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor0
1087fd4e5da5Sopenharmony_ciOpStore %v %22
1088fd4e5da5Sopenharmony_ci%23 = OpLoad %int %Idx
1089fd4e5da5Sopenharmony_ci%24 = OpAccessChain %_ptr_Function_float %v %23
1090fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor1
1091fd4e5da5Sopenharmony_ci%27 = OpFAdd %v4float %26 %19
1092fd4e5da5Sopenharmony_ciOpStore %v %27
1093fd4e5da5Sopenharmony_ciOpReturn
1094fd4e5da5Sopenharmony_ciOpFunctionEnd
1095fd4e5da5Sopenharmony_ci)";
1096fd4e5da5Sopenharmony_ci
1097fd4e5da5Sopenharmony_ci  const std::string after =
1098fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
1099fd4e5da5Sopenharmony_ci%21 = OpLabel
1100fd4e5da5Sopenharmony_ci%v = OpVariable %_ptr_Function_v4float Function
1101fd4e5da5Sopenharmony_ci%22 = OpLoad %v4float %BaseColor0
1102fd4e5da5Sopenharmony_ci%23 = OpLoad %int %Idx
1103fd4e5da5Sopenharmony_ci%24 = OpAccessChain %_ptr_Function_float %v %23
1104fd4e5da5Sopenharmony_ci%26 = OpLoad %v4float %BaseColor1
1105fd4e5da5Sopenharmony_ci%27 = OpFAdd %v4float %26 %19
1106fd4e5da5Sopenharmony_ciOpStore %v %27
1107fd4e5da5Sopenharmony_ciOpReturn
1108fd4e5da5Sopenharmony_ciOpFunctionEnd
1109fd4e5da5Sopenharmony_ci)";
1110fd4e5da5Sopenharmony_ci
1111fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1112fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<LocalSingleBlockLoadStoreElimPass>(
1113fd4e5da5Sopenharmony_ci      predefs + before, predefs + after, true, true);
1114fd4e5da5Sopenharmony_ci}
1115fd4e5da5Sopenharmony_ci
1116fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, VariablePointerTest) {
1117fd4e5da5Sopenharmony_ci  // Check that the load of the first variable is still used and that the load
1118fd4e5da5Sopenharmony_ci  // of the third variable is propagated.  The first load has to remain because
1119fd4e5da5Sopenharmony_ci  // of the store to the variable pointer.
1120fd4e5da5Sopenharmony_ci  const std::string text = R"(
1121fd4e5da5Sopenharmony_ci; CHECK: [[v1:%\w+]] = OpVariable
1122fd4e5da5Sopenharmony_ci; CHECK: [[v2:%\w+]] = OpVariable
1123fd4e5da5Sopenharmony_ci; CHECK: [[v3:%\w+]] = OpVariable
1124fd4e5da5Sopenharmony_ci; CHECK: [[phi:%\w+]] = OpPhi
1125fd4e5da5Sopenharmony_ci; CHECK: [[ld1:%\w+]] = OpLoad %int [[v1]]
1126fd4e5da5Sopenharmony_ci; CHECK: OpIAdd %int [[ld1]] %int_0
1127fd4e5da5Sopenharmony_ci               OpCapability Shader
1128fd4e5da5Sopenharmony_ci               OpCapability VariablePointers
1129fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1130fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1131fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %2 "main"
1132fd4e5da5Sopenharmony_ci               OpExecutionMode %2 LocalSize 1 1 1
1133fd4e5da5Sopenharmony_ci               OpSource GLSL 450
1134fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_3 0 Offset 0
1135fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_3 1 Offset 4
1136fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1137fd4e5da5Sopenharmony_ci          %5 = OpTypeFunction %void
1138fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
1139fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
1140fd4e5da5Sopenharmony_ci  %_struct_3 = OpTypeStruct %int %int
1141fd4e5da5Sopenharmony_ci%_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
1142fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
1143fd4e5da5Sopenharmony_ci       %true = OpConstantTrue %bool
1144fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
1145fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
1146fd4e5da5Sopenharmony_ci         %13 = OpConstantNull %_struct_3
1147fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %5
1148fd4e5da5Sopenharmony_ci         %14 = OpLabel
1149fd4e5da5Sopenharmony_ci         %15 = OpVariable %_ptr_Function_int Function
1150fd4e5da5Sopenharmony_ci         %16 = OpVariable %_ptr_Function_int Function
1151fd4e5da5Sopenharmony_ci         %17 = OpVariable %_ptr_Function_int Function
1152fd4e5da5Sopenharmony_ci               OpSelectionMerge %18 None
1153fd4e5da5Sopenharmony_ci               OpBranchConditional %true %19 %20
1154fd4e5da5Sopenharmony_ci         %19 = OpLabel
1155fd4e5da5Sopenharmony_ci               OpBranch %18
1156fd4e5da5Sopenharmony_ci         %20 = OpLabel
1157fd4e5da5Sopenharmony_ci               OpBranch %18
1158fd4e5da5Sopenharmony_ci         %18 = OpLabel
1159fd4e5da5Sopenharmony_ci         %21 = OpPhi %_ptr_Function_int %15 %19 %16 %20
1160fd4e5da5Sopenharmony_ci               OpStore %15 %int_1
1161fd4e5da5Sopenharmony_ci               OpStore %21 %int_0
1162fd4e5da5Sopenharmony_ci         %22 = OpLoad %int %15
1163fd4e5da5Sopenharmony_ci               OpStore %17 %int_0
1164fd4e5da5Sopenharmony_ci         %23 = OpLoad %int %17
1165fd4e5da5Sopenharmony_ci         %24 = OpIAdd %int %22 %23
1166fd4e5da5Sopenharmony_ci               OpReturn
1167fd4e5da5Sopenharmony_ci               OpFunctionEnd
1168fd4e5da5Sopenharmony_ci  )";
1169fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
1170fd4e5da5Sopenharmony_ci}
1171fd4e5da5Sopenharmony_ci
1172fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, DebugDeclareTest) {
1173fd4e5da5Sopenharmony_ci  // If OpenCL.DebugInfo.100 enabled, check that store/load is still
1174fd4e5da5Sopenharmony_ci  // optimized, but stores are not deleted for store/store.
1175fd4e5da5Sopenharmony_ci  //
1176fd4e5da5Sopenharmony_ci  // struct PS_INPUT {
1177fd4e5da5Sopenharmony_ci  //   float4 c0 : COLOR0;
1178fd4e5da5Sopenharmony_ci  //   float4 c1 : COLOR1;
1179fd4e5da5Sopenharmony_ci  // };
1180fd4e5da5Sopenharmony_ci  //
1181fd4e5da5Sopenharmony_ci  // struct PS_OUTPUT {
1182fd4e5da5Sopenharmony_ci  //   float4 vColor : SV_Target0;
1183fd4e5da5Sopenharmony_ci  // };
1184fd4e5da5Sopenharmony_ci  //
1185fd4e5da5Sopenharmony_ci  // PS_OUTPUT MainPs(PS_INPUT i) {
1186fd4e5da5Sopenharmony_ci  //   PS_OUTPUT ps_output;
1187fd4e5da5Sopenharmony_ci  //   float4 c;
1188fd4e5da5Sopenharmony_ci  //   c = i.c0;
1189fd4e5da5Sopenharmony_ci  //   c += i.c1;
1190fd4e5da5Sopenharmony_ci  //   c /= 2.0;
1191fd4e5da5Sopenharmony_ci  //   ps_output.vColor = c;
1192fd4e5da5Sopenharmony_ci  //   return ps_output;
1193fd4e5da5Sopenharmony_ci  // }
1194fd4e5da5Sopenharmony_ci  const std::string text = R"(
1195fd4e5da5Sopenharmony_ci               OpCapability Shader
1196fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.DebugInfo.100"
1197fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1198fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR0 %in_var_COLOR1 %out_var_SV_Target0
1199fd4e5da5Sopenharmony_ci               OpExecutionMode %MainPs OriginUpperLeft
1200fd4e5da5Sopenharmony_ci          %6 = OpString "foo3.frag"
1201fd4e5da5Sopenharmony_ci          %7 = OpString "PS_OUTPUT"
1202fd4e5da5Sopenharmony_ci          %8 = OpString "float"
1203fd4e5da5Sopenharmony_ci          %9 = OpString "vColor"
1204fd4e5da5Sopenharmony_ci         %10 = OpString "PS_INPUT"
1205fd4e5da5Sopenharmony_ci         %11 = OpString "c1"
1206fd4e5da5Sopenharmony_ci         %12 = OpString "c0"
1207fd4e5da5Sopenharmony_ci         %13 = OpString "src.MainPs"
1208fd4e5da5Sopenharmony_ci         %14 = OpString "c"
1209fd4e5da5Sopenharmony_ci         %15 = OpString "ps_output"
1210fd4e5da5Sopenharmony_ci         %16 = OpString "i"
1211fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR0 "in.var.COLOR0"
1212fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR1 "in.var.COLOR1"
1213fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target0 "out.var.SV_Target0"
1214fd4e5da5Sopenharmony_ci               OpName %MainPs "MainPs"
1215fd4e5da5Sopenharmony_ci               OpName %PS_INPUT "PS_INPUT"
1216fd4e5da5Sopenharmony_ci               OpMemberName %PS_INPUT 0 "c0"
1217fd4e5da5Sopenharmony_ci               OpMemberName %PS_INPUT 1 "c1"
1218fd4e5da5Sopenharmony_ci               OpName %param_var_i "param.var.i"
1219fd4e5da5Sopenharmony_ci               OpName %PS_OUTPUT "PS_OUTPUT"
1220fd4e5da5Sopenharmony_ci               OpMemberName %PS_OUTPUT 0 "vColor"
1221fd4e5da5Sopenharmony_ci               OpName %src_MainPs "src.MainPs"
1222fd4e5da5Sopenharmony_ci               OpName %i "i"
1223fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
1224fd4e5da5Sopenharmony_ci               OpName %ps_output "ps_output"
1225fd4e5da5Sopenharmony_ci               OpName %c "c"
1226fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR0 Location 0
1227fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR1 Location 1
1228fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target0 Location 0
1229fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
1230fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
1231fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
1232fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1233fd4e5da5Sopenharmony_ci    %float_2 = OpConstant %float 2
1234fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
1235fd4e5da5Sopenharmony_ci         %31 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
1236fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1237fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
1238fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1239fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1240fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1241fd4e5da5Sopenharmony_ci   %uint_128 = OpConstant %uint 128
1242fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
1243fd4e5da5Sopenharmony_ci   %uint_256 = OpConstant %uint 256
1244fd4e5da5Sopenharmony_ci         %40 = OpTypeFunction %void
1245fd4e5da5Sopenharmony_ci   %PS_INPUT = OpTypeStruct %v4float %v4float
1246fd4e5da5Sopenharmony_ci%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
1247fd4e5da5Sopenharmony_ci  %PS_OUTPUT = OpTypeStruct %v4float
1248fd4e5da5Sopenharmony_ci         %42 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
1249fd4e5da5Sopenharmony_ci%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
1250fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1251fd4e5da5Sopenharmony_ci%in_var_COLOR0 = OpVariable %_ptr_Input_v4float Input
1252fd4e5da5Sopenharmony_ci%in_var_COLOR1 = OpVariable %_ptr_Input_v4float Input
1253fd4e5da5Sopenharmony_ci%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
1254fd4e5da5Sopenharmony_ci         %45 = OpExtInst %void %1 DebugSource %6
1255fd4e5da5Sopenharmony_ci         %46 = OpExtInst %void %1 DebugCompilationUnit 1 4 %45 HLSL
1256fd4e5da5Sopenharmony_ci         %47 = OpExtInst %void %1 DebugTypeComposite %7 Structure %45 8 1 %46 %7 %uint_128 FlagIsProtected|FlagIsPrivate %48
1257fd4e5da5Sopenharmony_ci         %49 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
1258fd4e5da5Sopenharmony_ci         %50 = OpExtInst %void %1 DebugTypeVector %49 4
1259fd4e5da5Sopenharmony_ci         %48 = OpExtInst %void %1 DebugTypeMember %9 %50 %45 10 5 %47 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
1260fd4e5da5Sopenharmony_ci         %51 = OpExtInst %void %1 DebugTypeComposite %10 Structure %45 2 1 %46 %10 %uint_256 FlagIsProtected|FlagIsPrivate %52 %53
1261fd4e5da5Sopenharmony_ci         %53 = OpExtInst %void %1 DebugTypeMember %11 %50 %45 5 5 %51 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
1262fd4e5da5Sopenharmony_ci         %52 = OpExtInst %void %1 DebugTypeMember %12 %50 %45 4 5 %51 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
1263fd4e5da5Sopenharmony_ci         %54 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %47 %51
1264fd4e5da5Sopenharmony_ci         %55 = OpExtInst %void %1 DebugFunction %13 %54 %45 13 1 %46 %13 FlagIsProtected|FlagIsPrivate 14 %src_MainPs
1265fd4e5da5Sopenharmony_ci         %56 = OpExtInst %void %1 DebugLexicalBlock %45 14 1 %55
1266fd4e5da5Sopenharmony_ci         %57 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %56 FlagIsLocal
1267fd4e5da5Sopenharmony_ci         %58 = OpExtInst %void %1 DebugLocalVariable %15 %47 %45 15 15 %56 FlagIsLocal
1268fd4e5da5Sopenharmony_ci         %59 = OpExtInst %void %1 DebugExpression
1269fd4e5da5Sopenharmony_ci         %60 = OpExtInst %void %1 DebugLocalVariable %16 %51 %45 13 29 %55 FlagIsLocal 1
1270fd4e5da5Sopenharmony_ci         %61 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %55 FlagIsLocal 1
1271fd4e5da5Sopenharmony_ci     %MainPs = OpFunction %void None %40
1272fd4e5da5Sopenharmony_ci         %62 = OpLabel
1273fd4e5da5Sopenharmony_ci%param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
1274fd4e5da5Sopenharmony_ci         %63 = OpLoad %v4float %in_var_COLOR0
1275fd4e5da5Sopenharmony_ci         %64 = OpLoad %v4float %in_var_COLOR1
1276fd4e5da5Sopenharmony_ci         %65 = OpCompositeConstruct %PS_INPUT %63 %64
1277fd4e5da5Sopenharmony_ci               OpStore %param_var_i %65
1278fd4e5da5Sopenharmony_ci         %66 = OpFunctionCall %PS_OUTPUT %src_MainPs %param_var_i
1279fd4e5da5Sopenharmony_ci         %67 = OpCompositeExtract %v4float %66 0
1280fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target0 %67
1281fd4e5da5Sopenharmony_ci               OpReturn
1282fd4e5da5Sopenharmony_ci               OpFunctionEnd
1283fd4e5da5Sopenharmony_ci               OpLine %6 13 1
1284fd4e5da5Sopenharmony_ci %src_MainPs = OpFunction %PS_OUTPUT None %42
1285fd4e5da5Sopenharmony_ci         %83 = OpExtInst %void %1 DebugScope %55
1286fd4e5da5Sopenharmony_ci               OpLine %6 13 29
1287fd4e5da5Sopenharmony_ci          %i = OpFunctionParameter %_ptr_Function_PS_INPUT
1288fd4e5da5Sopenharmony_ci         %69 = OpExtInst %void %1 DebugDeclare %60 %i %59
1289fd4e5da5Sopenharmony_ci         %84 = OpExtInst %void %1 DebugNoScope
1290fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
1291fd4e5da5Sopenharmony_ci         %85 = OpExtInst %void %1 DebugScope %56
1292fd4e5da5Sopenharmony_ci  %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
1293fd4e5da5Sopenharmony_ci          %c = OpVariable %_ptr_Function_v4float Function
1294fd4e5da5Sopenharmony_ci         %71 = OpExtInst %void %1 DebugDeclare %61 %c %59
1295fd4e5da5Sopenharmony_ci               OpLine %6 18 9
1296fd4e5da5Sopenharmony_ci         %72 = OpAccessChain %_ptr_Function_v4float %i %int_0
1297fd4e5da5Sopenharmony_ci               OpLine %6 18 13
1298fd4e5da5Sopenharmony_ci         %73 = OpLoad %v4float %72
1299fd4e5da5Sopenharmony_ci               OpLine %6 18 5
1300fd4e5da5Sopenharmony_ci               OpStore %c %73
1301fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %73
1302fd4e5da5Sopenharmony_ci               OpLine %6 19 10
1303fd4e5da5Sopenharmony_ci         %74 = OpAccessChain %_ptr_Function_v4float %i %int_1
1304fd4e5da5Sopenharmony_ci               OpLine %6 19 14
1305fd4e5da5Sopenharmony_ci         %75 = OpLoad %v4float %74
1306fd4e5da5Sopenharmony_ci               OpLine %6 19 5
1307fd4e5da5Sopenharmony_ci         %76 = OpLoad %v4float %c
1308fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 19 5
1309fd4e5da5Sopenharmony_ci;CHECK-NOT: %76 = OpLoad %v4float %c
1310fd4e5da5Sopenharmony_ci               OpLine %6 19 7
1311fd4e5da5Sopenharmony_ci         %77 = OpFAdd %v4float %76 %75
1312fd4e5da5Sopenharmony_ci;CHECK-NOT: %77 = OpFAdd %v4float %76 %75
1313fd4e5da5Sopenharmony_ci;CHECK:     %77 = OpFAdd %v4float %73 %75
1314fd4e5da5Sopenharmony_ci               OpLine %6 19 5
1315fd4e5da5Sopenharmony_ci               OpStore %c %77
1316fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %77
1317fd4e5da5Sopenharmony_ci               OpLine %6 20 5
1318fd4e5da5Sopenharmony_ci         %78 = OpLoad %v4float %c
1319fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 20 5
1320fd4e5da5Sopenharmony_ci;CHECK-NOT: %78 = OpLoad %v4float %c
1321fd4e5da5Sopenharmony_ci               OpLine %6 20 7
1322fd4e5da5Sopenharmony_ci         %79 = OpFDiv %v4float %78 %31
1323fd4e5da5Sopenharmony_ci;CHECK-NOT %79 = OpFDiv %v4float %78 %31
1324fd4e5da5Sopenharmony_ci;CHECK:    %79 = OpFDiv %v4float %77 %31
1325fd4e5da5Sopenharmony_ci               OpLine %6 20 5
1326fd4e5da5Sopenharmony_ci               OpStore %c %79
1327fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %79
1328fd4e5da5Sopenharmony_ci               OpLine %6 22 26
1329fd4e5da5Sopenharmony_ci         %80 = OpLoad %v4float %c
1330fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 22 26
1331fd4e5da5Sopenharmony_ci;CHECK-NOT: %80 = OpLoad %v4float %c
1332fd4e5da5Sopenharmony_ci               OpLine %6 22 5
1333fd4e5da5Sopenharmony_ci         %81 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
1334fd4e5da5Sopenharmony_ci               OpStore %81 %80
1335fd4e5da5Sopenharmony_ci;CHECK-NOT:    OpStore %81 %80
1336fd4e5da5Sopenharmony_ci;CHECK:        OpStore %81 %79
1337fd4e5da5Sopenharmony_ci               OpLine %6 23 12
1338fd4e5da5Sopenharmony_ci         %82 = OpLoad %PS_OUTPUT %ps_output
1339fd4e5da5Sopenharmony_ci               OpLine %6 23 5
1340fd4e5da5Sopenharmony_ci               OpReturnValue %82
1341fd4e5da5Sopenharmony_ci         %86 = OpExtInst %void %1 DebugNoScope
1342fd4e5da5Sopenharmony_ci               OpFunctionEnd
1343fd4e5da5Sopenharmony_ci  )";
1344fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1345fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
1346fd4e5da5Sopenharmony_ci}
1347fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, DebugValueTest) {
1348fd4e5da5Sopenharmony_ci  // If OpenCL.DebugInfo.100 enabled, check that store/load is still
1349fd4e5da5Sopenharmony_ci  // optimized, but stores are not deleted for store/store.
1350fd4e5da5Sopenharmony_ci  // Same source as DebugDeclareTest; DebugDeclare replaced with
1351fd4e5da5Sopenharmony_ci  // equivalent DebugValue
1352fd4e5da5Sopenharmony_ci  const std::string text = R"(
1353fd4e5da5Sopenharmony_ci               OpCapability Shader
1354fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.DebugInfo.100"
1355fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1356fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR0 %in_var_COLOR1 %out_var_SV_Target0
1357fd4e5da5Sopenharmony_ci               OpExecutionMode %MainPs OriginUpperLeft
1358fd4e5da5Sopenharmony_ci          %6 = OpString "foo3.frag"
1359fd4e5da5Sopenharmony_ci          %7 = OpString "PS_OUTPUT"
1360fd4e5da5Sopenharmony_ci          %8 = OpString "float"
1361fd4e5da5Sopenharmony_ci          %9 = OpString "vColor"
1362fd4e5da5Sopenharmony_ci         %10 = OpString "PS_INPUT"
1363fd4e5da5Sopenharmony_ci         %11 = OpString "c1"
1364fd4e5da5Sopenharmony_ci         %12 = OpString "c0"
1365fd4e5da5Sopenharmony_ci         %13 = OpString "src.MainPs"
1366fd4e5da5Sopenharmony_ci         %14 = OpString "c"
1367fd4e5da5Sopenharmony_ci         %15 = OpString "ps_output"
1368fd4e5da5Sopenharmony_ci         %16 = OpString "i"
1369fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR0 "in.var.COLOR0"
1370fd4e5da5Sopenharmony_ci               OpName %in_var_COLOR1 "in.var.COLOR1"
1371fd4e5da5Sopenharmony_ci               OpName %out_var_SV_Target0 "out.var.SV_Target0"
1372fd4e5da5Sopenharmony_ci               OpName %MainPs "MainPs"
1373fd4e5da5Sopenharmony_ci               OpName %PS_INPUT "PS_INPUT"
1374fd4e5da5Sopenharmony_ci               OpMemberName %PS_INPUT 0 "c0"
1375fd4e5da5Sopenharmony_ci               OpMemberName %PS_INPUT 1 "c1"
1376fd4e5da5Sopenharmony_ci               OpName %param_var_i "param.var.i"
1377fd4e5da5Sopenharmony_ci               OpName %PS_OUTPUT "PS_OUTPUT"
1378fd4e5da5Sopenharmony_ci               OpMemberName %PS_OUTPUT 0 "vColor"
1379fd4e5da5Sopenharmony_ci               OpName %src_MainPs "src.MainPs"
1380fd4e5da5Sopenharmony_ci               OpName %i "i"
1381fd4e5da5Sopenharmony_ci               OpName %bb_entry "bb.entry"
1382fd4e5da5Sopenharmony_ci               OpName %ps_output "ps_output"
1383fd4e5da5Sopenharmony_ci               OpName %c "c"
1384fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR0 Location 0
1385fd4e5da5Sopenharmony_ci               OpDecorate %in_var_COLOR1 Location 1
1386fd4e5da5Sopenharmony_ci               OpDecorate %out_var_SV_Target0 Location 0
1387fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
1388fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
1389fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
1390fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
1391fd4e5da5Sopenharmony_ci    %float_2 = OpConstant %float 2
1392fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
1393fd4e5da5Sopenharmony_ci         %31 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
1394fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
1395fd4e5da5Sopenharmony_ci    %uint_32 = OpConstant %uint 32
1396fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
1397fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
1398fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1399fd4e5da5Sopenharmony_ci   %uint_128 = OpConstant %uint 128
1400fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
1401fd4e5da5Sopenharmony_ci   %uint_256 = OpConstant %uint 256
1402fd4e5da5Sopenharmony_ci         %40 = OpTypeFunction %void
1403fd4e5da5Sopenharmony_ci   %PS_INPUT = OpTypeStruct %v4float %v4float
1404fd4e5da5Sopenharmony_ci%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
1405fd4e5da5Sopenharmony_ci  %PS_OUTPUT = OpTypeStruct %v4float
1406fd4e5da5Sopenharmony_ci         %42 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
1407fd4e5da5Sopenharmony_ci%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
1408fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
1409fd4e5da5Sopenharmony_ci%in_var_COLOR0 = OpVariable %_ptr_Input_v4float Input
1410fd4e5da5Sopenharmony_ci%in_var_COLOR1 = OpVariable %_ptr_Input_v4float Input
1411fd4e5da5Sopenharmony_ci%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
1412fd4e5da5Sopenharmony_ci         %45 = OpExtInst %void %1 DebugSource %6
1413fd4e5da5Sopenharmony_ci         %46 = OpExtInst %void %1 DebugCompilationUnit 1 4 %45 HLSL
1414fd4e5da5Sopenharmony_ci         %47 = OpExtInst %void %1 DebugTypeComposite %7 Structure %45 8 1 %46 %7 %uint_128 FlagIsProtected|FlagIsPrivate %48
1415fd4e5da5Sopenharmony_ci         %49 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
1416fd4e5da5Sopenharmony_ci         %50 = OpExtInst %void %1 DebugTypeVector %49 4
1417fd4e5da5Sopenharmony_ci         %48 = OpExtInst %void %1 DebugTypeMember %9 %50 %45 10 5 %47 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
1418fd4e5da5Sopenharmony_ci         %51 = OpExtInst %void %1 DebugTypeComposite %10 Structure %45 2 1 %46 %10 %uint_256 FlagIsProtected|FlagIsPrivate %52 %53
1419fd4e5da5Sopenharmony_ci         %53 = OpExtInst %void %1 DebugTypeMember %11 %50 %45 5 5 %51 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
1420fd4e5da5Sopenharmony_ci         %52 = OpExtInst %void %1 DebugTypeMember %12 %50 %45 4 5 %51 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
1421fd4e5da5Sopenharmony_ci         %54 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %47 %51
1422fd4e5da5Sopenharmony_ci         %55 = OpExtInst %void %1 DebugFunction %13 %54 %45 13 1 %46 %13 FlagIsProtected|FlagIsPrivate 14 %src_MainPs
1423fd4e5da5Sopenharmony_ci         %56 = OpExtInst %void %1 DebugLexicalBlock %45 14 1 %55
1424fd4e5da5Sopenharmony_ci         %57 = OpExtInst %void %1 DebugLocalVariable %14 %50 %45 16 12 %56 FlagIsLocal
1425fd4e5da5Sopenharmony_ci         %58 = OpExtInst %void %1 DebugLocalVariable %15 %47 %45 15 15 %56 FlagIsLocal
1426fd4e5da5Sopenharmony_ci         %59 = OpExtInst %void %1 DebugExpression %60 = OpExtInst %void %1 DebugOperation Deref %61 = OpExtInst
1427fd4e5da5Sopenharmony_ci%void %1 DebugExpression %60 %62 = OpExtInst %void %1 DebugLocalVariable %16 %51
1428fd4e5da5Sopenharmony_ci%45 13 29 %55 FlagIsLocal 1 %63 = OpExtInst %void %1 DebugLocalVariable %14 %50
1429fd4e5da5Sopenharmony_ci%45 16 12 %55 FlagIsLocal 1 %MainPs = OpFunction %void None %40 %64 = OpLabel
1430fd4e5da5Sopenharmony_ci%param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
1431fd4e5da5Sopenharmony_ci         %65 = OpLoad %v4float %in_var_COLOR0
1432fd4e5da5Sopenharmony_ci         %66 = OpLoad %v4float %in_var_COLOR1
1433fd4e5da5Sopenharmony_ci         %67 = OpCompositeConstruct %PS_INPUT %65 %66
1434fd4e5da5Sopenharmony_ci               OpStore %param_var_i %67
1435fd4e5da5Sopenharmony_ci         %68 = OpFunctionCall %PS_OUTPUT %src_MainPs %param_var_i
1436fd4e5da5Sopenharmony_ci         %69 = OpCompositeExtract %v4float %68 0
1437fd4e5da5Sopenharmony_ci               OpStore %out_var_SV_Target0 %69
1438fd4e5da5Sopenharmony_ci               OpReturn
1439fd4e5da5Sopenharmony_ci               OpFunctionEnd
1440fd4e5da5Sopenharmony_ci               OpLine %6 13 1
1441fd4e5da5Sopenharmony_ci %src_MainPs = OpFunction %PS_OUTPUT None %42
1442fd4e5da5Sopenharmony_ci         %70 = OpExtInst %void %1 DebugScope %55
1443fd4e5da5Sopenharmony_ci               OpLine %6 13 29
1444fd4e5da5Sopenharmony_ci          %i = OpFunctionParameter %_ptr_Function_PS_INPUT
1445fd4e5da5Sopenharmony_ci         %71 = OpExtInst %void %1 DebugDeclare %62 %i %59
1446fd4e5da5Sopenharmony_ci         %72 = OpExtInst %void %1 DebugNoScope
1447fd4e5da5Sopenharmony_ci   %bb_entry = OpLabel
1448fd4e5da5Sopenharmony_ci         %73 = OpExtInst %void %1 DebugScope %56
1449fd4e5da5Sopenharmony_ci  %ps_output = OpVariable %_ptr_Function_PS_OUTPUT Function
1450fd4e5da5Sopenharmony_ci          %c = OpVariable %_ptr_Function_v4float Function
1451fd4e5da5Sopenharmony_ci         %74 = OpExtInst %void %1 DebugValue %63 %c %61
1452fd4e5da5Sopenharmony_ci               OpLine %6 18 9
1453fd4e5da5Sopenharmony_ci         %75 = OpAccessChain %_ptr_Function_v4float %i %int_0
1454fd4e5da5Sopenharmony_ci               OpLine %6 18 13
1455fd4e5da5Sopenharmony_ci         %76 = OpLoad %v4float %75
1456fd4e5da5Sopenharmony_ci               OpLine %6 18 5
1457fd4e5da5Sopenharmony_ci               OpStore %c %76
1458fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %76
1459fd4e5da5Sopenharmony_ci               OpLine %6 19 10
1460fd4e5da5Sopenharmony_ci         %77 = OpAccessChain %_ptr_Function_v4float %i %int_1
1461fd4e5da5Sopenharmony_ci               OpLine %6 19 14
1462fd4e5da5Sopenharmony_ci         %78 = OpLoad %v4float %77
1463fd4e5da5Sopenharmony_ci               OpLine %6 19 5
1464fd4e5da5Sopenharmony_ci         %79 = OpLoad %v4float %c
1465fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 19 5
1466fd4e5da5Sopenharmony_ci;CHECK-NOT: %79 = OpLoad %v4float %c
1467fd4e5da5Sopenharmony_ci               OpLine %6 19 7
1468fd4e5da5Sopenharmony_ci         %80 = OpFAdd %v4float %79 %78
1469fd4e5da5Sopenharmony_ci;CHECK-NOT: %80 = OpFAdd %v4float %79 %78
1470fd4e5da5Sopenharmony_ci;CHECK:     %80 = OpFAdd %v4float %76 %78
1471fd4e5da5Sopenharmony_ci               OpLine %6 19 5
1472fd4e5da5Sopenharmony_ci               OpStore %c %80
1473fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %80
1474fd4e5da5Sopenharmony_ci               OpLine %6 20 5
1475fd4e5da5Sopenharmony_ci         %81 = OpLoad %v4float %c
1476fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 20 5
1477fd4e5da5Sopenharmony_ci;CHECK-NOT: %81 = OpLoad %v4float %c
1478fd4e5da5Sopenharmony_ci               OpLine %6 20 7
1479fd4e5da5Sopenharmony_ci         %82 = OpFDiv %v4float %81 %31
1480fd4e5da5Sopenharmony_ci;CHECK-NOT: %82 = OpFDiv %v4float %81 %31
1481fd4e5da5Sopenharmony_ci;CHECK:     %82 = OpFDiv %v4float %80 %31
1482fd4e5da5Sopenharmony_ci               OpLine %6 20 5
1483fd4e5da5Sopenharmony_ci               OpStore %c %82
1484fd4e5da5Sopenharmony_ci;CHECK:        OpStore %c %82
1485fd4e5da5Sopenharmony_ci               OpLine %6 22 26
1486fd4e5da5Sopenharmony_ci         %83 = OpLoad %v4float %c
1487fd4e5da5Sopenharmony_ci;CHECK-NOT:       OpLine %6 22 26
1488fd4e5da5Sopenharmony_ci;CHECK-NOT: %83 = OpLoad %v4float %c
1489fd4e5da5Sopenharmony_ci               OpLine %6 22 5
1490fd4e5da5Sopenharmony_ci         %84 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
1491fd4e5da5Sopenharmony_ci               OpStore %84 %83
1492fd4e5da5Sopenharmony_ci;CHECK-NOT:    OpStore %84 %83
1493fd4e5da5Sopenharmony_ci;CHECK:        OpStore %84 %82
1494fd4e5da5Sopenharmony_ci               OpLine %6 23 12
1495fd4e5da5Sopenharmony_ci         %85 = OpLoad %PS_OUTPUT %ps_output
1496fd4e5da5Sopenharmony_ci               OpLine %6 23 5
1497fd4e5da5Sopenharmony_ci               OpReturnValue %85
1498fd4e5da5Sopenharmony_ci         %86 = OpExtInst %void %1 DebugNoScope
1499fd4e5da5Sopenharmony_ci               OpFunctionEnd
1500fd4e5da5Sopenharmony_ci  )";
1501fd4e5da5Sopenharmony_ci  SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1502fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
1503fd4e5da5Sopenharmony_ci}
1504fd4e5da5Sopenharmony_ci
1505fd4e5da5Sopenharmony_ciTEST_F(LocalSingleBlockLoadStoreElimTest, VkMemoryModelTest) {
1506fd4e5da5Sopenharmony_ci  const std::string text =
1507fd4e5da5Sopenharmony_ci      R"(
1508fd4e5da5Sopenharmony_ci; CHECK: OpCapability Shader
1509fd4e5da5Sopenharmony_ci; CHECK: OpCapability VulkanMemoryModel
1510fd4e5da5Sopenharmony_ci; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
1511fd4e5da5Sopenharmony_ci               OpCapability Shader
1512fd4e5da5Sopenharmony_ci               OpCapability VulkanMemoryModel
1513fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_vulkan_memory_model"
1514fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1515fd4e5da5Sopenharmony_ci               OpMemoryModel Logical Vulkan
1516fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "main"
1517fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
1518fd4e5da5Sopenharmony_ci               OpSource GLSL 450
1519fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1520fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
1521fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
1522fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int
1523fd4e5da5Sopenharmony_ci      %int_0 = OpConstant %int 0
1524fd4e5da5Sopenharmony_ci      %int_1 = OpConstant %int 1
1525fd4e5da5Sopenharmony_ci       %bool = OpTypeBool
1526fd4e5da5Sopenharmony_ci      %false = OpConstantFalse %bool
1527fd4e5da5Sopenharmony_ci; CHECK: OpFunction
1528fd4e5da5Sopenharmony_ci; CHECK-NEXT: OpLabel
1529fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[a:%\w+]] = OpVariable
1530fd4e5da5Sopenharmony_ci; CHECK-NEXT: [[b:%\w+]] = OpVariable
1531fd4e5da5Sopenharmony_ci; CHECK: OpStore [[a]] [[v:%\w+]]
1532fd4e5da5Sopenharmony_ci; CHECK-NOT: OpLoad %int [[a]]
1533fd4e5da5Sopenharmony_ci; CHECK: OpStore [[b]] [[v]]
1534fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
1535fd4e5da5Sopenharmony_ci          %5 = OpLabel
1536fd4e5da5Sopenharmony_ci          %a = OpVariable %_ptr_Function_int Function
1537fd4e5da5Sopenharmony_ci          %b = OpVariable %_ptr_Function_int Function
1538fd4e5da5Sopenharmony_ci               OpStore %a %int_0
1539fd4e5da5Sopenharmony_ci         %16 = OpLoad %int %a
1540fd4e5da5Sopenharmony_ci               OpStore %b %16
1541fd4e5da5Sopenharmony_ci               OpReturn
1542fd4e5da5Sopenharmony_ci               OpFunctionEnd
1543fd4e5da5Sopenharmony_ci)";
1544fd4e5da5Sopenharmony_ci
1545fd4e5da5Sopenharmony_ci  SinglePassRunAndMatch<LocalSingleBlockLoadStoreElimPass>(text, false);
1546fd4e5da5Sopenharmony_ci}
1547fd4e5da5Sopenharmony_ci
1548fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases:
1549fd4e5da5Sopenharmony_ci//
1550fd4e5da5Sopenharmony_ci//    Other target variable types
1551fd4e5da5Sopenharmony_ci//    InBounds Access Chains
1552fd4e5da5Sopenharmony_ci//    Check for correctness in the presence of function calls
1553fd4e5da5Sopenharmony_ci//    Others?
1554fd4e5da5Sopenharmony_ci
1555fd4e5da5Sopenharmony_ci}  // namespace
1556fd4e5da5Sopenharmony_ci}  // namespace opt
1557fd4e5da5Sopenharmony_ci}  // namespace spvtools
1558