1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 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 <string>
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
18fd4e5da5Sopenharmony_ci#include "gtest/gtest.h"
19fd4e5da5Sopenharmony_ci#include "source/opt/ir_context.h"
20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
22fd4e5da5Sopenharmony_ci
23fd4e5da5Sopenharmony_cinamespace spvtools {
24fd4e5da5Sopenharmony_cinamespace opt {
25fd4e5da5Sopenharmony_cinamespace {
26fd4e5da5Sopenharmony_ci
27fd4e5da5Sopenharmony_ciusing ::testing::ContainerEq;
28fd4e5da5Sopenharmony_ci
29fd4e5da5Sopenharmony_ciusing CFGTest = PassTest<::testing::Test>;
30fd4e5da5Sopenharmony_ci
31fd4e5da5Sopenharmony_ciTEST_F(CFGTest, ForEachBlockInPostOrderIf) {
32fd4e5da5Sopenharmony_ci  const std::string test = R"(
33fd4e5da5Sopenharmony_ciOpCapability Shader
34fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
35fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
36fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
37fd4e5da5Sopenharmony_ciOpName %main "main"
38fd4e5da5Sopenharmony_ci%bool = OpTypeBool
39fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
40fd4e5da5Sopenharmony_ci%void = OpTypeVoid
41fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
42fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
43fd4e5da5Sopenharmony_ci%5 = OpConstant %uint 5
44fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4
45fd4e5da5Sopenharmony_ci%8 = OpLabel
46fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None
47fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %10
48fd4e5da5Sopenharmony_ci%9 = OpLabel
49fd4e5da5Sopenharmony_ciOpBranch %10
50fd4e5da5Sopenharmony_ci%10 = OpLabel
51fd4e5da5Sopenharmony_ciOpReturn
52fd4e5da5Sopenharmony_ciOpFunctionEnd
53fd4e5da5Sopenharmony_ci)";
54fd4e5da5Sopenharmony_ci
55fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
56fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
57fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
58fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
59fd4e5da5Sopenharmony_ci
60fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
61fd4e5da5Sopenharmony_ci  Module* module = context->module();
62fd4e5da5Sopenharmony_ci  Function* function = &*module->begin();
63fd4e5da5Sopenharmony_ci  std::vector<uint32_t> order;
64fd4e5da5Sopenharmony_ci  cfg->ForEachBlockInPostOrder(&*function->begin(), [&order](BasicBlock* bb) {
65fd4e5da5Sopenharmony_ci    order.push_back(bb->id());
66fd4e5da5Sopenharmony_ci  });
67fd4e5da5Sopenharmony_ci
68fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result = {10, 9, 8};
69fd4e5da5Sopenharmony_ci  EXPECT_THAT(order, ContainerEq(expected_result));
70fd4e5da5Sopenharmony_ci}
71fd4e5da5Sopenharmony_ci
72fd4e5da5Sopenharmony_ciTEST_F(CFGTest, ForEachBlockInPostOrderLoop) {
73fd4e5da5Sopenharmony_ci  const std::string test = R"(
74fd4e5da5Sopenharmony_ciOpCapability Shader
75fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
76fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
77fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
78fd4e5da5Sopenharmony_ciOpName %main "main"
79fd4e5da5Sopenharmony_ci%bool = OpTypeBool
80fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
81fd4e5da5Sopenharmony_ci%void = OpTypeVoid
82fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
83fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
84fd4e5da5Sopenharmony_ci%5 = OpConstant %uint 5
85fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4
86fd4e5da5Sopenharmony_ci%8 = OpLabel
87fd4e5da5Sopenharmony_ciOpBranch %9
88fd4e5da5Sopenharmony_ci%9 = OpLabel
89fd4e5da5Sopenharmony_ciOpLoopMerge %11 %10 None
90fd4e5da5Sopenharmony_ciOpBranchConditional %true %11 %10
91fd4e5da5Sopenharmony_ci%10 = OpLabel
92fd4e5da5Sopenharmony_ciOpBranch %9
93fd4e5da5Sopenharmony_ci%11 = OpLabel
94fd4e5da5Sopenharmony_ciOpReturn
95fd4e5da5Sopenharmony_ciOpFunctionEnd
96fd4e5da5Sopenharmony_ci)";
97fd4e5da5Sopenharmony_ci
98fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
99fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
100fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
101fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
102fd4e5da5Sopenharmony_ci
103fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
104fd4e5da5Sopenharmony_ci  Module* module = context->module();
105fd4e5da5Sopenharmony_ci  Function* function = &*module->begin();
106fd4e5da5Sopenharmony_ci  std::vector<uint32_t> order;
107fd4e5da5Sopenharmony_ci  cfg->ForEachBlockInPostOrder(&*function->begin(), [&order](BasicBlock* bb) {
108fd4e5da5Sopenharmony_ci    order.push_back(bb->id());
109fd4e5da5Sopenharmony_ci  });
110fd4e5da5Sopenharmony_ci
111fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result1 = {10, 11, 9, 8};
112fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result2 = {11, 10, 9, 8};
113fd4e5da5Sopenharmony_ci  EXPECT_THAT(order, AnyOf(ContainerEq(expected_result1),
114fd4e5da5Sopenharmony_ci                           ContainerEq(expected_result2)));
115fd4e5da5Sopenharmony_ci}
116fd4e5da5Sopenharmony_ci
117fd4e5da5Sopenharmony_ciTEST_F(CFGTest, ForEachBlockInReversePostOrderIf) {
118fd4e5da5Sopenharmony_ci  const std::string test = R"(
119fd4e5da5Sopenharmony_ciOpCapability Shader
120fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
121fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
122fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
123fd4e5da5Sopenharmony_ciOpName %main "main"
124fd4e5da5Sopenharmony_ci%bool = OpTypeBool
125fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
126fd4e5da5Sopenharmony_ci%void = OpTypeVoid
127fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
128fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
129fd4e5da5Sopenharmony_ci%5 = OpConstant %uint 5
130fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4
131fd4e5da5Sopenharmony_ci%8 = OpLabel
132fd4e5da5Sopenharmony_ciOpSelectionMerge %10 None
133fd4e5da5Sopenharmony_ciOpBranchConditional %true %9 %10
134fd4e5da5Sopenharmony_ci%9 = OpLabel
135fd4e5da5Sopenharmony_ciOpBranch %10
136fd4e5da5Sopenharmony_ci%10 = OpLabel
137fd4e5da5Sopenharmony_ciOpReturn
138fd4e5da5Sopenharmony_ciOpFunctionEnd
139fd4e5da5Sopenharmony_ci)";
140fd4e5da5Sopenharmony_ci
141fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
142fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
143fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
144fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
145fd4e5da5Sopenharmony_ci
146fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
147fd4e5da5Sopenharmony_ci  Module* module = context->module();
148fd4e5da5Sopenharmony_ci  Function* function = &*module->begin();
149fd4e5da5Sopenharmony_ci  std::vector<uint32_t> order;
150fd4e5da5Sopenharmony_ci  cfg->ForEachBlockInReversePostOrder(
151fd4e5da5Sopenharmony_ci      &*function->begin(),
152fd4e5da5Sopenharmony_ci      [&order](BasicBlock* bb) { order.push_back(bb->id()); });
153fd4e5da5Sopenharmony_ci
154fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result = {8, 9, 10};
155fd4e5da5Sopenharmony_ci  EXPECT_THAT(order, ContainerEq(expected_result));
156fd4e5da5Sopenharmony_ci}
157fd4e5da5Sopenharmony_ci
158fd4e5da5Sopenharmony_ciTEST_F(CFGTest, ForEachBlockInReversePostOrderLoop) {
159fd4e5da5Sopenharmony_ci  const std::string test = R"(
160fd4e5da5Sopenharmony_ciOpCapability Shader
161fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
162fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
163fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
164fd4e5da5Sopenharmony_ciOpName %main "main"
165fd4e5da5Sopenharmony_ci%bool = OpTypeBool
166fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
167fd4e5da5Sopenharmony_ci%void = OpTypeVoid
168fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
169fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
170fd4e5da5Sopenharmony_ci%5 = OpConstant %uint 5
171fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4
172fd4e5da5Sopenharmony_ci%8 = OpLabel
173fd4e5da5Sopenharmony_ciOpBranch %9
174fd4e5da5Sopenharmony_ci%9 = OpLabel
175fd4e5da5Sopenharmony_ciOpLoopMerge %11 %10 None
176fd4e5da5Sopenharmony_ciOpBranchConditional %true %11 %10
177fd4e5da5Sopenharmony_ci%10 = OpLabel
178fd4e5da5Sopenharmony_ciOpBranch %9
179fd4e5da5Sopenharmony_ci%11 = OpLabel
180fd4e5da5Sopenharmony_ciOpReturn
181fd4e5da5Sopenharmony_ciOpFunctionEnd
182fd4e5da5Sopenharmony_ci)";
183fd4e5da5Sopenharmony_ci
184fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
185fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
186fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
187fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
188fd4e5da5Sopenharmony_ci
189fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
190fd4e5da5Sopenharmony_ci  Module* module = context->module();
191fd4e5da5Sopenharmony_ci  Function* function = &*module->begin();
192fd4e5da5Sopenharmony_ci  std::vector<uint32_t> order;
193fd4e5da5Sopenharmony_ci  cfg->ForEachBlockInReversePostOrder(
194fd4e5da5Sopenharmony_ci      &*function->begin(),
195fd4e5da5Sopenharmony_ci      [&order](BasicBlock* bb) { order.push_back(bb->id()); });
196fd4e5da5Sopenharmony_ci
197fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result1 = {8, 9, 10, 11};
198fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_result2 = {8, 9, 11, 10};
199fd4e5da5Sopenharmony_ci  EXPECT_THAT(order, AnyOf(ContainerEq(expected_result1),
200fd4e5da5Sopenharmony_ci                           ContainerEq(expected_result2)));
201fd4e5da5Sopenharmony_ci}
202fd4e5da5Sopenharmony_ci
203fd4e5da5Sopenharmony_ciTEST_F(CFGTest, SplitLoopHeaderForSingleBlockLoop) {
204fd4e5da5Sopenharmony_ci  const std::string test = R"(
205fd4e5da5Sopenharmony_ci               OpCapability Shader
206fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
207fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
208fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
209fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
210fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
211fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
212fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
213fd4e5da5Sopenharmony_ci          %6 = OpTypeFunction %void
214fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %6
215fd4e5da5Sopenharmony_ci          %7 = OpLabel
216fd4e5da5Sopenharmony_ci               OpBranch %8
217fd4e5da5Sopenharmony_ci          %8 = OpLabel
218fd4e5da5Sopenharmony_ci          %9 = OpPhi %uint %uint_0 %7 %9 %8
219fd4e5da5Sopenharmony_ci               OpLoopMerge %10 %8 None
220fd4e5da5Sopenharmony_ci               OpBranch %8
221fd4e5da5Sopenharmony_ci         %10 = OpLabel
222fd4e5da5Sopenharmony_ci               OpUnreachable
223fd4e5da5Sopenharmony_ci               OpFunctionEnd
224fd4e5da5Sopenharmony_ci)";
225fd4e5da5Sopenharmony_ci
226fd4e5da5Sopenharmony_ci  const std::string expected_result = R"(OpCapability Shader
227fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
228fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
229fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main"
230fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft
231fd4e5da5Sopenharmony_ci%void = OpTypeVoid
232fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
233fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0
234fd4e5da5Sopenharmony_ci%6 = OpTypeFunction %void
235fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %6
236fd4e5da5Sopenharmony_ci%7 = OpLabel
237fd4e5da5Sopenharmony_ciOpBranch %8
238fd4e5da5Sopenharmony_ci%8 = OpLabel
239fd4e5da5Sopenharmony_ciOpBranch %11
240fd4e5da5Sopenharmony_ci%11 = OpLabel
241fd4e5da5Sopenharmony_ci%9 = OpPhi %uint %9 %11 %uint_0 %8
242fd4e5da5Sopenharmony_ciOpLoopMerge %10 %11 None
243fd4e5da5Sopenharmony_ciOpBranch %11
244fd4e5da5Sopenharmony_ci%10 = OpLabel
245fd4e5da5Sopenharmony_ciOpUnreachable
246fd4e5da5Sopenharmony_ciOpFunctionEnd
247fd4e5da5Sopenharmony_ci)";
248fd4e5da5Sopenharmony_ci
249fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
250fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
251fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
252fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
253fd4e5da5Sopenharmony_ci
254fd4e5da5Sopenharmony_ci  BasicBlock* loop_header = context->get_instr_block(8);
255fd4e5da5Sopenharmony_ci  ASSERT_TRUE(loop_header->GetLoopMergeInst() != nullptr);
256fd4e5da5Sopenharmony_ci
257fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
258fd4e5da5Sopenharmony_ci  cfg->SplitLoopHeader(loop_header);
259fd4e5da5Sopenharmony_ci
260fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
261fd4e5da5Sopenharmony_ci  bool skip_nop = false;
262fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, skip_nop);
263fd4e5da5Sopenharmony_ci
264fd4e5da5Sopenharmony_ci  std::string optimized_asm;
265fd4e5da5Sopenharmony_ci  SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
266fd4e5da5Sopenharmony_ci  EXPECT_TRUE(tools.Disassemble(binary, &optimized_asm,
267fd4e5da5Sopenharmony_ci                                SpirvTools::kDefaultDisassembleOption))
268fd4e5da5Sopenharmony_ci      << "Disassembling failed for shader\n"
269fd4e5da5Sopenharmony_ci      << std::endl;
270fd4e5da5Sopenharmony_ci
271fd4e5da5Sopenharmony_ci  EXPECT_EQ(optimized_asm, expected_result);
272fd4e5da5Sopenharmony_ci}
273fd4e5da5Sopenharmony_ci
274fd4e5da5Sopenharmony_ciTEST_F(CFGTest, ComputeStructedOrderForLoop) {
275fd4e5da5Sopenharmony_ci  const std::string test = R"(
276fd4e5da5Sopenharmony_ciOpCapability Shader
277fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
278fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
279fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
280fd4e5da5Sopenharmony_ciOpName %main "main"
281fd4e5da5Sopenharmony_ci%bool = OpTypeBool
282fd4e5da5Sopenharmony_ci%true = OpConstantTrue %bool
283fd4e5da5Sopenharmony_ci%void = OpTypeVoid
284fd4e5da5Sopenharmony_ci%4 = OpTypeFunction %void
285fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
286fd4e5da5Sopenharmony_ci%5 = OpConstant %uint 5
287fd4e5da5Sopenharmony_ci%main = OpFunction %void None %4
288fd4e5da5Sopenharmony_ci%8 = OpLabel
289fd4e5da5Sopenharmony_ciOpBranch %9
290fd4e5da5Sopenharmony_ci%9 = OpLabel
291fd4e5da5Sopenharmony_ciOpLoopMerge %11 %10 None
292fd4e5da5Sopenharmony_ciOpBranchConditional %true %11 %10
293fd4e5da5Sopenharmony_ci%10 = OpLabel
294fd4e5da5Sopenharmony_ciOpBranch %9
295fd4e5da5Sopenharmony_ci%11 = OpLabel
296fd4e5da5Sopenharmony_ciOpBranch %12
297fd4e5da5Sopenharmony_ci%12 = OpLabel
298fd4e5da5Sopenharmony_ciOpReturn
299fd4e5da5Sopenharmony_ciOpFunctionEnd
300fd4e5da5Sopenharmony_ci)";
301fd4e5da5Sopenharmony_ci
302fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
303fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, test,
304fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
305fd4e5da5Sopenharmony_ci  ASSERT_NE(nullptr, context);
306fd4e5da5Sopenharmony_ci
307fd4e5da5Sopenharmony_ci  CFG* cfg = context->cfg();
308fd4e5da5Sopenharmony_ci  Module* module = context->module();
309fd4e5da5Sopenharmony_ci  Function* function = &*module->begin();
310fd4e5da5Sopenharmony_ci  std::list<BasicBlock*> order;
311fd4e5da5Sopenharmony_ci  cfg->ComputeStructuredOrder(function, context->get_instr_block(9),
312fd4e5da5Sopenharmony_ci                              context->get_instr_block(11), &order);
313fd4e5da5Sopenharmony_ci
314fd4e5da5Sopenharmony_ci  // Order should contain the loop header, the continue target, and the merge
315fd4e5da5Sopenharmony_ci  // node.
316fd4e5da5Sopenharmony_ci  std::list<BasicBlock*> expected_result = {context->get_instr_block(9),
317fd4e5da5Sopenharmony_ci                                            context->get_instr_block(10),
318fd4e5da5Sopenharmony_ci                                            context->get_instr_block(11)};
319fd4e5da5Sopenharmony_ci  EXPECT_THAT(order, ContainerEq(expected_result));
320fd4e5da5Sopenharmony_ci}
321fd4e5da5Sopenharmony_ci
322fd4e5da5Sopenharmony_ci}  // namespace
323fd4e5da5Sopenharmony_ci}  // namespace opt
324fd4e5da5Sopenharmony_ci}  // namespace spvtools
325