1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h"
18fd4e5da5Sopenharmony_ci#include "source/reduce/reduction_opportunity.h"
19fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace reduce {
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader1) {
26fd4e5da5Sopenharmony_ci  std::string shader = R"(
27fd4e5da5Sopenharmony_ci               OpCapability Shader
28fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
29fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
30fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
31fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
32fd4e5da5Sopenharmony_ci               OpSource ESSL 310
33fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
34fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
35fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
36fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
37fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
38fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
39fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
40fd4e5da5Sopenharmony_ci         %20 = OpConstant %6 1
41fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
42fd4e5da5Sopenharmony_ci          %5 = OpLabel
43fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
44fd4e5da5Sopenharmony_ci               OpStore %8 %9
45fd4e5da5Sopenharmony_ci               OpBranch %10
46fd4e5da5Sopenharmony_ci         %10 = OpLabel
47fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
48fd4e5da5Sopenharmony_ci               OpBranch %14
49fd4e5da5Sopenharmony_ci         %14 = OpLabel
50fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
51fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
52fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
53fd4e5da5Sopenharmony_ci         %11 = OpLabel
54fd4e5da5Sopenharmony_ci               OpBranch %13
55fd4e5da5Sopenharmony_ci         %13 = OpLabel
56fd4e5da5Sopenharmony_ci         %19 = OpLoad %6 %8
57fd4e5da5Sopenharmony_ci         %21 = OpIAdd %6 %19 %20
58fd4e5da5Sopenharmony_ci               OpStore %8 %21
59fd4e5da5Sopenharmony_ci               OpBranch %10
60fd4e5da5Sopenharmony_ci         %12 = OpLabel
61fd4e5da5Sopenharmony_ci               OpReturn
62fd4e5da5Sopenharmony_ci               OpFunctionEnd
63fd4e5da5Sopenharmony_ci  )";
64fd4e5da5Sopenharmony_ci
65fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
66fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
67fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
68fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
69fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
70fd4e5da5Sopenharmony_ci
71fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
72fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
73fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
74fd4e5da5Sopenharmony_ci
75fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
76fd4e5da5Sopenharmony_ci               OpCapability Shader
77fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
78fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
79fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
80fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
81fd4e5da5Sopenharmony_ci               OpSource ESSL 310
82fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
83fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
84fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
85fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
86fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
87fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
88fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
89fd4e5da5Sopenharmony_ci         %20 = OpConstant %6 1
90fd4e5da5Sopenharmony_ci         %22 = OpConstantTrue %17
91fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
92fd4e5da5Sopenharmony_ci          %5 = OpLabel
93fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
94fd4e5da5Sopenharmony_ci               OpStore %8 %9
95fd4e5da5Sopenharmony_ci               OpBranch %10
96fd4e5da5Sopenharmony_ci         %10 = OpLabel
97fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
98fd4e5da5Sopenharmony_ci               OpBranchConditional %22 %14 %12
99fd4e5da5Sopenharmony_ci         %14 = OpLabel
100fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
101fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
102fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
103fd4e5da5Sopenharmony_ci         %11 = OpLabel
104fd4e5da5Sopenharmony_ci               OpBranch %12
105fd4e5da5Sopenharmony_ci         %13 = OpLabel
106fd4e5da5Sopenharmony_ci         %19 = OpLoad %6 %8
107fd4e5da5Sopenharmony_ci         %21 = OpIAdd %6 %19 %20
108fd4e5da5Sopenharmony_ci               OpStore %8 %21
109fd4e5da5Sopenharmony_ci               OpBranch %10
110fd4e5da5Sopenharmony_ci         %12 = OpLabel
111fd4e5da5Sopenharmony_ci               OpReturn
112fd4e5da5Sopenharmony_ci               OpFunctionEnd
113fd4e5da5Sopenharmony_ci  )";
114fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
115fd4e5da5Sopenharmony_ci}
116fd4e5da5Sopenharmony_ci
117fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader2) {
118fd4e5da5Sopenharmony_ci  std::string shader = R"(
119fd4e5da5Sopenharmony_ci               OpCapability Shader
120fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
121fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
122fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
123fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
124fd4e5da5Sopenharmony_ci               OpSource ESSL 310
125fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
126fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
127fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
128fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
129fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
130fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
131fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
132fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 1
133fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
134fd4e5da5Sopenharmony_ci          %5 = OpLabel
135fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
136fd4e5da5Sopenharmony_ci         %19 = OpVariable %7 Function
137fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
138fd4e5da5Sopenharmony_ci         %40 = OpVariable %7 Function
139fd4e5da5Sopenharmony_ci               OpStore %8 %9
140fd4e5da5Sopenharmony_ci               OpBranch %10
141fd4e5da5Sopenharmony_ci         %10 = OpLabel
142fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
143fd4e5da5Sopenharmony_ci               OpBranch %14
144fd4e5da5Sopenharmony_ci         %14 = OpLabel
145fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
146fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
147fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
148fd4e5da5Sopenharmony_ci         %11 = OpLabel
149fd4e5da5Sopenharmony_ci               OpStore %19 %9
150fd4e5da5Sopenharmony_ci               OpBranch %20
151fd4e5da5Sopenharmony_ci         %20 = OpLabel
152fd4e5da5Sopenharmony_ci               OpLoopMerge %22 %23 None
153fd4e5da5Sopenharmony_ci               OpBranch %24
154fd4e5da5Sopenharmony_ci         %24 = OpLabel
155fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %19
156fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %17 %25 %16
157fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %21 %22
158fd4e5da5Sopenharmony_ci         %21 = OpLabel
159fd4e5da5Sopenharmony_ci               OpBranch %23
160fd4e5da5Sopenharmony_ci         %23 = OpLabel
161fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %19
162fd4e5da5Sopenharmony_ci         %29 = OpIAdd %6 %27 %28
163fd4e5da5Sopenharmony_ci               OpStore %19 %29
164fd4e5da5Sopenharmony_ci               OpBranch %20
165fd4e5da5Sopenharmony_ci         %22 = OpLabel
166fd4e5da5Sopenharmony_ci               OpBranch %13
167fd4e5da5Sopenharmony_ci         %13 = OpLabel
168fd4e5da5Sopenharmony_ci         %30 = OpLoad %6 %8
169fd4e5da5Sopenharmony_ci         %31 = OpIAdd %6 %30 %28
170fd4e5da5Sopenharmony_ci               OpStore %8 %31
171fd4e5da5Sopenharmony_ci               OpBranch %10
172fd4e5da5Sopenharmony_ci         %12 = OpLabel
173fd4e5da5Sopenharmony_ci               OpStore %32 %9
174fd4e5da5Sopenharmony_ci               OpBranch %33
175fd4e5da5Sopenharmony_ci         %33 = OpLabel
176fd4e5da5Sopenharmony_ci               OpLoopMerge %35 %36 None
177fd4e5da5Sopenharmony_ci               OpBranch %37
178fd4e5da5Sopenharmony_ci         %37 = OpLabel
179fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
180fd4e5da5Sopenharmony_ci         %39 = OpSLessThan %17 %38 %16
181fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %34 %35
182fd4e5da5Sopenharmony_ci         %34 = OpLabel
183fd4e5da5Sopenharmony_ci               OpStore %40 %9
184fd4e5da5Sopenharmony_ci               OpBranch %41
185fd4e5da5Sopenharmony_ci         %41 = OpLabel
186fd4e5da5Sopenharmony_ci               OpLoopMerge %43 %44 None
187fd4e5da5Sopenharmony_ci               OpBranch %45
188fd4e5da5Sopenharmony_ci         %45 = OpLabel
189fd4e5da5Sopenharmony_ci         %46 = OpLoad %6 %40
190fd4e5da5Sopenharmony_ci         %47 = OpSLessThan %17 %46 %16
191fd4e5da5Sopenharmony_ci               OpBranchConditional %47 %42 %43
192fd4e5da5Sopenharmony_ci         %42 = OpLabel
193fd4e5da5Sopenharmony_ci               OpBranch %44
194fd4e5da5Sopenharmony_ci         %44 = OpLabel
195fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %40
196fd4e5da5Sopenharmony_ci         %49 = OpIAdd %6 %48 %28
197fd4e5da5Sopenharmony_ci               OpStore %40 %49
198fd4e5da5Sopenharmony_ci               OpBranch %41
199fd4e5da5Sopenharmony_ci         %43 = OpLabel
200fd4e5da5Sopenharmony_ci               OpBranch %36
201fd4e5da5Sopenharmony_ci         %36 = OpLabel
202fd4e5da5Sopenharmony_ci         %50 = OpLoad %6 %32
203fd4e5da5Sopenharmony_ci         %51 = OpIAdd %6 %50 %28
204fd4e5da5Sopenharmony_ci               OpStore %32 %51
205fd4e5da5Sopenharmony_ci               OpBranch %33
206fd4e5da5Sopenharmony_ci         %35 = OpLabel
207fd4e5da5Sopenharmony_ci               OpReturn
208fd4e5da5Sopenharmony_ci               OpFunctionEnd
209fd4e5da5Sopenharmony_ci  )";
210fd4e5da5Sopenharmony_ci
211fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
212fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
213fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
214fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
215fd4e5da5Sopenharmony_ci  ASSERT_EQ(4, ops.size());
216fd4e5da5Sopenharmony_ci
217fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
218fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
219fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
220fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
221fd4e5da5Sopenharmony_ci               OpCapability Shader
222fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
223fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
224fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
225fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
226fd4e5da5Sopenharmony_ci               OpSource ESSL 310
227fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
228fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
229fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
230fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
231fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
232fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
233fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
234fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 1
235fd4e5da5Sopenharmony_ci         %52 = OpConstantTrue %17
236fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
237fd4e5da5Sopenharmony_ci          %5 = OpLabel
238fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
239fd4e5da5Sopenharmony_ci         %19 = OpVariable %7 Function
240fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
241fd4e5da5Sopenharmony_ci         %40 = OpVariable %7 Function
242fd4e5da5Sopenharmony_ci               OpStore %8 %9
243fd4e5da5Sopenharmony_ci               OpBranch %10
244fd4e5da5Sopenharmony_ci         %10 = OpLabel
245fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
246fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %14 %12
247fd4e5da5Sopenharmony_ci         %14 = OpLabel
248fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
249fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
250fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
251fd4e5da5Sopenharmony_ci         %11 = OpLabel
252fd4e5da5Sopenharmony_ci               OpStore %19 %9
253fd4e5da5Sopenharmony_ci               OpBranch %20
254fd4e5da5Sopenharmony_ci         %20 = OpLabel
255fd4e5da5Sopenharmony_ci               OpLoopMerge %22 %23 None
256fd4e5da5Sopenharmony_ci               OpBranch %24
257fd4e5da5Sopenharmony_ci         %24 = OpLabel
258fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %19
259fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %17 %25 %16
260fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %21 %22
261fd4e5da5Sopenharmony_ci         %21 = OpLabel
262fd4e5da5Sopenharmony_ci               OpBranch %23
263fd4e5da5Sopenharmony_ci         %23 = OpLabel
264fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %19
265fd4e5da5Sopenharmony_ci         %29 = OpIAdd %6 %27 %28
266fd4e5da5Sopenharmony_ci               OpStore %19 %29
267fd4e5da5Sopenharmony_ci               OpBranch %20
268fd4e5da5Sopenharmony_ci         %22 = OpLabel
269fd4e5da5Sopenharmony_ci               OpBranch %12
270fd4e5da5Sopenharmony_ci         %13 = OpLabel
271fd4e5da5Sopenharmony_ci         %30 = OpLoad %6 %8
272fd4e5da5Sopenharmony_ci         %31 = OpIAdd %6 %30 %28
273fd4e5da5Sopenharmony_ci               OpStore %8 %31
274fd4e5da5Sopenharmony_ci               OpBranch %10
275fd4e5da5Sopenharmony_ci         %12 = OpLabel
276fd4e5da5Sopenharmony_ci               OpStore %32 %9
277fd4e5da5Sopenharmony_ci               OpBranch %33
278fd4e5da5Sopenharmony_ci         %33 = OpLabel
279fd4e5da5Sopenharmony_ci               OpLoopMerge %35 %36 None
280fd4e5da5Sopenharmony_ci               OpBranch %37
281fd4e5da5Sopenharmony_ci         %37 = OpLabel
282fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
283fd4e5da5Sopenharmony_ci         %39 = OpSLessThan %17 %38 %16
284fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %34 %35
285fd4e5da5Sopenharmony_ci         %34 = OpLabel
286fd4e5da5Sopenharmony_ci               OpStore %40 %9
287fd4e5da5Sopenharmony_ci               OpBranch %41
288fd4e5da5Sopenharmony_ci         %41 = OpLabel
289fd4e5da5Sopenharmony_ci               OpLoopMerge %43 %44 None
290fd4e5da5Sopenharmony_ci               OpBranch %45
291fd4e5da5Sopenharmony_ci         %45 = OpLabel
292fd4e5da5Sopenharmony_ci         %46 = OpLoad %6 %40
293fd4e5da5Sopenharmony_ci         %47 = OpSLessThan %17 %46 %16
294fd4e5da5Sopenharmony_ci               OpBranchConditional %47 %42 %43
295fd4e5da5Sopenharmony_ci         %42 = OpLabel
296fd4e5da5Sopenharmony_ci               OpBranch %44
297fd4e5da5Sopenharmony_ci         %44 = OpLabel
298fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %40
299fd4e5da5Sopenharmony_ci         %49 = OpIAdd %6 %48 %28
300fd4e5da5Sopenharmony_ci               OpStore %40 %49
301fd4e5da5Sopenharmony_ci               OpBranch %41
302fd4e5da5Sopenharmony_ci         %43 = OpLabel
303fd4e5da5Sopenharmony_ci               OpBranch %36
304fd4e5da5Sopenharmony_ci         %36 = OpLabel
305fd4e5da5Sopenharmony_ci         %50 = OpLoad %6 %32
306fd4e5da5Sopenharmony_ci         %51 = OpIAdd %6 %50 %28
307fd4e5da5Sopenharmony_ci               OpStore %32 %51
308fd4e5da5Sopenharmony_ci               OpBranch %33
309fd4e5da5Sopenharmony_ci         %35 = OpLabel
310fd4e5da5Sopenharmony_ci               OpReturn
311fd4e5da5Sopenharmony_ci               OpFunctionEnd
312fd4e5da5Sopenharmony_ci  )";
313fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
314fd4e5da5Sopenharmony_ci
315fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
316fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
317fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
318fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
319fd4e5da5Sopenharmony_ci               OpCapability Shader
320fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
321fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
322fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
323fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
324fd4e5da5Sopenharmony_ci               OpSource ESSL 310
325fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
326fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
327fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
328fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
329fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
330fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
331fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
332fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 1
333fd4e5da5Sopenharmony_ci         %52 = OpConstantTrue %17
334fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
335fd4e5da5Sopenharmony_ci          %5 = OpLabel
336fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
337fd4e5da5Sopenharmony_ci         %19 = OpVariable %7 Function
338fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
339fd4e5da5Sopenharmony_ci         %40 = OpVariable %7 Function
340fd4e5da5Sopenharmony_ci               OpStore %8 %9
341fd4e5da5Sopenharmony_ci               OpBranch %10
342fd4e5da5Sopenharmony_ci         %10 = OpLabel
343fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
344fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %14 %12
345fd4e5da5Sopenharmony_ci         %14 = OpLabel
346fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
347fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
348fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
349fd4e5da5Sopenharmony_ci         %11 = OpLabel
350fd4e5da5Sopenharmony_ci               OpStore %19 %9
351fd4e5da5Sopenharmony_ci               OpBranch %20
352fd4e5da5Sopenharmony_ci         %20 = OpLabel
353fd4e5da5Sopenharmony_ci               OpSelectionMerge %22 None
354fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %24 %22
355fd4e5da5Sopenharmony_ci         %24 = OpLabel
356fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %19
357fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %17 %25 %16
358fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %21 %22
359fd4e5da5Sopenharmony_ci         %21 = OpLabel
360fd4e5da5Sopenharmony_ci               OpBranch %22
361fd4e5da5Sopenharmony_ci         %23 = OpLabel
362fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %19
363fd4e5da5Sopenharmony_ci         %29 = OpIAdd %6 %27 %28
364fd4e5da5Sopenharmony_ci               OpStore %19 %29
365fd4e5da5Sopenharmony_ci               OpBranch %20
366fd4e5da5Sopenharmony_ci         %22 = OpLabel
367fd4e5da5Sopenharmony_ci               OpBranch %12
368fd4e5da5Sopenharmony_ci         %13 = OpLabel
369fd4e5da5Sopenharmony_ci         %30 = OpLoad %6 %8
370fd4e5da5Sopenharmony_ci         %31 = OpIAdd %6 %30 %28
371fd4e5da5Sopenharmony_ci               OpStore %8 %31
372fd4e5da5Sopenharmony_ci               OpBranch %10
373fd4e5da5Sopenharmony_ci         %12 = OpLabel
374fd4e5da5Sopenharmony_ci               OpStore %32 %9
375fd4e5da5Sopenharmony_ci               OpBranch %33
376fd4e5da5Sopenharmony_ci         %33 = OpLabel
377fd4e5da5Sopenharmony_ci               OpLoopMerge %35 %36 None
378fd4e5da5Sopenharmony_ci               OpBranch %37
379fd4e5da5Sopenharmony_ci         %37 = OpLabel
380fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
381fd4e5da5Sopenharmony_ci         %39 = OpSLessThan %17 %38 %16
382fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %34 %35
383fd4e5da5Sopenharmony_ci         %34 = OpLabel
384fd4e5da5Sopenharmony_ci               OpStore %40 %9
385fd4e5da5Sopenharmony_ci               OpBranch %41
386fd4e5da5Sopenharmony_ci         %41 = OpLabel
387fd4e5da5Sopenharmony_ci               OpLoopMerge %43 %44 None
388fd4e5da5Sopenharmony_ci               OpBranch %45
389fd4e5da5Sopenharmony_ci         %45 = OpLabel
390fd4e5da5Sopenharmony_ci         %46 = OpLoad %6 %40
391fd4e5da5Sopenharmony_ci         %47 = OpSLessThan %17 %46 %16
392fd4e5da5Sopenharmony_ci               OpBranchConditional %47 %42 %43
393fd4e5da5Sopenharmony_ci         %42 = OpLabel
394fd4e5da5Sopenharmony_ci               OpBranch %44
395fd4e5da5Sopenharmony_ci         %44 = OpLabel
396fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %40
397fd4e5da5Sopenharmony_ci         %49 = OpIAdd %6 %48 %28
398fd4e5da5Sopenharmony_ci               OpStore %40 %49
399fd4e5da5Sopenharmony_ci               OpBranch %41
400fd4e5da5Sopenharmony_ci         %43 = OpLabel
401fd4e5da5Sopenharmony_ci               OpBranch %36
402fd4e5da5Sopenharmony_ci         %36 = OpLabel
403fd4e5da5Sopenharmony_ci         %50 = OpLoad %6 %32
404fd4e5da5Sopenharmony_ci         %51 = OpIAdd %6 %50 %28
405fd4e5da5Sopenharmony_ci               OpStore %32 %51
406fd4e5da5Sopenharmony_ci               OpBranch %33
407fd4e5da5Sopenharmony_ci         %35 = OpLabel
408fd4e5da5Sopenharmony_ci               OpReturn
409fd4e5da5Sopenharmony_ci               OpFunctionEnd
410fd4e5da5Sopenharmony_ci  )";
411fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
412fd4e5da5Sopenharmony_ci
413fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[2]->PreconditionHolds());
414fd4e5da5Sopenharmony_ci  ops[2]->TryToApply();
415fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
416fd4e5da5Sopenharmony_ci  std::string after_op_2 = R"(
417fd4e5da5Sopenharmony_ci               OpCapability Shader
418fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
419fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
420fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
421fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
422fd4e5da5Sopenharmony_ci               OpSource ESSL 310
423fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
424fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
425fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
426fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
427fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
428fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
429fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
430fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 1
431fd4e5da5Sopenharmony_ci         %52 = OpConstantTrue %17
432fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
433fd4e5da5Sopenharmony_ci          %5 = OpLabel
434fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
435fd4e5da5Sopenharmony_ci         %19 = OpVariable %7 Function
436fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
437fd4e5da5Sopenharmony_ci         %40 = OpVariable %7 Function
438fd4e5da5Sopenharmony_ci               OpStore %8 %9
439fd4e5da5Sopenharmony_ci               OpBranch %10
440fd4e5da5Sopenharmony_ci         %10 = OpLabel
441fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
442fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %14 %12
443fd4e5da5Sopenharmony_ci         %14 = OpLabel
444fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
445fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
446fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
447fd4e5da5Sopenharmony_ci         %11 = OpLabel
448fd4e5da5Sopenharmony_ci               OpStore %19 %9
449fd4e5da5Sopenharmony_ci               OpBranch %20
450fd4e5da5Sopenharmony_ci         %20 = OpLabel
451fd4e5da5Sopenharmony_ci               OpSelectionMerge %22 None
452fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %24 %22
453fd4e5da5Sopenharmony_ci         %24 = OpLabel
454fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %19
455fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %17 %25 %16
456fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %21 %22
457fd4e5da5Sopenharmony_ci         %21 = OpLabel
458fd4e5da5Sopenharmony_ci               OpBranch %22
459fd4e5da5Sopenharmony_ci         %23 = OpLabel
460fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %19
461fd4e5da5Sopenharmony_ci         %29 = OpIAdd %6 %27 %28
462fd4e5da5Sopenharmony_ci               OpStore %19 %29
463fd4e5da5Sopenharmony_ci               OpBranch %20
464fd4e5da5Sopenharmony_ci         %22 = OpLabel
465fd4e5da5Sopenharmony_ci               OpBranch %12
466fd4e5da5Sopenharmony_ci         %13 = OpLabel
467fd4e5da5Sopenharmony_ci         %30 = OpLoad %6 %8
468fd4e5da5Sopenharmony_ci         %31 = OpIAdd %6 %30 %28
469fd4e5da5Sopenharmony_ci               OpStore %8 %31
470fd4e5da5Sopenharmony_ci               OpBranch %10
471fd4e5da5Sopenharmony_ci         %12 = OpLabel
472fd4e5da5Sopenharmony_ci               OpStore %32 %9
473fd4e5da5Sopenharmony_ci               OpBranch %33
474fd4e5da5Sopenharmony_ci         %33 = OpLabel
475fd4e5da5Sopenharmony_ci               OpSelectionMerge %35 None
476fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %37 %35
477fd4e5da5Sopenharmony_ci         %37 = OpLabel
478fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
479fd4e5da5Sopenharmony_ci         %39 = OpSLessThan %17 %38 %16
480fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %34 %35
481fd4e5da5Sopenharmony_ci         %34 = OpLabel
482fd4e5da5Sopenharmony_ci               OpStore %40 %9
483fd4e5da5Sopenharmony_ci               OpBranch %41
484fd4e5da5Sopenharmony_ci         %41 = OpLabel
485fd4e5da5Sopenharmony_ci               OpLoopMerge %43 %44 None
486fd4e5da5Sopenharmony_ci               OpBranch %45
487fd4e5da5Sopenharmony_ci         %45 = OpLabel
488fd4e5da5Sopenharmony_ci         %46 = OpLoad %6 %40
489fd4e5da5Sopenharmony_ci         %47 = OpSLessThan %17 %46 %16
490fd4e5da5Sopenharmony_ci               OpBranchConditional %47 %42 %43
491fd4e5da5Sopenharmony_ci         %42 = OpLabel
492fd4e5da5Sopenharmony_ci               OpBranch %44
493fd4e5da5Sopenharmony_ci         %44 = OpLabel
494fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %40
495fd4e5da5Sopenharmony_ci         %49 = OpIAdd %6 %48 %28
496fd4e5da5Sopenharmony_ci               OpStore %40 %49
497fd4e5da5Sopenharmony_ci               OpBranch %41
498fd4e5da5Sopenharmony_ci         %43 = OpLabel
499fd4e5da5Sopenharmony_ci               OpBranch %35
500fd4e5da5Sopenharmony_ci         %36 = OpLabel
501fd4e5da5Sopenharmony_ci         %50 = OpLoad %6 %32
502fd4e5da5Sopenharmony_ci         %51 = OpIAdd %6 %50 %28
503fd4e5da5Sopenharmony_ci               OpStore %32 %51
504fd4e5da5Sopenharmony_ci               OpBranch %33
505fd4e5da5Sopenharmony_ci         %35 = OpLabel
506fd4e5da5Sopenharmony_ci               OpReturn
507fd4e5da5Sopenharmony_ci               OpFunctionEnd
508fd4e5da5Sopenharmony_ci  )";
509fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_2, context.get());
510fd4e5da5Sopenharmony_ci
511fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[3]->PreconditionHolds());
512fd4e5da5Sopenharmony_ci  ops[3]->TryToApply();
513fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
514fd4e5da5Sopenharmony_ci  std::string after_op_3 = R"(
515fd4e5da5Sopenharmony_ci               OpCapability Shader
516fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
517fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
518fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
519fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
520fd4e5da5Sopenharmony_ci               OpSource ESSL 310
521fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
522fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
523fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
524fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
525fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 0
526fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 100
527fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
528fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 1
529fd4e5da5Sopenharmony_ci         %52 = OpConstantTrue %17
530fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
531fd4e5da5Sopenharmony_ci          %5 = OpLabel
532fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
533fd4e5da5Sopenharmony_ci         %19 = OpVariable %7 Function
534fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
535fd4e5da5Sopenharmony_ci         %40 = OpVariable %7 Function
536fd4e5da5Sopenharmony_ci               OpStore %8 %9
537fd4e5da5Sopenharmony_ci               OpBranch %10
538fd4e5da5Sopenharmony_ci         %10 = OpLabel
539fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
540fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %14 %12
541fd4e5da5Sopenharmony_ci         %14 = OpLabel
542fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
543fd4e5da5Sopenharmony_ci         %18 = OpSLessThan %17 %15 %16
544fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
545fd4e5da5Sopenharmony_ci         %11 = OpLabel
546fd4e5da5Sopenharmony_ci               OpStore %19 %9
547fd4e5da5Sopenharmony_ci               OpBranch %20
548fd4e5da5Sopenharmony_ci         %20 = OpLabel
549fd4e5da5Sopenharmony_ci               OpSelectionMerge %22 None
550fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %24 %22
551fd4e5da5Sopenharmony_ci         %24 = OpLabel
552fd4e5da5Sopenharmony_ci         %25 = OpLoad %6 %19
553fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %17 %25 %16
554fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %21 %22
555fd4e5da5Sopenharmony_ci         %21 = OpLabel
556fd4e5da5Sopenharmony_ci               OpBranch %22
557fd4e5da5Sopenharmony_ci         %23 = OpLabel
558fd4e5da5Sopenharmony_ci         %27 = OpLoad %6 %19
559fd4e5da5Sopenharmony_ci         %29 = OpIAdd %6 %27 %28
560fd4e5da5Sopenharmony_ci               OpStore %19 %29
561fd4e5da5Sopenharmony_ci               OpBranch %20
562fd4e5da5Sopenharmony_ci         %22 = OpLabel
563fd4e5da5Sopenharmony_ci               OpBranch %12
564fd4e5da5Sopenharmony_ci         %13 = OpLabel
565fd4e5da5Sopenharmony_ci         %30 = OpLoad %6 %8
566fd4e5da5Sopenharmony_ci         %31 = OpIAdd %6 %30 %28
567fd4e5da5Sopenharmony_ci               OpStore %8 %31
568fd4e5da5Sopenharmony_ci               OpBranch %10
569fd4e5da5Sopenharmony_ci         %12 = OpLabel
570fd4e5da5Sopenharmony_ci               OpStore %32 %9
571fd4e5da5Sopenharmony_ci               OpBranch %33
572fd4e5da5Sopenharmony_ci         %33 = OpLabel
573fd4e5da5Sopenharmony_ci               OpSelectionMerge %35 None
574fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %37 %35
575fd4e5da5Sopenharmony_ci         %37 = OpLabel
576fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
577fd4e5da5Sopenharmony_ci         %39 = OpSLessThan %17 %38 %16
578fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %34 %35
579fd4e5da5Sopenharmony_ci         %34 = OpLabel
580fd4e5da5Sopenharmony_ci               OpStore %40 %9
581fd4e5da5Sopenharmony_ci               OpBranch %41
582fd4e5da5Sopenharmony_ci         %41 = OpLabel
583fd4e5da5Sopenharmony_ci               OpSelectionMerge %43 None
584fd4e5da5Sopenharmony_ci               OpBranchConditional %52 %45 %43
585fd4e5da5Sopenharmony_ci         %45 = OpLabel
586fd4e5da5Sopenharmony_ci         %46 = OpLoad %6 %40
587fd4e5da5Sopenharmony_ci         %47 = OpSLessThan %17 %46 %16
588fd4e5da5Sopenharmony_ci               OpBranchConditional %47 %42 %43
589fd4e5da5Sopenharmony_ci         %42 = OpLabel
590fd4e5da5Sopenharmony_ci               OpBranch %43
591fd4e5da5Sopenharmony_ci         %44 = OpLabel
592fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %40
593fd4e5da5Sopenharmony_ci         %49 = OpIAdd %6 %48 %28
594fd4e5da5Sopenharmony_ci               OpStore %40 %49
595fd4e5da5Sopenharmony_ci               OpBranch %41
596fd4e5da5Sopenharmony_ci         %43 = OpLabel
597fd4e5da5Sopenharmony_ci               OpBranch %35
598fd4e5da5Sopenharmony_ci         %36 = OpLabel
599fd4e5da5Sopenharmony_ci         %50 = OpLoad %6 %32
600fd4e5da5Sopenharmony_ci         %51 = OpIAdd %6 %50 %28
601fd4e5da5Sopenharmony_ci               OpStore %32 %51
602fd4e5da5Sopenharmony_ci               OpBranch %33
603fd4e5da5Sopenharmony_ci         %35 = OpLabel
604fd4e5da5Sopenharmony_ci               OpReturn
605fd4e5da5Sopenharmony_ci               OpFunctionEnd
606fd4e5da5Sopenharmony_ci  )";
607fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_3, context.get());
608fd4e5da5Sopenharmony_ci}
609fd4e5da5Sopenharmony_ci
610fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader3) {
611fd4e5da5Sopenharmony_ci  std::string shader = R"(
612fd4e5da5Sopenharmony_ci               OpCapability Shader
613fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
614fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
615fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
616fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
617fd4e5da5Sopenharmony_ci               OpSource ESSL 310
618fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
619fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
620fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
621fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
622fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 10
623fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 0
624fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
625fd4e5da5Sopenharmony_ci         %20 = OpConstant %6 1
626fd4e5da5Sopenharmony_ci         %23 = OpConstant %6 3
627fd4e5da5Sopenharmony_ci         %40 = OpConstant %6 5
628fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
629fd4e5da5Sopenharmony_ci          %5 = OpLabel
630fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
631fd4e5da5Sopenharmony_ci               OpStore %8 %9
632fd4e5da5Sopenharmony_ci               OpBranch %10
633fd4e5da5Sopenharmony_ci         %10 = OpLabel
634fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
635fd4e5da5Sopenharmony_ci               OpBranch %14
636fd4e5da5Sopenharmony_ci         %14 = OpLabel
637fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8
638fd4e5da5Sopenharmony_ci         %18 = OpSGreaterThan %17 %15 %16
639fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %11 %12
640fd4e5da5Sopenharmony_ci         %11 = OpLabel
641fd4e5da5Sopenharmony_ci         %19 = OpLoad %6 %8
642fd4e5da5Sopenharmony_ci         %21 = OpISub %6 %19 %20
643fd4e5da5Sopenharmony_ci               OpStore %8 %21
644fd4e5da5Sopenharmony_ci         %22 = OpLoad %6 %8
645fd4e5da5Sopenharmony_ci         %24 = OpSLessThan %17 %22 %23
646fd4e5da5Sopenharmony_ci               OpSelectionMerge %26 None
647fd4e5da5Sopenharmony_ci               OpBranchConditional %24 %25 %26
648fd4e5da5Sopenharmony_ci         %25 = OpLabel
649fd4e5da5Sopenharmony_ci               OpBranch %13
650fd4e5da5Sopenharmony_ci         %26 = OpLabel
651fd4e5da5Sopenharmony_ci               OpBranch %28
652fd4e5da5Sopenharmony_ci         %28 = OpLabel
653fd4e5da5Sopenharmony_ci               OpLoopMerge %30 %31 None
654fd4e5da5Sopenharmony_ci               OpBranch %29
655fd4e5da5Sopenharmony_ci         %29 = OpLabel
656fd4e5da5Sopenharmony_ci         %32 = OpLoad %6 %8
657fd4e5da5Sopenharmony_ci         %33 = OpISub %6 %32 %20
658fd4e5da5Sopenharmony_ci               OpStore %8 %33
659fd4e5da5Sopenharmony_ci         %34 = OpLoad %6 %8
660fd4e5da5Sopenharmony_ci         %35 = OpIEqual %17 %34 %20
661fd4e5da5Sopenharmony_ci               OpSelectionMerge %37 None
662fd4e5da5Sopenharmony_ci               OpBranchConditional %35 %36 %37
663fd4e5da5Sopenharmony_ci         %36 = OpLabel
664fd4e5da5Sopenharmony_ci               OpReturn ; This return spoils everything: it means the merge does not post-dominate the header.
665fd4e5da5Sopenharmony_ci         %37 = OpLabel
666fd4e5da5Sopenharmony_ci               OpBranch %31
667fd4e5da5Sopenharmony_ci         %31 = OpLabel
668fd4e5da5Sopenharmony_ci         %39 = OpLoad %6 %8
669fd4e5da5Sopenharmony_ci         %41 = OpSGreaterThan %17 %39 %40
670fd4e5da5Sopenharmony_ci               OpBranchConditional %41 %28 %30
671fd4e5da5Sopenharmony_ci         %30 = OpLabel
672fd4e5da5Sopenharmony_ci               OpBranch %13
673fd4e5da5Sopenharmony_ci         %13 = OpLabel
674fd4e5da5Sopenharmony_ci               OpBranch %10
675fd4e5da5Sopenharmony_ci         %12 = OpLabel
676fd4e5da5Sopenharmony_ci               OpReturn
677fd4e5da5Sopenharmony_ci               OpFunctionEnd
678fd4e5da5Sopenharmony_ci  )";
679fd4e5da5Sopenharmony_ci
680fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
681fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
682fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
683fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
684fd4e5da5Sopenharmony_ci  ASSERT_EQ(0, ops.size());
685fd4e5da5Sopenharmony_ci}
686fd4e5da5Sopenharmony_ci
687fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader4) {
688fd4e5da5Sopenharmony_ci  std::string shader = R"(
689fd4e5da5Sopenharmony_ci               OpCapability Shader
690fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
691fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
692fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
693fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
694fd4e5da5Sopenharmony_ci               OpSource ESSL 310
695fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
696fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
697fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
698fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
699fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %6 %7
700fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 0
701fd4e5da5Sopenharmony_ci         %22 = OpTypeBool
702fd4e5da5Sopenharmony_ci         %25 = OpConstant %6 1
703fd4e5da5Sopenharmony_ci         %39 = OpConstant %6 100
704fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
705fd4e5da5Sopenharmony_ci          %5 = OpLabel
706fd4e5da5Sopenharmony_ci         %45 = OpVariable %7 Function
707fd4e5da5Sopenharmony_ci         %46 = OpVariable %7 Function
708fd4e5da5Sopenharmony_ci         %47 = OpVariable %7 Function
709fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
710fd4e5da5Sopenharmony_ci         %42 = OpVariable %7 Function
711fd4e5da5Sopenharmony_ci               OpStore %32 %13
712fd4e5da5Sopenharmony_ci               OpBranch %33
713fd4e5da5Sopenharmony_ci         %33 = OpLabel
714fd4e5da5Sopenharmony_ci               OpLoopMerge %35 %36 None
715fd4e5da5Sopenharmony_ci               OpBranch %37
716fd4e5da5Sopenharmony_ci         %37 = OpLabel
717fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
718fd4e5da5Sopenharmony_ci         %40 = OpSLessThan %22 %38 %39
719fd4e5da5Sopenharmony_ci               OpBranchConditional %40 %34 %35
720fd4e5da5Sopenharmony_ci         %34 = OpLabel
721fd4e5da5Sopenharmony_ci               OpBranch %36
722fd4e5da5Sopenharmony_ci         %36 = OpLabel
723fd4e5da5Sopenharmony_ci         %41 = OpLoad %6 %32
724fd4e5da5Sopenharmony_ci               OpStore %42 %25
725fd4e5da5Sopenharmony_ci               OpStore %45 %13
726fd4e5da5Sopenharmony_ci               OpStore %46 %13
727fd4e5da5Sopenharmony_ci               OpBranch %48
728fd4e5da5Sopenharmony_ci         %48 = OpLabel
729fd4e5da5Sopenharmony_ci               OpLoopMerge %49 %50 None
730fd4e5da5Sopenharmony_ci               OpBranch %51
731fd4e5da5Sopenharmony_ci         %51 = OpLabel
732fd4e5da5Sopenharmony_ci         %52 = OpLoad %6 %46
733fd4e5da5Sopenharmony_ci         %53 = OpLoad %6 %42
734fd4e5da5Sopenharmony_ci         %54 = OpSLessThan %22 %52 %53
735fd4e5da5Sopenharmony_ci               OpBranchConditional %54 %55 %49
736fd4e5da5Sopenharmony_ci         %55 = OpLabel
737fd4e5da5Sopenharmony_ci         %56 = OpLoad %6 %45
738fd4e5da5Sopenharmony_ci         %57 = OpIAdd %6 %56 %25
739fd4e5da5Sopenharmony_ci               OpStore %45 %57
740fd4e5da5Sopenharmony_ci               OpBranch %50
741fd4e5da5Sopenharmony_ci         %50 = OpLabel
742fd4e5da5Sopenharmony_ci         %58 = OpLoad %6 %46
743fd4e5da5Sopenharmony_ci         %59 = OpIAdd %6 %58 %25
744fd4e5da5Sopenharmony_ci               OpStore %46 %59
745fd4e5da5Sopenharmony_ci               OpBranch %48
746fd4e5da5Sopenharmony_ci         %49 = OpLabel
747fd4e5da5Sopenharmony_ci         %60 = OpLoad %6 %45
748fd4e5da5Sopenharmony_ci               OpStore %47 %60
749fd4e5da5Sopenharmony_ci         %43 = OpLoad %6 %47
750fd4e5da5Sopenharmony_ci         %44 = OpIAdd %6 %41 %43
751fd4e5da5Sopenharmony_ci               OpStore %32 %44
752fd4e5da5Sopenharmony_ci               OpBranch %33
753fd4e5da5Sopenharmony_ci         %35 = OpLabel
754fd4e5da5Sopenharmony_ci               OpReturn
755fd4e5da5Sopenharmony_ci               OpFunctionEnd
756fd4e5da5Sopenharmony_ci  )";
757fd4e5da5Sopenharmony_ci
758fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
759fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
760fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
761fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
762fd4e5da5Sopenharmony_ci
763fd4e5da5Sopenharmony_ci  // Initially there are two opportunities.
764fd4e5da5Sopenharmony_ci  ASSERT_EQ(2, ops.size());
765fd4e5da5Sopenharmony_ci
766fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
767fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
768fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
769fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
770fd4e5da5Sopenharmony_ci               OpCapability Shader
771fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
772fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
773fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
774fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
775fd4e5da5Sopenharmony_ci               OpSource ESSL 310
776fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
777fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
778fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
779fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
780fd4e5da5Sopenharmony_ci          %8 = OpTypeFunction %6 %7
781fd4e5da5Sopenharmony_ci         %13 = OpConstant %6 0
782fd4e5da5Sopenharmony_ci         %22 = OpTypeBool
783fd4e5da5Sopenharmony_ci         %25 = OpConstant %6 1
784fd4e5da5Sopenharmony_ci         %39 = OpConstant %6 100
785fd4e5da5Sopenharmony_ci         %61 = OpConstantTrue %22
786fd4e5da5Sopenharmony_ci         %62 = OpUndef %6
787fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
788fd4e5da5Sopenharmony_ci          %5 = OpLabel
789fd4e5da5Sopenharmony_ci         %45 = OpVariable %7 Function
790fd4e5da5Sopenharmony_ci         %46 = OpVariable %7 Function
791fd4e5da5Sopenharmony_ci         %47 = OpVariable %7 Function
792fd4e5da5Sopenharmony_ci         %32 = OpVariable %7 Function
793fd4e5da5Sopenharmony_ci         %42 = OpVariable %7 Function
794fd4e5da5Sopenharmony_ci               OpStore %32 %13
795fd4e5da5Sopenharmony_ci               OpBranch %33
796fd4e5da5Sopenharmony_ci         %33 = OpLabel
797fd4e5da5Sopenharmony_ci               OpSelectionMerge %35 None
798fd4e5da5Sopenharmony_ci               OpBranchConditional %61 %37 %35
799fd4e5da5Sopenharmony_ci         %37 = OpLabel
800fd4e5da5Sopenharmony_ci         %38 = OpLoad %6 %32
801fd4e5da5Sopenharmony_ci         %40 = OpSLessThan %22 %38 %39
802fd4e5da5Sopenharmony_ci               OpBranchConditional %40 %34 %35
803fd4e5da5Sopenharmony_ci         %34 = OpLabel
804fd4e5da5Sopenharmony_ci               OpBranch %35
805fd4e5da5Sopenharmony_ci         %36 = OpLabel
806fd4e5da5Sopenharmony_ci         %41 = OpLoad %6 %32
807fd4e5da5Sopenharmony_ci               OpStore %42 %25
808fd4e5da5Sopenharmony_ci               OpStore %45 %13
809fd4e5da5Sopenharmony_ci               OpStore %46 %13
810fd4e5da5Sopenharmony_ci               OpBranch %48
811fd4e5da5Sopenharmony_ci         %48 = OpLabel
812fd4e5da5Sopenharmony_ci               OpLoopMerge %49 %50 None
813fd4e5da5Sopenharmony_ci               OpBranch %51
814fd4e5da5Sopenharmony_ci         %51 = OpLabel
815fd4e5da5Sopenharmony_ci         %52 = OpLoad %6 %46
816fd4e5da5Sopenharmony_ci         %53 = OpLoad %6 %42
817fd4e5da5Sopenharmony_ci         %54 = OpSLessThan %22 %52 %53
818fd4e5da5Sopenharmony_ci               OpBranchConditional %54 %55 %49
819fd4e5da5Sopenharmony_ci         %55 = OpLabel
820fd4e5da5Sopenharmony_ci         %56 = OpLoad %6 %45
821fd4e5da5Sopenharmony_ci         %57 = OpIAdd %6 %56 %25
822fd4e5da5Sopenharmony_ci               OpStore %45 %57
823fd4e5da5Sopenharmony_ci               OpBranch %50
824fd4e5da5Sopenharmony_ci         %50 = OpLabel
825fd4e5da5Sopenharmony_ci         %58 = OpLoad %6 %46
826fd4e5da5Sopenharmony_ci         %59 = OpIAdd %6 %58 %25
827fd4e5da5Sopenharmony_ci               OpStore %46 %59
828fd4e5da5Sopenharmony_ci               OpBranch %48
829fd4e5da5Sopenharmony_ci         %49 = OpLabel
830fd4e5da5Sopenharmony_ci         %60 = OpLoad %6 %45
831fd4e5da5Sopenharmony_ci               OpStore %47 %60
832fd4e5da5Sopenharmony_ci         %43 = OpLoad %6 %47
833fd4e5da5Sopenharmony_ci         %44 = OpIAdd %6 %62 %43
834fd4e5da5Sopenharmony_ci               OpStore %32 %44
835fd4e5da5Sopenharmony_ci               OpBranch %33
836fd4e5da5Sopenharmony_ci         %35 = OpLabel
837fd4e5da5Sopenharmony_ci               OpReturn
838fd4e5da5Sopenharmony_ci               OpFunctionEnd
839fd4e5da5Sopenharmony_ci  )";
840fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
841fd4e5da5Sopenharmony_ci
842fd4e5da5Sopenharmony_ci  // Applying the first opportunity has killed the second opportunity, because
843fd4e5da5Sopenharmony_ci  // there was a loop embedded in the continue target of the loop we have just
844fd4e5da5Sopenharmony_ci  // eliminated; the continue-embedded loop is now unreachable.
845fd4e5da5Sopenharmony_ci  ASSERT_FALSE(ops[1]->PreconditionHolds());
846fd4e5da5Sopenharmony_ci}
847fd4e5da5Sopenharmony_ci
848fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak1) {
849fd4e5da5Sopenharmony_ci  std::string shader = R"(
850fd4e5da5Sopenharmony_ci               OpCapability Shader
851fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
852fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
853fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
854fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
855fd4e5da5Sopenharmony_ci               OpSource ESSL 310
856fd4e5da5Sopenharmony_ci               OpName %4 "main"
857fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
858fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
859fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
860fd4e5da5Sopenharmony_ci         %11 = OpConstantFalse %10
861fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
862fd4e5da5Sopenharmony_ci          %5 = OpLabel
863fd4e5da5Sopenharmony_ci               OpBranch %6
864fd4e5da5Sopenharmony_ci          %6 = OpLabel
865fd4e5da5Sopenharmony_ci               OpLoopMerge %8 %9 None
866fd4e5da5Sopenharmony_ci               OpBranch %7
867fd4e5da5Sopenharmony_ci          %7 = OpLabel
868fd4e5da5Sopenharmony_ci               OpSelectionMerge %13 None
869fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %12 %13
870fd4e5da5Sopenharmony_ci         %12 = OpLabel
871fd4e5da5Sopenharmony_ci               OpBranch %8
872fd4e5da5Sopenharmony_ci         %13 = OpLabel
873fd4e5da5Sopenharmony_ci               OpBranch %9
874fd4e5da5Sopenharmony_ci          %9 = OpLabel
875fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %6 %8
876fd4e5da5Sopenharmony_ci          %8 = OpLabel
877fd4e5da5Sopenharmony_ci               OpReturn
878fd4e5da5Sopenharmony_ci               OpFunctionEnd
879fd4e5da5Sopenharmony_ci  )";
880fd4e5da5Sopenharmony_ci
881fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
882fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
883fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
884fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
885fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
886fd4e5da5Sopenharmony_ci
887fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
888fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
889fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
890fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
891fd4e5da5Sopenharmony_ci               OpCapability Shader
892fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
893fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
894fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
895fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
896fd4e5da5Sopenharmony_ci               OpSource ESSL 310
897fd4e5da5Sopenharmony_ci               OpName %4 "main"
898fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
899fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
900fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
901fd4e5da5Sopenharmony_ci         %11 = OpConstantFalse %10
902fd4e5da5Sopenharmony_ci         %14 = OpConstantTrue %10
903fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
904fd4e5da5Sopenharmony_ci          %5 = OpLabel
905fd4e5da5Sopenharmony_ci               OpBranch %6
906fd4e5da5Sopenharmony_ci          %6 = OpLabel
907fd4e5da5Sopenharmony_ci               OpSelectionMerge %8 None
908fd4e5da5Sopenharmony_ci               OpBranchConditional %14 %7 %8
909fd4e5da5Sopenharmony_ci          %7 = OpLabel
910fd4e5da5Sopenharmony_ci               OpSelectionMerge %13 None
911fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %12 %13
912fd4e5da5Sopenharmony_ci         %12 = OpLabel
913fd4e5da5Sopenharmony_ci               OpBranch %13
914fd4e5da5Sopenharmony_ci         %13 = OpLabel
915fd4e5da5Sopenharmony_ci               OpBranch %8
916fd4e5da5Sopenharmony_ci          %9 = OpLabel
917fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %6 %8
918fd4e5da5Sopenharmony_ci          %8 = OpLabel
919fd4e5da5Sopenharmony_ci               OpReturn
920fd4e5da5Sopenharmony_ci               OpFunctionEnd
921fd4e5da5Sopenharmony_ci  )";
922fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
923fd4e5da5Sopenharmony_ci}
924fd4e5da5Sopenharmony_ci
925fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak2) {
926fd4e5da5Sopenharmony_ci  std::string shader = R"(
927fd4e5da5Sopenharmony_ci               OpCapability Shader
928fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
929fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
930fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
931fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
932fd4e5da5Sopenharmony_ci               OpSource ESSL 310
933fd4e5da5Sopenharmony_ci               OpName %4 "main"
934fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
935fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
936fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
937fd4e5da5Sopenharmony_ci         %11 = OpConstantFalse %10
938fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
939fd4e5da5Sopenharmony_ci          %5 = OpLabel
940fd4e5da5Sopenharmony_ci               OpBranch %6
941fd4e5da5Sopenharmony_ci          %6 = OpLabel
942fd4e5da5Sopenharmony_ci               OpLoopMerge %8 %9 None
943fd4e5da5Sopenharmony_ci               OpBranch %7
944fd4e5da5Sopenharmony_ci          %7 = OpLabel
945fd4e5da5Sopenharmony_ci               OpSelectionMerge %13 None
946fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %8 %13
947fd4e5da5Sopenharmony_ci         %13 = OpLabel
948fd4e5da5Sopenharmony_ci               OpBranch %9
949fd4e5da5Sopenharmony_ci          %9 = OpLabel
950fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %6 %8
951fd4e5da5Sopenharmony_ci          %8 = OpLabel
952fd4e5da5Sopenharmony_ci               OpReturn
953fd4e5da5Sopenharmony_ci               OpFunctionEnd
954fd4e5da5Sopenharmony_ci  )";
955fd4e5da5Sopenharmony_ci
956fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
957fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
958fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
959fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
960fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
961fd4e5da5Sopenharmony_ci
962fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
963fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
964fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
965fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
966fd4e5da5Sopenharmony_ci               OpCapability Shader
967fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
968fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
969fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
970fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
971fd4e5da5Sopenharmony_ci               OpSource ESSL 310
972fd4e5da5Sopenharmony_ci               OpName %4 "main"
973fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
974fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
975fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
976fd4e5da5Sopenharmony_ci         %11 = OpConstantFalse %10
977fd4e5da5Sopenharmony_ci         %14 = OpConstantTrue %10
978fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
979fd4e5da5Sopenharmony_ci          %5 = OpLabel
980fd4e5da5Sopenharmony_ci               OpBranch %6
981fd4e5da5Sopenharmony_ci          %6 = OpLabel
982fd4e5da5Sopenharmony_ci               OpSelectionMerge %8 None
983fd4e5da5Sopenharmony_ci               OpBranchConditional %14 %7 %8
984fd4e5da5Sopenharmony_ci          %7 = OpLabel
985fd4e5da5Sopenharmony_ci               OpSelectionMerge %13 None
986fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %13 %13
987fd4e5da5Sopenharmony_ci         %13 = OpLabel
988fd4e5da5Sopenharmony_ci               OpBranch %8
989fd4e5da5Sopenharmony_ci          %9 = OpLabel
990fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %6 %8
991fd4e5da5Sopenharmony_ci          %8 = OpLabel
992fd4e5da5Sopenharmony_ci               OpReturn
993fd4e5da5Sopenharmony_ci               OpFunctionEnd
994fd4e5da5Sopenharmony_ci  )";
995fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
996fd4e5da5Sopenharmony_ci}
997fd4e5da5Sopenharmony_ci
998fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, UnconditionalBreak) {
999fd4e5da5Sopenharmony_ci  std::string shader = R"(
1000fd4e5da5Sopenharmony_ci               OpCapability Shader
1001fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1002fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1003fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
1004fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
1005fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1006fd4e5da5Sopenharmony_ci               OpName %4 "main"
1007fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
1008fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
1009fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
1010fd4e5da5Sopenharmony_ci          %5 = OpLabel
1011fd4e5da5Sopenharmony_ci               OpBranch %6
1012fd4e5da5Sopenharmony_ci          %6 = OpLabel
1013fd4e5da5Sopenharmony_ci               OpLoopMerge %8 %9 None
1014fd4e5da5Sopenharmony_ci               OpBranch %7
1015fd4e5da5Sopenharmony_ci          %7 = OpLabel
1016fd4e5da5Sopenharmony_ci               OpBranch %8
1017fd4e5da5Sopenharmony_ci          %9 = OpLabel
1018fd4e5da5Sopenharmony_ci               OpBranch %6
1019fd4e5da5Sopenharmony_ci          %8 = OpLabel
1020fd4e5da5Sopenharmony_ci               OpReturn
1021fd4e5da5Sopenharmony_ci               OpFunctionEnd
1022fd4e5da5Sopenharmony_ci  )";
1023fd4e5da5Sopenharmony_ci
1024fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
1025fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
1026fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
1027fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
1028fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
1029fd4e5da5Sopenharmony_ci
1030fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
1031fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
1032fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
1033fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
1034fd4e5da5Sopenharmony_ci               OpCapability Shader
1035fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1036fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1037fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
1038fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
1039fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1040fd4e5da5Sopenharmony_ci               OpName %4 "main"
1041fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
1042fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
1043fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
1044fd4e5da5Sopenharmony_ci         %11 = OpConstantTrue %10
1045fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
1046fd4e5da5Sopenharmony_ci          %5 = OpLabel
1047fd4e5da5Sopenharmony_ci               OpBranch %6
1048fd4e5da5Sopenharmony_ci          %6 = OpLabel
1049fd4e5da5Sopenharmony_ci               OpSelectionMerge %8 None
1050fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %7 %8
1051fd4e5da5Sopenharmony_ci          %7 = OpLabel
1052fd4e5da5Sopenharmony_ci               OpBranch %8
1053fd4e5da5Sopenharmony_ci          %9 = OpLabel
1054fd4e5da5Sopenharmony_ci               OpBranch %6
1055fd4e5da5Sopenharmony_ci          %8 = OpLabel
1056fd4e5da5Sopenharmony_ci               OpReturn
1057fd4e5da5Sopenharmony_ci               OpFunctionEnd
1058fd4e5da5Sopenharmony_ci  )";
1059fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
1060fd4e5da5Sopenharmony_ci}
1061fd4e5da5Sopenharmony_ci
1062fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, Complex) {
1063fd4e5da5Sopenharmony_ci  std::string shader = R"(
1064fd4e5da5Sopenharmony_ci               OpCapability Shader
1065fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1066fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1067fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1068fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1069fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1070fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1071fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1072fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1073fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1074fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1075fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1076fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1077fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1078fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1079fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1080fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1081fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
1082fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1083fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1084fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1085fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1086fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1087fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1088fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1089fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1090fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1091fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1092fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1093fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %10
1094fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1095fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1096fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1097fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1098fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1099fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1100fd4e5da5Sopenharmony_ci         %24 = OpLabel
1101fd4e5da5Sopenharmony_ci         %25 = OpVariable %9 Function
1102fd4e5da5Sopenharmony_ci         %26 = OpVariable %9 Function
1103fd4e5da5Sopenharmony_ci         %27 = OpVariable %9 Function
1104fd4e5da5Sopenharmony_ci         %28 = OpVariable %9 Function
1105fd4e5da5Sopenharmony_ci         %29 = OpVariable %9 Function
1106fd4e5da5Sopenharmony_ci         %30 = OpVariable %19 Function
1107fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1108fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1109fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1110fd4e5da5Sopenharmony_ci               OpStore %25 %33
1111fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1112fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1113fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1114fd4e5da5Sopenharmony_ci               OpStore %26 %36
1115fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1116fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1117fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1118fd4e5da5Sopenharmony_ci               OpStore %27 %39
1119fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1120fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1121fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1122fd4e5da5Sopenharmony_ci               OpStore %28 %42
1123fd4e5da5Sopenharmony_ci         %43 = OpLoad %8 %25
1124fd4e5da5Sopenharmony_ci               OpStore %29 %43
1125fd4e5da5Sopenharmony_ci               OpStore %30 %12
1126fd4e5da5Sopenharmony_ci               OpBranch %44
1127fd4e5da5Sopenharmony_ci         %44 = OpLabel
1128fd4e5da5Sopenharmony_ci               OpLoopMerge %45 %46 None
1129fd4e5da5Sopenharmony_ci               OpBranch %47
1130fd4e5da5Sopenharmony_ci         %47 = OpLabel
1131fd4e5da5Sopenharmony_ci         %48 = OpLoad %8 %29
1132fd4e5da5Sopenharmony_ci               OpBranchConditional %48 %49 %45
1133fd4e5da5Sopenharmony_ci         %49 = OpLabel
1134fd4e5da5Sopenharmony_ci         %50 = OpLoad %8 %25
1135fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1136fd4e5da5Sopenharmony_ci               OpBranchConditional %50 %52 %51
1137fd4e5da5Sopenharmony_ci         %52 = OpLabel
1138fd4e5da5Sopenharmony_ci         %53 = OpLoad %8 %26
1139fd4e5da5Sopenharmony_ci               OpStore %29 %53
1140fd4e5da5Sopenharmony_ci         %54 = OpLoad %10 %30
1141fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %54 %16
1142fd4e5da5Sopenharmony_ci               OpStore %30 %55
1143fd4e5da5Sopenharmony_ci               OpBranch %51
1144fd4e5da5Sopenharmony_ci         %51 = OpLabel
1145fd4e5da5Sopenharmony_ci         %56 = OpLoad %8 %26
1146fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1147fd4e5da5Sopenharmony_ci               OpBranchConditional %56 %58 %57
1148fd4e5da5Sopenharmony_ci         %58 = OpLabel
1149fd4e5da5Sopenharmony_ci         %59 = OpLoad %10 %30
1150fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %59 %16
1151fd4e5da5Sopenharmony_ci               OpStore %30 %60
1152fd4e5da5Sopenharmony_ci         %61 = OpLoad %8 %29
1153fd4e5da5Sopenharmony_ci         %62 = OpLoad %8 %25
1154fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %61 %62
1155fd4e5da5Sopenharmony_ci               OpStore %29 %63
1156fd4e5da5Sopenharmony_ci         %64 = OpLoad %8 %27
1157fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1158fd4e5da5Sopenharmony_ci               OpBranchConditional %64 %66 %65
1159fd4e5da5Sopenharmony_ci         %66 = OpLabel
1160fd4e5da5Sopenharmony_ci         %67 = OpLoad %10 %30
1161fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %67 %17
1162fd4e5da5Sopenharmony_ci               OpStore %30 %68
1163fd4e5da5Sopenharmony_ci         %69 = OpLoad %8 %29
1164fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %69
1165fd4e5da5Sopenharmony_ci               OpStore %29 %70
1166fd4e5da5Sopenharmony_ci               OpBranch %46
1167fd4e5da5Sopenharmony_ci         %65 = OpLabel
1168fd4e5da5Sopenharmony_ci         %71 = OpLoad %8 %29
1169fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %71 %20
1170fd4e5da5Sopenharmony_ci               OpStore %29 %72
1171fd4e5da5Sopenharmony_ci               OpBranch %46
1172fd4e5da5Sopenharmony_ci         %57 = OpLabel
1173fd4e5da5Sopenharmony_ci               OpBranch %73
1174fd4e5da5Sopenharmony_ci         %73 = OpLabel
1175fd4e5da5Sopenharmony_ci               OpLoopMerge %74 %75 None
1176fd4e5da5Sopenharmony_ci               OpBranch %76
1177fd4e5da5Sopenharmony_ci         %76 = OpLabel
1178fd4e5da5Sopenharmony_ci         %77 = OpLoad %8 %28
1179fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1180fd4e5da5Sopenharmony_ci               OpBranchConditional %77 %79 %80
1181fd4e5da5Sopenharmony_ci         %79 = OpLabel
1182fd4e5da5Sopenharmony_ci         %81 = OpLoad %10 %30
1183fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1184fd4e5da5Sopenharmony_ci               OpSwitch %81 %83 1 %84 2 %85
1185fd4e5da5Sopenharmony_ci         %83 = OpLabel
1186fd4e5da5Sopenharmony_ci               OpBranch %82
1187fd4e5da5Sopenharmony_ci         %84 = OpLabel
1188fd4e5da5Sopenharmony_ci         %86 = OpLoad %8 %29
1189fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %86 %16 %17
1190fd4e5da5Sopenharmony_ci         %88 = OpLoad %10 %30
1191fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %88 %87
1192fd4e5da5Sopenharmony_ci               OpStore %30 %89
1193fd4e5da5Sopenharmony_ci               OpBranch %82
1194fd4e5da5Sopenharmony_ci         %85 = OpLabel
1195fd4e5da5Sopenharmony_ci               OpBranch %75
1196fd4e5da5Sopenharmony_ci         %82 = OpLabel
1197fd4e5da5Sopenharmony_ci         %90 = OpLoad %8 %27
1198fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1199fd4e5da5Sopenharmony_ci               OpBranchConditional %90 %92 %91
1200fd4e5da5Sopenharmony_ci         %92 = OpLabel
1201fd4e5da5Sopenharmony_ci               OpBranch %75
1202fd4e5da5Sopenharmony_ci         %91 = OpLabel
1203fd4e5da5Sopenharmony_ci               OpBranch %78
1204fd4e5da5Sopenharmony_ci         %80 = OpLabel
1205fd4e5da5Sopenharmony_ci               OpBranch %74
1206fd4e5da5Sopenharmony_ci         %78 = OpLabel
1207fd4e5da5Sopenharmony_ci               OpBranch %75
1208fd4e5da5Sopenharmony_ci         %75 = OpLabel
1209fd4e5da5Sopenharmony_ci         %93 = OpLoad %8 %29
1210fd4e5da5Sopenharmony_ci               OpBranchConditional %93 %73 %74
1211fd4e5da5Sopenharmony_ci         %74 = OpLabel
1212fd4e5da5Sopenharmony_ci               OpBranch %46
1213fd4e5da5Sopenharmony_ci         %46 = OpLabel
1214fd4e5da5Sopenharmony_ci               OpBranch %44
1215fd4e5da5Sopenharmony_ci         %45 = OpLabel
1216fd4e5da5Sopenharmony_ci         %94 = OpLoad %10 %30
1217fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %94
1218fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1219fd4e5da5Sopenharmony_ci               OpStore %3 %96
1220fd4e5da5Sopenharmony_ci               OpReturn
1221fd4e5da5Sopenharmony_ci               OpFunctionEnd
1222fd4e5da5Sopenharmony_ci  )";
1223fd4e5da5Sopenharmony_ci
1224fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
1225fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
1226fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
1227fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
1228fd4e5da5Sopenharmony_ci
1229fd4e5da5Sopenharmony_ci  ASSERT_EQ(2, ops.size());
1230fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
1231fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
1232fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
1233fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
1234fd4e5da5Sopenharmony_ci               OpCapability Shader
1235fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1236fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1237fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1238fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1239fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1240fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1241fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1242fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1243fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1244fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1245fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1246fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1247fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1248fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1249fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1250fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1251fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
1252fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1253fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1254fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1255fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1256fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1257fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1258fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1259fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1260fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1261fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1262fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1263fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %10
1264fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1265fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1266fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1267fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1268fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1269fd4e5da5Sopenharmony_ci         %97 = OpConstantTrue %8
1270fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1271fd4e5da5Sopenharmony_ci         %24 = OpLabel
1272fd4e5da5Sopenharmony_ci         %25 = OpVariable %9 Function
1273fd4e5da5Sopenharmony_ci         %26 = OpVariable %9 Function
1274fd4e5da5Sopenharmony_ci         %27 = OpVariable %9 Function
1275fd4e5da5Sopenharmony_ci         %28 = OpVariable %9 Function
1276fd4e5da5Sopenharmony_ci         %29 = OpVariable %9 Function
1277fd4e5da5Sopenharmony_ci         %30 = OpVariable %19 Function
1278fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1279fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1280fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1281fd4e5da5Sopenharmony_ci               OpStore %25 %33
1282fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1283fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1284fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1285fd4e5da5Sopenharmony_ci               OpStore %26 %36
1286fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1287fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1288fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1289fd4e5da5Sopenharmony_ci               OpStore %27 %39
1290fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1291fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1292fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1293fd4e5da5Sopenharmony_ci               OpStore %28 %42
1294fd4e5da5Sopenharmony_ci         %43 = OpLoad %8 %25
1295fd4e5da5Sopenharmony_ci               OpStore %29 %43
1296fd4e5da5Sopenharmony_ci               OpStore %30 %12
1297fd4e5da5Sopenharmony_ci               OpBranch %44
1298fd4e5da5Sopenharmony_ci         %44 = OpLabel
1299fd4e5da5Sopenharmony_ci               OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None
1300fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %47 %45		 ; Was OpBranch %47
1301fd4e5da5Sopenharmony_ci         %47 = OpLabel
1302fd4e5da5Sopenharmony_ci         %48 = OpLoad %8 %29
1303fd4e5da5Sopenharmony_ci               OpBranchConditional %48 %49 %45
1304fd4e5da5Sopenharmony_ci         %49 = OpLabel
1305fd4e5da5Sopenharmony_ci         %50 = OpLoad %8 %25
1306fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1307fd4e5da5Sopenharmony_ci               OpBranchConditional %50 %52 %51
1308fd4e5da5Sopenharmony_ci         %52 = OpLabel
1309fd4e5da5Sopenharmony_ci         %53 = OpLoad %8 %26
1310fd4e5da5Sopenharmony_ci               OpStore %29 %53
1311fd4e5da5Sopenharmony_ci         %54 = OpLoad %10 %30
1312fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %54 %16
1313fd4e5da5Sopenharmony_ci               OpStore %30 %55
1314fd4e5da5Sopenharmony_ci               OpBranch %51
1315fd4e5da5Sopenharmony_ci         %51 = OpLabel
1316fd4e5da5Sopenharmony_ci         %56 = OpLoad %8 %26
1317fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1318fd4e5da5Sopenharmony_ci               OpBranchConditional %56 %58 %57
1319fd4e5da5Sopenharmony_ci         %58 = OpLabel
1320fd4e5da5Sopenharmony_ci         %59 = OpLoad %10 %30
1321fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %59 %16
1322fd4e5da5Sopenharmony_ci               OpStore %30 %60
1323fd4e5da5Sopenharmony_ci         %61 = OpLoad %8 %29
1324fd4e5da5Sopenharmony_ci         %62 = OpLoad %8 %25
1325fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %61 %62
1326fd4e5da5Sopenharmony_ci               OpStore %29 %63
1327fd4e5da5Sopenharmony_ci         %64 = OpLoad %8 %27
1328fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1329fd4e5da5Sopenharmony_ci               OpBranchConditional %64 %66 %65
1330fd4e5da5Sopenharmony_ci         %66 = OpLabel
1331fd4e5da5Sopenharmony_ci         %67 = OpLoad %10 %30
1332fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %67 %17
1333fd4e5da5Sopenharmony_ci               OpStore %30 %68
1334fd4e5da5Sopenharmony_ci         %69 = OpLoad %8 %29
1335fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %69
1336fd4e5da5Sopenharmony_ci               OpStore %29 %70
1337fd4e5da5Sopenharmony_ci               OpBranch %65 	; Was OpBranch %46
1338fd4e5da5Sopenharmony_ci         %65 = OpLabel
1339fd4e5da5Sopenharmony_ci         %71 = OpLoad %8 %29
1340fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %71 %20
1341fd4e5da5Sopenharmony_ci               OpStore %29 %72
1342fd4e5da5Sopenharmony_ci               OpBranch %57 	; Was OpBranch %46
1343fd4e5da5Sopenharmony_ci         %57 = OpLabel
1344fd4e5da5Sopenharmony_ci               OpBranch %73
1345fd4e5da5Sopenharmony_ci         %73 = OpLabel
1346fd4e5da5Sopenharmony_ci               OpLoopMerge %74 %75 None
1347fd4e5da5Sopenharmony_ci               OpBranch %76
1348fd4e5da5Sopenharmony_ci         %76 = OpLabel
1349fd4e5da5Sopenharmony_ci         %77 = OpLoad %8 %28
1350fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1351fd4e5da5Sopenharmony_ci               OpBranchConditional %77 %79 %80
1352fd4e5da5Sopenharmony_ci         %79 = OpLabel
1353fd4e5da5Sopenharmony_ci         %81 = OpLoad %10 %30
1354fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1355fd4e5da5Sopenharmony_ci               OpSwitch %81 %83 1 %84 2 %85
1356fd4e5da5Sopenharmony_ci         %83 = OpLabel
1357fd4e5da5Sopenharmony_ci               OpBranch %82
1358fd4e5da5Sopenharmony_ci         %84 = OpLabel
1359fd4e5da5Sopenharmony_ci         %86 = OpLoad %8 %29
1360fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %86 %16 %17
1361fd4e5da5Sopenharmony_ci         %88 = OpLoad %10 %30
1362fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %88 %87
1363fd4e5da5Sopenharmony_ci               OpStore %30 %89
1364fd4e5da5Sopenharmony_ci               OpBranch %82
1365fd4e5da5Sopenharmony_ci         %85 = OpLabel
1366fd4e5da5Sopenharmony_ci               OpBranch %75
1367fd4e5da5Sopenharmony_ci         %82 = OpLabel
1368fd4e5da5Sopenharmony_ci         %90 = OpLoad %8 %27
1369fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1370fd4e5da5Sopenharmony_ci               OpBranchConditional %90 %92 %91
1371fd4e5da5Sopenharmony_ci         %92 = OpLabel
1372fd4e5da5Sopenharmony_ci               OpBranch %75
1373fd4e5da5Sopenharmony_ci         %91 = OpLabel
1374fd4e5da5Sopenharmony_ci               OpBranch %78
1375fd4e5da5Sopenharmony_ci         %80 = OpLabel
1376fd4e5da5Sopenharmony_ci               OpBranch %74
1377fd4e5da5Sopenharmony_ci         %78 = OpLabel
1378fd4e5da5Sopenharmony_ci               OpBranch %75
1379fd4e5da5Sopenharmony_ci         %75 = OpLabel
1380fd4e5da5Sopenharmony_ci         %93 = OpLoad %8 %29
1381fd4e5da5Sopenharmony_ci               OpBranchConditional %93 %73 %74
1382fd4e5da5Sopenharmony_ci         %74 = OpLabel
1383fd4e5da5Sopenharmony_ci               OpBranch %45 	; Was OpBranch %46
1384fd4e5da5Sopenharmony_ci         %46 = OpLabel
1385fd4e5da5Sopenharmony_ci               OpBranch %44
1386fd4e5da5Sopenharmony_ci         %45 = OpLabel
1387fd4e5da5Sopenharmony_ci         %94 = OpLoad %10 %30
1388fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %94
1389fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1390fd4e5da5Sopenharmony_ci               OpStore %3 %96
1391fd4e5da5Sopenharmony_ci               OpReturn
1392fd4e5da5Sopenharmony_ci               OpFunctionEnd
1393fd4e5da5Sopenharmony_ci  )";
1394fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
1395fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
1396fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
1397fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
1398fd4e5da5Sopenharmony_ci
1399fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
1400fd4e5da5Sopenharmony_ci               OpCapability Shader
1401fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1402fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1403fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1404fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1405fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1406fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1407fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1408fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1409fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1410fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1411fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1412fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1413fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1414fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1415fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1416fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1417fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
1418fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1419fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1420fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1421fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1422fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1423fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1424fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1425fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1426fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1427fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1428fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1429fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %10
1430fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1431fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1432fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1433fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1434fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1435fd4e5da5Sopenharmony_ci         %97 = OpConstantTrue %8
1436fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1437fd4e5da5Sopenharmony_ci         %24 = OpLabel
1438fd4e5da5Sopenharmony_ci         %25 = OpVariable %9 Function
1439fd4e5da5Sopenharmony_ci         %26 = OpVariable %9 Function
1440fd4e5da5Sopenharmony_ci         %27 = OpVariable %9 Function
1441fd4e5da5Sopenharmony_ci         %28 = OpVariable %9 Function
1442fd4e5da5Sopenharmony_ci         %29 = OpVariable %9 Function
1443fd4e5da5Sopenharmony_ci         %30 = OpVariable %19 Function
1444fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1445fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1446fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1447fd4e5da5Sopenharmony_ci               OpStore %25 %33
1448fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1449fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1450fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1451fd4e5da5Sopenharmony_ci               OpStore %26 %36
1452fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1453fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1454fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1455fd4e5da5Sopenharmony_ci               OpStore %27 %39
1456fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1457fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1458fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1459fd4e5da5Sopenharmony_ci               OpStore %28 %42
1460fd4e5da5Sopenharmony_ci         %43 = OpLoad %8 %25
1461fd4e5da5Sopenharmony_ci               OpStore %29 %43
1462fd4e5da5Sopenharmony_ci               OpStore %30 %12
1463fd4e5da5Sopenharmony_ci               OpBranch %44
1464fd4e5da5Sopenharmony_ci         %44 = OpLabel
1465fd4e5da5Sopenharmony_ci               OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None
1466fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %47 %45		 ; Was OpBranch %47
1467fd4e5da5Sopenharmony_ci         %47 = OpLabel
1468fd4e5da5Sopenharmony_ci         %48 = OpLoad %8 %29
1469fd4e5da5Sopenharmony_ci               OpBranchConditional %48 %49 %45
1470fd4e5da5Sopenharmony_ci         %49 = OpLabel
1471fd4e5da5Sopenharmony_ci         %50 = OpLoad %8 %25
1472fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1473fd4e5da5Sopenharmony_ci               OpBranchConditional %50 %52 %51
1474fd4e5da5Sopenharmony_ci         %52 = OpLabel
1475fd4e5da5Sopenharmony_ci         %53 = OpLoad %8 %26
1476fd4e5da5Sopenharmony_ci               OpStore %29 %53
1477fd4e5da5Sopenharmony_ci         %54 = OpLoad %10 %30
1478fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %54 %16
1479fd4e5da5Sopenharmony_ci               OpStore %30 %55
1480fd4e5da5Sopenharmony_ci               OpBranch %51
1481fd4e5da5Sopenharmony_ci         %51 = OpLabel
1482fd4e5da5Sopenharmony_ci         %56 = OpLoad %8 %26
1483fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1484fd4e5da5Sopenharmony_ci               OpBranchConditional %56 %58 %57
1485fd4e5da5Sopenharmony_ci         %58 = OpLabel
1486fd4e5da5Sopenharmony_ci         %59 = OpLoad %10 %30
1487fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %59 %16
1488fd4e5da5Sopenharmony_ci               OpStore %30 %60
1489fd4e5da5Sopenharmony_ci         %61 = OpLoad %8 %29
1490fd4e5da5Sopenharmony_ci         %62 = OpLoad %8 %25
1491fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %61 %62
1492fd4e5da5Sopenharmony_ci               OpStore %29 %63
1493fd4e5da5Sopenharmony_ci         %64 = OpLoad %8 %27
1494fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1495fd4e5da5Sopenharmony_ci               OpBranchConditional %64 %66 %65
1496fd4e5da5Sopenharmony_ci         %66 = OpLabel
1497fd4e5da5Sopenharmony_ci         %67 = OpLoad %10 %30
1498fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %67 %17
1499fd4e5da5Sopenharmony_ci               OpStore %30 %68
1500fd4e5da5Sopenharmony_ci         %69 = OpLoad %8 %29
1501fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %69
1502fd4e5da5Sopenharmony_ci               OpStore %29 %70
1503fd4e5da5Sopenharmony_ci               OpBranch %65 	; Was OpBranch %46
1504fd4e5da5Sopenharmony_ci         %65 = OpLabel
1505fd4e5da5Sopenharmony_ci         %71 = OpLoad %8 %29
1506fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %71 %20
1507fd4e5da5Sopenharmony_ci               OpStore %29 %72
1508fd4e5da5Sopenharmony_ci               OpBranch %57 	; Was OpBranch %46
1509fd4e5da5Sopenharmony_ci         %57 = OpLabel
1510fd4e5da5Sopenharmony_ci               OpBranch %73
1511fd4e5da5Sopenharmony_ci         %73 = OpLabel
1512fd4e5da5Sopenharmony_ci               OpSelectionMerge %74 None ; Was OpLoopMerge %74 %75 None
1513fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %76 %74 ; Was OpBranch %76
1514fd4e5da5Sopenharmony_ci         %76 = OpLabel
1515fd4e5da5Sopenharmony_ci         %77 = OpLoad %8 %28
1516fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1517fd4e5da5Sopenharmony_ci               OpBranchConditional %77 %79 %80
1518fd4e5da5Sopenharmony_ci         %79 = OpLabel
1519fd4e5da5Sopenharmony_ci         %81 = OpLoad %10 %30
1520fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1521fd4e5da5Sopenharmony_ci               OpSwitch %81 %83 1 %84 2 %85
1522fd4e5da5Sopenharmony_ci         %83 = OpLabel
1523fd4e5da5Sopenharmony_ci               OpBranch %82
1524fd4e5da5Sopenharmony_ci         %84 = OpLabel
1525fd4e5da5Sopenharmony_ci         %86 = OpLoad %8 %29
1526fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %86 %16 %17
1527fd4e5da5Sopenharmony_ci         %88 = OpLoad %10 %30
1528fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %88 %87
1529fd4e5da5Sopenharmony_ci               OpStore %30 %89
1530fd4e5da5Sopenharmony_ci               OpBranch %82
1531fd4e5da5Sopenharmony_ci         %85 = OpLabel
1532fd4e5da5Sopenharmony_ci               OpBranch %82
1533fd4e5da5Sopenharmony_ci         %82 = OpLabel
1534fd4e5da5Sopenharmony_ci         %90 = OpLoad %8 %27
1535fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1536fd4e5da5Sopenharmony_ci               OpBranchConditional %90 %92 %91
1537fd4e5da5Sopenharmony_ci         %92 = OpLabel
1538fd4e5da5Sopenharmony_ci               OpBranch %91
1539fd4e5da5Sopenharmony_ci         %91 = OpLabel
1540fd4e5da5Sopenharmony_ci               OpBranch %78
1541fd4e5da5Sopenharmony_ci         %80 = OpLabel
1542fd4e5da5Sopenharmony_ci               OpBranch %78 ; Was OpBranch %74
1543fd4e5da5Sopenharmony_ci         %78 = OpLabel
1544fd4e5da5Sopenharmony_ci               OpBranch %74
1545fd4e5da5Sopenharmony_ci         %75 = OpLabel
1546fd4e5da5Sopenharmony_ci         %93 = OpLoad %8 %29
1547fd4e5da5Sopenharmony_ci               OpBranchConditional %93 %73 %74
1548fd4e5da5Sopenharmony_ci         %74 = OpLabel
1549fd4e5da5Sopenharmony_ci               OpBranch %45 	; Was OpBranch %46
1550fd4e5da5Sopenharmony_ci         %46 = OpLabel
1551fd4e5da5Sopenharmony_ci               OpBranch %44
1552fd4e5da5Sopenharmony_ci         %45 = OpLabel
1553fd4e5da5Sopenharmony_ci         %94 = OpLoad %10 %30
1554fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %94
1555fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1556fd4e5da5Sopenharmony_ci               OpStore %3 %96
1557fd4e5da5Sopenharmony_ci               OpReturn
1558fd4e5da5Sopenharmony_ci               OpFunctionEnd
1559fd4e5da5Sopenharmony_ci  )";
1560fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
1561fd4e5da5Sopenharmony_ci}
1562fd4e5da5Sopenharmony_ci
1563fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ComplexOptimized) {
1564fd4e5da5Sopenharmony_ci  std::string shader = R"(
1565fd4e5da5Sopenharmony_ci               OpCapability Shader
1566fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1567fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1568fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1569fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1570fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1571fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1572fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1573fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1574fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1575fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1576fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1577fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1578fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1579fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1580fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1581fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1582fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1583fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1584fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1585fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1586fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1587fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1588fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1589fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1590fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1591fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1592fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1593fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1594fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1595fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1596fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1597fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1598fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1599fd4e5da5Sopenharmony_ci         %24 = OpLabel
1600fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1601fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1602fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1603fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1604fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1605fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1606fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1607fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1608fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1609fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1610fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1611fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1612fd4e5da5Sopenharmony_ci               OpBranch %44
1613fd4e5da5Sopenharmony_ci         %44 = OpLabel
1614fd4e5da5Sopenharmony_ci         %98 = OpPhi %10 %12 %24 %107 %46
1615fd4e5da5Sopenharmony_ci         %97 = OpPhi %8 %33 %24 %105 %46
1616fd4e5da5Sopenharmony_ci               OpLoopMerge %45 %46 None
1617fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %49 %45
1618fd4e5da5Sopenharmony_ci         %49 = OpLabel
1619fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1620fd4e5da5Sopenharmony_ci               OpBranchConditional %33 %52 %51
1621fd4e5da5Sopenharmony_ci         %52 = OpLabel
1622fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %98 %16
1623fd4e5da5Sopenharmony_ci               OpBranch %51
1624fd4e5da5Sopenharmony_ci         %51 = OpLabel
1625fd4e5da5Sopenharmony_ci        %100 = OpPhi %10 %98 %49 %55 %52
1626fd4e5da5Sopenharmony_ci        %113 = OpSelect %8 %33 %36 %97
1627fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1628fd4e5da5Sopenharmony_ci               OpBranchConditional %36 %58 %57
1629fd4e5da5Sopenharmony_ci         %58 = OpLabel
1630fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %100 %16
1631fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %113 %33
1632fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1633fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %66 %65
1634fd4e5da5Sopenharmony_ci         %66 = OpLabel
1635fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %100 %18
1636fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %63
1637fd4e5da5Sopenharmony_ci               OpBranch %46
1638fd4e5da5Sopenharmony_ci         %65 = OpLabel
1639fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %63 %20
1640fd4e5da5Sopenharmony_ci               OpBranch %46
1641fd4e5da5Sopenharmony_ci         %57 = OpLabel
1642fd4e5da5Sopenharmony_ci               OpBranch %73
1643fd4e5da5Sopenharmony_ci         %73 = OpLabel
1644fd4e5da5Sopenharmony_ci         %99 = OpPhi %10 %100 %57 %109 %75
1645fd4e5da5Sopenharmony_ci               OpLoopMerge %74 %75 None
1646fd4e5da5Sopenharmony_ci               OpBranch %76
1647fd4e5da5Sopenharmony_ci         %76 = OpLabel
1648fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1649fd4e5da5Sopenharmony_ci               OpBranchConditional %42 %79 %80
1650fd4e5da5Sopenharmony_ci         %79 = OpLabel
1651fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1652fd4e5da5Sopenharmony_ci               OpSwitch %99 %83 1 %84 2 %85
1653fd4e5da5Sopenharmony_ci         %83 = OpLabel
1654fd4e5da5Sopenharmony_ci               OpBranch %82
1655fd4e5da5Sopenharmony_ci         %84 = OpLabel
1656fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %113 %16 %17
1657fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %99 %87
1658fd4e5da5Sopenharmony_ci               OpBranch %82
1659fd4e5da5Sopenharmony_ci         %85 = OpLabel
1660fd4e5da5Sopenharmony_ci               OpBranch %75
1661fd4e5da5Sopenharmony_ci         %82 = OpLabel
1662fd4e5da5Sopenharmony_ci        %110 = OpPhi %10 %99 %83 %89 %84
1663fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1664fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %92 %91
1665fd4e5da5Sopenharmony_ci         %92 = OpLabel
1666fd4e5da5Sopenharmony_ci               OpBranch %75
1667fd4e5da5Sopenharmony_ci         %91 = OpLabel
1668fd4e5da5Sopenharmony_ci               OpBranch %78
1669fd4e5da5Sopenharmony_ci         %80 = OpLabel
1670fd4e5da5Sopenharmony_ci               OpBranch %74
1671fd4e5da5Sopenharmony_ci         %78 = OpLabel
1672fd4e5da5Sopenharmony_ci               OpBranch %75
1673fd4e5da5Sopenharmony_ci         %75 = OpLabel
1674fd4e5da5Sopenharmony_ci        %109 = OpPhi %10 %99 %85 %110 %92 %110 %78
1675fd4e5da5Sopenharmony_ci               OpBranchConditional %113 %73 %74
1676fd4e5da5Sopenharmony_ci         %74 = OpLabel
1677fd4e5da5Sopenharmony_ci        %108 = OpPhi %10 %99 %80 %109 %75
1678fd4e5da5Sopenharmony_ci               OpBranch %46
1679fd4e5da5Sopenharmony_ci         %46 = OpLabel
1680fd4e5da5Sopenharmony_ci        %107 = OpPhi %10 %68 %66 %60 %65 %108 %74
1681fd4e5da5Sopenharmony_ci        %105 = OpPhi %8 %70 %66 %72 %65 %113 %74
1682fd4e5da5Sopenharmony_ci               OpBranch %44
1683fd4e5da5Sopenharmony_ci         %45 = OpLabel
1684fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %98
1685fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1686fd4e5da5Sopenharmony_ci               OpStore %3 %96
1687fd4e5da5Sopenharmony_ci               OpReturn
1688fd4e5da5Sopenharmony_ci               OpFunctionEnd
1689fd4e5da5Sopenharmony_ci  )";
1690fd4e5da5Sopenharmony_ci
1691fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
1692fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
1693fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
1694fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
1695fd4e5da5Sopenharmony_ci
1696fd4e5da5Sopenharmony_ci  ASSERT_EQ(2, ops.size());
1697fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
1698fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
1699fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
1700fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
1701fd4e5da5Sopenharmony_ci               OpCapability Shader
1702fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1703fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1704fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1705fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1706fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1707fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1708fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1709fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1710fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1711fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1712fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1713fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1714fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1715fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1716fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1717fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1718fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1719fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1720fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1721fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1722fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1723fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1724fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1725fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1726fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1727fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1728fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1729fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1730fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1731fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1732fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1733fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1734fd4e5da5Sopenharmony_ci        %114 = OpUndef %10
1735fd4e5da5Sopenharmony_ci        %115 = OpUndef %8
1736fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1737fd4e5da5Sopenharmony_ci         %24 = OpLabel
1738fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1739fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1740fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1741fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1742fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1743fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1744fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1745fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1746fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1747fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1748fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1749fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1750fd4e5da5Sopenharmony_ci               OpBranch %44
1751fd4e5da5Sopenharmony_ci         %44 = OpLabel
1752fd4e5da5Sopenharmony_ci         %98 = OpPhi %10 %12 %24 %114 %46
1753fd4e5da5Sopenharmony_ci         %97 = OpPhi %8 %33 %24 %115 %46
1754fd4e5da5Sopenharmony_ci               OpSelectionMerge %45 None	; Was OpLoopMerge %45 %46 None
1755fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %49 %45
1756fd4e5da5Sopenharmony_ci         %49 = OpLabel
1757fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1758fd4e5da5Sopenharmony_ci               OpBranchConditional %33 %52 %51
1759fd4e5da5Sopenharmony_ci         %52 = OpLabel
1760fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %98 %16
1761fd4e5da5Sopenharmony_ci               OpBranch %51
1762fd4e5da5Sopenharmony_ci         %51 = OpLabel
1763fd4e5da5Sopenharmony_ci        %100 = OpPhi %10 %98 %49 %55 %52
1764fd4e5da5Sopenharmony_ci        %113 = OpSelect %8 %33 %36 %97
1765fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1766fd4e5da5Sopenharmony_ci               OpBranchConditional %36 %58 %57
1767fd4e5da5Sopenharmony_ci         %58 = OpLabel
1768fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %100 %16
1769fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %113 %33
1770fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1771fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %66 %65
1772fd4e5da5Sopenharmony_ci         %66 = OpLabel
1773fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %100 %18
1774fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %63
1775fd4e5da5Sopenharmony_ci               OpBranch %65 	; Was OpBranch %46
1776fd4e5da5Sopenharmony_ci         %65 = OpLabel
1777fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %63 %20
1778fd4e5da5Sopenharmony_ci               OpBranch %57     ; Was OpBranch %46
1779fd4e5da5Sopenharmony_ci         %57 = OpLabel
1780fd4e5da5Sopenharmony_ci               OpBranch %73
1781fd4e5da5Sopenharmony_ci         %73 = OpLabel
1782fd4e5da5Sopenharmony_ci         %99 = OpPhi %10 %100 %57 %109 %75
1783fd4e5da5Sopenharmony_ci               OpLoopMerge %74 %75 None
1784fd4e5da5Sopenharmony_ci               OpBranch %76
1785fd4e5da5Sopenharmony_ci         %76 = OpLabel
1786fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1787fd4e5da5Sopenharmony_ci               OpBranchConditional %42 %79 %80
1788fd4e5da5Sopenharmony_ci         %79 = OpLabel
1789fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1790fd4e5da5Sopenharmony_ci               OpSwitch %99 %83 1 %84 2 %85
1791fd4e5da5Sopenharmony_ci         %83 = OpLabel
1792fd4e5da5Sopenharmony_ci               OpBranch %82
1793fd4e5da5Sopenharmony_ci         %84 = OpLabel
1794fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %113 %16 %17
1795fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %99 %87
1796fd4e5da5Sopenharmony_ci               OpBranch %82
1797fd4e5da5Sopenharmony_ci         %85 = OpLabel
1798fd4e5da5Sopenharmony_ci               OpBranch %75
1799fd4e5da5Sopenharmony_ci         %82 = OpLabel
1800fd4e5da5Sopenharmony_ci        %110 = OpPhi %10 %99 %83 %89 %84
1801fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1802fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %92 %91
1803fd4e5da5Sopenharmony_ci         %92 = OpLabel
1804fd4e5da5Sopenharmony_ci               OpBranch %75
1805fd4e5da5Sopenharmony_ci         %91 = OpLabel
1806fd4e5da5Sopenharmony_ci               OpBranch %78
1807fd4e5da5Sopenharmony_ci         %80 = OpLabel
1808fd4e5da5Sopenharmony_ci               OpBranch %74
1809fd4e5da5Sopenharmony_ci         %78 = OpLabel
1810fd4e5da5Sopenharmony_ci               OpBranch %75
1811fd4e5da5Sopenharmony_ci         %75 = OpLabel
1812fd4e5da5Sopenharmony_ci        %109 = OpPhi %10 %99 %85 %110 %92 %110 %78
1813fd4e5da5Sopenharmony_ci               OpBranchConditional %113 %73 %74
1814fd4e5da5Sopenharmony_ci         %74 = OpLabel
1815fd4e5da5Sopenharmony_ci        %108 = OpPhi %10 %99 %80 %109 %75
1816fd4e5da5Sopenharmony_ci               OpBranch %45 	; Was OpBranch %46
1817fd4e5da5Sopenharmony_ci         %46 = OpLabel
1818fd4e5da5Sopenharmony_ci        %107 = OpPhi %10      ; Was OpPhi %10 %68 %66 %60 %65 %108 %74
1819fd4e5da5Sopenharmony_ci        %105 = OpPhi %8       ; Was OpPhi %8 %70 %66 %72 %65 %113 %74
1820fd4e5da5Sopenharmony_ci               OpBranch %44
1821fd4e5da5Sopenharmony_ci         %45 = OpLabel
1822fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %98
1823fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1824fd4e5da5Sopenharmony_ci               OpStore %3 %96
1825fd4e5da5Sopenharmony_ci               OpReturn
1826fd4e5da5Sopenharmony_ci               OpFunctionEnd
1827fd4e5da5Sopenharmony_ci  )";
1828fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
1829fd4e5da5Sopenharmony_ci
1830fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
1831fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
1832fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
1833fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
1834fd4e5da5Sopenharmony_ci               OpCapability Shader
1835fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1836fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1837fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main" %3
1838fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1839fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1840fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 0 Offset 0
1841fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 1 Offset 4
1842fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 2 Offset 8
1843fd4e5da5Sopenharmony_ci               OpMemberDecorate %4 3 Offset 12
1844fd4e5da5Sopenharmony_ci               OpDecorate %4 Block
1845fd4e5da5Sopenharmony_ci               OpDecorate %5 DescriptorSet 0
1846fd4e5da5Sopenharmony_ci               OpDecorate %5 Binding 0
1847fd4e5da5Sopenharmony_ci               OpDecorate %3 Location 0
1848fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1849fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1850fd4e5da5Sopenharmony_ci          %8 = OpTypeBool
1851fd4e5da5Sopenharmony_ci         %10 = OpTypeInt 32 1
1852fd4e5da5Sopenharmony_ci          %4 = OpTypeStruct %10 %10 %10 %10
1853fd4e5da5Sopenharmony_ci         %11 = OpTypePointer Uniform %4
1854fd4e5da5Sopenharmony_ci          %5 = OpVariable %11 Uniform
1855fd4e5da5Sopenharmony_ci         %12 = OpConstant %10 0
1856fd4e5da5Sopenharmony_ci         %13 = OpTypePointer Uniform %10
1857fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1858fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 0
1859fd4e5da5Sopenharmony_ci         %16 = OpConstant %10 1
1860fd4e5da5Sopenharmony_ci         %17 = OpConstant %10 2
1861fd4e5da5Sopenharmony_ci         %18 = OpConstant %10 3
1862fd4e5da5Sopenharmony_ci         %20 = OpConstantFalse %8
1863fd4e5da5Sopenharmony_ci         %21 = OpTypeFloat 32
1864fd4e5da5Sopenharmony_ci         %22 = OpTypeVector %21 4
1865fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Output %22
1866fd4e5da5Sopenharmony_ci          %3 = OpVariable %23 Output
1867fd4e5da5Sopenharmony_ci        %114 = OpUndef %10
1868fd4e5da5Sopenharmony_ci        %115 = OpUndef %8
1869fd4e5da5Sopenharmony_ci        %116 = OpConstantTrue %8
1870fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1871fd4e5da5Sopenharmony_ci         %24 = OpLabel
1872fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %13 %5 %12
1873fd4e5da5Sopenharmony_ci         %32 = OpLoad %10 %31
1874fd4e5da5Sopenharmony_ci         %33 = OpINotEqual %8 %32 %15
1875fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %13 %5 %16
1876fd4e5da5Sopenharmony_ci         %35 = OpLoad %10 %34
1877fd4e5da5Sopenharmony_ci         %36 = OpINotEqual %8 %35 %15
1878fd4e5da5Sopenharmony_ci         %37 = OpAccessChain %13 %5 %17
1879fd4e5da5Sopenharmony_ci         %38 = OpLoad %10 %37
1880fd4e5da5Sopenharmony_ci         %39 = OpINotEqual %8 %38 %15
1881fd4e5da5Sopenharmony_ci         %40 = OpAccessChain %13 %5 %18
1882fd4e5da5Sopenharmony_ci         %41 = OpLoad %10 %40
1883fd4e5da5Sopenharmony_ci         %42 = OpINotEqual %8 %41 %15
1884fd4e5da5Sopenharmony_ci               OpBranch %44
1885fd4e5da5Sopenharmony_ci         %44 = OpLabel
1886fd4e5da5Sopenharmony_ci         %98 = OpPhi %10 %12 %24 %114 %46
1887fd4e5da5Sopenharmony_ci         %97 = OpPhi %8 %33 %24 %115 %46
1888fd4e5da5Sopenharmony_ci               OpSelectionMerge %45 None	; Was OpLoopMerge %45 %46 None
1889fd4e5da5Sopenharmony_ci               OpBranchConditional %97 %49 %45
1890fd4e5da5Sopenharmony_ci         %49 = OpLabel
1891fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
1892fd4e5da5Sopenharmony_ci               OpBranchConditional %33 %52 %51
1893fd4e5da5Sopenharmony_ci         %52 = OpLabel
1894fd4e5da5Sopenharmony_ci         %55 = OpIAdd %10 %98 %16
1895fd4e5da5Sopenharmony_ci               OpBranch %51
1896fd4e5da5Sopenharmony_ci         %51 = OpLabel
1897fd4e5da5Sopenharmony_ci        %100 = OpPhi %10 %98 %49 %55 %52
1898fd4e5da5Sopenharmony_ci        %113 = OpSelect %8 %33 %36 %97
1899fd4e5da5Sopenharmony_ci               OpSelectionMerge %57 None
1900fd4e5da5Sopenharmony_ci               OpBranchConditional %36 %58 %57
1901fd4e5da5Sopenharmony_ci         %58 = OpLabel
1902fd4e5da5Sopenharmony_ci         %60 = OpIAdd %10 %100 %16
1903fd4e5da5Sopenharmony_ci         %63 = OpLogicalOr %8 %113 %33
1904fd4e5da5Sopenharmony_ci               OpSelectionMerge %65 None
1905fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %66 %65
1906fd4e5da5Sopenharmony_ci         %66 = OpLabel
1907fd4e5da5Sopenharmony_ci         %68 = OpIAdd %10 %100 %18
1908fd4e5da5Sopenharmony_ci         %70 = OpLogicalNot %8 %63
1909fd4e5da5Sopenharmony_ci               OpBranch %65 	; Was OpBranch %46
1910fd4e5da5Sopenharmony_ci         %65 = OpLabel
1911fd4e5da5Sopenharmony_ci         %72 = OpLogicalOr %8 %63 %20
1912fd4e5da5Sopenharmony_ci               OpBranch %57     ; Was OpBranch %46
1913fd4e5da5Sopenharmony_ci         %57 = OpLabel
1914fd4e5da5Sopenharmony_ci               OpBranch %73
1915fd4e5da5Sopenharmony_ci         %73 = OpLabel
1916fd4e5da5Sopenharmony_ci         %99 = OpPhi %10 %100 %57 %114 %75
1917fd4e5da5Sopenharmony_ci               OpSelectionMerge %74 None ; Was OpLoopMerge %74 %75 None
1918fd4e5da5Sopenharmony_ci               OpBranchConditional %116 %76 %74
1919fd4e5da5Sopenharmony_ci         %76 = OpLabel
1920fd4e5da5Sopenharmony_ci               OpSelectionMerge %78 None
1921fd4e5da5Sopenharmony_ci               OpBranchConditional %42 %79 %80
1922fd4e5da5Sopenharmony_ci         %79 = OpLabel
1923fd4e5da5Sopenharmony_ci               OpSelectionMerge %82 None
1924fd4e5da5Sopenharmony_ci               OpSwitch %99 %83 1 %84 2 %85
1925fd4e5da5Sopenharmony_ci         %83 = OpLabel
1926fd4e5da5Sopenharmony_ci               OpBranch %82
1927fd4e5da5Sopenharmony_ci         %84 = OpLabel
1928fd4e5da5Sopenharmony_ci         %87 = OpSelect %10 %113 %16 %17
1929fd4e5da5Sopenharmony_ci         %89 = OpIAdd %10 %99 %87
1930fd4e5da5Sopenharmony_ci               OpBranch %82
1931fd4e5da5Sopenharmony_ci         %85 = OpLabel
1932fd4e5da5Sopenharmony_ci               OpBranch %82 	; Was OpBranch %75
1933fd4e5da5Sopenharmony_ci         %82 = OpLabel
1934fd4e5da5Sopenharmony_ci        %110 = OpPhi %10 %99 %83 %89 %84 %114 %85 ; Was OpPhi %10 %99 %83 %89 %84
1935fd4e5da5Sopenharmony_ci               OpSelectionMerge %91 None
1936fd4e5da5Sopenharmony_ci               OpBranchConditional %39 %92 %91
1937fd4e5da5Sopenharmony_ci         %92 = OpLabel
1938fd4e5da5Sopenharmony_ci               OpBranch %91 	; OpBranch %75
1939fd4e5da5Sopenharmony_ci         %91 = OpLabel
1940fd4e5da5Sopenharmony_ci               OpBranch %78
1941fd4e5da5Sopenharmony_ci         %80 = OpLabel
1942fd4e5da5Sopenharmony_ci               OpBranch %78 	; Was OpBranch %74
1943fd4e5da5Sopenharmony_ci         %78 = OpLabel
1944fd4e5da5Sopenharmony_ci               OpBranch %74     ; Was OpBranch %75
1945fd4e5da5Sopenharmony_ci         %75 = OpLabel
1946fd4e5da5Sopenharmony_ci        %109 = OpPhi %10 ; Was OpPhi %10 %99 %85 %110 %92 %110 %78
1947fd4e5da5Sopenharmony_ci               OpBranchConditional %115 %73 %74
1948fd4e5da5Sopenharmony_ci         %74 = OpLabel
1949fd4e5da5Sopenharmony_ci        %108 = OpPhi %10 %114 %75 %114 %78 %114 %73 ; Was OpPhi %10 %99 %80 %109 %75
1950fd4e5da5Sopenharmony_ci               OpBranch %45 	; Was OpBranch %46
1951fd4e5da5Sopenharmony_ci         %46 = OpLabel
1952fd4e5da5Sopenharmony_ci        %107 = OpPhi %10      ; Was OpPhi %10 %68 %66 %60 %65 %108 %74
1953fd4e5da5Sopenharmony_ci        %105 = OpPhi %8       ; Was OpPhi %8 %70 %66 %72 %65 %113 %74
1954fd4e5da5Sopenharmony_ci               OpBranch %44
1955fd4e5da5Sopenharmony_ci         %45 = OpLabel
1956fd4e5da5Sopenharmony_ci         %95 = OpConvertSToF %21 %98
1957fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %22 %95 %95 %95 %95
1958fd4e5da5Sopenharmony_ci               OpStore %3 %96
1959fd4e5da5Sopenharmony_ci               OpReturn
1960fd4e5da5Sopenharmony_ci               OpFunctionEnd
1961fd4e5da5Sopenharmony_ci  )";
1962fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
1963fd4e5da5Sopenharmony_ci}
1964fd4e5da5Sopenharmony_ci
1965fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, DominanceIssue) {
1966fd4e5da5Sopenharmony_ci  // Exposes a scenario where redirecting edges results in uses of ids being
1967fd4e5da5Sopenharmony_ci  // non-dominated.  We replace such uses with OpUndef to account for this.
1968fd4e5da5Sopenharmony_ci  std::string shader = R"(
1969fd4e5da5Sopenharmony_ci               OpCapability Shader
1970fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1971fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1972fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
1973fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
1974fd4e5da5Sopenharmony_ci               OpSource ESSL 310
1975fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
1976fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
1977fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
1978fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %5
1979fd4e5da5Sopenharmony_ci          %6 = OpTypeBool
1980fd4e5da5Sopenharmony_ci          %8 = OpConstantTrue %6
1981fd4e5da5Sopenharmony_ci          %9 = OpConstant %5 10
1982fd4e5da5Sopenharmony_ci         %10 = OpConstant %5 20
1983fd4e5da5Sopenharmony_ci         %11 = OpConstant %5 30
1984fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
1985fd4e5da5Sopenharmony_ci         %12 = OpLabel
1986fd4e5da5Sopenharmony_ci               OpBranch %13
1987fd4e5da5Sopenharmony_ci         %13 = OpLabel
1988fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %15 None
1989fd4e5da5Sopenharmony_ci               OpBranch %16
1990fd4e5da5Sopenharmony_ci         %16 = OpLabel
1991fd4e5da5Sopenharmony_ci               OpSelectionMerge %17 None
1992fd4e5da5Sopenharmony_ci               OpBranchConditional %8 %18 %19
1993fd4e5da5Sopenharmony_ci         %18 = OpLabel
1994fd4e5da5Sopenharmony_ci               OpBranch %14
1995fd4e5da5Sopenharmony_ci         %19 = OpLabel
1996fd4e5da5Sopenharmony_ci         %20 = OpIAdd %5 %9 %10
1997fd4e5da5Sopenharmony_ci               OpBranch %17
1998fd4e5da5Sopenharmony_ci         %17 = OpLabel
1999fd4e5da5Sopenharmony_ci         %21 = OpIAdd %5 %20 %11
2000fd4e5da5Sopenharmony_ci               OpBranchConditional %8 %14 %15
2001fd4e5da5Sopenharmony_ci         %15 = OpLabel
2002fd4e5da5Sopenharmony_ci               OpBranch %13
2003fd4e5da5Sopenharmony_ci         %14 = OpLabel
2004fd4e5da5Sopenharmony_ci               OpReturn
2005fd4e5da5Sopenharmony_ci               OpFunctionEnd
2006fd4e5da5Sopenharmony_ci  )";
2007fd4e5da5Sopenharmony_ci
2008fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2009fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2010fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2011fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2012fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2013fd4e5da5Sopenharmony_ci
2014fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2015fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2016fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2017fd4e5da5Sopenharmony_ci
2018fd4e5da5Sopenharmony_ci  std::string expected = R"(
2019fd4e5da5Sopenharmony_ci               OpCapability Shader
2020fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2021fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2022fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
2023fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2024fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2025fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2026fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2027fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2028fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %5
2029fd4e5da5Sopenharmony_ci          %6 = OpTypeBool
2030fd4e5da5Sopenharmony_ci          %8 = OpConstantTrue %6
2031fd4e5da5Sopenharmony_ci          %9 = OpConstant %5 10
2032fd4e5da5Sopenharmony_ci         %10 = OpConstant %5 20
2033fd4e5da5Sopenharmony_ci         %11 = OpConstant %5 30
2034fd4e5da5Sopenharmony_ci         %22 = OpUndef %5
2035fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2036fd4e5da5Sopenharmony_ci         %12 = OpLabel
2037fd4e5da5Sopenharmony_ci               OpBranch %13
2038fd4e5da5Sopenharmony_ci         %13 = OpLabel
2039fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2040fd4e5da5Sopenharmony_ci               OpBranchConditional %8 %16 %14
2041fd4e5da5Sopenharmony_ci         %16 = OpLabel
2042fd4e5da5Sopenharmony_ci               OpSelectionMerge %17 None
2043fd4e5da5Sopenharmony_ci               OpBranchConditional %8 %18 %19
2044fd4e5da5Sopenharmony_ci         %18 = OpLabel
2045fd4e5da5Sopenharmony_ci               OpBranch %17
2046fd4e5da5Sopenharmony_ci         %19 = OpLabel
2047fd4e5da5Sopenharmony_ci         %20 = OpIAdd %5 %9 %10
2048fd4e5da5Sopenharmony_ci               OpBranch %17
2049fd4e5da5Sopenharmony_ci         %17 = OpLabel
2050fd4e5da5Sopenharmony_ci         %21 = OpIAdd %5 %22 %11
2051fd4e5da5Sopenharmony_ci               OpBranchConditional %8 %14 %14
2052fd4e5da5Sopenharmony_ci         %15 = OpLabel
2053fd4e5da5Sopenharmony_ci               OpBranch %13
2054fd4e5da5Sopenharmony_ci         %14 = OpLabel
2055fd4e5da5Sopenharmony_ci               OpReturn
2056fd4e5da5Sopenharmony_ci               OpFunctionEnd
2057fd4e5da5Sopenharmony_ci  )";
2058fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2059fd4e5da5Sopenharmony_ci}
2060fd4e5da5Sopenharmony_ci
2061fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, AccessChainIssue) {
2062fd4e5da5Sopenharmony_ci  // Exposes a scenario where redirecting edges results in a use of an id
2063fd4e5da5Sopenharmony_ci  // generated by an access chain being non-dominated.
2064fd4e5da5Sopenharmony_ci  std::string shader = R"(
2065fd4e5da5Sopenharmony_ci               OpCapability Shader
2066fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2067fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2068fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %56
2069fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2070fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2071fd4e5da5Sopenharmony_ci               OpMemberDecorate %28 0 Offset 0
2072fd4e5da5Sopenharmony_ci               OpDecorate %28 Block
2073fd4e5da5Sopenharmony_ci               OpDecorate %30 DescriptorSet 0
2074fd4e5da5Sopenharmony_ci               OpDecorate %30 Binding 0
2075fd4e5da5Sopenharmony_ci               OpDecorate %56 Location 0
2076fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2077fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2078fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
2079fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 2
2080fd4e5da5Sopenharmony_ci          %8 = OpTypePointer Function %7
2081fd4e5da5Sopenharmony_ci         %60 = OpTypePointer Private %7
2082fd4e5da5Sopenharmony_ci         %10 = OpConstant %6 0
2083fd4e5da5Sopenharmony_ci         %11 = OpConstantComposite %7 %10 %10
2084fd4e5da5Sopenharmony_ci         %12 = OpTypePointer Function %6
2085fd4e5da5Sopenharmony_ci         %59 = OpTypePointer Private %6
2086fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 1
2087fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Function %14
2088fd4e5da5Sopenharmony_ci         %17 = OpConstant %14 0
2089fd4e5da5Sopenharmony_ci         %24 = OpConstant %14 100
2090fd4e5da5Sopenharmony_ci         %25 = OpTypeBool
2091fd4e5da5Sopenharmony_ci         %28 = OpTypeStruct %6
2092fd4e5da5Sopenharmony_ci         %29 = OpTypePointer Uniform %28
2093fd4e5da5Sopenharmony_ci         %30 = OpVariable %29 Uniform
2094fd4e5da5Sopenharmony_ci         %31 = OpTypePointer Uniform %6
2095fd4e5da5Sopenharmony_ci         %39 = OpTypeInt 32 0
2096fd4e5da5Sopenharmony_ci         %40 = OpConstant %39 1
2097fd4e5da5Sopenharmony_ci         %45 = OpConstant %39 0
2098fd4e5da5Sopenharmony_ci         %52 = OpConstant %14 1
2099fd4e5da5Sopenharmony_ci         %54 = OpTypeVector %6 4
2100fd4e5da5Sopenharmony_ci         %55 = OpTypePointer Output %54
2101fd4e5da5Sopenharmony_ci         %56 = OpVariable %55 Output
2102fd4e5da5Sopenharmony_ci          %9 = OpVariable %60 Private
2103fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2104fd4e5da5Sopenharmony_ci          %5 = OpLabel
2105fd4e5da5Sopenharmony_ci         %13 = OpVariable %12 Function
2106fd4e5da5Sopenharmony_ci         %16 = OpVariable %15 Function
2107fd4e5da5Sopenharmony_ci         %38 = OpVariable %12 Function
2108fd4e5da5Sopenharmony_ci               OpStore %9 %11
2109fd4e5da5Sopenharmony_ci               OpStore %13 %10
2110fd4e5da5Sopenharmony_ci               OpStore %16 %17
2111fd4e5da5Sopenharmony_ci               OpBranch %18
2112fd4e5da5Sopenharmony_ci         %18 = OpLabel
2113fd4e5da5Sopenharmony_ci               OpLoopMerge %20 %21 None
2114fd4e5da5Sopenharmony_ci               OpBranch %22
2115fd4e5da5Sopenharmony_ci         %22 = OpLabel
2116fd4e5da5Sopenharmony_ci         %23 = OpLoad %14 %16
2117fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %25 %23 %24
2118fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %19 %20
2119fd4e5da5Sopenharmony_ci         %19 = OpLabel
2120fd4e5da5Sopenharmony_ci         %27 = OpLoad %14 %16
2121fd4e5da5Sopenharmony_ci         %32 = OpAccessChain %31 %30 %17
2122fd4e5da5Sopenharmony_ci         %33 = OpLoad %6 %32
2123fd4e5da5Sopenharmony_ci         %34 = OpConvertFToS %14 %33
2124fd4e5da5Sopenharmony_ci         %35 = OpSLessThan %25 %27 %34
2125fd4e5da5Sopenharmony_ci               OpSelectionMerge %37 None
2126fd4e5da5Sopenharmony_ci               OpBranchConditional %35 %36 %44
2127fd4e5da5Sopenharmony_ci         %36 = OpLabel
2128fd4e5da5Sopenharmony_ci         %41 = OpAccessChain %59 %9 %40
2129fd4e5da5Sopenharmony_ci         %42 = OpLoad %6 %41
2130fd4e5da5Sopenharmony_ci               OpStore %38 %42
2131fd4e5da5Sopenharmony_ci               OpBranch %20
2132fd4e5da5Sopenharmony_ci         %44 = OpLabel
2133fd4e5da5Sopenharmony_ci         %46 = OpAccessChain %59 %9 %45
2134fd4e5da5Sopenharmony_ci               OpBranch %37
2135fd4e5da5Sopenharmony_ci         %37 = OpLabel
2136fd4e5da5Sopenharmony_ci         %47 = OpLoad %6 %46
2137fd4e5da5Sopenharmony_ci               OpStore %38 %47
2138fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %38
2139fd4e5da5Sopenharmony_ci         %49 = OpLoad %6 %13
2140fd4e5da5Sopenharmony_ci         %50 = OpFAdd %6 %49 %48
2141fd4e5da5Sopenharmony_ci               OpStore %13 %50
2142fd4e5da5Sopenharmony_ci               OpBranch %21
2143fd4e5da5Sopenharmony_ci         %21 = OpLabel
2144fd4e5da5Sopenharmony_ci         %51 = OpLoad %14 %16
2145fd4e5da5Sopenharmony_ci         %53 = OpIAdd %14 %51 %52
2146fd4e5da5Sopenharmony_ci               OpStore %16 %53
2147fd4e5da5Sopenharmony_ci               OpBranch %18
2148fd4e5da5Sopenharmony_ci         %20 = OpLabel
2149fd4e5da5Sopenharmony_ci         %57 = OpLoad %6 %13
2150fd4e5da5Sopenharmony_ci         %58 = OpCompositeConstruct %54 %57 %57 %57 %57
2151fd4e5da5Sopenharmony_ci               OpStore %56 %58
2152fd4e5da5Sopenharmony_ci               OpReturn
2153fd4e5da5Sopenharmony_ci               OpFunctionEnd
2154fd4e5da5Sopenharmony_ci  )";
2155fd4e5da5Sopenharmony_ci
2156fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2157fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2158fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2159fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2160fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2161fd4e5da5Sopenharmony_ci
2162fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2163fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2164fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2165fd4e5da5Sopenharmony_ci
2166fd4e5da5Sopenharmony_ci  std::string expected = R"(
2167fd4e5da5Sopenharmony_ci               OpCapability Shader
2168fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2169fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2170fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %56
2171fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2172fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2173fd4e5da5Sopenharmony_ci               OpMemberDecorate %28 0 Offset 0
2174fd4e5da5Sopenharmony_ci               OpDecorate %28 Block
2175fd4e5da5Sopenharmony_ci               OpDecorate %30 DescriptorSet 0
2176fd4e5da5Sopenharmony_ci               OpDecorate %30 Binding 0
2177fd4e5da5Sopenharmony_ci               OpDecorate %56 Location 0
2178fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2179fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2180fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
2181fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 2
2182fd4e5da5Sopenharmony_ci          %8 = OpTypePointer Function %7
2183fd4e5da5Sopenharmony_ci         %60 = OpTypePointer Private %7
2184fd4e5da5Sopenharmony_ci         %10 = OpConstant %6 0
2185fd4e5da5Sopenharmony_ci         %11 = OpConstantComposite %7 %10 %10
2186fd4e5da5Sopenharmony_ci         %12 = OpTypePointer Function %6
2187fd4e5da5Sopenharmony_ci         %59 = OpTypePointer Private %6
2188fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 1
2189fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Function %14
2190fd4e5da5Sopenharmony_ci         %17 = OpConstant %14 0
2191fd4e5da5Sopenharmony_ci         %24 = OpConstant %14 100
2192fd4e5da5Sopenharmony_ci         %25 = OpTypeBool
2193fd4e5da5Sopenharmony_ci         %28 = OpTypeStruct %6
2194fd4e5da5Sopenharmony_ci         %29 = OpTypePointer Uniform %28
2195fd4e5da5Sopenharmony_ci         %30 = OpVariable %29 Uniform
2196fd4e5da5Sopenharmony_ci         %31 = OpTypePointer Uniform %6
2197fd4e5da5Sopenharmony_ci         %39 = OpTypeInt 32 0
2198fd4e5da5Sopenharmony_ci         %40 = OpConstant %39 1
2199fd4e5da5Sopenharmony_ci         %45 = OpConstant %39 0
2200fd4e5da5Sopenharmony_ci         %52 = OpConstant %14 1
2201fd4e5da5Sopenharmony_ci         %54 = OpTypeVector %6 4
2202fd4e5da5Sopenharmony_ci         %55 = OpTypePointer Output %54
2203fd4e5da5Sopenharmony_ci         %56 = OpVariable %55 Output
2204fd4e5da5Sopenharmony_ci          %9 = OpVariable %60 Private
2205fd4e5da5Sopenharmony_ci         %61 = OpConstantTrue %25
2206fd4e5da5Sopenharmony_ci         %62 = OpVariable %59 Private
2207fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2208fd4e5da5Sopenharmony_ci          %5 = OpLabel
2209fd4e5da5Sopenharmony_ci         %13 = OpVariable %12 Function
2210fd4e5da5Sopenharmony_ci         %16 = OpVariable %15 Function
2211fd4e5da5Sopenharmony_ci         %38 = OpVariable %12 Function
2212fd4e5da5Sopenharmony_ci               OpStore %9 %11
2213fd4e5da5Sopenharmony_ci               OpStore %13 %10
2214fd4e5da5Sopenharmony_ci               OpStore %16 %17
2215fd4e5da5Sopenharmony_ci               OpBranch %18
2216fd4e5da5Sopenharmony_ci         %18 = OpLabel
2217fd4e5da5Sopenharmony_ci               OpSelectionMerge %20 None
2218fd4e5da5Sopenharmony_ci               OpBranchConditional %61 %22 %20
2219fd4e5da5Sopenharmony_ci         %22 = OpLabel
2220fd4e5da5Sopenharmony_ci         %23 = OpLoad %14 %16
2221fd4e5da5Sopenharmony_ci         %26 = OpSLessThan %25 %23 %24
2222fd4e5da5Sopenharmony_ci               OpBranchConditional %26 %19 %20
2223fd4e5da5Sopenharmony_ci         %19 = OpLabel
2224fd4e5da5Sopenharmony_ci         %27 = OpLoad %14 %16
2225fd4e5da5Sopenharmony_ci         %32 = OpAccessChain %31 %30 %17
2226fd4e5da5Sopenharmony_ci         %33 = OpLoad %6 %32
2227fd4e5da5Sopenharmony_ci         %34 = OpConvertFToS %14 %33
2228fd4e5da5Sopenharmony_ci         %35 = OpSLessThan %25 %27 %34
2229fd4e5da5Sopenharmony_ci               OpSelectionMerge %37 None
2230fd4e5da5Sopenharmony_ci               OpBranchConditional %35 %36 %44
2231fd4e5da5Sopenharmony_ci         %36 = OpLabel
2232fd4e5da5Sopenharmony_ci         %41 = OpAccessChain %59 %9 %40
2233fd4e5da5Sopenharmony_ci         %42 = OpLoad %6 %41
2234fd4e5da5Sopenharmony_ci               OpStore %38 %42
2235fd4e5da5Sopenharmony_ci               OpBranch %37
2236fd4e5da5Sopenharmony_ci         %44 = OpLabel
2237fd4e5da5Sopenharmony_ci         %46 = OpAccessChain %59 %9 %45
2238fd4e5da5Sopenharmony_ci               OpBranch %37
2239fd4e5da5Sopenharmony_ci         %37 = OpLabel
2240fd4e5da5Sopenharmony_ci         %47 = OpLoad %6 %62
2241fd4e5da5Sopenharmony_ci               OpStore %38 %47
2242fd4e5da5Sopenharmony_ci         %48 = OpLoad %6 %38
2243fd4e5da5Sopenharmony_ci         %49 = OpLoad %6 %13
2244fd4e5da5Sopenharmony_ci         %50 = OpFAdd %6 %49 %48
2245fd4e5da5Sopenharmony_ci               OpStore %13 %50
2246fd4e5da5Sopenharmony_ci               OpBranch %20
2247fd4e5da5Sopenharmony_ci         %21 = OpLabel
2248fd4e5da5Sopenharmony_ci         %51 = OpLoad %14 %16
2249fd4e5da5Sopenharmony_ci         %53 = OpIAdd %14 %51 %52
2250fd4e5da5Sopenharmony_ci               OpStore %16 %53
2251fd4e5da5Sopenharmony_ci               OpBranch %18
2252fd4e5da5Sopenharmony_ci         %20 = OpLabel
2253fd4e5da5Sopenharmony_ci         %57 = OpLoad %6 %13
2254fd4e5da5Sopenharmony_ci         %58 = OpCompositeConstruct %54 %57 %57 %57 %57
2255fd4e5da5Sopenharmony_ci               OpStore %56 %58
2256fd4e5da5Sopenharmony_ci               OpReturn
2257fd4e5da5Sopenharmony_ci               OpFunctionEnd
2258fd4e5da5Sopenharmony_ci  )";
2259fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2260fd4e5da5Sopenharmony_ci}
2261fd4e5da5Sopenharmony_ci
2262fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, DominanceAndPhiIssue) {
2263fd4e5da5Sopenharmony_ci  // Exposes an interesting scenario where a use in a phi stops being dominated
2264fd4e5da5Sopenharmony_ci  // by the block with which it is associated in the phi.
2265fd4e5da5Sopenharmony_ci  std::string shader = R"(
2266fd4e5da5Sopenharmony_ci               OpCapability Shader
2267fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2268fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2269fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
2270fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2271fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2272fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2273fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2274fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
2275fd4e5da5Sopenharmony_ci         %18 = OpConstantTrue %17
2276fd4e5da5Sopenharmony_ci         %19 = OpConstantFalse %17
2277fd4e5da5Sopenharmony_ci         %20 = OpTypeInt 32 1
2278fd4e5da5Sopenharmony_ci         %21 = OpConstant %20 5
2279fd4e5da5Sopenharmony_ci         %22 = OpConstant %20 6
2280fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2281fd4e5da5Sopenharmony_ci          %5 = OpLabel
2282fd4e5da5Sopenharmony_ci               OpBranch %6
2283fd4e5da5Sopenharmony_ci         %6 = OpLabel
2284fd4e5da5Sopenharmony_ci              OpLoopMerge %16 %15 None
2285fd4e5da5Sopenharmony_ci              OpBranch %7
2286fd4e5da5Sopenharmony_ci         %7 = OpLabel
2287fd4e5da5Sopenharmony_ci              OpSelectionMerge %13 None
2288fd4e5da5Sopenharmony_ci              OpBranchConditional %18 %8 %9
2289fd4e5da5Sopenharmony_ci         %8 = OpLabel
2290fd4e5da5Sopenharmony_ci              OpSelectionMerge %12 None
2291fd4e5da5Sopenharmony_ci              OpBranchConditional %18 %10 %11
2292fd4e5da5Sopenharmony_ci         %9 = OpLabel
2293fd4e5da5Sopenharmony_ci              OpBranch %16
2294fd4e5da5Sopenharmony_ci        %10 = OpLabel
2295fd4e5da5Sopenharmony_ci              OpBranch %16
2296fd4e5da5Sopenharmony_ci        %11 = OpLabel
2297fd4e5da5Sopenharmony_ci        %23 = OpIAdd %20 %21 %22
2298fd4e5da5Sopenharmony_ci              OpBranch %12
2299fd4e5da5Sopenharmony_ci        %12 = OpLabel
2300fd4e5da5Sopenharmony_ci              OpBranch %13
2301fd4e5da5Sopenharmony_ci        %13 = OpLabel
2302fd4e5da5Sopenharmony_ci              OpBranch %14
2303fd4e5da5Sopenharmony_ci        %14 = OpLabel
2304fd4e5da5Sopenharmony_ci        %24 = OpPhi %20 %23 %13
2305fd4e5da5Sopenharmony_ci              OpBranchConditional %19 %15 %16
2306fd4e5da5Sopenharmony_ci        %15 = OpLabel
2307fd4e5da5Sopenharmony_ci              OpBranch %6
2308fd4e5da5Sopenharmony_ci        %16 = OpLabel
2309fd4e5da5Sopenharmony_ci              OpReturn
2310fd4e5da5Sopenharmony_ci              OpFunctionEnd
2311fd4e5da5Sopenharmony_ci  )";
2312fd4e5da5Sopenharmony_ci
2313fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2314fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2315fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2316fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2317fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2318fd4e5da5Sopenharmony_ci
2319fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2320fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2321fd4e5da5Sopenharmony_ci
2322fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2323fd4e5da5Sopenharmony_ci
2324fd4e5da5Sopenharmony_ci  std::string expected = R"(
2325fd4e5da5Sopenharmony_ci               OpCapability Shader
2326fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2327fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2328fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
2329fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2330fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2331fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2332fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2333fd4e5da5Sopenharmony_ci         %17 = OpTypeBool
2334fd4e5da5Sopenharmony_ci         %18 = OpConstantTrue %17
2335fd4e5da5Sopenharmony_ci         %19 = OpConstantFalse %17
2336fd4e5da5Sopenharmony_ci         %20 = OpTypeInt 32 1
2337fd4e5da5Sopenharmony_ci         %21 = OpConstant %20 5
2338fd4e5da5Sopenharmony_ci         %22 = OpConstant %20 6
2339fd4e5da5Sopenharmony_ci         %25 = OpUndef %20
2340fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2341fd4e5da5Sopenharmony_ci          %5 = OpLabel
2342fd4e5da5Sopenharmony_ci               OpBranch %6
2343fd4e5da5Sopenharmony_ci         %6 = OpLabel
2344fd4e5da5Sopenharmony_ci              OpSelectionMerge %16 None
2345fd4e5da5Sopenharmony_ci              OpBranchConditional %18 %7 %16
2346fd4e5da5Sopenharmony_ci         %7 = OpLabel
2347fd4e5da5Sopenharmony_ci              OpSelectionMerge %13 None
2348fd4e5da5Sopenharmony_ci              OpBranchConditional %18 %8 %9
2349fd4e5da5Sopenharmony_ci         %8 = OpLabel
2350fd4e5da5Sopenharmony_ci              OpSelectionMerge %12 None
2351fd4e5da5Sopenharmony_ci              OpBranchConditional %18 %10 %11
2352fd4e5da5Sopenharmony_ci         %9 = OpLabel
2353fd4e5da5Sopenharmony_ci              OpBranch %13
2354fd4e5da5Sopenharmony_ci        %10 = OpLabel
2355fd4e5da5Sopenharmony_ci              OpBranch %12
2356fd4e5da5Sopenharmony_ci        %11 = OpLabel
2357fd4e5da5Sopenharmony_ci        %23 = OpIAdd %20 %21 %22
2358fd4e5da5Sopenharmony_ci              OpBranch %12
2359fd4e5da5Sopenharmony_ci        %12 = OpLabel
2360fd4e5da5Sopenharmony_ci              OpBranch %13
2361fd4e5da5Sopenharmony_ci        %13 = OpLabel
2362fd4e5da5Sopenharmony_ci              OpBranch %14
2363fd4e5da5Sopenharmony_ci        %14 = OpLabel
2364fd4e5da5Sopenharmony_ci        %24 = OpPhi %20 %25 %13
2365fd4e5da5Sopenharmony_ci              OpBranchConditional %19 %16 %16
2366fd4e5da5Sopenharmony_ci        %15 = OpLabel
2367fd4e5da5Sopenharmony_ci              OpBranch %6
2368fd4e5da5Sopenharmony_ci        %16 = OpLabel
2369fd4e5da5Sopenharmony_ci              OpReturn
2370fd4e5da5Sopenharmony_ci              OpFunctionEnd
2371fd4e5da5Sopenharmony_ci  )";
2372fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2373fd4e5da5Sopenharmony_ci}
2374fd4e5da5Sopenharmony_ci
2375fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, OpLineBeforeOpPhi) {
2376fd4e5da5Sopenharmony_ci  // Test to ensure the pass knows OpLine and OpPhi instructions can be
2377fd4e5da5Sopenharmony_ci  // interleaved.
2378fd4e5da5Sopenharmony_ci  std::string shader = R"(
2379fd4e5da5Sopenharmony_ci               OpCapability Shader
2380fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2381fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2382fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
2383fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
2384fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2385fd4e5da5Sopenharmony_ci          %3 = OpString "somefile"
2386fd4e5da5Sopenharmony_ci          %4 = OpTypeVoid
2387fd4e5da5Sopenharmony_ci          %5 = OpTypeFunction %4
2388fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
2389fd4e5da5Sopenharmony_ci          %7 = OpConstant %6 10
2390fd4e5da5Sopenharmony_ci          %8 = OpConstant %6 20
2391fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 30
2392fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
2393fd4e5da5Sopenharmony_ci         %11 = OpConstantTrue %10
2394fd4e5da5Sopenharmony_ci          %2 = OpFunction %4 None %5
2395fd4e5da5Sopenharmony_ci         %12 = OpLabel
2396fd4e5da5Sopenharmony_ci               OpBranch %13
2397fd4e5da5Sopenharmony_ci         %13 = OpLabel
2398fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %15 None
2399fd4e5da5Sopenharmony_ci               OpBranch %16
2400fd4e5da5Sopenharmony_ci         %16 = OpLabel
2401fd4e5da5Sopenharmony_ci               OpSelectionMerge %17 None
2402fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %18 %19
2403fd4e5da5Sopenharmony_ci         %18 = OpLabel
2404fd4e5da5Sopenharmony_ci         %20 = OpIAdd %6 %7 %8
2405fd4e5da5Sopenharmony_ci         %21 = OpIAdd %6 %7 %9
2406fd4e5da5Sopenharmony_ci               OpBranch %17
2407fd4e5da5Sopenharmony_ci         %19 = OpLabel
2408fd4e5da5Sopenharmony_ci               OpBranch %14
2409fd4e5da5Sopenharmony_ci         %17 = OpLabel
2410fd4e5da5Sopenharmony_ci         %22 = OpPhi %6 %20 %18
2411fd4e5da5Sopenharmony_ci               OpLine %3 0 0
2412fd4e5da5Sopenharmony_ci         %23 = OpPhi %6 %21 %18
2413fd4e5da5Sopenharmony_ci               OpBranch %15
2414fd4e5da5Sopenharmony_ci         %15 = OpLabel
2415fd4e5da5Sopenharmony_ci               OpBranch %13
2416fd4e5da5Sopenharmony_ci         %14 = OpLabel
2417fd4e5da5Sopenharmony_ci               OpReturn
2418fd4e5da5Sopenharmony_ci               OpFunctionEnd
2419fd4e5da5Sopenharmony_ci  )";
2420fd4e5da5Sopenharmony_ci
2421fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2422fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2423fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2424fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2425fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2426fd4e5da5Sopenharmony_ci
2427fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2428fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2429fd4e5da5Sopenharmony_ci
2430fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2431fd4e5da5Sopenharmony_ci
2432fd4e5da5Sopenharmony_ci  std::string expected = R"(
2433fd4e5da5Sopenharmony_ci               OpCapability Shader
2434fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2435fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2436fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
2437fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
2438fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2439fd4e5da5Sopenharmony_ci          %3 = OpString "somefile"
2440fd4e5da5Sopenharmony_ci          %4 = OpTypeVoid
2441fd4e5da5Sopenharmony_ci          %5 = OpTypeFunction %4
2442fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
2443fd4e5da5Sopenharmony_ci          %7 = OpConstant %6 10
2444fd4e5da5Sopenharmony_ci          %8 = OpConstant %6 20
2445fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 30
2446fd4e5da5Sopenharmony_ci         %10 = OpTypeBool
2447fd4e5da5Sopenharmony_ci         %11 = OpConstantTrue %10
2448fd4e5da5Sopenharmony_ci         %24 = OpUndef %6
2449fd4e5da5Sopenharmony_ci          %2 = OpFunction %4 None %5
2450fd4e5da5Sopenharmony_ci         %12 = OpLabel
2451fd4e5da5Sopenharmony_ci               OpBranch %13
2452fd4e5da5Sopenharmony_ci         %13 = OpLabel
2453fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2454fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %16 %14
2455fd4e5da5Sopenharmony_ci         %16 = OpLabel
2456fd4e5da5Sopenharmony_ci               OpSelectionMerge %17 None
2457fd4e5da5Sopenharmony_ci               OpBranchConditional %11 %18 %19
2458fd4e5da5Sopenharmony_ci         %18 = OpLabel
2459fd4e5da5Sopenharmony_ci         %20 = OpIAdd %6 %7 %8
2460fd4e5da5Sopenharmony_ci         %21 = OpIAdd %6 %7 %9
2461fd4e5da5Sopenharmony_ci               OpBranch %17
2462fd4e5da5Sopenharmony_ci         %19 = OpLabel
2463fd4e5da5Sopenharmony_ci               OpBranch %17
2464fd4e5da5Sopenharmony_ci         %17 = OpLabel
2465fd4e5da5Sopenharmony_ci         %22 = OpPhi %6 %20 %18 %24 %19
2466fd4e5da5Sopenharmony_ci               OpLine %3 0 0
2467fd4e5da5Sopenharmony_ci         %23 = OpPhi %6 %21 %18 %24 %19
2468fd4e5da5Sopenharmony_ci               OpBranch %14
2469fd4e5da5Sopenharmony_ci         %15 = OpLabel
2470fd4e5da5Sopenharmony_ci               OpBranch %13
2471fd4e5da5Sopenharmony_ci         %14 = OpLabel
2472fd4e5da5Sopenharmony_ci               OpReturn
2473fd4e5da5Sopenharmony_ci               OpFunctionEnd
2474fd4e5da5Sopenharmony_ci  )";
2475fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2476fd4e5da5Sopenharmony_ci}
2477fd4e5da5Sopenharmony_ci
2478fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
2479fd4e5da5Sopenharmony_ci     SelectionMergeIsContinueTarget) {
2480fd4e5da5Sopenharmony_ci  // Example where a loop's continue target is also the target of a selection.
2481fd4e5da5Sopenharmony_ci  // In this scenario we cautiously do not apply the transformation.
2482fd4e5da5Sopenharmony_ci  std::string shader = R"(
2483fd4e5da5Sopenharmony_ci               OpCapability Shader
2484fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2485fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2486fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2487fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2488fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2489fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2490fd4e5da5Sopenharmony_ci          %5 = OpLabel
2491fd4e5da5Sopenharmony_ci          %6 = OpUndef %3
2492fd4e5da5Sopenharmony_ci               OpBranch %7
2493fd4e5da5Sopenharmony_ci          %7 = OpLabel
2494fd4e5da5Sopenharmony_ci          %8 = OpPhi %3 %6 %5 %9 %10
2495fd4e5da5Sopenharmony_ci               OpLoopMerge %11 %10 None
2496fd4e5da5Sopenharmony_ci               OpBranch %12
2497fd4e5da5Sopenharmony_ci         %12 = OpLabel
2498fd4e5da5Sopenharmony_ci         %13 = OpUndef %3
2499fd4e5da5Sopenharmony_ci               OpSelectionMerge %10 None
2500fd4e5da5Sopenharmony_ci               OpBranchConditional %13 %14 %10
2501fd4e5da5Sopenharmony_ci         %14 = OpLabel
2502fd4e5da5Sopenharmony_ci               OpBranch %10
2503fd4e5da5Sopenharmony_ci         %10 = OpLabel
2504fd4e5da5Sopenharmony_ci          %9 = OpUndef %3
2505fd4e5da5Sopenharmony_ci               OpBranchConditional %9 %7 %11
2506fd4e5da5Sopenharmony_ci         %11 = OpLabel
2507fd4e5da5Sopenharmony_ci               OpReturn
2508fd4e5da5Sopenharmony_ci               OpFunctionEnd
2509fd4e5da5Sopenharmony_ci  )";
2510fd4e5da5Sopenharmony_ci
2511fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2512fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2513fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2514fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2515fd4e5da5Sopenharmony_ci
2516fd4e5da5Sopenharmony_ci  // There should be no opportunities.
2517fd4e5da5Sopenharmony_ci  ASSERT_EQ(0, ops.size());
2518fd4e5da5Sopenharmony_ci}
2519fd4e5da5Sopenharmony_ci
2520fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
2521fd4e5da5Sopenharmony_ci     SwitchSelectionMergeIsContinueTarget) {
2522fd4e5da5Sopenharmony_ci  // Another example where a loop's continue target is also the target of a
2523fd4e5da5Sopenharmony_ci  // selection; this time a selection associated with an OpSwitch.  We
2524fd4e5da5Sopenharmony_ci  // cautiously do not apply the transformation.
2525fd4e5da5Sopenharmony_ci  std::string shader = R"(
2526fd4e5da5Sopenharmony_ci               OpCapability Shader
2527fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2528fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2529fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2530fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2531fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2532fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2533fd4e5da5Sopenharmony_ci          %6 = OpConstant %5 2
2534fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2535fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2536fd4e5da5Sopenharmony_ci          %8 = OpLabel
2537fd4e5da5Sopenharmony_ci               OpBranch %9
2538fd4e5da5Sopenharmony_ci          %9 = OpLabel
2539fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %15 None
2540fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %10 %14
2541fd4e5da5Sopenharmony_ci         %10 = OpLabel
2542fd4e5da5Sopenharmony_ci               OpSelectionMerge %15 None
2543fd4e5da5Sopenharmony_ci               OpSwitch %6 %12 1 %11 2 %11 3 %15
2544fd4e5da5Sopenharmony_ci         %11 = OpLabel
2545fd4e5da5Sopenharmony_ci               OpBranch %12
2546fd4e5da5Sopenharmony_ci         %12 = OpLabel
2547fd4e5da5Sopenharmony_ci               OpBranch %15
2548fd4e5da5Sopenharmony_ci         %15 = OpLabel
2549fd4e5da5Sopenharmony_ci               OpBranch %9
2550fd4e5da5Sopenharmony_ci         %14 = OpLabel
2551fd4e5da5Sopenharmony_ci               OpReturn
2552fd4e5da5Sopenharmony_ci               OpFunctionEnd
2553fd4e5da5Sopenharmony_ci  )";
2554fd4e5da5Sopenharmony_ci
2555fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2556fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2557fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2558fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2559fd4e5da5Sopenharmony_ci
2560fd4e5da5Sopenharmony_ci  // There should be no opportunities.
2561fd4e5da5Sopenharmony_ci  ASSERT_EQ(0, ops.size());
2562fd4e5da5Sopenharmony_ci}
2563fd4e5da5Sopenharmony_ci
2564fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ContinueTargetIsSwitchTarget) {
2565fd4e5da5Sopenharmony_ci  std::string shader = R"(
2566fd4e5da5Sopenharmony_ci               OpCapability Shader
2567fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2568fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2569fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2570fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2571fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2572fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2573fd4e5da5Sopenharmony_ci          %6 = OpConstant %5 2
2574fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2575fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2576fd4e5da5Sopenharmony_ci          %8 = OpLabel
2577fd4e5da5Sopenharmony_ci               OpBranch %9
2578fd4e5da5Sopenharmony_ci          %9 = OpLabel
2579fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %12 None
2580fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %10 %14
2581fd4e5da5Sopenharmony_ci         %10 = OpLabel
2582fd4e5da5Sopenharmony_ci               OpSelectionMerge %15 None
2583fd4e5da5Sopenharmony_ci               OpSwitch %6 %12 1 %11 2 %11 3 %15
2584fd4e5da5Sopenharmony_ci         %11 = OpLabel
2585fd4e5da5Sopenharmony_ci               OpBranch %12
2586fd4e5da5Sopenharmony_ci         %12 = OpLabel
2587fd4e5da5Sopenharmony_ci               OpBranch %9
2588fd4e5da5Sopenharmony_ci         %15 = OpLabel
2589fd4e5da5Sopenharmony_ci               OpBranch %14
2590fd4e5da5Sopenharmony_ci         %14 = OpLabel
2591fd4e5da5Sopenharmony_ci               OpReturn
2592fd4e5da5Sopenharmony_ci               OpFunctionEnd
2593fd4e5da5Sopenharmony_ci  )";
2594fd4e5da5Sopenharmony_ci
2595fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2596fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2597fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2598fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2599fd4e5da5Sopenharmony_ci
2600fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2601fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2602fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2603fd4e5da5Sopenharmony_ci
2604fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2605fd4e5da5Sopenharmony_ci
2606fd4e5da5Sopenharmony_ci  std::string expected = R"(
2607fd4e5da5Sopenharmony_ci               OpCapability Shader
2608fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2609fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2610fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2611fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2612fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2613fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2614fd4e5da5Sopenharmony_ci          %6 = OpConstant %5 2
2615fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2616fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2617fd4e5da5Sopenharmony_ci          %8 = OpLabel
2618fd4e5da5Sopenharmony_ci               OpBranch %9
2619fd4e5da5Sopenharmony_ci          %9 = OpLabel
2620fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2621fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %10 %14
2622fd4e5da5Sopenharmony_ci         %10 = OpLabel
2623fd4e5da5Sopenharmony_ci               OpSelectionMerge %15 None
2624fd4e5da5Sopenharmony_ci               OpSwitch %6 %15 1 %11 2 %11 3 %15
2625fd4e5da5Sopenharmony_ci         %11 = OpLabel
2626fd4e5da5Sopenharmony_ci               OpBranch %15
2627fd4e5da5Sopenharmony_ci         %12 = OpLabel
2628fd4e5da5Sopenharmony_ci               OpBranch %9
2629fd4e5da5Sopenharmony_ci         %15 = OpLabel
2630fd4e5da5Sopenharmony_ci               OpBranch %14
2631fd4e5da5Sopenharmony_ci         %14 = OpLabel
2632fd4e5da5Sopenharmony_ci               OpReturn
2633fd4e5da5Sopenharmony_ci               OpFunctionEnd
2634fd4e5da5Sopenharmony_ci  )";
2635fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2636fd4e5da5Sopenharmony_ci}
2637fd4e5da5Sopenharmony_ci
2638fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
2639fd4e5da5Sopenharmony_ci     MultipleSwitchTargetsAreContinueTarget) {
2640fd4e5da5Sopenharmony_ci  std::string shader = R"(
2641fd4e5da5Sopenharmony_ci               OpCapability Shader
2642fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2643fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2644fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2645fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2646fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2647fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2648fd4e5da5Sopenharmony_ci          %6 = OpConstant %5 2
2649fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2650fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2651fd4e5da5Sopenharmony_ci          %8 = OpLabel
2652fd4e5da5Sopenharmony_ci               OpBranch %9
2653fd4e5da5Sopenharmony_ci          %9 = OpLabel
2654fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %12 None
2655fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %10 %14
2656fd4e5da5Sopenharmony_ci         %10 = OpLabel
2657fd4e5da5Sopenharmony_ci               OpSelectionMerge %15 None
2658fd4e5da5Sopenharmony_ci               OpSwitch %6 %11 1 %12 2 %12 3 %15
2659fd4e5da5Sopenharmony_ci         %11 = OpLabel
2660fd4e5da5Sopenharmony_ci               OpBranch %12
2661fd4e5da5Sopenharmony_ci         %12 = OpLabel
2662fd4e5da5Sopenharmony_ci               OpBranch %9
2663fd4e5da5Sopenharmony_ci         %15 = OpLabel
2664fd4e5da5Sopenharmony_ci               OpBranch %14
2665fd4e5da5Sopenharmony_ci         %14 = OpLabel
2666fd4e5da5Sopenharmony_ci               OpReturn
2667fd4e5da5Sopenharmony_ci               OpFunctionEnd
2668fd4e5da5Sopenharmony_ci  )";
2669fd4e5da5Sopenharmony_ci
2670fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2671fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2672fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2673fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2674fd4e5da5Sopenharmony_ci
2675fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2676fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2677fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2678fd4e5da5Sopenharmony_ci
2679fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2680fd4e5da5Sopenharmony_ci
2681fd4e5da5Sopenharmony_ci  std::string expected = R"(
2682fd4e5da5Sopenharmony_ci               OpCapability Shader
2683fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2684fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2685fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2686fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2687fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
2688fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2689fd4e5da5Sopenharmony_ci          %6 = OpConstant %5 2
2690fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2691fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2692fd4e5da5Sopenharmony_ci          %8 = OpLabel
2693fd4e5da5Sopenharmony_ci               OpBranch %9
2694fd4e5da5Sopenharmony_ci          %9 = OpLabel
2695fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2696fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %10 %14
2697fd4e5da5Sopenharmony_ci         %10 = OpLabel
2698fd4e5da5Sopenharmony_ci               OpSelectionMerge %15 None
2699fd4e5da5Sopenharmony_ci               OpSwitch %6 %11 1 %15 2 %15 3 %15
2700fd4e5da5Sopenharmony_ci         %11 = OpLabel
2701fd4e5da5Sopenharmony_ci               OpBranch %15
2702fd4e5da5Sopenharmony_ci         %12 = OpLabel
2703fd4e5da5Sopenharmony_ci               OpBranch %9
2704fd4e5da5Sopenharmony_ci         %15 = OpLabel
2705fd4e5da5Sopenharmony_ci               OpBranch %14
2706fd4e5da5Sopenharmony_ci         %14 = OpLabel
2707fd4e5da5Sopenharmony_ci               OpReturn
2708fd4e5da5Sopenharmony_ci               OpFunctionEnd
2709fd4e5da5Sopenharmony_ci  )";
2710fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2711fd4e5da5Sopenharmony_ci}
2712fd4e5da5Sopenharmony_ci
2713fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopBranchesStraightToMerge) {
2714fd4e5da5Sopenharmony_ci  std::string shader = R"(
2715fd4e5da5Sopenharmony_ci               OpCapability Shader
2716fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2717fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2718fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2719fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2720fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2721fd4e5da5Sopenharmony_ci          %8 = OpLabel
2722fd4e5da5Sopenharmony_ci               OpBranch %9
2723fd4e5da5Sopenharmony_ci          %9 = OpLabel
2724fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %12 None
2725fd4e5da5Sopenharmony_ci               OpBranch %14
2726fd4e5da5Sopenharmony_ci         %12 = OpLabel
2727fd4e5da5Sopenharmony_ci               OpBranch %9
2728fd4e5da5Sopenharmony_ci         %14 = OpLabel
2729fd4e5da5Sopenharmony_ci               OpReturn
2730fd4e5da5Sopenharmony_ci               OpFunctionEnd
2731fd4e5da5Sopenharmony_ci  )";
2732fd4e5da5Sopenharmony_ci
2733fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2734fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2735fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2736fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2737fd4e5da5Sopenharmony_ci
2738fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2739fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2740fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2741fd4e5da5Sopenharmony_ci
2742fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2743fd4e5da5Sopenharmony_ci
2744fd4e5da5Sopenharmony_ci  std::string expected = R"(
2745fd4e5da5Sopenharmony_ci               OpCapability Shader
2746fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2747fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2748fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2749fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2750fd4e5da5Sopenharmony_ci         %15 = OpTypeBool
2751fd4e5da5Sopenharmony_ci         %16 = OpConstantTrue %15
2752fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2753fd4e5da5Sopenharmony_ci          %8 = OpLabel
2754fd4e5da5Sopenharmony_ci               OpBranch %9
2755fd4e5da5Sopenharmony_ci          %9 = OpLabel
2756fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2757fd4e5da5Sopenharmony_ci               OpBranchConditional %16 %14 %14
2758fd4e5da5Sopenharmony_ci         %12 = OpLabel
2759fd4e5da5Sopenharmony_ci               OpBranch %9
2760fd4e5da5Sopenharmony_ci         %14 = OpLabel
2761fd4e5da5Sopenharmony_ci               OpReturn
2762fd4e5da5Sopenharmony_ci               OpFunctionEnd
2763fd4e5da5Sopenharmony_ci  )";
2764fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2765fd4e5da5Sopenharmony_ci}
2766fd4e5da5Sopenharmony_ci
2767fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
2768fd4e5da5Sopenharmony_ci     LoopConditionallyJumpsToMergeOrContinue) {
2769fd4e5da5Sopenharmony_ci  std::string shader = R"(
2770fd4e5da5Sopenharmony_ci               OpCapability Shader
2771fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2772fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2773fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2774fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2775fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2776fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2777fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2778fd4e5da5Sopenharmony_ci          %8 = OpLabel
2779fd4e5da5Sopenharmony_ci               OpBranch %9
2780fd4e5da5Sopenharmony_ci          %9 = OpLabel
2781fd4e5da5Sopenharmony_ci               OpLoopMerge %14 %12 None
2782fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %14 %12
2783fd4e5da5Sopenharmony_ci         %12 = OpLabel
2784fd4e5da5Sopenharmony_ci               OpBranch %9
2785fd4e5da5Sopenharmony_ci         %14 = OpLabel
2786fd4e5da5Sopenharmony_ci               OpReturn
2787fd4e5da5Sopenharmony_ci               OpFunctionEnd
2788fd4e5da5Sopenharmony_ci  )";
2789fd4e5da5Sopenharmony_ci
2790fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2791fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2792fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2793fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2794fd4e5da5Sopenharmony_ci
2795fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2796fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2797fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2798fd4e5da5Sopenharmony_ci
2799fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2800fd4e5da5Sopenharmony_ci
2801fd4e5da5Sopenharmony_ci  std::string expected = R"(
2802fd4e5da5Sopenharmony_ci               OpCapability Shader
2803fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2804fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %1 "main"
2805fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2806fd4e5da5Sopenharmony_ci          %3 = OpTypeBool
2807fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %2
2808fd4e5da5Sopenharmony_ci          %7 = OpConstantTrue %3
2809fd4e5da5Sopenharmony_ci          %1 = OpFunction %2 None %4
2810fd4e5da5Sopenharmony_ci          %8 = OpLabel
2811fd4e5da5Sopenharmony_ci               OpBranch %9
2812fd4e5da5Sopenharmony_ci          %9 = OpLabel
2813fd4e5da5Sopenharmony_ci               OpSelectionMerge %14 None
2814fd4e5da5Sopenharmony_ci               OpBranchConditional %7 %14 %14
2815fd4e5da5Sopenharmony_ci         %12 = OpLabel
2816fd4e5da5Sopenharmony_ci               OpBranch %9
2817fd4e5da5Sopenharmony_ci         %14 = OpLabel
2818fd4e5da5Sopenharmony_ci               OpReturn
2819fd4e5da5Sopenharmony_ci               OpFunctionEnd
2820fd4e5da5Sopenharmony_ci  )";
2821fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2822fd4e5da5Sopenharmony_ci}
2823fd4e5da5Sopenharmony_ci
2824fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, MultipleAccessChains) {
2825fd4e5da5Sopenharmony_ci  std::string shader = R"(
2826fd4e5da5Sopenharmony_ci               OpCapability Shader
2827fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2828fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2829fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
2830fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2831fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2832fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2833fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2834fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
2835fd4e5da5Sopenharmony_ci          %7 = OpTypeStruct %6
2836fd4e5da5Sopenharmony_ci          %8 = OpTypeStruct %7
2837fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
2838fd4e5da5Sopenharmony_ci         %11 = OpConstant %6 3
2839fd4e5da5Sopenharmony_ci         %12 = OpConstantComposite %7 %11
2840fd4e5da5Sopenharmony_ci         %13 = OpConstantComposite %8 %12
2841fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Function %7
2842fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 0
2843fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %6
2844fd4e5da5Sopenharmony_ci         %15 = OpTypeBool
2845fd4e5da5Sopenharmony_ci         %18 = OpConstantTrue %15
2846fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2847fd4e5da5Sopenharmony_ci          %5 = OpLabel
2848fd4e5da5Sopenharmony_ci         %10 = OpVariable %9 Function
2849fd4e5da5Sopenharmony_ci         %20 = OpVariable %19 Function
2850fd4e5da5Sopenharmony_ci               OpStore %10 %13
2851fd4e5da5Sopenharmony_ci               OpBranch %23
2852fd4e5da5Sopenharmony_ci         %23 = OpLabel
2853fd4e5da5Sopenharmony_ci               OpLoopMerge %25 %26 None
2854fd4e5da5Sopenharmony_ci               OpBranch %27
2855fd4e5da5Sopenharmony_ci         %27 = OpLabel
2856fd4e5da5Sopenharmony_ci               OpSelectionMerge %28 None
2857fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %29 %25
2858fd4e5da5Sopenharmony_ci         %29 = OpLabel
2859fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %14 %10 %16
2860fd4e5da5Sopenharmony_ci               OpBranch %28
2861fd4e5da5Sopenharmony_ci         %28 = OpLabel
2862fd4e5da5Sopenharmony_ci         %21 = OpAccessChain %19 %17 %16
2863fd4e5da5Sopenharmony_ci         %22 = OpLoad %6 %21
2864fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %19 %10 %16 %16
2865fd4e5da5Sopenharmony_ci               OpStore %24 %22
2866fd4e5da5Sopenharmony_ci               OpBranch %25
2867fd4e5da5Sopenharmony_ci         %26 = OpLabel
2868fd4e5da5Sopenharmony_ci               OpBranch %23
2869fd4e5da5Sopenharmony_ci         %25 = OpLabel
2870fd4e5da5Sopenharmony_ci               OpReturn
2871fd4e5da5Sopenharmony_ci               OpFunctionEnd
2872fd4e5da5Sopenharmony_ci  )";
2873fd4e5da5Sopenharmony_ci
2874fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2875fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2876fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2877fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2878fd4e5da5Sopenharmony_ci
2879fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
2880fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2881fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2882fd4e5da5Sopenharmony_ci
2883fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2884fd4e5da5Sopenharmony_ci
2885fd4e5da5Sopenharmony_ci  std::string expected = R"(
2886fd4e5da5Sopenharmony_ci               OpCapability Shader
2887fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2888fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2889fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
2890fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
2891fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2892fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
2893fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
2894fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
2895fd4e5da5Sopenharmony_ci          %7 = OpTypeStruct %6
2896fd4e5da5Sopenharmony_ci          %8 = OpTypeStruct %7
2897fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
2898fd4e5da5Sopenharmony_ci         %11 = OpConstant %6 3
2899fd4e5da5Sopenharmony_ci         %12 = OpConstantComposite %7 %11
2900fd4e5da5Sopenharmony_ci         %13 = OpConstantComposite %8 %12
2901fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Function %7
2902fd4e5da5Sopenharmony_ci         %16 = OpConstant %6 0
2903fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Function %6
2904fd4e5da5Sopenharmony_ci         %15 = OpTypeBool
2905fd4e5da5Sopenharmony_ci         %18 = OpConstantTrue %15
2906fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
2907fd4e5da5Sopenharmony_ci          %5 = OpLabel
2908fd4e5da5Sopenharmony_ci         %10 = OpVariable %9 Function
2909fd4e5da5Sopenharmony_ci         %20 = OpVariable %19 Function
2910fd4e5da5Sopenharmony_ci         %30 = OpVariable %14 Function
2911fd4e5da5Sopenharmony_ci               OpStore %10 %13
2912fd4e5da5Sopenharmony_ci               OpBranch %23
2913fd4e5da5Sopenharmony_ci         %23 = OpLabel
2914fd4e5da5Sopenharmony_ci               OpSelectionMerge %25 None
2915fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %27 %25
2916fd4e5da5Sopenharmony_ci         %27 = OpLabel
2917fd4e5da5Sopenharmony_ci               OpSelectionMerge %28 None
2918fd4e5da5Sopenharmony_ci               OpBranchConditional %18 %29 %28
2919fd4e5da5Sopenharmony_ci         %29 = OpLabel
2920fd4e5da5Sopenharmony_ci         %17 = OpAccessChain %14 %10 %16
2921fd4e5da5Sopenharmony_ci               OpBranch %28
2922fd4e5da5Sopenharmony_ci         %28 = OpLabel
2923fd4e5da5Sopenharmony_ci         %21 = OpAccessChain %19 %30 %16
2924fd4e5da5Sopenharmony_ci         %22 = OpLoad %6 %21
2925fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %19 %10 %16 %16
2926fd4e5da5Sopenharmony_ci               OpStore %24 %22
2927fd4e5da5Sopenharmony_ci               OpBranch %25
2928fd4e5da5Sopenharmony_ci         %26 = OpLabel
2929fd4e5da5Sopenharmony_ci               OpBranch %23
2930fd4e5da5Sopenharmony_ci         %25 = OpLabel
2931fd4e5da5Sopenharmony_ci               OpReturn
2932fd4e5da5Sopenharmony_ci               OpFunctionEnd
2933fd4e5da5Sopenharmony_ci  )";
2934fd4e5da5Sopenharmony_ci  CheckEqual(env, expected, context.get());
2935fd4e5da5Sopenharmony_ci}
2936fd4e5da5Sopenharmony_ci
2937fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
2938fd4e5da5Sopenharmony_ci     UnreachableInnerLoopContinueBranchingToOuterLoopMerge) {
2939fd4e5da5Sopenharmony_ci  std::string shader = R"(
2940fd4e5da5Sopenharmony_ci               OpCapability Shader
2941fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2942fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2943fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
2944fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
2945fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2946fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
2947fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
2948fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
2949fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
2950fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
2951fd4e5da5Sopenharmony_ci          %7 = OpLabel
2952fd4e5da5Sopenharmony_ci               OpBranch %8
2953fd4e5da5Sopenharmony_ci          %8 = OpLabel
2954fd4e5da5Sopenharmony_ci               OpLoopMerge %9 %10 None
2955fd4e5da5Sopenharmony_ci               OpBranch %11
2956fd4e5da5Sopenharmony_ci         %11 = OpLabel
2957fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
2958fd4e5da5Sopenharmony_ci               OpBranch %12
2959fd4e5da5Sopenharmony_ci         %13 = OpLabel
2960fd4e5da5Sopenharmony_ci               OpBranch %11
2961fd4e5da5Sopenharmony_ci         %12 = OpLabel
2962fd4e5da5Sopenharmony_ci               OpBranch %10
2963fd4e5da5Sopenharmony_ci         %10 = OpLabel
2964fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
2965fd4e5da5Sopenharmony_ci          %9 = OpLabel
2966fd4e5da5Sopenharmony_ci               OpReturn
2967fd4e5da5Sopenharmony_ci               OpFunctionEnd
2968fd4e5da5Sopenharmony_ci  )";
2969fd4e5da5Sopenharmony_ci
2970fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
2971fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
2972fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
2973fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
2974fd4e5da5Sopenharmony_ci
2975fd4e5da5Sopenharmony_ci  ASSERT_EQ(2, ops.size());
2976fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
2977fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
2978fd4e5da5Sopenharmony_ci
2979fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
2980fd4e5da5Sopenharmony_ci
2981fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
2982fd4e5da5Sopenharmony_ci               OpCapability Shader
2983fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
2984fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
2985fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
2986fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
2987fd4e5da5Sopenharmony_ci               OpSource ESSL 310
2988fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
2989fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
2990fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
2991fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
2992fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
2993fd4e5da5Sopenharmony_ci          %7 = OpLabel
2994fd4e5da5Sopenharmony_ci               OpBranch %8
2995fd4e5da5Sopenharmony_ci          %8 = OpLabel
2996fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
2997fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
2998fd4e5da5Sopenharmony_ci         %11 = OpLabel
2999fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
3000fd4e5da5Sopenharmony_ci               OpBranch %12
3001fd4e5da5Sopenharmony_ci         %13 = OpLabel
3002fd4e5da5Sopenharmony_ci               OpBranch %11
3003fd4e5da5Sopenharmony_ci         %12 = OpLabel
3004fd4e5da5Sopenharmony_ci               OpBranch %9
3005fd4e5da5Sopenharmony_ci         %10 = OpLabel
3006fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3007fd4e5da5Sopenharmony_ci          %9 = OpLabel
3008fd4e5da5Sopenharmony_ci               OpReturn
3009fd4e5da5Sopenharmony_ci               OpFunctionEnd
3010fd4e5da5Sopenharmony_ci  )";
3011fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
3012fd4e5da5Sopenharmony_ci
3013fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
3014fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
3015fd4e5da5Sopenharmony_ci
3016fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3017fd4e5da5Sopenharmony_ci
3018fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
3019fd4e5da5Sopenharmony_ci               OpCapability Shader
3020fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3021fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3022fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3023fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3024fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3025fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3026fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3027fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3028fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3029fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3030fd4e5da5Sopenharmony_ci          %7 = OpLabel
3031fd4e5da5Sopenharmony_ci               OpBranch %8
3032fd4e5da5Sopenharmony_ci          %8 = OpLabel
3033fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
3034fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
3035fd4e5da5Sopenharmony_ci         %11 = OpLabel
3036fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
3037fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %12 %12
3038fd4e5da5Sopenharmony_ci         %13 = OpLabel
3039fd4e5da5Sopenharmony_ci               OpBranch %11
3040fd4e5da5Sopenharmony_ci         %12 = OpLabel
3041fd4e5da5Sopenharmony_ci               OpBranch %9
3042fd4e5da5Sopenharmony_ci         %10 = OpLabel
3043fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3044fd4e5da5Sopenharmony_ci          %9 = OpLabel
3045fd4e5da5Sopenharmony_ci               OpReturn
3046fd4e5da5Sopenharmony_ci               OpFunctionEnd
3047fd4e5da5Sopenharmony_ci  )";
3048fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
3049fd4e5da5Sopenharmony_ci}
3050fd4e5da5Sopenharmony_ci
3051fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
3052fd4e5da5Sopenharmony_ci     UnreachableInnerLoopContinueBranchingToOuterLoopMerge2) {
3053fd4e5da5Sopenharmony_ci  // In this test, the unreachable continue is composed of multiple blocks.
3054fd4e5da5Sopenharmony_ci  std::string shader = R"(
3055fd4e5da5Sopenharmony_ci               OpCapability Shader
3056fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3057fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3058fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3059fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3060fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3061fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3062fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3063fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3064fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3065fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3066fd4e5da5Sopenharmony_ci          %7 = OpLabel
3067fd4e5da5Sopenharmony_ci               OpBranch %8
3068fd4e5da5Sopenharmony_ci          %8 = OpLabel
3069fd4e5da5Sopenharmony_ci               OpLoopMerge %9 %10 None
3070fd4e5da5Sopenharmony_ci               OpBranch %11
3071fd4e5da5Sopenharmony_ci         %11 = OpLabel
3072fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
3073fd4e5da5Sopenharmony_ci               OpBranch %12
3074fd4e5da5Sopenharmony_ci         %13 = OpLabel
3075fd4e5da5Sopenharmony_ci               OpBranch %14
3076fd4e5da5Sopenharmony_ci         %14 = OpLabel
3077fd4e5da5Sopenharmony_ci               OpBranch %11
3078fd4e5da5Sopenharmony_ci         %12 = OpLabel
3079fd4e5da5Sopenharmony_ci               OpBranch %10
3080fd4e5da5Sopenharmony_ci         %10 = OpLabel
3081fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3082fd4e5da5Sopenharmony_ci          %9 = OpLabel
3083fd4e5da5Sopenharmony_ci               OpReturn
3084fd4e5da5Sopenharmony_ci               OpFunctionEnd
3085fd4e5da5Sopenharmony_ci  )";
3086fd4e5da5Sopenharmony_ci
3087fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
3088fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
3089fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
3090fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
3091fd4e5da5Sopenharmony_ci
3092fd4e5da5Sopenharmony_ci  ASSERT_EQ(2, ops.size());
3093fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
3094fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
3095fd4e5da5Sopenharmony_ci
3096fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3097fd4e5da5Sopenharmony_ci
3098fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
3099fd4e5da5Sopenharmony_ci               OpCapability Shader
3100fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3101fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3102fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3103fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3104fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3105fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3106fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3107fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3108fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3109fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3110fd4e5da5Sopenharmony_ci          %7 = OpLabel
3111fd4e5da5Sopenharmony_ci               OpBranch %8
3112fd4e5da5Sopenharmony_ci          %8 = OpLabel
3113fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
3114fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
3115fd4e5da5Sopenharmony_ci         %11 = OpLabel
3116fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
3117fd4e5da5Sopenharmony_ci               OpBranch %12
3118fd4e5da5Sopenharmony_ci         %13 = OpLabel
3119fd4e5da5Sopenharmony_ci               OpBranch %14
3120fd4e5da5Sopenharmony_ci         %14 = OpLabel
3121fd4e5da5Sopenharmony_ci               OpBranch %11
3122fd4e5da5Sopenharmony_ci         %12 = OpLabel
3123fd4e5da5Sopenharmony_ci               OpBranch %9
3124fd4e5da5Sopenharmony_ci         %10 = OpLabel
3125fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3126fd4e5da5Sopenharmony_ci          %9 = OpLabel
3127fd4e5da5Sopenharmony_ci               OpReturn
3128fd4e5da5Sopenharmony_ci               OpFunctionEnd
3129fd4e5da5Sopenharmony_ci  )";
3130fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
3131fd4e5da5Sopenharmony_ci
3132fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
3133fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
3134fd4e5da5Sopenharmony_ci
3135fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3136fd4e5da5Sopenharmony_ci
3137fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
3138fd4e5da5Sopenharmony_ci               OpCapability Shader
3139fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3140fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3141fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3142fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3143fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3144fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3145fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3146fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3147fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3148fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3149fd4e5da5Sopenharmony_ci          %7 = OpLabel
3150fd4e5da5Sopenharmony_ci               OpBranch %8
3151fd4e5da5Sopenharmony_ci          %8 = OpLabel
3152fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
3153fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
3154fd4e5da5Sopenharmony_ci         %11 = OpLabel
3155fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
3156fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %12 %12
3157fd4e5da5Sopenharmony_ci         %13 = OpLabel
3158fd4e5da5Sopenharmony_ci               OpBranch %14
3159fd4e5da5Sopenharmony_ci         %14 = OpLabel
3160fd4e5da5Sopenharmony_ci               OpBranch %11
3161fd4e5da5Sopenharmony_ci         %12 = OpLabel
3162fd4e5da5Sopenharmony_ci               OpBranch %9
3163fd4e5da5Sopenharmony_ci         %10 = OpLabel
3164fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3165fd4e5da5Sopenharmony_ci          %9 = OpLabel
3166fd4e5da5Sopenharmony_ci               OpReturn
3167fd4e5da5Sopenharmony_ci               OpFunctionEnd
3168fd4e5da5Sopenharmony_ci  )";
3169fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
3170fd4e5da5Sopenharmony_ci}
3171fd4e5da5Sopenharmony_ci
3172fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
3173fd4e5da5Sopenharmony_ci     InnerLoopHeaderBranchesToOuterLoopMerge) {
3174fd4e5da5Sopenharmony_ci  std::string shader = R"(
3175fd4e5da5Sopenharmony_ci               OpCapability Shader
3176fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3177fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3178fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3179fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3180fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3181fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3182fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3183fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3184fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3185fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3186fd4e5da5Sopenharmony_ci          %7 = OpLabel
3187fd4e5da5Sopenharmony_ci               OpBranch %8
3188fd4e5da5Sopenharmony_ci          %8 = OpLabel
3189fd4e5da5Sopenharmony_ci               OpLoopMerge %9 %10 None
3190fd4e5da5Sopenharmony_ci               OpBranch %11
3191fd4e5da5Sopenharmony_ci         %11 = OpLabel
3192fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
3193fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %13
3194fd4e5da5Sopenharmony_ci         %13 = OpLabel
3195fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %12
3196fd4e5da5Sopenharmony_ci         %12 = OpLabel
3197fd4e5da5Sopenharmony_ci               OpBranch %10
3198fd4e5da5Sopenharmony_ci         %10 = OpLabel
3199fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3200fd4e5da5Sopenharmony_ci          %9 = OpLabel
3201fd4e5da5Sopenharmony_ci               OpReturn
3202fd4e5da5Sopenharmony_ci               OpFunctionEnd
3203fd4e5da5Sopenharmony_ci  )";
3204fd4e5da5Sopenharmony_ci
3205fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
3206fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
3207fd4e5da5Sopenharmony_ci  auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
3208fd4e5da5Sopenharmony_ci                 .GetAvailableOpportunities(context.get(), 0);
3209fd4e5da5Sopenharmony_ci
3210fd4e5da5Sopenharmony_ci  // We cannot transform the inner loop due to its header jumping straight to
3211fd4e5da5Sopenharmony_ci  // the outer loop merge (the inner loop's merge does not post-dominate its
3212fd4e5da5Sopenharmony_ci  // header).
3213fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
3214fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
3215fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
3216fd4e5da5Sopenharmony_ci
3217fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3218fd4e5da5Sopenharmony_ci
3219fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
3220fd4e5da5Sopenharmony_ci               OpCapability Shader
3221fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3222fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3223fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3224fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3225fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3226fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3227fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3228fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3229fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3230fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3231fd4e5da5Sopenharmony_ci          %7 = OpLabel
3232fd4e5da5Sopenharmony_ci               OpBranch %8
3233fd4e5da5Sopenharmony_ci          %8 = OpLabel
3234fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
3235fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
3236fd4e5da5Sopenharmony_ci         %11 = OpLabel
3237fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %13 None
3238fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %12 %13
3239fd4e5da5Sopenharmony_ci         %13 = OpLabel
3240fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %12
3241fd4e5da5Sopenharmony_ci         %12 = OpLabel
3242fd4e5da5Sopenharmony_ci               OpBranch %9
3243fd4e5da5Sopenharmony_ci         %10 = OpLabel
3244fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3245fd4e5da5Sopenharmony_ci          %9 = OpLabel
3246fd4e5da5Sopenharmony_ci               OpReturn
3247fd4e5da5Sopenharmony_ci               OpFunctionEnd
3248fd4e5da5Sopenharmony_ci  )";
3249fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
3250fd4e5da5Sopenharmony_ci
3251fd4e5da5Sopenharmony_ci  // Now look again for more opportunities.
3252fd4e5da5Sopenharmony_ci  ops = StructuredLoopToSelectionReductionOpportunityFinder()
3253fd4e5da5Sopenharmony_ci            .GetAvailableOpportunities(context.get(), 0);
3254fd4e5da5Sopenharmony_ci
3255fd4e5da5Sopenharmony_ci  // What was the inner loop should now be transformable, as the jump to the
3256fd4e5da5Sopenharmony_ci  // outer loop's merge has been redirected.
3257fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
3258fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
3259fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
3260fd4e5da5Sopenharmony_ci
3261fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3262fd4e5da5Sopenharmony_ci
3263fd4e5da5Sopenharmony_ci  std::string after_another_op_0 = R"(
3264fd4e5da5Sopenharmony_ci               OpCapability Shader
3265fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3266fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3267fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3268fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3269fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3270fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3271fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3272fd4e5da5Sopenharmony_ci          %5 = OpTypeBool
3273fd4e5da5Sopenharmony_ci          %6 = OpConstantTrue %5
3274fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3275fd4e5da5Sopenharmony_ci          %7 = OpLabel
3276fd4e5da5Sopenharmony_ci               OpBranch %8
3277fd4e5da5Sopenharmony_ci          %8 = OpLabel
3278fd4e5da5Sopenharmony_ci               OpSelectionMerge %9 None
3279fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %9
3280fd4e5da5Sopenharmony_ci         %11 = OpLabel
3281fd4e5da5Sopenharmony_ci               OpSelectionMerge %12 None
3282fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %12 %12
3283fd4e5da5Sopenharmony_ci         %13 = OpLabel
3284fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %11 %12
3285fd4e5da5Sopenharmony_ci         %12 = OpLabel
3286fd4e5da5Sopenharmony_ci               OpBranch %9
3287fd4e5da5Sopenharmony_ci         %10 = OpLabel
3288fd4e5da5Sopenharmony_ci               OpBranchConditional %6 %9 %8
3289fd4e5da5Sopenharmony_ci          %9 = OpLabel
3290fd4e5da5Sopenharmony_ci               OpReturn
3291fd4e5da5Sopenharmony_ci               OpFunctionEnd
3292fd4e5da5Sopenharmony_ci  )";
3293fd4e5da5Sopenharmony_ci  CheckEqual(env, after_another_op_0, context.get());
3294fd4e5da5Sopenharmony_ci}
3295fd4e5da5Sopenharmony_ci
3296fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LongAccessChains) {
3297fd4e5da5Sopenharmony_ci  std::string shader = R"(
3298fd4e5da5Sopenharmony_ci               OpCapability Shader
3299fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3300fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3301fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
3302fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
3303fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3304fd4e5da5Sopenharmony_ci          %3 = OpTypeVoid
3305fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %3
3306fd4e5da5Sopenharmony_ci          %5 = OpTypeInt 32 1
3307fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 0
3308fd4e5da5Sopenharmony_ci          %7 = OpConstant %6 5
3309fd4e5da5Sopenharmony_ci          %8 = OpTypeArray %5 %7
3310fd4e5da5Sopenharmony_ci          %9 = OpTypeStruct %8
3311fd4e5da5Sopenharmony_ci         %10 = OpTypeStruct %9 %9
3312fd4e5da5Sopenharmony_ci         %11 = OpConstant %6 2
3313fd4e5da5Sopenharmony_ci         %12 = OpTypeArray %10 %11
3314fd4e5da5Sopenharmony_ci         %13 = OpTypeStruct %12
3315fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Function %13
3316fd4e5da5Sopenharmony_ci         %15 = OpConstant %5 0
3317fd4e5da5Sopenharmony_ci         %16 = OpConstant %5 1
3318fd4e5da5Sopenharmony_ci         %17 = OpConstant %5 2
3319fd4e5da5Sopenharmony_ci         %18 = OpConstant %5 3
3320fd4e5da5Sopenharmony_ci         %19 = OpConstant %5 4
3321fd4e5da5Sopenharmony_ci         %20 = OpConstantComposite %8 %15 %16 %17 %18 %19
3322fd4e5da5Sopenharmony_ci         %21 = OpConstantComposite %9 %20
3323fd4e5da5Sopenharmony_ci         %22 = OpConstant %5 5
3324fd4e5da5Sopenharmony_ci         %23 = OpConstant %5 6
3325fd4e5da5Sopenharmony_ci         %24 = OpConstant %5 7
3326fd4e5da5Sopenharmony_ci         %25 = OpConstant %5 8
3327fd4e5da5Sopenharmony_ci         %26 = OpConstant %5 9
3328fd4e5da5Sopenharmony_ci         %27 = OpConstantComposite %8 %22 %23 %24 %25 %26
3329fd4e5da5Sopenharmony_ci         %28 = OpConstantComposite %9 %27
3330fd4e5da5Sopenharmony_ci         %29 = OpConstantComposite %10 %21 %28
3331fd4e5da5Sopenharmony_ci         %30 = OpConstant %5 10
3332fd4e5da5Sopenharmony_ci         %31 = OpConstant %5 11
3333fd4e5da5Sopenharmony_ci         %32 = OpConstant %5 12
3334fd4e5da5Sopenharmony_ci         %33 = OpConstant %5 13
3335fd4e5da5Sopenharmony_ci         %34 = OpConstant %5 14
3336fd4e5da5Sopenharmony_ci         %35 = OpConstantComposite %8 %30 %31 %32 %33 %34
3337fd4e5da5Sopenharmony_ci         %36 = OpConstantComposite %9 %35
3338fd4e5da5Sopenharmony_ci         %37 = OpConstant %5 15
3339fd4e5da5Sopenharmony_ci         %38 = OpConstant %5 16
3340fd4e5da5Sopenharmony_ci         %39 = OpConstant %5 17
3341fd4e5da5Sopenharmony_ci         %40 = OpConstant %5 18
3342fd4e5da5Sopenharmony_ci         %41 = OpConstant %5 19
3343fd4e5da5Sopenharmony_ci         %42 = OpConstantComposite %8 %37 %38 %39 %40 %41
3344fd4e5da5Sopenharmony_ci         %43 = OpConstantComposite %9 %42
3345fd4e5da5Sopenharmony_ci         %44 = OpConstantComposite %10 %36 %43
3346fd4e5da5Sopenharmony_ci         %45 = OpConstantComposite %12 %29 %44
3347fd4e5da5Sopenharmony_ci         %46 = OpConstantComposite %13 %45
3348fd4e5da5Sopenharmony_ci         %47 = OpTypePointer Function %12
3349fd4e5da5Sopenharmony_ci         %48 = OpTypePointer Function %10
3350fd4e5da5Sopenharmony_ci         %49 = OpTypePointer Function %9
3351fd4e5da5Sopenharmony_ci         %50 = OpTypePointer Function %8
3352fd4e5da5Sopenharmony_ci         %51 = OpTypePointer Function %5
3353fd4e5da5Sopenharmony_ci         %52 = OpTypeBool
3354fd4e5da5Sopenharmony_ci         %53 = OpConstantTrue %52
3355fd4e5da5Sopenharmony_ci          %2 = OpFunction %3 None %4
3356fd4e5da5Sopenharmony_ci         %54 = OpLabel
3357fd4e5da5Sopenharmony_ci         %55 = OpVariable %14 Function
3358fd4e5da5Sopenharmony_ci               OpStore %55 %46
3359fd4e5da5Sopenharmony_ci               OpBranch %56
3360fd4e5da5Sopenharmony_ci         %56 = OpLabel
3361fd4e5da5Sopenharmony_ci               OpLoopMerge %57 %58 None
3362fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %57 %59
3363fd4e5da5Sopenharmony_ci         %59 = OpLabel
3364fd4e5da5Sopenharmony_ci               OpSelectionMerge %60 None
3365fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %61 %57
3366fd4e5da5Sopenharmony_ci         %61 = OpLabel
3367fd4e5da5Sopenharmony_ci         %62 = OpAccessChain %47 %55 %15
3368fd4e5da5Sopenharmony_ci               OpBranch %63
3369fd4e5da5Sopenharmony_ci         %63 = OpLabel
3370fd4e5da5Sopenharmony_ci               OpSelectionMerge %64 None
3371fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %65 %57
3372fd4e5da5Sopenharmony_ci         %65 = OpLabel
3373fd4e5da5Sopenharmony_ci         %66 = OpAccessChain %48 %62 %16
3374fd4e5da5Sopenharmony_ci               OpBranch %67
3375fd4e5da5Sopenharmony_ci         %67 = OpLabel
3376fd4e5da5Sopenharmony_ci               OpSelectionMerge %68 None
3377fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %69 %57
3378fd4e5da5Sopenharmony_ci         %69 = OpLabel
3379fd4e5da5Sopenharmony_ci         %70 = OpAccessChain %49 %66 %16
3380fd4e5da5Sopenharmony_ci               OpBranch %71
3381fd4e5da5Sopenharmony_ci         %71 = OpLabel
3382fd4e5da5Sopenharmony_ci               OpSelectionMerge %72 None
3383fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %73 %57
3384fd4e5da5Sopenharmony_ci         %73 = OpLabel
3385fd4e5da5Sopenharmony_ci         %74 = OpAccessChain %50 %70 %15
3386fd4e5da5Sopenharmony_ci               OpBranch %75
3387fd4e5da5Sopenharmony_ci         %75 = OpLabel
3388fd4e5da5Sopenharmony_ci               OpSelectionMerge %76 None
3389fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %77 %57
3390fd4e5da5Sopenharmony_ci         %77 = OpLabel
3391fd4e5da5Sopenharmony_ci         %78 = OpAccessChain %51 %74 %17
3392fd4e5da5Sopenharmony_ci               OpBranch %79
3393fd4e5da5Sopenharmony_ci         %79 = OpLabel
3394fd4e5da5Sopenharmony_ci               OpSelectionMerge %80 None
3395fd4e5da5Sopenharmony_ci               OpBranchConditional %53 %81 %57
3396fd4e5da5Sopenharmony_ci         %81 = OpLabel
3397fd4e5da5Sopenharmony_ci         %82 = OpLoad %5 %78
3398fd4e5da5Sopenharmony_ci               OpBranch %80
3399fd4e5da5Sopenharmony_ci         %80 = OpLabel
3400fd4e5da5Sopenharmony_ci               OpBranch %76
3401fd4e5da5Sopenharmony_ci         %76 = OpLabel
3402fd4e5da5Sopenharmony_ci               OpBranch %72
3403fd4e5da5Sopenharmony_ci         %72 = OpLabel
3404fd4e5da5Sopenharmony_ci               OpBranch %68
3405fd4e5da5Sopenharmony_ci         %68 = OpLabel
3406fd4e5da5Sopenharmony_ci               OpBranch %64
3407fd4e5da5Sopenharmony_ci         %64 = OpLabel
3408fd4e5da5Sopenharmony_ci               OpBranch %60
3409fd4e5da5Sopenharmony_ci         %60 = OpLabel
3410fd4e5da5Sopenharmony_ci               OpBranch %58
3411fd4e5da5Sopenharmony_ci         %58 = OpLabel
3412fd4e5da5Sopenharmony_ci               OpBranch %56
3413fd4e5da5Sopenharmony_ci         %57 = OpLabel
3414fd4e5da5Sopenharmony_ci               OpReturn
3415fd4e5da5Sopenharmony_ci               OpFunctionEnd
3416fd4e5da5Sopenharmony_ci  )";
3417fd4e5da5Sopenharmony_ci
3418fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
3419fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
3420fd4e5da5Sopenharmony_ci  auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
3421fd4e5da5Sopenharmony_ci                 .GetAvailableOpportunities(context.get(), 0);
3422fd4e5da5Sopenharmony_ci
3423fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
3424fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
3425fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
3426fd4e5da5Sopenharmony_ci
3427fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3428fd4e5da5Sopenharmony_ci
3429fd4e5da5Sopenharmony_ci  // TODO(2183): When we have a more general solution for handling access
3430fd4e5da5Sopenharmony_ci  // chains, write an expected result for this test.
3431fd4e5da5Sopenharmony_ci  // std::string expected = R"(
3432fd4e5da5Sopenharmony_ci  // Expected text for transformed shader
3433fd4e5da5Sopenharmony_ci  //)";
3434fd4e5da5Sopenharmony_ci  // CheckEqual(env, expected, context.get());
3435fd4e5da5Sopenharmony_ci}
3436fd4e5da5Sopenharmony_ci
3437fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShaderWithOpDecorate) {
3438fd4e5da5Sopenharmony_ci  // A shader containing a function that contains a loop and some definitions
3439fd4e5da5Sopenharmony_ci  // that are "used" in OpDecorate instructions (outside the function). These
3440fd4e5da5Sopenharmony_ci  // "uses" were causing segfaults because we try to calculate their dominance
3441fd4e5da5Sopenharmony_ci  // information, which doesn't make sense.
3442fd4e5da5Sopenharmony_ci
3443fd4e5da5Sopenharmony_ci  std::string shader = R"(
3444fd4e5da5Sopenharmony_ci               OpCapability Shader
3445fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3446fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3447fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %9
3448fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
3449fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3450fd4e5da5Sopenharmony_ci               OpName %4 "main"
3451fd4e5da5Sopenharmony_ci               OpName %9 "_GLF_color"
3452fd4e5da5Sopenharmony_ci               OpName %14 "buf0"
3453fd4e5da5Sopenharmony_ci               OpMemberName %14 0 "a"
3454fd4e5da5Sopenharmony_ci               OpName %16 ""
3455fd4e5da5Sopenharmony_ci               OpDecorate %9 RelaxedPrecision
3456fd4e5da5Sopenharmony_ci               OpDecorate %9 Location 0
3457fd4e5da5Sopenharmony_ci               OpMemberDecorate %14 0 RelaxedPrecision
3458fd4e5da5Sopenharmony_ci               OpMemberDecorate %14 0 Offset 0
3459fd4e5da5Sopenharmony_ci               OpDecorate %14 Block
3460fd4e5da5Sopenharmony_ci               OpDecorate %16 DescriptorSet 0
3461fd4e5da5Sopenharmony_ci               OpDecorate %16 Binding 0
3462fd4e5da5Sopenharmony_ci               OpDecorate %21 RelaxedPrecision
3463fd4e5da5Sopenharmony_ci               OpDecorate %35 RelaxedPrecision
3464fd4e5da5Sopenharmony_ci               OpDecorate %36 RelaxedPrecision
3465fd4e5da5Sopenharmony_ci               OpDecorate %39 RelaxedPrecision
3466fd4e5da5Sopenharmony_ci               OpDecorate %40 RelaxedPrecision
3467fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
3468fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
3469fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
3470fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
3471fd4e5da5Sopenharmony_ci          %8 = OpTypePointer Output %7
3472fd4e5da5Sopenharmony_ci          %9 = OpVariable %8 Output
3473fd4e5da5Sopenharmony_ci         %10 = OpConstant %6 1
3474fd4e5da5Sopenharmony_ci         %11 = OpConstantComposite %7 %10 %10 %10 %10
3475fd4e5da5Sopenharmony_ci         %14 = OpTypeStruct %6
3476fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Uniform %14
3477fd4e5da5Sopenharmony_ci         %16 = OpVariable %15 Uniform
3478fd4e5da5Sopenharmony_ci         %17 = OpTypeInt 32 1
3479fd4e5da5Sopenharmony_ci         %18 = OpConstant %17 0
3480fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Uniform %6
3481fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 2
3482fd4e5da5Sopenharmony_ci         %29 = OpTypeBool
3483fd4e5da5Sopenharmony_ci         %31 = OpTypeInt 32 0
3484fd4e5da5Sopenharmony_ci         %32 = OpConstant %31 0
3485fd4e5da5Sopenharmony_ci         %33 = OpTypePointer Output %6
3486fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
3487fd4e5da5Sopenharmony_ci          %5 = OpLabel
3488fd4e5da5Sopenharmony_ci               OpStore %9 %11
3489fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %19 %16 %18
3490fd4e5da5Sopenharmony_ci         %21 = OpLoad %6 %20
3491fd4e5da5Sopenharmony_ci               OpBranch %22
3492fd4e5da5Sopenharmony_ci         %22 = OpLabel
3493fd4e5da5Sopenharmony_ci         %40 = OpPhi %6 %21 %5 %39 %23
3494fd4e5da5Sopenharmony_ci         %30 = OpFOrdLessThan %29 %40 %28
3495fd4e5da5Sopenharmony_ci               OpLoopMerge %24 %23 None
3496fd4e5da5Sopenharmony_ci               OpBranchConditional %30 %23 %24
3497fd4e5da5Sopenharmony_ci         %23 = OpLabel
3498fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %33 %9 %32
3499fd4e5da5Sopenharmony_ci         %35 = OpLoad %6 %34
3500fd4e5da5Sopenharmony_ci         %36 = OpFAdd %6 %35 %10
3501fd4e5da5Sopenharmony_ci               OpStore %34 %36
3502fd4e5da5Sopenharmony_ci         %39 = OpFAdd %6 %40 %10
3503fd4e5da5Sopenharmony_ci               OpBranch %22
3504fd4e5da5Sopenharmony_ci         %24 = OpLabel
3505fd4e5da5Sopenharmony_ci               OpReturn
3506fd4e5da5Sopenharmony_ci               OpFunctionEnd
3507fd4e5da5Sopenharmony_ci  )";
3508fd4e5da5Sopenharmony_ci
3509fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
3510fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
3511fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
3512fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
3513fd4e5da5Sopenharmony_ci  ASSERT_EQ(1, ops.size());
3514fd4e5da5Sopenharmony_ci
3515fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
3516fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
3517fd4e5da5Sopenharmony_ci  CheckValid(env, context.get());
3518fd4e5da5Sopenharmony_ci
3519fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
3520fd4e5da5Sopenharmony_ci               OpCapability Shader
3521fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3522fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3523fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %9
3524fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
3525fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3526fd4e5da5Sopenharmony_ci               OpName %4 "main"
3527fd4e5da5Sopenharmony_ci               OpName %9 "_GLF_color"
3528fd4e5da5Sopenharmony_ci               OpName %14 "buf0"
3529fd4e5da5Sopenharmony_ci               OpMemberName %14 0 "a"
3530fd4e5da5Sopenharmony_ci               OpName %16 ""
3531fd4e5da5Sopenharmony_ci               OpDecorate %9 RelaxedPrecision
3532fd4e5da5Sopenharmony_ci               OpDecorate %9 Location 0
3533fd4e5da5Sopenharmony_ci               OpMemberDecorate %14 0 RelaxedPrecision
3534fd4e5da5Sopenharmony_ci               OpMemberDecorate %14 0 Offset 0
3535fd4e5da5Sopenharmony_ci               OpDecorate %14 Block
3536fd4e5da5Sopenharmony_ci               OpDecorate %16 DescriptorSet 0
3537fd4e5da5Sopenharmony_ci               OpDecorate %16 Binding 0
3538fd4e5da5Sopenharmony_ci               OpDecorate %21 RelaxedPrecision
3539fd4e5da5Sopenharmony_ci               OpDecorate %35 RelaxedPrecision
3540fd4e5da5Sopenharmony_ci               OpDecorate %36 RelaxedPrecision
3541fd4e5da5Sopenharmony_ci               OpDecorate %39 RelaxedPrecision
3542fd4e5da5Sopenharmony_ci               OpDecorate %40 RelaxedPrecision
3543fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
3544fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
3545fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
3546fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
3547fd4e5da5Sopenharmony_ci          %8 = OpTypePointer Output %7
3548fd4e5da5Sopenharmony_ci          %9 = OpVariable %8 Output
3549fd4e5da5Sopenharmony_ci         %10 = OpConstant %6 1
3550fd4e5da5Sopenharmony_ci         %11 = OpConstantComposite %7 %10 %10 %10 %10
3551fd4e5da5Sopenharmony_ci         %14 = OpTypeStruct %6
3552fd4e5da5Sopenharmony_ci         %15 = OpTypePointer Uniform %14
3553fd4e5da5Sopenharmony_ci         %16 = OpVariable %15 Uniform
3554fd4e5da5Sopenharmony_ci         %17 = OpTypeInt 32 1
3555fd4e5da5Sopenharmony_ci         %18 = OpConstant %17 0
3556fd4e5da5Sopenharmony_ci         %19 = OpTypePointer Uniform %6
3557fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 2
3558fd4e5da5Sopenharmony_ci         %29 = OpTypeBool
3559fd4e5da5Sopenharmony_ci         %31 = OpTypeInt 32 0
3560fd4e5da5Sopenharmony_ci         %32 = OpConstant %31 0
3561fd4e5da5Sopenharmony_ci         %33 = OpTypePointer Output %6
3562fd4e5da5Sopenharmony_ci         %41 = OpUndef %6                          ; Added
3563fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
3564fd4e5da5Sopenharmony_ci          %5 = OpLabel
3565fd4e5da5Sopenharmony_ci               OpStore %9 %11
3566fd4e5da5Sopenharmony_ci         %20 = OpAccessChain %19 %16 %18
3567fd4e5da5Sopenharmony_ci         %21 = OpLoad %6 %20
3568fd4e5da5Sopenharmony_ci               OpBranch %22
3569fd4e5da5Sopenharmony_ci         %22 = OpLabel
3570fd4e5da5Sopenharmony_ci         %40 = OpPhi %6 %21 %5 %41 %23             ; Changed
3571fd4e5da5Sopenharmony_ci         %30 = OpFOrdLessThan %29 %40 %28
3572fd4e5da5Sopenharmony_ci               OpSelectionMerge %24 None           ; Changed
3573fd4e5da5Sopenharmony_ci               OpBranchConditional %30 %24 %24
3574fd4e5da5Sopenharmony_ci         %23 = OpLabel
3575fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %33 %9 %32
3576fd4e5da5Sopenharmony_ci         %35 = OpLoad %6 %34
3577fd4e5da5Sopenharmony_ci         %36 = OpFAdd %6 %35 %10
3578fd4e5da5Sopenharmony_ci               OpStore %34 %36
3579fd4e5da5Sopenharmony_ci         %39 = OpFAdd %6 %41 %10                   ; Changed
3580fd4e5da5Sopenharmony_ci               OpBranch %22
3581fd4e5da5Sopenharmony_ci         %24 = OpLabel
3582fd4e5da5Sopenharmony_ci               OpReturn
3583fd4e5da5Sopenharmony_ci               OpFunctionEnd
3584fd4e5da5Sopenharmony_ci  )";
3585fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
3586fd4e5da5Sopenharmony_ci}
3587fd4e5da5Sopenharmony_ci
3588fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest,
3589fd4e5da5Sopenharmony_ci     LoopWithCombinedHeaderAndContinue) {
3590fd4e5da5Sopenharmony_ci  // A shader containing a loop where the header is also the continue target.
3591fd4e5da5Sopenharmony_ci  // For now, we don't simplify such loops.
3592fd4e5da5Sopenharmony_ci
3593fd4e5da5Sopenharmony_ci  std::string shader = R"(
3594fd4e5da5Sopenharmony_ci               OpCapability Shader
3595fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
3596fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
3597fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
3598fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
3599fd4e5da5Sopenharmony_ci               OpSource ESSL 310
3600fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
3601fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
3602fd4e5da5Sopenharmony_ci          %6 = OpTypeBool
3603fd4e5da5Sopenharmony_ci         %30 = OpConstantFalse %6
3604fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
3605fd4e5da5Sopenharmony_ci          %5 = OpLabel
3606fd4e5da5Sopenharmony_ci               OpBranch %10
3607fd4e5da5Sopenharmony_ci         %10 = OpLabel                       ; loop header and continue target
3608fd4e5da5Sopenharmony_ci               OpLoopMerge %12 %10 None
3609fd4e5da5Sopenharmony_ci               OpBranchConditional %30 %10 %12
3610fd4e5da5Sopenharmony_ci         %12 = OpLabel
3611fd4e5da5Sopenharmony_ci               OpReturn
3612fd4e5da5Sopenharmony_ci               OpFunctionEnd
3613fd4e5da5Sopenharmony_ci  )";
3614fd4e5da5Sopenharmony_ci
3615fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
3616fd4e5da5Sopenharmony_ci  const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
3617fd4e5da5Sopenharmony_ci  const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
3618fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
3619fd4e5da5Sopenharmony_ci  ASSERT_EQ(0, ops.size());
3620fd4e5da5Sopenharmony_ci}
3621fd4e5da5Sopenharmony_ci
3622fd4e5da5Sopenharmony_ci}  // namespace
3623fd4e5da5Sopenharmony_ci}  // namespace reduce
3624fd4e5da5Sopenharmony_ci}  // namespace spvtools
3625