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 <memory>
16fd4e5da5Sopenharmony_ci#include <unordered_set>
17fd4e5da5Sopenharmony_ci#include <vector>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
20fd4e5da5Sopenharmony_ci#include "source/opt/register_pressure.h"
21fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h"
22fd4e5da5Sopenharmony_ci#include "test/opt/function_utils.h"
23fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
24fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
25fd4e5da5Sopenharmony_ci
26fd4e5da5Sopenharmony_cinamespace spvtools {
27fd4e5da5Sopenharmony_cinamespace opt {
28fd4e5da5Sopenharmony_cinamespace {
29fd4e5da5Sopenharmony_ci
30fd4e5da5Sopenharmony_ciusing ::testing::UnorderedElementsAre;
31fd4e5da5Sopenharmony_ciusing PassClassTest = PassTest<::testing::Test>;
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_civoid CompareSets(const std::unordered_set<Instruction*>& computed,
34fd4e5da5Sopenharmony_ci                 const std::unordered_set<uint32_t>& expected) {
35fd4e5da5Sopenharmony_ci  for (Instruction* insn : computed) {
36fd4e5da5Sopenharmony_ci    EXPECT_TRUE(expected.count(insn->result_id()))
37fd4e5da5Sopenharmony_ci        << "Unexpected instruction in live set: " << *insn;
38fd4e5da5Sopenharmony_ci  }
39fd4e5da5Sopenharmony_ci  EXPECT_EQ(computed.size(), expected.size());
40fd4e5da5Sopenharmony_ci}
41fd4e5da5Sopenharmony_ci
42fd4e5da5Sopenharmony_ci/*
43fd4e5da5Sopenharmony_ciGenerated from the following GLSL
44fd4e5da5Sopenharmony_ci
45fd4e5da5Sopenharmony_ci#version 330
46fd4e5da5Sopenharmony_ciin vec4 BaseColor;
47fd4e5da5Sopenharmony_ciflat in int Count;
48fd4e5da5Sopenharmony_civoid main()
49fd4e5da5Sopenharmony_ci{
50fd4e5da5Sopenharmony_ci  vec4 color = BaseColor;
51fd4e5da5Sopenharmony_ci  vec4 acc;
52fd4e5da5Sopenharmony_ci  if (Count == 0) {
53fd4e5da5Sopenharmony_ci    acc = color;
54fd4e5da5Sopenharmony_ci  }
55fd4e5da5Sopenharmony_ci  else {
56fd4e5da5Sopenharmony_ci    acc = color + vec4(0,1,2,0);
57fd4e5da5Sopenharmony_ci  }
58fd4e5da5Sopenharmony_ci  gl_FragColor = acc + color;
59fd4e5da5Sopenharmony_ci}
60fd4e5da5Sopenharmony_ci*/
61fd4e5da5Sopenharmony_ciTEST_F(PassClassTest, LivenessWithIf) {
62fd4e5da5Sopenharmony_ci  const std::string text = R"(
63fd4e5da5Sopenharmony_ci               OpCapability Shader
64fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
65fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
66fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %11 %15 %32
67fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginLowerLeft
68fd4e5da5Sopenharmony_ci               OpSource GLSL 330
69fd4e5da5Sopenharmony_ci               OpName %4 "main"
70fd4e5da5Sopenharmony_ci               OpName %11 "BaseColor"
71fd4e5da5Sopenharmony_ci               OpName %15 "Count"
72fd4e5da5Sopenharmony_ci               OpName %32 "gl_FragColor"
73fd4e5da5Sopenharmony_ci               OpDecorate %11 Location 0
74fd4e5da5Sopenharmony_ci               OpDecorate %15 Flat
75fd4e5da5Sopenharmony_ci               OpDecorate %15 Location 0
76fd4e5da5Sopenharmony_ci               OpDecorate %32 Location 0
77fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
78fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
79fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
80fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
81fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Input %7
82fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Input
83fd4e5da5Sopenharmony_ci         %13 = OpTypeInt 32 1
84fd4e5da5Sopenharmony_ci         %14 = OpTypePointer Input %13
85fd4e5da5Sopenharmony_ci         %15 = OpVariable %14 Input
86fd4e5da5Sopenharmony_ci         %17 = OpConstant %13 0
87fd4e5da5Sopenharmony_ci         %18 = OpTypeBool
88fd4e5da5Sopenharmony_ci         %26 = OpConstant %6 0
89fd4e5da5Sopenharmony_ci         %27 = OpConstant %6 1
90fd4e5da5Sopenharmony_ci         %28 = OpConstant %6 2
91fd4e5da5Sopenharmony_ci         %29 = OpConstantComposite %7 %26 %27 %28 %26
92fd4e5da5Sopenharmony_ci         %31 = OpTypePointer Output %7
93fd4e5da5Sopenharmony_ci         %32 = OpVariable %31 Output
94fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
95fd4e5da5Sopenharmony_ci          %5 = OpLabel
96fd4e5da5Sopenharmony_ci         %12 = OpLoad %7 %11
97fd4e5da5Sopenharmony_ci         %16 = OpLoad %13 %15
98fd4e5da5Sopenharmony_ci         %19 = OpIEqual %18 %16 %17
99fd4e5da5Sopenharmony_ci               OpSelectionMerge %21 None
100fd4e5da5Sopenharmony_ci               OpBranchConditional %19 %20 %24
101fd4e5da5Sopenharmony_ci         %20 = OpLabel
102fd4e5da5Sopenharmony_ci               OpBranch %21
103fd4e5da5Sopenharmony_ci         %24 = OpLabel
104fd4e5da5Sopenharmony_ci         %30 = OpFAdd %7 %12 %29
105fd4e5da5Sopenharmony_ci               OpBranch %21
106fd4e5da5Sopenharmony_ci         %21 = OpLabel
107fd4e5da5Sopenharmony_ci         %36 = OpPhi %7 %12 %20 %30 %24
108fd4e5da5Sopenharmony_ci         %35 = OpFAdd %7 %36 %12
109fd4e5da5Sopenharmony_ci               OpStore %32 %35
110fd4e5da5Sopenharmony_ci               OpReturn
111fd4e5da5Sopenharmony_ci               OpFunctionEnd
112fd4e5da5Sopenharmony_ci  )";
113fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
114fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
115fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
116fd4e5da5Sopenharmony_ci  Module* module = context->module();
117fd4e5da5Sopenharmony_ci  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
118fd4e5da5Sopenharmony_ci                             << text << std::endl;
119fd4e5da5Sopenharmony_ci  Function* f = &*module->begin();
120fd4e5da5Sopenharmony_ci  LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
121fd4e5da5Sopenharmony_ci  const RegisterLiveness* register_liveness = liveness_analysis->Get(f);
122fd4e5da5Sopenharmony_ci  {
123fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 5");
124fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(5);
125fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
126fd4e5da5Sopenharmony_ci        11,  // %11 = OpVariable %10 Input
127fd4e5da5Sopenharmony_ci        15,  // %15 = OpVariable %14 Input
128fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
129fd4e5da5Sopenharmony_ci    };
130fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
131fd4e5da5Sopenharmony_ci
132fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
133fd4e5da5Sopenharmony_ci        12,  // %12 = OpLoad %7 %11
134fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
135fd4e5da5Sopenharmony_ci    };
136fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
137fd4e5da5Sopenharmony_ci  }
138fd4e5da5Sopenharmony_ci  {
139fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 20");
140fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(20);
141fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
142fd4e5da5Sopenharmony_ci        12,  // %12 = OpLoad %7 %11
143fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
144fd4e5da5Sopenharmony_ci    };
145fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
146fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
147fd4e5da5Sopenharmony_ci  }
148fd4e5da5Sopenharmony_ci  {
149fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 24");
150fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(24);
151fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
152fd4e5da5Sopenharmony_ci        12,  // %12 = OpLoad %7 %11
153fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
154fd4e5da5Sopenharmony_ci    };
155fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
156fd4e5da5Sopenharmony_ci
157fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
158fd4e5da5Sopenharmony_ci        12,  // %12 = OpLoad %7 %11
159fd4e5da5Sopenharmony_ci        30,  // %30 = OpFAdd %7 %12 %29
160fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
161fd4e5da5Sopenharmony_ci    };
162fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
163fd4e5da5Sopenharmony_ci  }
164fd4e5da5Sopenharmony_ci  {
165fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 21");
166fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(21);
167fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
168fd4e5da5Sopenharmony_ci        12,  // %12 = OpLoad %7 %11
169fd4e5da5Sopenharmony_ci        32,  // %32 = OpVariable %31 Output
170fd4e5da5Sopenharmony_ci        36,  // %36 = OpPhi %7 %12 %20 %30 %24
171fd4e5da5Sopenharmony_ci    };
172fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
173fd4e5da5Sopenharmony_ci
174fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{};
175fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
176fd4e5da5Sopenharmony_ci  }
177fd4e5da5Sopenharmony_ci}
178fd4e5da5Sopenharmony_ci
179fd4e5da5Sopenharmony_ci/*
180fd4e5da5Sopenharmony_ciGenerated from the following GLSL
181fd4e5da5Sopenharmony_ci#version 330
182fd4e5da5Sopenharmony_ciin vec4 bigColor;
183fd4e5da5Sopenharmony_ciin vec4 BaseColor;
184fd4e5da5Sopenharmony_ciin float f;
185fd4e5da5Sopenharmony_ciflat in int Count;
186fd4e5da5Sopenharmony_ciflat in uvec4 v4;
187fd4e5da5Sopenharmony_civoid main()
188fd4e5da5Sopenharmony_ci{
189fd4e5da5Sopenharmony_ci    vec4 color = BaseColor;
190fd4e5da5Sopenharmony_ci    for (int i = 0; i < Count; ++i)
191fd4e5da5Sopenharmony_ci        color += bigColor;
192fd4e5da5Sopenharmony_ci    float sum = 0.0;
193fd4e5da5Sopenharmony_ci    for (int i = 0; i < 4; ++i) {
194fd4e5da5Sopenharmony_ci      float acc = 0.0;
195fd4e5da5Sopenharmony_ci      if (sum == 0.0) {
196fd4e5da5Sopenharmony_ci        acc = v4[i];
197fd4e5da5Sopenharmony_ci      }
198fd4e5da5Sopenharmony_ci      else {
199fd4e5da5Sopenharmony_ci        acc = BaseColor[i];
200fd4e5da5Sopenharmony_ci      }
201fd4e5da5Sopenharmony_ci      sum += acc + v4[i];
202fd4e5da5Sopenharmony_ci    }
203fd4e5da5Sopenharmony_ci    vec4 tv4;
204fd4e5da5Sopenharmony_ci    for (int i = 0; i < 4; ++i)
205fd4e5da5Sopenharmony_ci        tv4[i] = v4[i] * 4u;
206fd4e5da5Sopenharmony_ci    color += vec4(sum) + tv4;
207fd4e5da5Sopenharmony_ci    vec4 r;
208fd4e5da5Sopenharmony_ci    r.xyz = BaseColor.xyz;
209fd4e5da5Sopenharmony_ci    for (int i = 0; i < Count; ++i)
210fd4e5da5Sopenharmony_ci        r.w = f;
211fd4e5da5Sopenharmony_ci    color.xyz += r.xyz;
212fd4e5da5Sopenharmony_ci    for (int i = 0; i < 16; i += 4)
213fd4e5da5Sopenharmony_ci      for (int j = 0; j < 4; j++)
214fd4e5da5Sopenharmony_ci        color *= f;
215fd4e5da5Sopenharmony_ci    gl_FragColor = color + tv4;
216fd4e5da5Sopenharmony_ci}
217fd4e5da5Sopenharmony_ci*/
218fd4e5da5Sopenharmony_ciTEST_F(PassClassTest, RegisterLiveness) {
219fd4e5da5Sopenharmony_ci  const std::string text = R"(
220fd4e5da5Sopenharmony_ci               OpCapability Shader
221fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
222fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
223fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main" %11 %24 %28 %55 %124 %176
224fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginLowerLeft
225fd4e5da5Sopenharmony_ci               OpSource GLSL 330
226fd4e5da5Sopenharmony_ci               OpName %4 "main"
227fd4e5da5Sopenharmony_ci               OpName %11 "BaseColor"
228fd4e5da5Sopenharmony_ci               OpName %24 "Count"
229fd4e5da5Sopenharmony_ci               OpName %28 "bigColor"
230fd4e5da5Sopenharmony_ci               OpName %55 "v4"
231fd4e5da5Sopenharmony_ci               OpName %84 "tv4"
232fd4e5da5Sopenharmony_ci               OpName %124 "f"
233fd4e5da5Sopenharmony_ci               OpName %176 "gl_FragColor"
234fd4e5da5Sopenharmony_ci               OpDecorate %11 Location 0
235fd4e5da5Sopenharmony_ci               OpDecorate %24 Flat
236fd4e5da5Sopenharmony_ci               OpDecorate %24 Location 0
237fd4e5da5Sopenharmony_ci               OpDecorate %28 Location 0
238fd4e5da5Sopenharmony_ci               OpDecorate %55 Flat
239fd4e5da5Sopenharmony_ci               OpDecorate %55 Location 0
240fd4e5da5Sopenharmony_ci               OpDecorate %124 Location 0
241fd4e5da5Sopenharmony_ci               OpDecorate %176 Location 0
242fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
243fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
244fd4e5da5Sopenharmony_ci          %6 = OpTypeFloat 32
245fd4e5da5Sopenharmony_ci          %7 = OpTypeVector %6 4
246fd4e5da5Sopenharmony_ci          %8 = OpTypePointer Function %7
247fd4e5da5Sopenharmony_ci         %10 = OpTypePointer Input %7
248fd4e5da5Sopenharmony_ci         %11 = OpVariable %10 Input
249fd4e5da5Sopenharmony_ci         %13 = OpTypeInt 32 1
250fd4e5da5Sopenharmony_ci         %16 = OpConstant %13 0
251fd4e5da5Sopenharmony_ci         %23 = OpTypePointer Input %13
252fd4e5da5Sopenharmony_ci         %24 = OpVariable %23 Input
253fd4e5da5Sopenharmony_ci         %26 = OpTypeBool
254fd4e5da5Sopenharmony_ci         %28 = OpVariable %10 Input
255fd4e5da5Sopenharmony_ci         %33 = OpConstant %13 1
256fd4e5da5Sopenharmony_ci         %35 = OpTypePointer Function %6
257fd4e5da5Sopenharmony_ci         %37 = OpConstant %6 0
258fd4e5da5Sopenharmony_ci         %45 = OpConstant %13 4
259fd4e5da5Sopenharmony_ci         %52 = OpTypeInt 32 0
260fd4e5da5Sopenharmony_ci         %53 = OpTypeVector %52 4
261fd4e5da5Sopenharmony_ci         %54 = OpTypePointer Input %53
262fd4e5da5Sopenharmony_ci         %55 = OpVariable %54 Input
263fd4e5da5Sopenharmony_ci         %57 = OpTypePointer Input %52
264fd4e5da5Sopenharmony_ci         %63 = OpTypePointer Input %6
265fd4e5da5Sopenharmony_ci         %89 = OpConstant %52 4
266fd4e5da5Sopenharmony_ci        %102 = OpTypeVector %6 3
267fd4e5da5Sopenharmony_ci        %124 = OpVariable %63 Input
268fd4e5da5Sopenharmony_ci        %158 = OpConstant %13 16
269fd4e5da5Sopenharmony_ci        %175 = OpTypePointer Output %7
270fd4e5da5Sopenharmony_ci        %176 = OpVariable %175 Output
271fd4e5da5Sopenharmony_ci        %195 = OpUndef %7
272fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
273fd4e5da5Sopenharmony_ci          %5 = OpLabel
274fd4e5da5Sopenharmony_ci         %84 = OpVariable %8 Function
275fd4e5da5Sopenharmony_ci         %12 = OpLoad %7 %11
276fd4e5da5Sopenharmony_ci               OpBranch %17
277fd4e5da5Sopenharmony_ci         %17 = OpLabel
278fd4e5da5Sopenharmony_ci        %191 = OpPhi %7 %12 %5 %31 %18
279fd4e5da5Sopenharmony_ci        %184 = OpPhi %13 %16 %5 %34 %18
280fd4e5da5Sopenharmony_ci         %25 = OpLoad %13 %24
281fd4e5da5Sopenharmony_ci         %27 = OpSLessThan %26 %184 %25
282fd4e5da5Sopenharmony_ci               OpLoopMerge %19 %18 None
283fd4e5da5Sopenharmony_ci               OpBranchConditional %27 %18 %19
284fd4e5da5Sopenharmony_ci         %18 = OpLabel
285fd4e5da5Sopenharmony_ci         %29 = OpLoad %7 %28
286fd4e5da5Sopenharmony_ci         %31 = OpFAdd %7 %191 %29
287fd4e5da5Sopenharmony_ci         %34 = OpIAdd %13 %184 %33
288fd4e5da5Sopenharmony_ci               OpBranch %17
289fd4e5da5Sopenharmony_ci         %19 = OpLabel
290fd4e5da5Sopenharmony_ci               OpBranch %39
291fd4e5da5Sopenharmony_ci         %39 = OpLabel
292fd4e5da5Sopenharmony_ci        %188 = OpPhi %6 %37 %19 %73 %51
293fd4e5da5Sopenharmony_ci        %185 = OpPhi %13 %16 %19 %75 %51
294fd4e5da5Sopenharmony_ci         %46 = OpSLessThan %26 %185 %45
295fd4e5da5Sopenharmony_ci               OpLoopMerge %41 %51 None
296fd4e5da5Sopenharmony_ci               OpBranchConditional %46 %40 %41
297fd4e5da5Sopenharmony_ci         %40 = OpLabel
298fd4e5da5Sopenharmony_ci         %49 = OpFOrdEqual %26 %188 %37
299fd4e5da5Sopenharmony_ci               OpSelectionMerge %51 None
300fd4e5da5Sopenharmony_ci               OpBranchConditional %49 %50 %61
301fd4e5da5Sopenharmony_ci         %50 = OpLabel
302fd4e5da5Sopenharmony_ci         %58 = OpAccessChain %57 %55 %185
303fd4e5da5Sopenharmony_ci         %59 = OpLoad %52 %58
304fd4e5da5Sopenharmony_ci         %60 = OpConvertUToF %6 %59
305fd4e5da5Sopenharmony_ci               OpBranch %51
306fd4e5da5Sopenharmony_ci         %61 = OpLabel
307fd4e5da5Sopenharmony_ci         %64 = OpAccessChain %63 %11 %185
308fd4e5da5Sopenharmony_ci         %65 = OpLoad %6 %64
309fd4e5da5Sopenharmony_ci               OpBranch %51
310fd4e5da5Sopenharmony_ci         %51 = OpLabel
311fd4e5da5Sopenharmony_ci        %210 = OpPhi %6 %60 %50 %65 %61
312fd4e5da5Sopenharmony_ci         %68 = OpAccessChain %57 %55 %185
313fd4e5da5Sopenharmony_ci         %69 = OpLoad %52 %68
314fd4e5da5Sopenharmony_ci         %70 = OpConvertUToF %6 %69
315fd4e5da5Sopenharmony_ci         %71 = OpFAdd %6 %210 %70
316fd4e5da5Sopenharmony_ci         %73 = OpFAdd %6 %188 %71
317fd4e5da5Sopenharmony_ci         %75 = OpIAdd %13 %185 %33
318fd4e5da5Sopenharmony_ci               OpBranch %39
319fd4e5da5Sopenharmony_ci         %41 = OpLabel
320fd4e5da5Sopenharmony_ci               OpBranch %77
321fd4e5da5Sopenharmony_ci         %77 = OpLabel
322fd4e5da5Sopenharmony_ci        %186 = OpPhi %13 %16 %41 %94 %78
323fd4e5da5Sopenharmony_ci         %83 = OpSLessThan %26 %186 %45
324fd4e5da5Sopenharmony_ci               OpLoopMerge %79 %78 None
325fd4e5da5Sopenharmony_ci               OpBranchConditional %83 %78 %79
326fd4e5da5Sopenharmony_ci         %78 = OpLabel
327fd4e5da5Sopenharmony_ci         %87 = OpAccessChain %57 %55 %186
328fd4e5da5Sopenharmony_ci         %88 = OpLoad %52 %87
329fd4e5da5Sopenharmony_ci         %90 = OpIMul %52 %88 %89
330fd4e5da5Sopenharmony_ci         %91 = OpConvertUToF %6 %90
331fd4e5da5Sopenharmony_ci         %92 = OpAccessChain %35 %84 %186
332fd4e5da5Sopenharmony_ci               OpStore %92 %91
333fd4e5da5Sopenharmony_ci         %94 = OpIAdd %13 %186 %33
334fd4e5da5Sopenharmony_ci               OpBranch %77
335fd4e5da5Sopenharmony_ci         %79 = OpLabel
336fd4e5da5Sopenharmony_ci         %96 = OpCompositeConstruct %7 %188 %188 %188 %188
337fd4e5da5Sopenharmony_ci         %97 = OpLoad %7 %84
338fd4e5da5Sopenharmony_ci         %98 = OpFAdd %7 %96 %97
339fd4e5da5Sopenharmony_ci        %100 = OpFAdd %7 %191 %98
340fd4e5da5Sopenharmony_ci        %104 = OpVectorShuffle %102 %12 %12 0 1 2
341fd4e5da5Sopenharmony_ci        %106 = OpVectorShuffle %7 %195 %104 4 5 6 3
342fd4e5da5Sopenharmony_ci               OpBranch %108
343fd4e5da5Sopenharmony_ci        %108 = OpLabel
344fd4e5da5Sopenharmony_ci        %197 = OpPhi %7 %106 %79 %208 %133
345fd4e5da5Sopenharmony_ci        %196 = OpPhi %13 %16 %79 %143 %133
346fd4e5da5Sopenharmony_ci        %115 = OpSLessThan %26 %196 %25
347fd4e5da5Sopenharmony_ci               OpLoopMerge %110 %133 None
348fd4e5da5Sopenharmony_ci               OpBranchConditional %115 %109 %110
349fd4e5da5Sopenharmony_ci        %109 = OpLabel
350fd4e5da5Sopenharmony_ci               OpBranch %117
351fd4e5da5Sopenharmony_ci        %117 = OpLabel
352fd4e5da5Sopenharmony_ci        %209 = OpPhi %7 %197 %109 %181 %118
353fd4e5da5Sopenharmony_ci        %204 = OpPhi %13 %16 %109 %129 %118
354fd4e5da5Sopenharmony_ci        %123 = OpSLessThan %26 %204 %45
355fd4e5da5Sopenharmony_ci               OpLoopMerge %119 %118 None
356fd4e5da5Sopenharmony_ci               OpBranchConditional %123 %118 %119
357fd4e5da5Sopenharmony_ci        %118 = OpLabel
358fd4e5da5Sopenharmony_ci        %125 = OpLoad %6 %124
359fd4e5da5Sopenharmony_ci        %181 = OpCompositeInsert %7 %125 %209 3
360fd4e5da5Sopenharmony_ci        %129 = OpIAdd %13 %204 %33
361fd4e5da5Sopenharmony_ci               OpBranch %117
362fd4e5da5Sopenharmony_ci        %119 = OpLabel
363fd4e5da5Sopenharmony_ci               OpBranch %131
364fd4e5da5Sopenharmony_ci        %131 = OpLabel
365fd4e5da5Sopenharmony_ci        %208 = OpPhi %7 %209 %119 %183 %132
366fd4e5da5Sopenharmony_ci        %205 = OpPhi %13 %16 %119 %141 %132
367fd4e5da5Sopenharmony_ci        %137 = OpSLessThan %26 %205 %45
368fd4e5da5Sopenharmony_ci               OpLoopMerge %133 %132 None
369fd4e5da5Sopenharmony_ci               OpBranchConditional %137 %132 %133
370fd4e5da5Sopenharmony_ci        %132 = OpLabel
371fd4e5da5Sopenharmony_ci        %138 = OpLoad %6 %124
372fd4e5da5Sopenharmony_ci        %183 = OpCompositeInsert %7 %138 %208 3
373fd4e5da5Sopenharmony_ci        %141 = OpIAdd %13 %205 %33
374fd4e5da5Sopenharmony_ci               OpBranch %131
375fd4e5da5Sopenharmony_ci        %133 = OpLabel
376fd4e5da5Sopenharmony_ci        %143 = OpIAdd %13 %196 %33
377fd4e5da5Sopenharmony_ci               OpBranch %108
378fd4e5da5Sopenharmony_ci        %110 = OpLabel
379fd4e5da5Sopenharmony_ci        %145 = OpVectorShuffle %102 %197 %197 0 1 2
380fd4e5da5Sopenharmony_ci        %147 = OpVectorShuffle %102 %100 %100 0 1 2
381fd4e5da5Sopenharmony_ci        %148 = OpFAdd %102 %147 %145
382fd4e5da5Sopenharmony_ci        %150 = OpVectorShuffle %7 %100 %148 4 5 6 3
383fd4e5da5Sopenharmony_ci               OpBranch %152
384fd4e5da5Sopenharmony_ci        %152 = OpLabel
385fd4e5da5Sopenharmony_ci        %200 = OpPhi %7 %150 %110 %203 %163
386fd4e5da5Sopenharmony_ci        %199 = OpPhi %13 %16 %110 %174 %163
387fd4e5da5Sopenharmony_ci        %159 = OpSLessThan %26 %199 %158
388fd4e5da5Sopenharmony_ci               OpLoopMerge %154 %163 None
389fd4e5da5Sopenharmony_ci               OpBranchConditional %159 %153 %154
390fd4e5da5Sopenharmony_ci        %153 = OpLabel
391fd4e5da5Sopenharmony_ci               OpBranch %161
392fd4e5da5Sopenharmony_ci        %161 = OpLabel
393fd4e5da5Sopenharmony_ci        %203 = OpPhi %7 %200 %153 %170 %162
394fd4e5da5Sopenharmony_ci        %201 = OpPhi %13 %16 %153 %172 %162
395fd4e5da5Sopenharmony_ci        %167 = OpSLessThan %26 %201 %45
396fd4e5da5Sopenharmony_ci               OpLoopMerge %163 %162 None
397fd4e5da5Sopenharmony_ci               OpBranchConditional %167 %162 %163
398fd4e5da5Sopenharmony_ci        %162 = OpLabel
399fd4e5da5Sopenharmony_ci        %168 = OpLoad %6 %124
400fd4e5da5Sopenharmony_ci        %170 = OpVectorTimesScalar %7 %203 %168
401fd4e5da5Sopenharmony_ci        %172 = OpIAdd %13 %201 %33
402fd4e5da5Sopenharmony_ci               OpBranch %161
403fd4e5da5Sopenharmony_ci        %163 = OpLabel
404fd4e5da5Sopenharmony_ci        %174 = OpIAdd %13 %199 %45
405fd4e5da5Sopenharmony_ci               OpBranch %152
406fd4e5da5Sopenharmony_ci        %154 = OpLabel
407fd4e5da5Sopenharmony_ci        %178 = OpLoad %7 %84
408fd4e5da5Sopenharmony_ci        %179 = OpFAdd %7 %200 %178
409fd4e5da5Sopenharmony_ci               OpStore %176 %179
410fd4e5da5Sopenharmony_ci               OpReturn
411fd4e5da5Sopenharmony_ci               OpFunctionEnd
412fd4e5da5Sopenharmony_ci  )";
413fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
414fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
415fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
416fd4e5da5Sopenharmony_ci  Module* module = context->module();
417fd4e5da5Sopenharmony_ci  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
418fd4e5da5Sopenharmony_ci                             << text << std::endl;
419fd4e5da5Sopenharmony_ci  Function* f = &*module->begin();
420fd4e5da5Sopenharmony_ci  LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
421fd4e5da5Sopenharmony_ci  const RegisterLiveness* register_liveness = liveness_analysis->Get(f);
422fd4e5da5Sopenharmony_ci  LoopDescriptor& ld = *context->GetLoopDescriptor(f);
423fd4e5da5Sopenharmony_ci
424fd4e5da5Sopenharmony_ci  {
425fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 5");
426fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(5);
427fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
428fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
429fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
430fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
431fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
432fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
433fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
434fd4e5da5Sopenharmony_ci    };
435fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
436fd4e5da5Sopenharmony_ci
437fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
438fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
439fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
440fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
441fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
442fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
443fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
444fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
445fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
446fd4e5da5Sopenharmony_ci    };
447fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
448fd4e5da5Sopenharmony_ci
449fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
450fd4e5da5Sopenharmony_ci  }
451fd4e5da5Sopenharmony_ci  {
452fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 17");
453fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(17);
454fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
455fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
456fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
457fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
458fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
459fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
460fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
461fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
462fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
463fd4e5da5Sopenharmony_ci        184,  // %184 = OpPhi %13 %16 %5 %34 %18
464fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
465fd4e5da5Sopenharmony_ci    };
466fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
467fd4e5da5Sopenharmony_ci
468fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
469fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
470fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
471fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
472fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
473fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
474fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
475fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
476fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
477fd4e5da5Sopenharmony_ci        184,  // %184 = OpPhi %13 %16 %5 %34 %18
478fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
479fd4e5da5Sopenharmony_ci    };
480fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
481fd4e5da5Sopenharmony_ci
482fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 11u);
483fd4e5da5Sopenharmony_ci  }
484fd4e5da5Sopenharmony_ci  {
485fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 18");
486fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(18);
487fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
488fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
489fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
490fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
491fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
492fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
493fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
494fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
495fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
496fd4e5da5Sopenharmony_ci        184,  // %184 = OpPhi %13 %16 %5 %34 %18
497fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
498fd4e5da5Sopenharmony_ci    };
499fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
500fd4e5da5Sopenharmony_ci
501fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
502fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
503fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
504fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
505fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
506fd4e5da5Sopenharmony_ci        31,   // %31 = OpFAdd %7 %191 %29
507fd4e5da5Sopenharmony_ci        34,   // %34 = OpIAdd %13 %184 %33
508fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
509fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
510fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
511fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
512fd4e5da5Sopenharmony_ci    };
513fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
514fd4e5da5Sopenharmony_ci
515fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 12u);
516fd4e5da5Sopenharmony_ci  }
517fd4e5da5Sopenharmony_ci  {
518fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 19");
519fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(19);
520fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
521fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
522fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
523fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
524fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
525fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
526fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
527fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
528fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
529fd4e5da5Sopenharmony_ci    };
530fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
531fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
532fd4e5da5Sopenharmony_ci
533fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
534fd4e5da5Sopenharmony_ci  }
535fd4e5da5Sopenharmony_ci  {
536fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 39");
537fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(39);
538fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
539fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
540fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
541fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
542fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
543fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
544fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
545fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
546fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
547fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
548fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
549fd4e5da5Sopenharmony_ci    };
550fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
551fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
552fd4e5da5Sopenharmony_ci
553fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 11u);
554fd4e5da5Sopenharmony_ci  }
555fd4e5da5Sopenharmony_ci  {
556fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 40");
557fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(40);
558fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
559fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
560fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
561fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
562fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
563fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
564fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
565fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
566fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
567fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
568fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
569fd4e5da5Sopenharmony_ci    };
570fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
571fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
572fd4e5da5Sopenharmony_ci
573fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 11u);
574fd4e5da5Sopenharmony_ci  }
575fd4e5da5Sopenharmony_ci  {
576fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 50");
577fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(50);
578fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
579fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
580fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
581fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
582fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
583fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
584fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
585fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
586fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
587fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
588fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
589fd4e5da5Sopenharmony_ci    };
590fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
591fd4e5da5Sopenharmony_ci
592fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
593fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
594fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
595fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
596fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
597fd4e5da5Sopenharmony_ci        60,   // %60 = OpConvertUToF %6 %59
598fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
599fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
600fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
601fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
602fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
603fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
604fd4e5da5Sopenharmony_ci    };
605fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
606fd4e5da5Sopenharmony_ci
607fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 12u);
608fd4e5da5Sopenharmony_ci  }
609fd4e5da5Sopenharmony_ci  {
610fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 61");
611fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(61);
612fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
613fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
614fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
615fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
616fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
617fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
618fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
619fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
620fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
621fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
622fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
623fd4e5da5Sopenharmony_ci    };
624fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
625fd4e5da5Sopenharmony_ci
626fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
627fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
628fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
629fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
630fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
631fd4e5da5Sopenharmony_ci        65,   // %65 = OpLoad %6 %64
632fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
633fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
634fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
635fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
636fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
637fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
638fd4e5da5Sopenharmony_ci    };
639fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
640fd4e5da5Sopenharmony_ci
641fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 12u);
642fd4e5da5Sopenharmony_ci  }
643fd4e5da5Sopenharmony_ci  {
644fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 51");
645fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(51);
646fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
647fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
648fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
649fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
650fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
651fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
652fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
653fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
654fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
655fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
656fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
657fd4e5da5Sopenharmony_ci        210,  // %210 = OpPhi %6 %60 %50 %65 %61
658fd4e5da5Sopenharmony_ci    };
659fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
660fd4e5da5Sopenharmony_ci
661fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
662fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
663fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
664fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
665fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
666fd4e5da5Sopenharmony_ci        73,   // %73 = OpFAdd %6 %188 %71
667fd4e5da5Sopenharmony_ci        75,   // %75 = OpIAdd %13 %185 %33
668fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
669fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
670fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
671fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
672fd4e5da5Sopenharmony_ci    };
673fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
674fd4e5da5Sopenharmony_ci
675fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 13u);
676fd4e5da5Sopenharmony_ci  }
677fd4e5da5Sopenharmony_ci  {
678fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 41");
679fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(41);
680fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
681fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
682fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
683fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
684fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
685fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
686fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
687fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
688fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
689fd4e5da5Sopenharmony_ci    };
690fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
691fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
692fd4e5da5Sopenharmony_ci
693fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
694fd4e5da5Sopenharmony_ci  }
695fd4e5da5Sopenharmony_ci  {
696fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 77");
697fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(77);
698fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
699fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
700fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
701fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
702fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
703fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
704fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
705fd4e5da5Sopenharmony_ci        186,  // %186 = OpPhi %13 %16 %41 %94 %78
706fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
707fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
708fd4e5da5Sopenharmony_ci    };
709fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
710fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
711fd4e5da5Sopenharmony_ci
712fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 10u);
713fd4e5da5Sopenharmony_ci  }
714fd4e5da5Sopenharmony_ci  {
715fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 78");
716fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(78);
717fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
718fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
719fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
720fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
721fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
722fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
723fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
724fd4e5da5Sopenharmony_ci        186,  // %186 = OpPhi %13 %16 %41 %94 %78
725fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
726fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
727fd4e5da5Sopenharmony_ci    };
728fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
729fd4e5da5Sopenharmony_ci
730fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
731fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
732fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
733fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
734fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
735fd4e5da5Sopenharmony_ci        94,   // %94 = OpIAdd %13 %186 %33
736fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
737fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
738fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
739fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
740fd4e5da5Sopenharmony_ci    };
741fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
742fd4e5da5Sopenharmony_ci
743fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 11u);
744fd4e5da5Sopenharmony_ci  }
745fd4e5da5Sopenharmony_ci  {
746fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 79");
747fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(79);
748fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
749fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
750fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
751fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
752fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
753fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
754fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
755fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
756fd4e5da5Sopenharmony_ci    };
757fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
758fd4e5da5Sopenharmony_ci
759fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
760fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
761fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
762fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
763fd4e5da5Sopenharmony_ci        106,  // %106 = OpVectorShuffle %7 %195 %104 4 5 6 3
764fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
765fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
766fd4e5da5Sopenharmony_ci    };
767fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
768fd4e5da5Sopenharmony_ci
769fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 9u);
770fd4e5da5Sopenharmony_ci  }
771fd4e5da5Sopenharmony_ci  {
772fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 108");
773fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(108);
774fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
775fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
776fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
777fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
778fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
779fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
780fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
781fd4e5da5Sopenharmony_ci        197,  // %197 = OpPhi %7 %106 %79 %208 %133
782fd4e5da5Sopenharmony_ci    };
783fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
784fd4e5da5Sopenharmony_ci
785fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
786fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
787fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
788fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
789fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
790fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
791fd4e5da5Sopenharmony_ci        197,  // %197 = OpPhi %7 %106 %79 %208 %133
792fd4e5da5Sopenharmony_ci    };
793fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
794fd4e5da5Sopenharmony_ci
795fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
796fd4e5da5Sopenharmony_ci  }
797fd4e5da5Sopenharmony_ci  {
798fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 109");
799fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(109);
800fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
801fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
802fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
803fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
804fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
805fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
806fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
807fd4e5da5Sopenharmony_ci        197,  // %197 = OpPhi %7 %106 %79 %208 %133
808fd4e5da5Sopenharmony_ci    };
809fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
810fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
811fd4e5da5Sopenharmony_ci
812fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 7u);
813fd4e5da5Sopenharmony_ci  }
814fd4e5da5Sopenharmony_ci  {
815fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 117");
816fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(117);
817fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
818fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
819fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
820fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
821fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
822fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
823fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
824fd4e5da5Sopenharmony_ci        204,  // %204 = OpPhi %13 %16 %109 %129 %118
825fd4e5da5Sopenharmony_ci        209,  // %209 = OpPhi %7 %197 %109 %181 %118
826fd4e5da5Sopenharmony_ci    };
827fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
828fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
829fd4e5da5Sopenharmony_ci
830fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 9u);
831fd4e5da5Sopenharmony_ci  }
832fd4e5da5Sopenharmony_ci  {
833fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 118");
834fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(118);
835fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
836fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
837fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
838fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
839fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
840fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
841fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
842fd4e5da5Sopenharmony_ci        204,  // %204 = OpPhi %13 %16 %109 %129 %118
843fd4e5da5Sopenharmony_ci        209,  // %209 = OpPhi %7 %197 %109 %181 %118
844fd4e5da5Sopenharmony_ci    };
845fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
846fd4e5da5Sopenharmony_ci
847fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
848fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
849fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
850fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
851fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
852fd4e5da5Sopenharmony_ci        129,  // %129 = OpIAdd %13 %204 %33
853fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
854fd4e5da5Sopenharmony_ci        181,  // %181 = OpCompositeInsert %7 %125 %209 3
855fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
856fd4e5da5Sopenharmony_ci    };
857fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
858fd4e5da5Sopenharmony_ci
859fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 10u);
860fd4e5da5Sopenharmony_ci  }
861fd4e5da5Sopenharmony_ci  {
862fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 119");
863fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(119);
864fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
865fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
866fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
867fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
868fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
869fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
870fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
871fd4e5da5Sopenharmony_ci        209,  // %209 = OpPhi %7 %197 %109 %181 %118
872fd4e5da5Sopenharmony_ci    };
873fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
874fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
875fd4e5da5Sopenharmony_ci
876fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 7u);
877fd4e5da5Sopenharmony_ci  }
878fd4e5da5Sopenharmony_ci  {
879fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 131");
880fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(131);
881fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
882fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
883fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
884fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
885fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
886fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
887fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
888fd4e5da5Sopenharmony_ci        205,  // %205 = OpPhi %13 %16 %119 %141 %132
889fd4e5da5Sopenharmony_ci        208,  // %208 = OpPhi %7 %209 %119 %183 %132
890fd4e5da5Sopenharmony_ci    };
891fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
892fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
893fd4e5da5Sopenharmony_ci
894fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 9u);
895fd4e5da5Sopenharmony_ci  }
896fd4e5da5Sopenharmony_ci  {
897fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 132");
898fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(132);
899fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
900fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
901fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
902fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
903fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
904fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
905fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
906fd4e5da5Sopenharmony_ci        205,  // %205 = OpPhi %13 %16 %119 %141 %132
907fd4e5da5Sopenharmony_ci        208,  // %208 = OpPhi %7 %209 %119 %183 %132
908fd4e5da5Sopenharmony_ci    };
909fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
910fd4e5da5Sopenharmony_ci
911fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
912fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
913fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
914fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
915fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
916fd4e5da5Sopenharmony_ci        141,  // %141 = OpIAdd %13 %205 %33
917fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
918fd4e5da5Sopenharmony_ci        183,  // %183 = OpCompositeInsert %7 %138 %208 3
919fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
920fd4e5da5Sopenharmony_ci    };
921fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
922fd4e5da5Sopenharmony_ci
923fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 10u);
924fd4e5da5Sopenharmony_ci  }
925fd4e5da5Sopenharmony_ci  {
926fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 133");
927fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(133);
928fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
929fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
930fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
931fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
932fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
933fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
934fd4e5da5Sopenharmony_ci        196,  // %196 = OpPhi %13 %16 %79 %143 %133
935fd4e5da5Sopenharmony_ci        208,  // %208 = OpPhi %7 %209 %119 %183 %132
936fd4e5da5Sopenharmony_ci    };
937fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
938fd4e5da5Sopenharmony_ci
939fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
940fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
941fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
942fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
943fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
944fd4e5da5Sopenharmony_ci        143,  // %143 = OpIAdd %13 %196 %33
945fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
946fd4e5da5Sopenharmony_ci        208,  // %208 = OpPhi %7 %209 %119 %183 %132
947fd4e5da5Sopenharmony_ci    };
948fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
949fd4e5da5Sopenharmony_ci
950fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
951fd4e5da5Sopenharmony_ci  }
952fd4e5da5Sopenharmony_ci  {
953fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 110");
954fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(110);
955fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
956fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
957fd4e5da5Sopenharmony_ci        100,  // %100 = OpFAdd %7 %191 %98
958fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
959fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
960fd4e5da5Sopenharmony_ci        197,  // %197 = OpPhi %7 %106 %79 %208 %133
961fd4e5da5Sopenharmony_ci    };
962fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
963fd4e5da5Sopenharmony_ci
964fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
965fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
966fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
967fd4e5da5Sopenharmony_ci        150,  // %150 = OpVectorShuffle %7 %100 %148 4 5 6 3
968fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
969fd4e5da5Sopenharmony_ci    };
970fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
971fd4e5da5Sopenharmony_ci
972fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 7u);
973fd4e5da5Sopenharmony_ci  }
974fd4e5da5Sopenharmony_ci  {
975fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 152");
976fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(152);
977fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
978fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
979fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
980fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
981fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
982fd4e5da5Sopenharmony_ci        200,  // %200 = OpPhi %7 %150 %110 %203 %163
983fd4e5da5Sopenharmony_ci    };
984fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
985fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
986fd4e5da5Sopenharmony_ci
987fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 6u);
988fd4e5da5Sopenharmony_ci  }
989fd4e5da5Sopenharmony_ci  {
990fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 153");
991fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(153);
992fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
993fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
994fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
995fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
996fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
997fd4e5da5Sopenharmony_ci        200,  // %200 = OpPhi %7 %150 %110 %203 %163
998fd4e5da5Sopenharmony_ci    };
999fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
1000fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
1001fd4e5da5Sopenharmony_ci
1002fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 5u);
1003fd4e5da5Sopenharmony_ci  }
1004fd4e5da5Sopenharmony_ci  {
1005fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 161");
1006fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(161);
1007fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_inout{
1008fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1009fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1010fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1011fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
1012fd4e5da5Sopenharmony_ci        201,  // %201 = OpPhi %13 %16 %153 %172 %162
1013fd4e5da5Sopenharmony_ci        203,  // %203 = OpPhi %7 %200 %153 %170 %162
1014fd4e5da5Sopenharmony_ci    };
1015fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_inout);
1016fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_inout);
1017fd4e5da5Sopenharmony_ci
1018fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 7u);
1019fd4e5da5Sopenharmony_ci  }
1020fd4e5da5Sopenharmony_ci  {
1021fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 162");
1022fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(162);
1023fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
1024fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1025fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1026fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1027fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
1028fd4e5da5Sopenharmony_ci        201,  // %201 = OpPhi %13 %16 %153 %172 %162
1029fd4e5da5Sopenharmony_ci        203,  // %203 = OpPhi %7 %200 %153 %170 %162
1030fd4e5da5Sopenharmony_ci    };
1031fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
1032fd4e5da5Sopenharmony_ci
1033fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
1034fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1035fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1036fd4e5da5Sopenharmony_ci        170,  // %170 = OpVectorTimesScalar %7 %203 %168
1037fd4e5da5Sopenharmony_ci        172,  // %172 = OpIAdd %13 %201 %33
1038fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1039fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
1040fd4e5da5Sopenharmony_ci    };
1041fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
1042fd4e5da5Sopenharmony_ci
1043fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 8u);
1044fd4e5da5Sopenharmony_ci  }
1045fd4e5da5Sopenharmony_ci  {
1046fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 163");
1047fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(163);
1048fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
1049fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1050fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1051fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1052fd4e5da5Sopenharmony_ci        199,  // %199 = OpPhi %13 %16 %110 %174 %163
1053fd4e5da5Sopenharmony_ci        203,  // %203 = OpPhi %7 %200 %153 %170 %162
1054fd4e5da5Sopenharmony_ci    };
1055fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
1056fd4e5da5Sopenharmony_ci
1057fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
1058fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1059fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1060fd4e5da5Sopenharmony_ci        174,  // %174 = OpIAdd %13 %199 %45
1061fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1062fd4e5da5Sopenharmony_ci        203,  // %203 = OpPhi %7 %200 %153 %170 %162
1063fd4e5da5Sopenharmony_ci    };
1064fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
1065fd4e5da5Sopenharmony_ci
1066fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 6u);
1067fd4e5da5Sopenharmony_ci  }
1068fd4e5da5Sopenharmony_ci  {
1069fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Block 154");
1070fd4e5da5Sopenharmony_ci    auto live_sets = register_liveness->Get(154);
1071fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
1072fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1073fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1074fd4e5da5Sopenharmony_ci        200,  // %200 = OpPhi %7 %150 %110 %203 %163
1075fd4e5da5Sopenharmony_ci    };
1076fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_in_, live_in);
1077fd4e5da5Sopenharmony_ci
1078fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{};
1079fd4e5da5Sopenharmony_ci    CompareSets(live_sets->live_out_, live_out);
1080fd4e5da5Sopenharmony_ci
1081fd4e5da5Sopenharmony_ci    EXPECT_EQ(live_sets->used_registers_, 4u);
1082fd4e5da5Sopenharmony_ci  }
1083fd4e5da5Sopenharmony_ci
1084fd4e5da5Sopenharmony_ci  {
1085fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Compute loop pressure");
1086fd4e5da5Sopenharmony_ci    RegisterLiveness::RegionRegisterLiveness loop_reg_pressure;
1087fd4e5da5Sopenharmony_ci    register_liveness->ComputeLoopRegisterPressure(*ld[39], &loop_reg_pressure);
1088fd4e5da5Sopenharmony_ci    // Generate(*context->cfg()->block(39), &loop_reg_pressure);
1089fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
1090fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
1091fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
1092fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
1093fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
1094fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1095fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1096fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1097fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
1098fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
1099fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
1100fd4e5da5Sopenharmony_ci    };
1101fd4e5da5Sopenharmony_ci    CompareSets(loop_reg_pressure.live_in_, live_in);
1102fd4e5da5Sopenharmony_ci
1103fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
1104fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
1105fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
1106fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
1107fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1108fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1109fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1110fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
1111fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
1112fd4e5da5Sopenharmony_ci    };
1113fd4e5da5Sopenharmony_ci    CompareSets(loop_reg_pressure.live_out_, live_out);
1114fd4e5da5Sopenharmony_ci
1115fd4e5da5Sopenharmony_ci    EXPECT_EQ(loop_reg_pressure.used_registers_, 13u);
1116fd4e5da5Sopenharmony_ci  }
1117fd4e5da5Sopenharmony_ci
1118fd4e5da5Sopenharmony_ci  {
1119fd4e5da5Sopenharmony_ci    SCOPED_TRACE("Loop Fusion simulation");
1120fd4e5da5Sopenharmony_ci    RegisterLiveness::RegionRegisterLiveness simulation_resut;
1121fd4e5da5Sopenharmony_ci    register_liveness->SimulateFusion(*ld[17], *ld[39], &simulation_resut);
1122fd4e5da5Sopenharmony_ci
1123fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_in{
1124fd4e5da5Sopenharmony_ci        11,   // %11 = OpVariable %10 Input
1125fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
1126fd4e5da5Sopenharmony_ci        24,   // %24 = OpVariable %23 Input
1127fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
1128fd4e5da5Sopenharmony_ci        28,   // %28 = OpVariable %10 Input
1129fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
1130fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1131fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1132fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1133fd4e5da5Sopenharmony_ci        184,  // %184 = OpPhi %13 %16 %5 %34 %18
1134fd4e5da5Sopenharmony_ci        185,  // %185 = OpPhi %13 %16 %19 %75 %51
1135fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
1136fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
1137fd4e5da5Sopenharmony_ci    };
1138fd4e5da5Sopenharmony_ci    CompareSets(simulation_resut.live_in_, live_in);
1139fd4e5da5Sopenharmony_ci
1140fd4e5da5Sopenharmony_ci    std::unordered_set<uint32_t> live_out{
1141fd4e5da5Sopenharmony_ci        12,   // %12 = OpLoad %7 %11
1142fd4e5da5Sopenharmony_ci        25,   // %25 = OpLoad %13 %24
1143fd4e5da5Sopenharmony_ci        55,   // %55 = OpVariable %54 Input
1144fd4e5da5Sopenharmony_ci        84,   // %84 = OpVariable %8 Function
1145fd4e5da5Sopenharmony_ci        124,  // %124 = OpVariable %63 Input
1146fd4e5da5Sopenharmony_ci        176,  // %176 = OpVariable %175 Output
1147fd4e5da5Sopenharmony_ci        188,  // %188 = OpPhi %6 %37 %19 %73 %51
1148fd4e5da5Sopenharmony_ci        191,  // %191 = OpPhi %7 %12 %5 %31 %18
1149fd4e5da5Sopenharmony_ci    };
1150fd4e5da5Sopenharmony_ci    CompareSets(simulation_resut.live_out_, live_out);
1151fd4e5da5Sopenharmony_ci
1152fd4e5da5Sopenharmony_ci    EXPECT_EQ(simulation_resut.used_registers_, 17u);
1153fd4e5da5Sopenharmony_ci  }
1154fd4e5da5Sopenharmony_ci}
1155fd4e5da5Sopenharmony_ci
1156fd4e5da5Sopenharmony_ciTEST_F(PassClassTest, FissionSimulation) {
1157fd4e5da5Sopenharmony_ci  const std::string source = R"(
1158fd4e5da5Sopenharmony_ci               OpCapability Shader
1159fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1160fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1161fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
1162fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginUpperLeft
1163fd4e5da5Sopenharmony_ci               OpSource GLSL 430
1164fd4e5da5Sopenharmony_ci               OpName %2 "main"
1165fd4e5da5Sopenharmony_ci               OpName %3 "i"
1166fd4e5da5Sopenharmony_ci               OpName %4 "A"
1167fd4e5da5Sopenharmony_ci               OpName %5 "B"
1168fd4e5da5Sopenharmony_ci          %6 = OpTypeVoid
1169fd4e5da5Sopenharmony_ci          %7 = OpTypeFunction %6
1170fd4e5da5Sopenharmony_ci          %8 = OpTypeInt 32 1
1171fd4e5da5Sopenharmony_ci          %9 = OpTypePointer Function %8
1172fd4e5da5Sopenharmony_ci         %10 = OpConstant %8 0
1173fd4e5da5Sopenharmony_ci         %11 = OpConstant %8 10
1174fd4e5da5Sopenharmony_ci         %12 = OpTypeBool
1175fd4e5da5Sopenharmony_ci         %13 = OpTypeFloat 32
1176fd4e5da5Sopenharmony_ci         %14 = OpTypeInt 32 0
1177fd4e5da5Sopenharmony_ci         %15 = OpConstant %14 10
1178fd4e5da5Sopenharmony_ci         %16 = OpTypeArray %13 %15
1179fd4e5da5Sopenharmony_ci         %17 = OpTypePointer Function %16
1180fd4e5da5Sopenharmony_ci         %18 = OpTypePointer Function %13
1181fd4e5da5Sopenharmony_ci         %19 = OpConstant %8 1
1182fd4e5da5Sopenharmony_ci          %2 = OpFunction %6 None %7
1183fd4e5da5Sopenharmony_ci         %20 = OpLabel
1184fd4e5da5Sopenharmony_ci          %3 = OpVariable %9 Function
1185fd4e5da5Sopenharmony_ci          %4 = OpVariable %17 Function
1186fd4e5da5Sopenharmony_ci          %5 = OpVariable %17 Function
1187fd4e5da5Sopenharmony_ci               OpBranch %21
1188fd4e5da5Sopenharmony_ci         %21 = OpLabel
1189fd4e5da5Sopenharmony_ci         %22 = OpPhi %8 %10 %20 %23 %24
1190fd4e5da5Sopenharmony_ci               OpLoopMerge %25 %24 None
1191fd4e5da5Sopenharmony_ci               OpBranch %26
1192fd4e5da5Sopenharmony_ci         %26 = OpLabel
1193fd4e5da5Sopenharmony_ci         %27 = OpSLessThan %12 %22 %11
1194fd4e5da5Sopenharmony_ci               OpBranchConditional %27 %28 %25
1195fd4e5da5Sopenharmony_ci         %28 = OpLabel
1196fd4e5da5Sopenharmony_ci         %29 = OpAccessChain %18 %5 %22
1197fd4e5da5Sopenharmony_ci         %30 = OpLoad %13 %29
1198fd4e5da5Sopenharmony_ci         %31 = OpAccessChain %18 %4 %22
1199fd4e5da5Sopenharmony_ci               OpStore %31 %30
1200fd4e5da5Sopenharmony_ci         %32 = OpAccessChain %18 %4 %22
1201fd4e5da5Sopenharmony_ci         %33 = OpLoad %13 %32
1202fd4e5da5Sopenharmony_ci         %34 = OpAccessChain %18 %5 %22
1203fd4e5da5Sopenharmony_ci               OpStore %34 %33
1204fd4e5da5Sopenharmony_ci               OpBranch %24
1205fd4e5da5Sopenharmony_ci         %24 = OpLabel
1206fd4e5da5Sopenharmony_ci         %23 = OpIAdd %8 %22 %19
1207fd4e5da5Sopenharmony_ci               OpBranch %21
1208fd4e5da5Sopenharmony_ci         %25 = OpLabel
1209fd4e5da5Sopenharmony_ci               OpStore %3 %22
1210fd4e5da5Sopenharmony_ci               OpReturn
1211fd4e5da5Sopenharmony_ci               OpFunctionEnd
1212fd4e5da5Sopenharmony_ci    )";
1213fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1214fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
1215fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1216fd4e5da5Sopenharmony_ci  Module* module = context->module();
1217fd4e5da5Sopenharmony_ci  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
1218fd4e5da5Sopenharmony_ci                             << source << std::endl;
1219fd4e5da5Sopenharmony_ci  Function* f = &*module->begin();
1220fd4e5da5Sopenharmony_ci  LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
1221fd4e5da5Sopenharmony_ci  const RegisterLiveness* register_liveness = liveness_analysis->Get(f);
1222fd4e5da5Sopenharmony_ci  LoopDescriptor& ld = *context->GetLoopDescriptor(f);
1223fd4e5da5Sopenharmony_ci  analysis::DefUseManager& def_use_mgr = *context->get_def_use_mgr();
1224fd4e5da5Sopenharmony_ci
1225fd4e5da5Sopenharmony_ci  {
1226fd4e5da5Sopenharmony_ci    RegisterLiveness::RegionRegisterLiveness l1_sim_resut;
1227fd4e5da5Sopenharmony_ci    RegisterLiveness::RegionRegisterLiveness l2_sim_resut;
1228fd4e5da5Sopenharmony_ci    std::unordered_set<Instruction*> moved_instructions{
1229fd4e5da5Sopenharmony_ci        def_use_mgr.GetDef(29), def_use_mgr.GetDef(30), def_use_mgr.GetDef(31),
1230fd4e5da5Sopenharmony_ci        def_use_mgr.GetDef(31)->NextNode()};
1231fd4e5da5Sopenharmony_ci    std::unordered_set<Instruction*> copied_instructions{
1232fd4e5da5Sopenharmony_ci        def_use_mgr.GetDef(22), def_use_mgr.GetDef(27),
1233fd4e5da5Sopenharmony_ci        def_use_mgr.GetDef(27)->NextNode(), def_use_mgr.GetDef(23)};
1234fd4e5da5Sopenharmony_ci
1235fd4e5da5Sopenharmony_ci    register_liveness->SimulateFission(*ld[21], moved_instructions,
1236fd4e5da5Sopenharmony_ci                                       copied_instructions, &l1_sim_resut,
1237fd4e5da5Sopenharmony_ci                                       &l2_sim_resut);
1238fd4e5da5Sopenharmony_ci    {
1239fd4e5da5Sopenharmony_ci      SCOPED_TRACE("L1 simulation");
1240fd4e5da5Sopenharmony_ci      std::unordered_set<uint32_t> live_in{
1241fd4e5da5Sopenharmony_ci          3,   // %3 = OpVariable %9 Function
1242fd4e5da5Sopenharmony_ci          4,   // %4 = OpVariable %17 Function
1243fd4e5da5Sopenharmony_ci          5,   // %5 = OpVariable %17 Function
1244fd4e5da5Sopenharmony_ci          22,  // %22 = OpPhi %8 %10 %20 %23 %24
1245fd4e5da5Sopenharmony_ci      };
1246fd4e5da5Sopenharmony_ci      CompareSets(l1_sim_resut.live_in_, live_in);
1247fd4e5da5Sopenharmony_ci
1248fd4e5da5Sopenharmony_ci      std::unordered_set<uint32_t> live_out{
1249fd4e5da5Sopenharmony_ci          3,   // %3 = OpVariable %9 Function
1250fd4e5da5Sopenharmony_ci          4,   // %4 = OpVariable %17 Function
1251fd4e5da5Sopenharmony_ci          5,   // %5 = OpVariable %17 Function
1252fd4e5da5Sopenharmony_ci          22,  // %22 = OpPhi %8 %10 %20 %23 %24
1253fd4e5da5Sopenharmony_ci      };
1254fd4e5da5Sopenharmony_ci      CompareSets(l1_sim_resut.live_out_, live_out);
1255fd4e5da5Sopenharmony_ci
1256fd4e5da5Sopenharmony_ci      EXPECT_EQ(l1_sim_resut.used_registers_, 6u);
1257fd4e5da5Sopenharmony_ci    }
1258fd4e5da5Sopenharmony_ci    {
1259fd4e5da5Sopenharmony_ci      SCOPED_TRACE("L2 simulation");
1260fd4e5da5Sopenharmony_ci      std::unordered_set<uint32_t> live_in{
1261fd4e5da5Sopenharmony_ci          3,   // %3 = OpVariable %9 Function
1262fd4e5da5Sopenharmony_ci          4,   // %4 = OpVariable %17 Function
1263fd4e5da5Sopenharmony_ci          5,   // %5 = OpVariable %17 Function
1264fd4e5da5Sopenharmony_ci          22,  // %22 = OpPhi %8 %10 %20 %23 %24
1265fd4e5da5Sopenharmony_ci      };
1266fd4e5da5Sopenharmony_ci      CompareSets(l2_sim_resut.live_in_, live_in);
1267fd4e5da5Sopenharmony_ci
1268fd4e5da5Sopenharmony_ci      std::unordered_set<uint32_t> live_out{
1269fd4e5da5Sopenharmony_ci          3,   // %3 = OpVariable %9 Function
1270fd4e5da5Sopenharmony_ci          22,  // %22 = OpPhi %8 %10 %20 %23 %24
1271fd4e5da5Sopenharmony_ci      };
1272fd4e5da5Sopenharmony_ci      CompareSets(l2_sim_resut.live_out_, live_out);
1273fd4e5da5Sopenharmony_ci
1274fd4e5da5Sopenharmony_ci      EXPECT_EQ(l2_sim_resut.used_registers_, 6u);
1275fd4e5da5Sopenharmony_ci    }
1276fd4e5da5Sopenharmony_ci  }
1277fd4e5da5Sopenharmony_ci}
1278fd4e5da5Sopenharmony_ci
1279fd4e5da5Sopenharmony_ci// Test that register liveness does not fail when there is an unreachable block.
1280fd4e5da5Sopenharmony_ci// We are not testing if the liveness is computed correctly because the specific
1281fd4e5da5Sopenharmony_ci// results do not matter for unreachable blocks.
1282fd4e5da5Sopenharmony_ciTEST_F(PassClassTest, RegisterLivenessWithUnreachableBlock) {
1283fd4e5da5Sopenharmony_ci  const std::string text = R"(
1284fd4e5da5Sopenharmony_ci               OpCapability Shader
1285fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
1286fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
1287fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %2 "main"
1288fd4e5da5Sopenharmony_ci               OpExecutionMode %2 OriginLowerLeft
1289fd4e5da5Sopenharmony_ci               OpSource GLSL 330
1290fd4e5da5Sopenharmony_ci               OpSourceExtension "GL_ARB_shading_language_420pack"
1291fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
1292fd4e5da5Sopenharmony_ci          %4 = OpTypeFunction %void
1293fd4e5da5Sopenharmony_ci          %2 = OpFunction %void None %4
1294fd4e5da5Sopenharmony_ci          %5 = OpLabel
1295fd4e5da5Sopenharmony_ci               OpBranch %6
1296fd4e5da5Sopenharmony_ci          %6 = OpLabel
1297fd4e5da5Sopenharmony_ci               OpLoopMerge %7 %8 None
1298fd4e5da5Sopenharmony_ci               OpBranch %9
1299fd4e5da5Sopenharmony_ci          %9 = OpLabel
1300fd4e5da5Sopenharmony_ci               OpBranch %7
1301fd4e5da5Sopenharmony_ci          %8 = OpLabel
1302fd4e5da5Sopenharmony_ci               OpBranch %6
1303fd4e5da5Sopenharmony_ci          %7 = OpLabel
1304fd4e5da5Sopenharmony_ci               OpReturn
1305fd4e5da5Sopenharmony_ci               OpFunctionEnd
1306fd4e5da5Sopenharmony_ci  )";
1307fd4e5da5Sopenharmony_ci
1308fd4e5da5Sopenharmony_ci  std::unique_ptr<IRContext> context =
1309fd4e5da5Sopenharmony_ci      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
1310fd4e5da5Sopenharmony_ci                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1311fd4e5da5Sopenharmony_ci  Module* module = context->module();
1312fd4e5da5Sopenharmony_ci  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
1313fd4e5da5Sopenharmony_ci                             << text << std::endl;
1314fd4e5da5Sopenharmony_ci  Function* f = &*module->begin();
1315fd4e5da5Sopenharmony_ci  LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
1316fd4e5da5Sopenharmony_ci  liveness_analysis->Get(f);
1317fd4e5da5Sopenharmony_ci}
1318fd4e5da5Sopenharmony_ci
1319fd4e5da5Sopenharmony_ci}  // namespace
1320fd4e5da5Sopenharmony_ci}  // namespace opt
1321fd4e5da5Sopenharmony_ci}  // namespace spvtools
1322