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 "source/opt/simplification_pass.h"
19fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
20fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
21fd4e5da5Sopenharmony_ci
22fd4e5da5Sopenharmony_cinamespace spvtools {
23fd4e5da5Sopenharmony_cinamespace opt {
24fd4e5da5Sopenharmony_cinamespace {
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_ciusing InsertExtractElimTest = PassTest<::testing::Test>;
27fd4e5da5Sopenharmony_ci
28fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, Simple) {
29fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
30fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
31fd4e5da5Sopenharmony_ci  // reference each other.
32fd4e5da5Sopenharmony_ci  //
33fd4e5da5Sopenharmony_ci  // #version 140
34fd4e5da5Sopenharmony_ci  //
35fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
36fd4e5da5Sopenharmony_ci  //
37fd4e5da5Sopenharmony_ci  // struct S_t {
38fd4e5da5Sopenharmony_ci  //     vec4 v0;
39fd4e5da5Sopenharmony_ci  //     vec4 v1;
40fd4e5da5Sopenharmony_ci  // };
41fd4e5da5Sopenharmony_ci  //
42fd4e5da5Sopenharmony_ci  // void main()
43fd4e5da5Sopenharmony_ci  // {
44fd4e5da5Sopenharmony_ci  //     S_t s0;
45fd4e5da5Sopenharmony_ci  //     s0.v1 = BaseColor;
46fd4e5da5Sopenharmony_ci  //     gl_FragColor = s0.v1;
47fd4e5da5Sopenharmony_ci  // }
48fd4e5da5Sopenharmony_ci
49fd4e5da5Sopenharmony_ci  const std::string predefs =
50fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
51fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
52fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
53fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
54fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
55fd4e5da5Sopenharmony_ciOpSource GLSL 140
56fd4e5da5Sopenharmony_ciOpName %main "main"
57fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
58fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
59fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
60fd4e5da5Sopenharmony_ciOpName %s0 "s0"
61fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
62fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
63fd4e5da5Sopenharmony_ci%void = OpTypeVoid
64fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
65fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
66fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
67fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float
68fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
69fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
70fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
71fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
72fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
73fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
74fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
75fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
76fd4e5da5Sopenharmony_ci)";
77fd4e5da5Sopenharmony_ci
78fd4e5da5Sopenharmony_ci  const std::string before =
79fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
80fd4e5da5Sopenharmony_ci%17 = OpLabel
81fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
82fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor
83fd4e5da5Sopenharmony_ci%19 = OpLoad %S_t %s0
84fd4e5da5Sopenharmony_ci%20 = OpCompositeInsert %S_t %18 %19 1
85fd4e5da5Sopenharmony_ciOpStore %s0 %20
86fd4e5da5Sopenharmony_ci%21 = OpCompositeExtract %v4float %20 1
87fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %21
88fd4e5da5Sopenharmony_ciOpReturn
89fd4e5da5Sopenharmony_ciOpFunctionEnd
90fd4e5da5Sopenharmony_ci)";
91fd4e5da5Sopenharmony_ci
92fd4e5da5Sopenharmony_ci  const std::string after =
93fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
94fd4e5da5Sopenharmony_ci%17 = OpLabel
95fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
96fd4e5da5Sopenharmony_ci%18 = OpLoad %v4float %BaseColor
97fd4e5da5Sopenharmony_ci%19 = OpLoad %S_t %s0
98fd4e5da5Sopenharmony_ci%20 = OpCompositeInsert %S_t %18 %19 1
99fd4e5da5Sopenharmony_ciOpStore %s0 %20
100fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %18
101fd4e5da5Sopenharmony_ciOpReturn
102fd4e5da5Sopenharmony_ciOpFunctionEnd
103fd4e5da5Sopenharmony_ci)";
104fd4e5da5Sopenharmony_ci
105fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
106fd4e5da5Sopenharmony_ci                                            true, true);
107fd4e5da5Sopenharmony_ci}
108fd4e5da5Sopenharmony_ci
109fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, OptimizeAcrossNonConflictingInsert) {
110fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
111fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
112fd4e5da5Sopenharmony_ci  // reference each other.
113fd4e5da5Sopenharmony_ci  //
114fd4e5da5Sopenharmony_ci  // #version 140
115fd4e5da5Sopenharmony_ci  //
116fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
117fd4e5da5Sopenharmony_ci  //
118fd4e5da5Sopenharmony_ci  // struct S_t {
119fd4e5da5Sopenharmony_ci  //     vec4 v0;
120fd4e5da5Sopenharmony_ci  //     vec4 v1;
121fd4e5da5Sopenharmony_ci  // };
122fd4e5da5Sopenharmony_ci  //
123fd4e5da5Sopenharmony_ci  // void main()
124fd4e5da5Sopenharmony_ci  // {
125fd4e5da5Sopenharmony_ci  //     S_t s0;
126fd4e5da5Sopenharmony_ci  //     s0.v1 = BaseColor;
127fd4e5da5Sopenharmony_ci  //     s0.v0[2] = 0.0;
128fd4e5da5Sopenharmony_ci  //     gl_FragColor = s0.v1;
129fd4e5da5Sopenharmony_ci  // }
130fd4e5da5Sopenharmony_ci
131fd4e5da5Sopenharmony_ci  const std::string predefs =
132fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
133fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
134fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
135fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
136fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
137fd4e5da5Sopenharmony_ciOpSource GLSL 140
138fd4e5da5Sopenharmony_ciOpName %main "main"
139fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
140fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
141fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
142fd4e5da5Sopenharmony_ciOpName %s0 "s0"
143fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
144fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
145fd4e5da5Sopenharmony_ci%void = OpTypeVoid
146fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
147fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
148fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
149fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float
150fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
151fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
152fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
153fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
154fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
155fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
156fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
157fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
158fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
159fd4e5da5Sopenharmony_ci)";
160fd4e5da5Sopenharmony_ci
161fd4e5da5Sopenharmony_ci  const std::string before =
162fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
163fd4e5da5Sopenharmony_ci%18 = OpLabel
164fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
165fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor
166fd4e5da5Sopenharmony_ci%20 = OpLoad %S_t %s0
167fd4e5da5Sopenharmony_ci%21 = OpCompositeInsert %S_t %19 %20 1
168fd4e5da5Sopenharmony_ci%22 = OpCompositeInsert %S_t %float_0 %21 0 2
169fd4e5da5Sopenharmony_ciOpStore %s0 %22
170fd4e5da5Sopenharmony_ci%23 = OpCompositeExtract %v4float %22 1
171fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23
172fd4e5da5Sopenharmony_ciOpReturn
173fd4e5da5Sopenharmony_ciOpFunctionEnd
174fd4e5da5Sopenharmony_ci)";
175fd4e5da5Sopenharmony_ci
176fd4e5da5Sopenharmony_ci  const std::string after =
177fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
178fd4e5da5Sopenharmony_ci%18 = OpLabel
179fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
180fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor
181fd4e5da5Sopenharmony_ci%20 = OpLoad %S_t %s0
182fd4e5da5Sopenharmony_ci%21 = OpCompositeInsert %S_t %19 %20 1
183fd4e5da5Sopenharmony_ci%22 = OpCompositeInsert %S_t %float_0 %21 0 2
184fd4e5da5Sopenharmony_ciOpStore %s0 %22
185fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %19
186fd4e5da5Sopenharmony_ciOpReturn
187fd4e5da5Sopenharmony_ciOpFunctionEnd
188fd4e5da5Sopenharmony_ci)";
189fd4e5da5Sopenharmony_ci
190fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
191fd4e5da5Sopenharmony_ci                                            true, true);
192fd4e5da5Sopenharmony_ci}
193fd4e5da5Sopenharmony_ci
194fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, OptimizeOpaque) {
195fd4e5da5Sopenharmony_ci  // SPIR-V not representable in GLSL; not generatable from HLSL
196fd4e5da5Sopenharmony_ci  // for the moment.
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ci  const std::string predefs =
199fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
200fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
201fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
202fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %outColor %texCoords
203fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
204fd4e5da5Sopenharmony_ciOpSource GLSL 140
205fd4e5da5Sopenharmony_ciOpName %main "main"
206fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
207fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
208fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
209fd4e5da5Sopenharmony_ciOpMemberName %S_t 2 "smp"
210fd4e5da5Sopenharmony_ciOpName %outColor "outColor"
211fd4e5da5Sopenharmony_ciOpName %sampler15 "sampler15"
212fd4e5da5Sopenharmony_ciOpName %s0 "s0"
213fd4e5da5Sopenharmony_ciOpName %texCoords "texCoords"
214fd4e5da5Sopenharmony_ciOpDecorate %sampler15 DescriptorSet 0
215fd4e5da5Sopenharmony_ci%void = OpTypeVoid
216fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %void
217fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
218fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
219fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
220fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
221fd4e5da5Sopenharmony_ci%outColor = OpVariable %_ptr_Output_v4float Output
222fd4e5da5Sopenharmony_ci%14 = OpTypeImage %float 2D 0 0 0 1 Unknown
223fd4e5da5Sopenharmony_ci%15 = OpTypeSampledImage %14
224fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v2float %v2float %15
225fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
226fd4e5da5Sopenharmony_ci%17 = OpTypeFunction %void %_ptr_Function_S_t
227fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
228fd4e5da5Sopenharmony_ci%_ptr_Function_15 = OpTypePointer Function %15
229fd4e5da5Sopenharmony_ci%sampler15 = OpVariable %_ptr_UniformConstant_15 UniformConstant
230fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
231fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
232fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2
233fd4e5da5Sopenharmony_ci%_ptr_Function_v2float = OpTypePointer Function %v2float
234fd4e5da5Sopenharmony_ci%_ptr_Input_v2float = OpTypePointer Input %v2float
235fd4e5da5Sopenharmony_ci%texCoords = OpVariable %_ptr_Input_v2float Input
236fd4e5da5Sopenharmony_ci)";
237fd4e5da5Sopenharmony_ci
238fd4e5da5Sopenharmony_ci  const std::string before =
239fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %9
240fd4e5da5Sopenharmony_ci%25 = OpLabel
241fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
242fd4e5da5Sopenharmony_ci%26 = OpLoad %v2float %texCoords
243fd4e5da5Sopenharmony_ci%27 = OpLoad %S_t %s0
244fd4e5da5Sopenharmony_ci%28 = OpCompositeInsert %S_t %26 %27 0
245fd4e5da5Sopenharmony_ci%29 = OpLoad %15 %sampler15
246fd4e5da5Sopenharmony_ci%30 = OpCompositeInsert %S_t %29 %28 2
247fd4e5da5Sopenharmony_ciOpStore %s0 %30
248fd4e5da5Sopenharmony_ci%31 = OpCompositeExtract %15 %30 2
249fd4e5da5Sopenharmony_ci%32 = OpCompositeExtract %v2float %30 0
250fd4e5da5Sopenharmony_ci%33 = OpImageSampleImplicitLod %v4float %31 %32
251fd4e5da5Sopenharmony_ciOpStore %outColor %33
252fd4e5da5Sopenharmony_ciOpReturn
253fd4e5da5Sopenharmony_ciOpFunctionEnd
254fd4e5da5Sopenharmony_ci)";
255fd4e5da5Sopenharmony_ci
256fd4e5da5Sopenharmony_ci  const std::string after =
257fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %9
258fd4e5da5Sopenharmony_ci%25 = OpLabel
259fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
260fd4e5da5Sopenharmony_ci%26 = OpLoad %v2float %texCoords
261fd4e5da5Sopenharmony_ci%27 = OpLoad %S_t %s0
262fd4e5da5Sopenharmony_ci%28 = OpCompositeInsert %S_t %26 %27 0
263fd4e5da5Sopenharmony_ci%29 = OpLoad %15 %sampler15
264fd4e5da5Sopenharmony_ci%30 = OpCompositeInsert %S_t %29 %28 2
265fd4e5da5Sopenharmony_ciOpStore %s0 %30
266fd4e5da5Sopenharmony_ci%33 = OpImageSampleImplicitLod %v4float %29 %26
267fd4e5da5Sopenharmony_ciOpStore %outColor %33
268fd4e5da5Sopenharmony_ciOpReturn
269fd4e5da5Sopenharmony_ciOpFunctionEnd
270fd4e5da5Sopenharmony_ci)";
271fd4e5da5Sopenharmony_ci
272fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
273fd4e5da5Sopenharmony_ci                                            true, true);
274fd4e5da5Sopenharmony_ci}
275fd4e5da5Sopenharmony_ci
276fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, OptimizeNestedStruct) {
277fd4e5da5Sopenharmony_ci  // The following HLSL has been pre-optimized to get the SPIR-V:
278fd4e5da5Sopenharmony_ci  // struct S0
279fd4e5da5Sopenharmony_ci  // {
280fd4e5da5Sopenharmony_ci  //     int x;
281fd4e5da5Sopenharmony_ci  //     SamplerState ss;
282fd4e5da5Sopenharmony_ci  // };
283fd4e5da5Sopenharmony_ci  //
284fd4e5da5Sopenharmony_ci  // struct S1
285fd4e5da5Sopenharmony_ci  // {
286fd4e5da5Sopenharmony_ci  //     float b;
287fd4e5da5Sopenharmony_ci  //     S0 s0;
288fd4e5da5Sopenharmony_ci  // };
289fd4e5da5Sopenharmony_ci  //
290fd4e5da5Sopenharmony_ci  // struct S2
291fd4e5da5Sopenharmony_ci  // {
292fd4e5da5Sopenharmony_ci  //     int a1;
293fd4e5da5Sopenharmony_ci  //     S1 resources;
294fd4e5da5Sopenharmony_ci  // };
295fd4e5da5Sopenharmony_ci  //
296fd4e5da5Sopenharmony_ci  // SamplerState samp;
297fd4e5da5Sopenharmony_ci  // Texture2D tex;
298fd4e5da5Sopenharmony_ci  //
299fd4e5da5Sopenharmony_ci  // float4 main(float4 vpos : VPOS) : COLOR0
300fd4e5da5Sopenharmony_ci  // {
301fd4e5da5Sopenharmony_ci  //     S1 s1;
302fd4e5da5Sopenharmony_ci  //     S2 s2;
303fd4e5da5Sopenharmony_ci  //     s1.s0.ss = samp;
304fd4e5da5Sopenharmony_ci  //     s2.resources = s1;
305fd4e5da5Sopenharmony_ci  //     return tex.Sample(s2.resources.s0.ss, float2(0.5));
306fd4e5da5Sopenharmony_ci  // }
307fd4e5da5Sopenharmony_ci
308fd4e5da5Sopenharmony_ci  const std::string predefs =
309fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
310fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
311fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
312fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %_entryPointOutput
313fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
314fd4e5da5Sopenharmony_ciOpSource HLSL 500
315fd4e5da5Sopenharmony_ciOpName %main "main"
316fd4e5da5Sopenharmony_ciOpName %S0 "S0"
317fd4e5da5Sopenharmony_ciOpMemberName %S0 0 "x"
318fd4e5da5Sopenharmony_ciOpMemberName %S0 1 "ss"
319fd4e5da5Sopenharmony_ciOpName %S1 "S1"
320fd4e5da5Sopenharmony_ciOpMemberName %S1 0 "b"
321fd4e5da5Sopenharmony_ciOpMemberName %S1 1 "s0"
322fd4e5da5Sopenharmony_ciOpName %samp "samp"
323fd4e5da5Sopenharmony_ciOpName %S2 "S2"
324fd4e5da5Sopenharmony_ciOpMemberName %S2 0 "a1"
325fd4e5da5Sopenharmony_ciOpMemberName %S2 1 "resources"
326fd4e5da5Sopenharmony_ciOpName %tex "tex"
327fd4e5da5Sopenharmony_ciOpName %_entryPointOutput "@entryPointOutput"
328fd4e5da5Sopenharmony_ciOpDecorate %samp DescriptorSet 0
329fd4e5da5Sopenharmony_ciOpDecorate %tex DescriptorSet 0
330fd4e5da5Sopenharmony_ciOpDecorate %_entryPointOutput Location 0
331fd4e5da5Sopenharmony_ci%void = OpTypeVoid
332fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void
333fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
334fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
335fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
336fd4e5da5Sopenharmony_ci%14 = OpTypeFunction %v4float %_ptr_Function_v4float
337fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
338fd4e5da5Sopenharmony_ci%16 = OpTypeSampler
339fd4e5da5Sopenharmony_ci%S0 = OpTypeStruct %int %16
340fd4e5da5Sopenharmony_ci%S1 = OpTypeStruct %float %S0
341fd4e5da5Sopenharmony_ci%_ptr_Function_S1 = OpTypePointer Function %S1
342fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
343fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
344fd4e5da5Sopenharmony_ci%samp = OpVariable %_ptr_UniformConstant_16 UniformConstant
345fd4e5da5Sopenharmony_ci%_ptr_Function_16 = OpTypePointer Function %16
346fd4e5da5Sopenharmony_ci%S2 = OpTypeStruct %int %S1
347fd4e5da5Sopenharmony_ci%_ptr_Function_S2 = OpTypePointer Function %S2
348fd4e5da5Sopenharmony_ci%22 = OpTypeImage %float 2D 0 0 0 1 Unknown
349fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
350fd4e5da5Sopenharmony_ci%tex = OpVariable %_ptr_UniformConstant_22 UniformConstant
351fd4e5da5Sopenharmony_ci%24 = OpTypeSampledImage %22
352fd4e5da5Sopenharmony_ci%v2float = OpTypeVector %float 2
353fd4e5da5Sopenharmony_ci%float_0_5 = OpConstant %float 0.5
354fd4e5da5Sopenharmony_ci%27 = OpConstantComposite %v2float %float_0_5 %float_0_5
355fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
356fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
357fd4e5da5Sopenharmony_ci%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
358fd4e5da5Sopenharmony_ci)";
359fd4e5da5Sopenharmony_ci
360fd4e5da5Sopenharmony_ci  const std::string before =
361fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
362fd4e5da5Sopenharmony_ci%30 = OpLabel
363fd4e5da5Sopenharmony_ci%31 = OpVariable %_ptr_Function_S1 Function
364fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_S2 Function
365fd4e5da5Sopenharmony_ci%33 = OpLoad %16 %samp
366fd4e5da5Sopenharmony_ci%34 = OpLoad %S1 %31
367fd4e5da5Sopenharmony_ci%35 = OpCompositeInsert %S1 %33 %34 1 1
368fd4e5da5Sopenharmony_ciOpStore %31 %35
369fd4e5da5Sopenharmony_ci%36 = OpLoad %S2 %32
370fd4e5da5Sopenharmony_ci%37 = OpCompositeInsert %S2 %35 %36 1
371fd4e5da5Sopenharmony_ciOpStore %32 %37
372fd4e5da5Sopenharmony_ci%38 = OpLoad %22 %tex
373fd4e5da5Sopenharmony_ci%39 = OpCompositeExtract %16 %37 1 1 1
374fd4e5da5Sopenharmony_ci%40 = OpSampledImage %24 %38 %39
375fd4e5da5Sopenharmony_ci%41 = OpImageSampleImplicitLod %v4float %40 %27
376fd4e5da5Sopenharmony_ciOpStore %_entryPointOutput %41
377fd4e5da5Sopenharmony_ciOpReturn
378fd4e5da5Sopenharmony_ciOpFunctionEnd
379fd4e5da5Sopenharmony_ci)";
380fd4e5da5Sopenharmony_ci
381fd4e5da5Sopenharmony_ci  const std::string after =
382fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %10
383fd4e5da5Sopenharmony_ci%30 = OpLabel
384fd4e5da5Sopenharmony_ci%31 = OpVariable %_ptr_Function_S1 Function
385fd4e5da5Sopenharmony_ci%32 = OpVariable %_ptr_Function_S2 Function
386fd4e5da5Sopenharmony_ci%33 = OpLoad %16 %samp
387fd4e5da5Sopenharmony_ci%34 = OpLoad %S1 %31
388fd4e5da5Sopenharmony_ci%35 = OpCompositeInsert %S1 %33 %34 1 1
389fd4e5da5Sopenharmony_ciOpStore %31 %35
390fd4e5da5Sopenharmony_ci%36 = OpLoad %S2 %32
391fd4e5da5Sopenharmony_ci%37 = OpCompositeInsert %S2 %35 %36 1
392fd4e5da5Sopenharmony_ciOpStore %32 %37
393fd4e5da5Sopenharmony_ci%38 = OpLoad %22 %tex
394fd4e5da5Sopenharmony_ci%40 = OpSampledImage %24 %38 %33
395fd4e5da5Sopenharmony_ci%41 = OpImageSampleImplicitLod %v4float %40 %27
396fd4e5da5Sopenharmony_ciOpStore %_entryPointOutput %41
397fd4e5da5Sopenharmony_ciOpReturn
398fd4e5da5Sopenharmony_ciOpFunctionEnd
399fd4e5da5Sopenharmony_ci)";
400fd4e5da5Sopenharmony_ci
401fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
402fd4e5da5Sopenharmony_ci                                            true, true);
403fd4e5da5Sopenharmony_ci}
404fd4e5da5Sopenharmony_ci
405fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, ConflictingInsertPreventsOptimization) {
406fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
407fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
408fd4e5da5Sopenharmony_ci  // reference each other.
409fd4e5da5Sopenharmony_ci  //
410fd4e5da5Sopenharmony_ci  // #version 140
411fd4e5da5Sopenharmony_ci  //
412fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
413fd4e5da5Sopenharmony_ci  //
414fd4e5da5Sopenharmony_ci  // struct S_t {
415fd4e5da5Sopenharmony_ci  //     vec4 v0;
416fd4e5da5Sopenharmony_ci  //     vec4 v1;
417fd4e5da5Sopenharmony_ci  // };
418fd4e5da5Sopenharmony_ci  //
419fd4e5da5Sopenharmony_ci  // void main()
420fd4e5da5Sopenharmony_ci  // {
421fd4e5da5Sopenharmony_ci  //     S_t s0;
422fd4e5da5Sopenharmony_ci  //     s0.v1 = BaseColor;
423fd4e5da5Sopenharmony_ci  //     s0.v1[2] = 0.0;
424fd4e5da5Sopenharmony_ci  //     gl_FragColor = s0.v1;
425fd4e5da5Sopenharmony_ci  // }
426fd4e5da5Sopenharmony_ci
427fd4e5da5Sopenharmony_ci  const std::string assembly =
428fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
429fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
430fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
431fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
432fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
433fd4e5da5Sopenharmony_ciOpSource GLSL 140
434fd4e5da5Sopenharmony_ciOpName %main "main"
435fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
436fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
437fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
438fd4e5da5Sopenharmony_ciOpName %s0 "s0"
439fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
440fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
441fd4e5da5Sopenharmony_ci%void = OpTypeVoid
442fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
443fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
444fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
445fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float
446fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
447fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
448fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
449fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
450fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
451fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
452fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
453fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
454fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
455fd4e5da5Sopenharmony_ci%main = OpFunction %void None %8
456fd4e5da5Sopenharmony_ci%18 = OpLabel
457fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
458fd4e5da5Sopenharmony_ci%19 = OpLoad %v4float %BaseColor
459fd4e5da5Sopenharmony_ci%20 = OpLoad %S_t %s0
460fd4e5da5Sopenharmony_ci%21 = OpCompositeInsert %S_t %19 %20 1
461fd4e5da5Sopenharmony_ci%22 = OpCompositeInsert %S_t %float_0 %21 1 2
462fd4e5da5Sopenharmony_ciOpStore %s0 %22
463fd4e5da5Sopenharmony_ci%23 = OpCompositeExtract %v4float %22 1
464fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %23
465fd4e5da5Sopenharmony_ciOpReturn
466fd4e5da5Sopenharmony_ciOpFunctionEnd
467fd4e5da5Sopenharmony_ci)";
468fd4e5da5Sopenharmony_ci
469fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(assembly, assembly, true, true);
470fd4e5da5Sopenharmony_ci}
471fd4e5da5Sopenharmony_ci
472fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, ConflictingInsertPreventsOptimization2) {
473fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
474fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
475fd4e5da5Sopenharmony_ci  // reference each other.
476fd4e5da5Sopenharmony_ci  //
477fd4e5da5Sopenharmony_ci  // #version 140
478fd4e5da5Sopenharmony_ci  //
479fd4e5da5Sopenharmony_ci  // in vec4 BaseColor;
480fd4e5da5Sopenharmony_ci  //
481fd4e5da5Sopenharmony_ci  // struct S_t {
482fd4e5da5Sopenharmony_ci  //     vec4 v0;
483fd4e5da5Sopenharmony_ci  //     vec4 v1;
484fd4e5da5Sopenharmony_ci  // };
485fd4e5da5Sopenharmony_ci  //
486fd4e5da5Sopenharmony_ci  // void main()
487fd4e5da5Sopenharmony_ci  // {
488fd4e5da5Sopenharmony_ci  //     S_t s0;
489fd4e5da5Sopenharmony_ci  //     s0.v1[1] = 1.0; // dead
490fd4e5da5Sopenharmony_ci  //     s0.v1 = Baseline;
491fd4e5da5Sopenharmony_ci  //     gl_FragColor = vec4(s0.v1[1], 0.0, 0.0, 0.0);
492fd4e5da5Sopenharmony_ci  // }
493fd4e5da5Sopenharmony_ci
494fd4e5da5Sopenharmony_ci  const std::string before_predefs =
495fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
496fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
497fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
498fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
499fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
500fd4e5da5Sopenharmony_ciOpSource GLSL 140
501fd4e5da5Sopenharmony_ciOpName %main "main"
502fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
503fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
504fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
505fd4e5da5Sopenharmony_ciOpName %s0 "s0"
506fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
507fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
508fd4e5da5Sopenharmony_ci%void = OpTypeVoid
509fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
510fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
511fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
512fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float
513fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
514fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
515fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
516fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
517fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
518fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
519fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
520fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
521fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
522fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
523fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
524fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
525fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
526fd4e5da5Sopenharmony_ci)";
527fd4e5da5Sopenharmony_ci
528fd4e5da5Sopenharmony_ci  const std::string after_predefs =
529fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
530fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
531fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
532fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %BaseColor %gl_FragColor
533fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
534fd4e5da5Sopenharmony_ciOpSource GLSL 140
535fd4e5da5Sopenharmony_ciOpName %main "main"
536fd4e5da5Sopenharmony_ciOpName %S_t "S_t"
537fd4e5da5Sopenharmony_ciOpMemberName %S_t 0 "v0"
538fd4e5da5Sopenharmony_ciOpMemberName %S_t 1 "v1"
539fd4e5da5Sopenharmony_ciOpName %s0 "s0"
540fd4e5da5Sopenharmony_ciOpName %BaseColor "BaseColor"
541fd4e5da5Sopenharmony_ciOpName %gl_FragColor "gl_FragColor"
542fd4e5da5Sopenharmony_ci%void = OpTypeVoid
543fd4e5da5Sopenharmony_ci%8 = OpTypeFunction %void
544fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
545fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
546fd4e5da5Sopenharmony_ci%S_t = OpTypeStruct %v4float %v4float
547fd4e5da5Sopenharmony_ci%_ptr_Function_S_t = OpTypePointer Function %S_t
548fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1
549fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
550fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
551fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
552fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
553fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
554fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float
555fd4e5da5Sopenharmony_ci%BaseColor = OpVariable %_ptr_Input_v4float Input
556fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
557fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
558fd4e5da5Sopenharmony_ci%gl_FragColor = OpVariable %_ptr_Output_v4float Output
559fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
560fd4e5da5Sopenharmony_ci)";
561fd4e5da5Sopenharmony_ci
562fd4e5da5Sopenharmony_ci  const std::string before =
563fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
564fd4e5da5Sopenharmony_ci%22 = OpLabel
565fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
566fd4e5da5Sopenharmony_ci%23 = OpLoad %S_t %s0
567fd4e5da5Sopenharmony_ci%24 = OpCompositeInsert %S_t %float_1 %23 1 1
568fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %BaseColor
569fd4e5da5Sopenharmony_ci%26 = OpCompositeInsert %S_t %25 %24 1
570fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %float %26 1 1
571fd4e5da5Sopenharmony_ci%28 = OpCompositeConstruct %v4float %27 %float_0 %float_0 %float_0
572fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %28
573fd4e5da5Sopenharmony_ciOpReturn
574fd4e5da5Sopenharmony_ciOpFunctionEnd
575fd4e5da5Sopenharmony_ci)";
576fd4e5da5Sopenharmony_ci
577fd4e5da5Sopenharmony_ci  const std::string after =
578fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %8
579fd4e5da5Sopenharmony_ci%22 = OpLabel
580fd4e5da5Sopenharmony_ci%s0 = OpVariable %_ptr_Function_S_t Function
581fd4e5da5Sopenharmony_ci%23 = OpLoad %S_t %s0
582fd4e5da5Sopenharmony_ci%24 = OpCompositeInsert %S_t %float_1 %23 1 1
583fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %BaseColor
584fd4e5da5Sopenharmony_ci%26 = OpCompositeInsert %S_t %25 %24 1
585fd4e5da5Sopenharmony_ci%27 = OpCompositeExtract %float %25 1
586fd4e5da5Sopenharmony_ci%28 = OpCompositeConstruct %v4float %27 %float_0 %float_0 %float_0
587fd4e5da5Sopenharmony_ciOpStore %gl_FragColor %28
588fd4e5da5Sopenharmony_ciOpReturn
589fd4e5da5Sopenharmony_ciOpFunctionEnd
590fd4e5da5Sopenharmony_ci)";
591fd4e5da5Sopenharmony_ci
592fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(before_predefs + before,
593fd4e5da5Sopenharmony_ci                                            after_predefs + after, true, true);
594fd4e5da5Sopenharmony_ci}
595fd4e5da5Sopenharmony_ci
596fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, MixWithConstants) {
597fd4e5da5Sopenharmony_ci  // Extract component of FMix with 0.0 or 1.0 as the a-value.
598fd4e5da5Sopenharmony_ci  //
599fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
600fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
601fd4e5da5Sopenharmony_ci  // reference each other.
602fd4e5da5Sopenharmony_ci  //
603fd4e5da5Sopenharmony_ci  // #version 450
604fd4e5da5Sopenharmony_ci  //
605fd4e5da5Sopenharmony_ci  // layout (location=0) in float bc;
606fd4e5da5Sopenharmony_ci  // layout (location=1) in float bc2;
607fd4e5da5Sopenharmony_ci  // layout (location=2) in float m;
608fd4e5da5Sopenharmony_ci  // layout (location=3) in float m2;
609fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
610fd4e5da5Sopenharmony_ci  //
611fd4e5da5Sopenharmony_ci  // void main()
612fd4e5da5Sopenharmony_ci  // {
613fd4e5da5Sopenharmony_ci  //     vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
614fd4e5da5Sopenharmony_ci  //     vec4 bcv2 = vec4(bc2, bc, 1.0, 0.0);
615fd4e5da5Sopenharmony_ci  //     vec4 v = mix(bcv, bcv2, vec4(0.0,1.0,m,m2));
616fd4e5da5Sopenharmony_ci  //     OutColor = vec4(v.y);
617fd4e5da5Sopenharmony_ci  // }
618fd4e5da5Sopenharmony_ci
619fd4e5da5Sopenharmony_ci  const std::string predefs =
620fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
621fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
622fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
623fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %bc %bc2 %m %m2 %OutColor
624fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
625fd4e5da5Sopenharmony_ciOpSource GLSL 450
626fd4e5da5Sopenharmony_ciOpName %main "main"
627fd4e5da5Sopenharmony_ciOpName %bc "bc"
628fd4e5da5Sopenharmony_ciOpName %bc2 "bc2"
629fd4e5da5Sopenharmony_ciOpName %m "m"
630fd4e5da5Sopenharmony_ciOpName %m2 "m2"
631fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
632fd4e5da5Sopenharmony_ciOpDecorate %bc Location 0
633fd4e5da5Sopenharmony_ciOpDecorate %bc2 Location 1
634fd4e5da5Sopenharmony_ciOpDecorate %m Location 2
635fd4e5da5Sopenharmony_ciOpDecorate %m2 Location 3
636fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
637fd4e5da5Sopenharmony_ci%void = OpTypeVoid
638fd4e5da5Sopenharmony_ci%9 = OpTypeFunction %void
639fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
640fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
641fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
642fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
643fd4e5da5Sopenharmony_ci%bc = OpVariable %_ptr_Input_float Input
644fd4e5da5Sopenharmony_ci%bc2 = OpVariable %_ptr_Input_float Input
645fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
646fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
647fd4e5da5Sopenharmony_ci%m = OpVariable %_ptr_Input_float Input
648fd4e5da5Sopenharmony_ci%m2 = OpVariable %_ptr_Input_float Input
649fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
650fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
651fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
652fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
653fd4e5da5Sopenharmony_ci)";
654fd4e5da5Sopenharmony_ci
655fd4e5da5Sopenharmony_ci  const std::string before =
656fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %9
657fd4e5da5Sopenharmony_ci%19 = OpLabel
658fd4e5da5Sopenharmony_ci%20 = OpLoad %float %bc
659fd4e5da5Sopenharmony_ci%21 = OpLoad %float %bc2
660fd4e5da5Sopenharmony_ci%22 = OpCompositeConstruct %v4float %20 %21 %float_0 %float_1
661fd4e5da5Sopenharmony_ci%23 = OpLoad %float %bc2
662fd4e5da5Sopenharmony_ci%24 = OpLoad %float %bc
663fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %23 %24 %float_1 %float_0
664fd4e5da5Sopenharmony_ci%26 = OpLoad %float %m
665fd4e5da5Sopenharmony_ci%27 = OpLoad %float %m2
666fd4e5da5Sopenharmony_ci%28 = OpCompositeConstruct %v4float %float_0 %float_1 %26 %27
667fd4e5da5Sopenharmony_ci%29 = OpExtInst %v4float %1 FMix %22 %25 %28
668fd4e5da5Sopenharmony_ci%30 = OpCompositeExtract %float %29 1
669fd4e5da5Sopenharmony_ci%31 = OpCompositeConstruct %v4float %30 %30 %30 %30
670fd4e5da5Sopenharmony_ciOpStore %OutColor %31
671fd4e5da5Sopenharmony_ciOpReturn
672fd4e5da5Sopenharmony_ciOpFunctionEnd
673fd4e5da5Sopenharmony_ci)";
674fd4e5da5Sopenharmony_ci
675fd4e5da5Sopenharmony_ci  const std::string after =
676fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %9
677fd4e5da5Sopenharmony_ci%19 = OpLabel
678fd4e5da5Sopenharmony_ci%20 = OpLoad %float %bc
679fd4e5da5Sopenharmony_ci%21 = OpLoad %float %bc2
680fd4e5da5Sopenharmony_ci%22 = OpCompositeConstruct %v4float %20 %21 %float_0 %float_1
681fd4e5da5Sopenharmony_ci%23 = OpLoad %float %bc2
682fd4e5da5Sopenharmony_ci%24 = OpLoad %float %bc
683fd4e5da5Sopenharmony_ci%25 = OpCompositeConstruct %v4float %23 %24 %float_1 %float_0
684fd4e5da5Sopenharmony_ci%26 = OpLoad %float %m
685fd4e5da5Sopenharmony_ci%27 = OpLoad %float %m2
686fd4e5da5Sopenharmony_ci%28 = OpCompositeConstruct %v4float %float_0 %float_1 %26 %27
687fd4e5da5Sopenharmony_ci%29 = OpExtInst %v4float %1 FMix %22 %25 %28
688fd4e5da5Sopenharmony_ci%31 = OpCompositeConstruct %v4float %24 %24 %24 %24
689fd4e5da5Sopenharmony_ciOpStore %OutColor %31
690fd4e5da5Sopenharmony_ciOpReturn
691fd4e5da5Sopenharmony_ciOpFunctionEnd
692fd4e5da5Sopenharmony_ci)";
693fd4e5da5Sopenharmony_ci
694fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs + before, predefs + after,
695fd4e5da5Sopenharmony_ci                                            true, true);
696fd4e5da5Sopenharmony_ci}
697fd4e5da5Sopenharmony_ci
698fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, VectorShuffle1) {
699fd4e5da5Sopenharmony_ci  // Extract component from first vector in VectorShuffle
700fd4e5da5Sopenharmony_ci  //
701fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
702fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
703fd4e5da5Sopenharmony_ci  // reference each other.
704fd4e5da5Sopenharmony_ci  //
705fd4e5da5Sopenharmony_ci  // #version 450
706fd4e5da5Sopenharmony_ci  //
707fd4e5da5Sopenharmony_ci  // layout (location=0) in float bc;
708fd4e5da5Sopenharmony_ci  // layout (location=1) in float bc2;
709fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
710fd4e5da5Sopenharmony_ci  //
711fd4e5da5Sopenharmony_ci  // void main()
712fd4e5da5Sopenharmony_ci  // {
713fd4e5da5Sopenharmony_ci  //     vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
714fd4e5da5Sopenharmony_ci  //     vec4 v = bcv.zwxy;
715fd4e5da5Sopenharmony_ci  //     OutColor = vec4(v.y);
716fd4e5da5Sopenharmony_ci  // }
717fd4e5da5Sopenharmony_ci
718fd4e5da5Sopenharmony_ci  const std::string predefs_before =
719fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
720fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
721fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
722fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
723fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
724fd4e5da5Sopenharmony_ciOpSource GLSL 450
725fd4e5da5Sopenharmony_ciOpName %main "main"
726fd4e5da5Sopenharmony_ciOpName %bc "bc"
727fd4e5da5Sopenharmony_ciOpName %bc2 "bc2"
728fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
729fd4e5da5Sopenharmony_ciOpDecorate %bc Location 0
730fd4e5da5Sopenharmony_ciOpDecorate %bc2 Location 1
731fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
732fd4e5da5Sopenharmony_ci%void = OpTypeVoid
733fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
734fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
735fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
736fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
737fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
738fd4e5da5Sopenharmony_ci%bc = OpVariable %_ptr_Input_float Input
739fd4e5da5Sopenharmony_ci%bc2 = OpVariable %_ptr_Input_float Input
740fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
741fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
742fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
743fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
744fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
745fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
746fd4e5da5Sopenharmony_ci)";
747fd4e5da5Sopenharmony_ci
748fd4e5da5Sopenharmony_ci  const std::string predefs_after = predefs_before +
749fd4e5da5Sopenharmony_ci                                    "%24 = OpConstantComposite %v4float "
750fd4e5da5Sopenharmony_ci                                    "%float_1 %float_1 %float_1 %float_1\n";
751fd4e5da5Sopenharmony_ci
752fd4e5da5Sopenharmony_ci  const std::string before =
753fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
754fd4e5da5Sopenharmony_ci%17 = OpLabel
755fd4e5da5Sopenharmony_ci%18 = OpLoad %float %bc
756fd4e5da5Sopenharmony_ci%19 = OpLoad %float %bc2
757fd4e5da5Sopenharmony_ci%20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
758fd4e5da5Sopenharmony_ci%21 = OpVectorShuffle %v4float %20 %20 2 3 0 1
759fd4e5da5Sopenharmony_ci%22 = OpCompositeExtract %float %21 1
760fd4e5da5Sopenharmony_ci%23 = OpCompositeConstruct %v4float %22 %22 %22 %22
761fd4e5da5Sopenharmony_ciOpStore %OutColor %23
762fd4e5da5Sopenharmony_ciOpReturn
763fd4e5da5Sopenharmony_ciOpFunctionEnd
764fd4e5da5Sopenharmony_ci)";
765fd4e5da5Sopenharmony_ci
766fd4e5da5Sopenharmony_ci  const std::string after =
767fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
768fd4e5da5Sopenharmony_ci%17 = OpLabel
769fd4e5da5Sopenharmony_ci%18 = OpLoad %float %bc
770fd4e5da5Sopenharmony_ci%19 = OpLoad %float %bc2
771fd4e5da5Sopenharmony_ci%20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
772fd4e5da5Sopenharmony_ci%21 = OpVectorShuffle %v4float %20 %20 2 3 0 1
773fd4e5da5Sopenharmony_ciOpStore %OutColor %24
774fd4e5da5Sopenharmony_ciOpReturn
775fd4e5da5Sopenharmony_ciOpFunctionEnd
776fd4e5da5Sopenharmony_ci)";
777fd4e5da5Sopenharmony_ci
778fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs_before + before,
779fd4e5da5Sopenharmony_ci                                            predefs_after + after, true, true);
780fd4e5da5Sopenharmony_ci}
781fd4e5da5Sopenharmony_ci
782fd4e5da5Sopenharmony_ciTEST_F(InsertExtractElimTest, VectorShuffle2) {
783fd4e5da5Sopenharmony_ci  // Extract component from second vector in VectorShuffle
784fd4e5da5Sopenharmony_ci  // Identical to test VectorShuffle1 except for the vector
785fd4e5da5Sopenharmony_ci  // shuffle index of 7.
786fd4e5da5Sopenharmony_ci  //
787fd4e5da5Sopenharmony_ci  // Note: The SPIR-V assembly has had store/load elimination
788fd4e5da5Sopenharmony_ci  // performed to allow the inserts and extracts to directly
789fd4e5da5Sopenharmony_ci  // reference each other.
790fd4e5da5Sopenharmony_ci  //
791fd4e5da5Sopenharmony_ci  // #version 450
792fd4e5da5Sopenharmony_ci  //
793fd4e5da5Sopenharmony_ci  // layout (location=0) in float bc;
794fd4e5da5Sopenharmony_ci  // layout (location=1) in float bc2;
795fd4e5da5Sopenharmony_ci  // layout (location=0) out vec4 OutColor;
796fd4e5da5Sopenharmony_ci  //
797fd4e5da5Sopenharmony_ci  // void main()
798fd4e5da5Sopenharmony_ci  // {
799fd4e5da5Sopenharmony_ci  //     vec4 bcv = vec4(bc, bc2, 0.0, 1.0);
800fd4e5da5Sopenharmony_ci  //     vec4 v = bcv.zwxy;
801fd4e5da5Sopenharmony_ci  //     OutColor = vec4(v.y);
802fd4e5da5Sopenharmony_ci  // }
803fd4e5da5Sopenharmony_ci
804fd4e5da5Sopenharmony_ci  const std::string predefs_before =
805fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
806fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
807fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
808fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
809fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
810fd4e5da5Sopenharmony_ciOpSource GLSL 450
811fd4e5da5Sopenharmony_ciOpName %main "main"
812fd4e5da5Sopenharmony_ciOpName %bc "bc"
813fd4e5da5Sopenharmony_ciOpName %bc2 "bc2"
814fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
815fd4e5da5Sopenharmony_ciOpDecorate %bc Location 0
816fd4e5da5Sopenharmony_ciOpDecorate %bc2 Location 1
817fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
818fd4e5da5Sopenharmony_ci%void = OpTypeVoid
819fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
820fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
821fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
822fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
823fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
824fd4e5da5Sopenharmony_ci%bc = OpVariable %_ptr_Input_float Input
825fd4e5da5Sopenharmony_ci%bc2 = OpVariable %_ptr_Input_float Input
826fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
827fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
828fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
829fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
830fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
831fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
832fd4e5da5Sopenharmony_ci)";
833fd4e5da5Sopenharmony_ci
834fd4e5da5Sopenharmony_ci  const std::string predefs_after =
835fd4e5da5Sopenharmony_ci      R"(OpCapability Shader
836fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
837fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
838fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %bc %bc2 %OutColor
839fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
840fd4e5da5Sopenharmony_ciOpSource GLSL 450
841fd4e5da5Sopenharmony_ciOpName %main "main"
842fd4e5da5Sopenharmony_ciOpName %bc "bc"
843fd4e5da5Sopenharmony_ciOpName %bc2 "bc2"
844fd4e5da5Sopenharmony_ciOpName %OutColor "OutColor"
845fd4e5da5Sopenharmony_ciOpDecorate %bc Location 0
846fd4e5da5Sopenharmony_ciOpDecorate %bc2 Location 1
847fd4e5da5Sopenharmony_ciOpDecorate %OutColor Location 0
848fd4e5da5Sopenharmony_ci%void = OpTypeVoid
849fd4e5da5Sopenharmony_ci%7 = OpTypeFunction %void
850fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
851fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
852fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
853fd4e5da5Sopenharmony_ci%_ptr_Input_float = OpTypePointer Input %float
854fd4e5da5Sopenharmony_ci%bc = OpVariable %_ptr_Input_float Input
855fd4e5da5Sopenharmony_ci%bc2 = OpVariable %_ptr_Input_float Input
856fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0
857fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1
858fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float
859fd4e5da5Sopenharmony_ci%OutColor = OpVariable %_ptr_Output_v4float Output
860fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
861fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
862fd4e5da5Sopenharmony_ci%24 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
863fd4e5da5Sopenharmony_ci)";
864fd4e5da5Sopenharmony_ci
865fd4e5da5Sopenharmony_ci  const std::string before =
866fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
867fd4e5da5Sopenharmony_ci%17 = OpLabel
868fd4e5da5Sopenharmony_ci%18 = OpLoad %float %bc
869fd4e5da5Sopenharmony_ci%19 = OpLoad %float %bc2
870fd4e5da5Sopenharmony_ci%20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
871fd4e5da5Sopenharmony_ci%21 = OpVectorShuffle %v4float %20 %20 2 7 0 1
872fd4e5da5Sopenharmony_ci%22 = OpCompositeExtract %float %21 1
873fd4e5da5Sopenharmony_ci%23 = OpCompositeConstruct %v4float %22 %22 %22 %22
874fd4e5da5Sopenharmony_ciOpStore %OutColor %23
875fd4e5da5Sopenharmony_ciOpReturn
876fd4e5da5Sopenharmony_ciOpFunctionEnd
877fd4e5da5Sopenharmony_ci)";
878fd4e5da5Sopenharmony_ci
879fd4e5da5Sopenharmony_ci  const std::string after =
880fd4e5da5Sopenharmony_ci      R"(%main = OpFunction %void None %7
881fd4e5da5Sopenharmony_ci%17 = OpLabel
882fd4e5da5Sopenharmony_ci%18 = OpLoad %float %bc
883fd4e5da5Sopenharmony_ci%19 = OpLoad %float %bc2
884fd4e5da5Sopenharmony_ci%20 = OpCompositeConstruct %v4float %18 %19 %float_0 %float_1
885fd4e5da5Sopenharmony_ci%21 = OpVectorShuffle %v4float %20 %20 2 7 0 1
886fd4e5da5Sopenharmony_ciOpStore %OutColor %24
887fd4e5da5Sopenharmony_ciOpReturn
888fd4e5da5Sopenharmony_ciOpFunctionEnd
889fd4e5da5Sopenharmony_ci)";
890fd4e5da5Sopenharmony_ci
891fd4e5da5Sopenharmony_ci  SinglePassRunAndCheck<SimplificationPass>(predefs_before + before,
892fd4e5da5Sopenharmony_ci                                            predefs_after + after, true, true);
893fd4e5da5Sopenharmony_ci}
894fd4e5da5Sopenharmony_ci
895fd4e5da5Sopenharmony_ci// TODO(greg-lunarg): Add tests to verify handling of these cases:
896fd4e5da5Sopenharmony_ci//
897fd4e5da5Sopenharmony_ci
898fd4e5da5Sopenharmony_ci}  // namespace
899fd4e5da5Sopenharmony_ci}  // namespace opt
900fd4e5da5Sopenharmony_ci}  // namespace spvtools
901