1fd4e5da5Sopenharmony_ci// Copyright (c) 2016 Google Inc.
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#include <tuple>
17fd4e5da5Sopenharmony_ci#include <unordered_set>
18fd4e5da5Sopenharmony_ci#include <utility>
19fd4e5da5Sopenharmony_ci#include <vector>
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h"
22fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h"
23fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h"
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_cinamespace spvtools {
26fd4e5da5Sopenharmony_cinamespace opt {
27fd4e5da5Sopenharmony_cinamespace {
28fd4e5da5Sopenharmony_ci
29fd4e5da5Sopenharmony_ci// Returns the types defining instructions commonly used in many tests.
30fd4e5da5Sopenharmony_cistd::vector<std::string> CommonTypes() {
31fd4e5da5Sopenharmony_ci  return std::vector<std::string>{
32fd4e5da5Sopenharmony_ci      // clang-format off
33fd4e5da5Sopenharmony_ci    // scalar types
34fd4e5da5Sopenharmony_ci    "%bool = OpTypeBool",
35fd4e5da5Sopenharmony_ci    "%uint = OpTypeInt 32 0",
36fd4e5da5Sopenharmony_ci    "%int = OpTypeInt 32 1",
37fd4e5da5Sopenharmony_ci    "%uint64 = OpTypeInt 64 0",
38fd4e5da5Sopenharmony_ci    "%int64 = OpTypeInt 64 1",
39fd4e5da5Sopenharmony_ci    "%float = OpTypeFloat 32",
40fd4e5da5Sopenharmony_ci    "%double = OpTypeFloat 64",
41fd4e5da5Sopenharmony_ci    // vector types
42fd4e5da5Sopenharmony_ci    "%v2bool = OpTypeVector %bool 2",
43fd4e5da5Sopenharmony_ci    "%v2uint = OpTypeVector %uint 2",
44fd4e5da5Sopenharmony_ci    "%v2int = OpTypeVector %int 2",
45fd4e5da5Sopenharmony_ci    "%v3int = OpTypeVector %int 3",
46fd4e5da5Sopenharmony_ci    "%v4int = OpTypeVector %int 4",
47fd4e5da5Sopenharmony_ci    "%v2float = OpTypeVector %float 2",
48fd4e5da5Sopenharmony_ci    "%v3float = OpTypeVector %float 3",
49fd4e5da5Sopenharmony_ci    "%v2double = OpTypeVector %double 2",
50fd4e5da5Sopenharmony_ci    // struct types
51fd4e5da5Sopenharmony_ci    "%inner_struct = OpTypeStruct %bool %float",
52fd4e5da5Sopenharmony_ci    "%outer_struct = OpTypeStruct %inner_struct %int %double",
53fd4e5da5Sopenharmony_ci    "%flat_struct = OpTypeStruct %bool %int %float %double",
54fd4e5da5Sopenharmony_ci    // variable pointer types
55fd4e5da5Sopenharmony_ci    "%_pf_bool = OpTypePointer Function %bool",
56fd4e5da5Sopenharmony_ci    "%_pf_uint = OpTypePointer Function %uint",
57fd4e5da5Sopenharmony_ci    "%_pf_int = OpTypePointer Function %int",
58fd4e5da5Sopenharmony_ci    "%_pf_uint64 = OpTypePointer Function %uint64",
59fd4e5da5Sopenharmony_ci    "%_pf_int64 = OpTypePointer Function %int64",
60fd4e5da5Sopenharmony_ci    "%_pf_float = OpTypePointer Function %float",
61fd4e5da5Sopenharmony_ci    "%_pf_double = OpTypePointer Function %double",
62fd4e5da5Sopenharmony_ci    "%_pf_v2int = OpTypePointer Function %v2int",
63fd4e5da5Sopenharmony_ci    "%_pf_v3int = OpTypePointer Function %v3int",
64fd4e5da5Sopenharmony_ci    "%_pf_v4int = OpTypePointer Function %v4int",
65fd4e5da5Sopenharmony_ci    "%_pf_v2float = OpTypePointer Function %v2float",
66fd4e5da5Sopenharmony_ci    "%_pf_v3float = OpTypePointer Function %v3float",
67fd4e5da5Sopenharmony_ci    "%_pf_v2double = OpTypePointer Function %v2double",
68fd4e5da5Sopenharmony_ci    "%_pf_inner_struct = OpTypePointer Function %inner_struct",
69fd4e5da5Sopenharmony_ci    "%_pf_outer_struct = OpTypePointer Function %outer_struct",
70fd4e5da5Sopenharmony_ci    "%_pf_flat_struct = OpTypePointer Function %flat_struct",
71fd4e5da5Sopenharmony_ci      // clang-format on
72fd4e5da5Sopenharmony_ci  };
73fd4e5da5Sopenharmony_ci}
74fd4e5da5Sopenharmony_ci
75fd4e5da5Sopenharmony_ci// A helper function to strip OpName instructions from the given string of
76fd4e5da5Sopenharmony_ci// disassembly code and put those debug instructions to a set. Returns the
77fd4e5da5Sopenharmony_ci// string with all OpName instruction stripped and a set of OpName
78fd4e5da5Sopenharmony_ci// instructions.
79fd4e5da5Sopenharmony_cistd::tuple<std::string, std::unordered_set<std::string>>
80fd4e5da5Sopenharmony_ciStripOpNameInstructionsToSet(const std::string& str) {
81fd4e5da5Sopenharmony_ci  std::stringstream ss(str);
82fd4e5da5Sopenharmony_ci  std::ostringstream oss;
83fd4e5da5Sopenharmony_ci  std::string inst_str;
84fd4e5da5Sopenharmony_ci  std::unordered_set<std::string> opname_instructions;
85fd4e5da5Sopenharmony_ci  while (std::getline(ss, inst_str, '\n')) {
86fd4e5da5Sopenharmony_ci    if (inst_str.find("OpName %") == std::string::npos) {
87fd4e5da5Sopenharmony_ci      oss << inst_str << '\n';
88fd4e5da5Sopenharmony_ci    } else {
89fd4e5da5Sopenharmony_ci      opname_instructions.insert(inst_str);
90fd4e5da5Sopenharmony_ci    }
91fd4e5da5Sopenharmony_ci  }
92fd4e5da5Sopenharmony_ci  return std::make_tuple(oss.str(), std::move(opname_instructions));
93fd4e5da5Sopenharmony_ci}
94fd4e5da5Sopenharmony_ci
95fd4e5da5Sopenharmony_ci// The test fixture for all tests of UnifyConstantPass. This fixture defines
96fd4e5da5Sopenharmony_ci// the rule of checking: all the optimized code should be exactly the same as
97fd4e5da5Sopenharmony_ci// the expected code, except the OpName instructions, which can be different in
98fd4e5da5Sopenharmony_ci// order.
99fd4e5da5Sopenharmony_citemplate <typename T>
100fd4e5da5Sopenharmony_ciclass UnifyConstantTest : public PassTest<T> {
101fd4e5da5Sopenharmony_ci protected:
102fd4e5da5Sopenharmony_ci  // Runs UnifyConstantPass on the code built from the given |test_builder|,
103fd4e5da5Sopenharmony_ci  // and checks whether the optimization result matches with the code built
104fd4e5da5Sopenharmony_ci  // from |expected_builder|.
105fd4e5da5Sopenharmony_ci  void Check(const AssemblyBuilder& expected_builder,
106fd4e5da5Sopenharmony_ci             const AssemblyBuilder& test_builder) {
107fd4e5da5Sopenharmony_ci    // unoptimized code
108fd4e5da5Sopenharmony_ci    const std::string original_before_strip = test_builder.GetCode();
109fd4e5da5Sopenharmony_ci    std::string original_without_opnames;
110fd4e5da5Sopenharmony_ci    std::unordered_set<std::string> original_opnames;
111fd4e5da5Sopenharmony_ci    std::tie(original_without_opnames, original_opnames) =
112fd4e5da5Sopenharmony_ci        StripOpNameInstructionsToSet(original_before_strip);
113fd4e5da5Sopenharmony_ci
114fd4e5da5Sopenharmony_ci    // expected code
115fd4e5da5Sopenharmony_ci    std::string expected_without_opnames;
116fd4e5da5Sopenharmony_ci    std::unordered_set<std::string> expected_opnames;
117fd4e5da5Sopenharmony_ci    std::tie(expected_without_opnames, expected_opnames) =
118fd4e5da5Sopenharmony_ci        StripOpNameInstructionsToSet(expected_builder.GetCode());
119fd4e5da5Sopenharmony_ci
120fd4e5da5Sopenharmony_ci    // optimized code
121fd4e5da5Sopenharmony_ci    std::string optimized_before_strip;
122fd4e5da5Sopenharmony_ci    auto status = Pass::Status::SuccessWithoutChange;
123fd4e5da5Sopenharmony_ci    std::tie(optimized_before_strip, status) =
124fd4e5da5Sopenharmony_ci        this->template SinglePassRunAndDisassemble<UnifyConstantPass>(
125fd4e5da5Sopenharmony_ci            test_builder.GetCode(),
126fd4e5da5Sopenharmony_ci            /* skip_nop = */ true, /* do_validation = */ false);
127fd4e5da5Sopenharmony_ci    std::string optimized_without_opnames;
128fd4e5da5Sopenharmony_ci    std::unordered_set<std::string> optimized_opnames;
129fd4e5da5Sopenharmony_ci    std::tie(optimized_without_opnames, optimized_opnames) =
130fd4e5da5Sopenharmony_ci        StripOpNameInstructionsToSet(optimized_before_strip);
131fd4e5da5Sopenharmony_ci
132fd4e5da5Sopenharmony_ci    // Flag "status" should be returned correctly.
133fd4e5da5Sopenharmony_ci    EXPECT_NE(Pass::Status::Failure, status);
134fd4e5da5Sopenharmony_ci    EXPECT_EQ(expected_without_opnames == original_without_opnames,
135fd4e5da5Sopenharmony_ci              status == Pass::Status::SuccessWithoutChange);
136fd4e5da5Sopenharmony_ci    // Code except OpName instructions should be exactly the same.
137fd4e5da5Sopenharmony_ci    EXPECT_EQ(expected_without_opnames, optimized_without_opnames);
138fd4e5da5Sopenharmony_ci    // OpName instructions can be in different order, but the content must be
139fd4e5da5Sopenharmony_ci    // the same.
140fd4e5da5Sopenharmony_ci    EXPECT_EQ(expected_opnames, optimized_opnames);
141fd4e5da5Sopenharmony_ci  }
142fd4e5da5Sopenharmony_ci};
143fd4e5da5Sopenharmony_ci
144fd4e5da5Sopenharmony_ciusing UnifyFrontEndConstantSingleTest =
145fd4e5da5Sopenharmony_ci    UnifyConstantTest<PassTest<::testing::Test>>;
146fd4e5da5Sopenharmony_ci
147fd4e5da5Sopenharmony_ciTEST_F(UnifyFrontEndConstantSingleTest, Basic) {
148fd4e5da5Sopenharmony_ci  AssemblyBuilder test_builder;
149fd4e5da5Sopenharmony_ci  AssemblyBuilder expected_builder;
150fd4e5da5Sopenharmony_ci
151fd4e5da5Sopenharmony_ci  test_builder
152fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
153fd4e5da5Sopenharmony_ci          "%uint = OpTypeInt 32 0", "%_pf_uint = OpTypePointer Function %uint",
154fd4e5da5Sopenharmony_ci          "%unsigned_1 = OpConstant %uint 1",
155fd4e5da5Sopenharmony_ci          "%unsigned_1_duplicate = OpConstant %uint 1",  // duplicated constant
156fd4e5da5Sopenharmony_ci      })
157fd4e5da5Sopenharmony_ci      .AppendInMain({
158fd4e5da5Sopenharmony_ci          "%uint_var = OpVariable %_pf_uint Function",
159fd4e5da5Sopenharmony_ci          "OpStore %uint_var %unsigned_1_duplicate",
160fd4e5da5Sopenharmony_ci      });
161fd4e5da5Sopenharmony_ci
162fd4e5da5Sopenharmony_ci  expected_builder
163fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
164fd4e5da5Sopenharmony_ci          "%uint = OpTypeInt 32 0",
165fd4e5da5Sopenharmony_ci          "%_pf_uint = OpTypePointer Function %uint",
166fd4e5da5Sopenharmony_ci          "%unsigned_1 = OpConstant %uint 1",
167fd4e5da5Sopenharmony_ci      })
168fd4e5da5Sopenharmony_ci      .AppendInMain({
169fd4e5da5Sopenharmony_ci          "%uint_var = OpVariable %_pf_uint Function",
170fd4e5da5Sopenharmony_ci          "OpStore %uint_var %unsigned_1",
171fd4e5da5Sopenharmony_ci      })
172fd4e5da5Sopenharmony_ci      .AppendNames({
173fd4e5da5Sopenharmony_ci          "OpName %unsigned_1 \"unsigned_1_duplicate\"",  // the OpName
174fd4e5da5Sopenharmony_ci                                                          // instruction of the
175fd4e5da5Sopenharmony_ci                                                          // removed duplicated
176fd4e5da5Sopenharmony_ci                                                          // constant won't be
177fd4e5da5Sopenharmony_ci                                                          // erased.
178fd4e5da5Sopenharmony_ci      });
179fd4e5da5Sopenharmony_ci  Check(expected_builder, test_builder);
180fd4e5da5Sopenharmony_ci}
181fd4e5da5Sopenharmony_ci
182fd4e5da5Sopenharmony_ciTEST_F(UnifyFrontEndConstantSingleTest, SkipWhenResultIdHasDecorations) {
183fd4e5da5Sopenharmony_ci  AssemblyBuilder test_builder;
184fd4e5da5Sopenharmony_ci  AssemblyBuilder expected_builder;
185fd4e5da5Sopenharmony_ci
186fd4e5da5Sopenharmony_ci  test_builder
187fd4e5da5Sopenharmony_ci      .AppendAnnotations({
188fd4e5da5Sopenharmony_ci          // So far we don't have valid decorations for constants. This is
189fd4e5da5Sopenharmony_ci          // preparing for the future updates of SPIR-V.
190fd4e5da5Sopenharmony_ci          // TODO(qining): change to a valid decoration once they are available.
191fd4e5da5Sopenharmony_ci          "OpDecorate %f_1 RelaxedPrecision",
192fd4e5da5Sopenharmony_ci          "OpDecorate %f_2_dup RelaxedPrecision",
193fd4e5da5Sopenharmony_ci      })
194fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
195fd4e5da5Sopenharmony_ci          // clang-format off
196fd4e5da5Sopenharmony_ci          "%float = OpTypeFloat 32",
197fd4e5da5Sopenharmony_ci          "%_pf_float = OpTypePointer Function %float",
198fd4e5da5Sopenharmony_ci          "%f_1 = OpConstant %float 1",
199fd4e5da5Sopenharmony_ci          // %f_1 has decoration, so %f_1 will not be used to replace %f_1_dup.
200fd4e5da5Sopenharmony_ci          "%f_1_dup = OpConstant %float 1",
201fd4e5da5Sopenharmony_ci          "%f_2 = OpConstant %float 2",
202fd4e5da5Sopenharmony_ci          // %_2_dup has decoration, so %f_2 will not replace %f_2_dup.
203fd4e5da5Sopenharmony_ci          "%f_2_dup = OpConstant %float 2",
204fd4e5da5Sopenharmony_ci          // no decoration for %f_3 or %f_3_dup, %f_3_dup should be replaced.
205fd4e5da5Sopenharmony_ci          "%f_3 = OpConstant %float 3",
206fd4e5da5Sopenharmony_ci          "%f_3_dup = OpConstant %float 3",
207fd4e5da5Sopenharmony_ci          // clang-format on
208fd4e5da5Sopenharmony_ci      })
209fd4e5da5Sopenharmony_ci      .AppendInMain({
210fd4e5da5Sopenharmony_ci          // clang-format off
211fd4e5da5Sopenharmony_ci          "%f_var = OpVariable %_pf_float Function",
212fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_1_dup",
213fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_2_dup",
214fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_3_dup",
215fd4e5da5Sopenharmony_ci          // clang-format on
216fd4e5da5Sopenharmony_ci      });
217fd4e5da5Sopenharmony_ci
218fd4e5da5Sopenharmony_ci  expected_builder
219fd4e5da5Sopenharmony_ci      .AppendAnnotations({
220fd4e5da5Sopenharmony_ci          "OpDecorate %f_1 RelaxedPrecision",
221fd4e5da5Sopenharmony_ci          "OpDecorate %f_2_dup RelaxedPrecision",
222fd4e5da5Sopenharmony_ci      })
223fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
224fd4e5da5Sopenharmony_ci          // clang-format off
225fd4e5da5Sopenharmony_ci          "%float = OpTypeFloat 32",
226fd4e5da5Sopenharmony_ci          "%_pf_float = OpTypePointer Function %float",
227fd4e5da5Sopenharmony_ci          "%f_1 = OpConstant %float 1",
228fd4e5da5Sopenharmony_ci          "%f_1_dup = OpConstant %float 1",
229fd4e5da5Sopenharmony_ci          "%f_2 = OpConstant %float 2",
230fd4e5da5Sopenharmony_ci          "%f_2_dup = OpConstant %float 2",
231fd4e5da5Sopenharmony_ci          "%f_3 = OpConstant %float 3",
232fd4e5da5Sopenharmony_ci          // clang-format on
233fd4e5da5Sopenharmony_ci      })
234fd4e5da5Sopenharmony_ci      .AppendInMain({
235fd4e5da5Sopenharmony_ci          // clang-format off
236fd4e5da5Sopenharmony_ci          "%f_var = OpVariable %_pf_float Function",
237fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_1_dup",
238fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_2_dup",
239fd4e5da5Sopenharmony_ci          "OpStore %f_var %f_3",
240fd4e5da5Sopenharmony_ci          // clang-format on
241fd4e5da5Sopenharmony_ci      })
242fd4e5da5Sopenharmony_ci      .AppendNames({
243fd4e5da5Sopenharmony_ci          "OpName %f_3 \"f_3_dup\"",
244fd4e5da5Sopenharmony_ci      });
245fd4e5da5Sopenharmony_ci
246fd4e5da5Sopenharmony_ci  Check(expected_builder, test_builder);
247fd4e5da5Sopenharmony_ci}
248fd4e5da5Sopenharmony_ci
249fd4e5da5Sopenharmony_ciTEST_F(UnifyFrontEndConstantSingleTest, UnifyWithDecorationOnTypes) {
250fd4e5da5Sopenharmony_ci  AssemblyBuilder test_builder;
251fd4e5da5Sopenharmony_ci  AssemblyBuilder expected_builder;
252fd4e5da5Sopenharmony_ci
253fd4e5da5Sopenharmony_ci  test_builder
254fd4e5da5Sopenharmony_ci      .AppendAnnotations({
255fd4e5da5Sopenharmony_ci          "OpMemberDecorate %flat_d 1 RelaxedPrecision",
256fd4e5da5Sopenharmony_ci      })
257fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
258fd4e5da5Sopenharmony_ci          // clang-format off
259fd4e5da5Sopenharmony_ci          "%int = OpTypeInt 32 1",
260fd4e5da5Sopenharmony_ci          "%float = OpTypeFloat 32",
261fd4e5da5Sopenharmony_ci          "%flat = OpTypeStruct %int %float",
262fd4e5da5Sopenharmony_ci          "%_pf_flat = OpTypePointer Function %flat",
263fd4e5da5Sopenharmony_ci          // decorated flat struct
264fd4e5da5Sopenharmony_ci          "%flat_d = OpTypeStruct %int %float",
265fd4e5da5Sopenharmony_ci          "%_pf_flat_d = OpTypePointer Function %flat_d",
266fd4e5da5Sopenharmony_ci          // preserved constants. %flat_1 and %flat_d has same members, but
267fd4e5da5Sopenharmony_ci          // their type are different in decorations, so they should not be
268fd4e5da5Sopenharmony_ci          // used to replace each other.
269fd4e5da5Sopenharmony_ci          "%int_1 = OpConstant %int 1",
270fd4e5da5Sopenharmony_ci          "%float_1 = OpConstant %float 1",
271fd4e5da5Sopenharmony_ci          "%flat_1 = OpConstantComposite %flat %int_1 %float_1",
272fd4e5da5Sopenharmony_ci          "%flat_d_1 = OpConstantComposite %flat_d %int_1 %float_1",
273fd4e5da5Sopenharmony_ci          // duplicated constants.
274fd4e5da5Sopenharmony_ci          "%flat_1_dup = OpConstantComposite %flat %int_1 %float_1",
275fd4e5da5Sopenharmony_ci          "%flat_d_1_dup = OpConstantComposite %flat_d %int_1 %float_1",
276fd4e5da5Sopenharmony_ci          // clang-format on
277fd4e5da5Sopenharmony_ci      })
278fd4e5da5Sopenharmony_ci      .AppendInMain({
279fd4e5da5Sopenharmony_ci          "%flat_var = OpVariable %_pf_flat Function",
280fd4e5da5Sopenharmony_ci          "OpStore %flat_var %flat_1_dup",
281fd4e5da5Sopenharmony_ci          "%flat_d_var = OpVariable %_pf_flat_d Function",
282fd4e5da5Sopenharmony_ci          "OpStore %flat_d_var %flat_d_1_dup",
283fd4e5da5Sopenharmony_ci      });
284fd4e5da5Sopenharmony_ci
285fd4e5da5Sopenharmony_ci  expected_builder
286fd4e5da5Sopenharmony_ci      .AppendAnnotations({
287fd4e5da5Sopenharmony_ci          "OpMemberDecorate %flat_d 1 RelaxedPrecision",
288fd4e5da5Sopenharmony_ci      })
289fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals({
290fd4e5da5Sopenharmony_ci          // clang-format off
291fd4e5da5Sopenharmony_ci          "%int = OpTypeInt 32 1",
292fd4e5da5Sopenharmony_ci          "%float = OpTypeFloat 32",
293fd4e5da5Sopenharmony_ci          "%flat = OpTypeStruct %int %float",
294fd4e5da5Sopenharmony_ci          "%_pf_flat = OpTypePointer Function %flat",
295fd4e5da5Sopenharmony_ci          // decorated flat struct
296fd4e5da5Sopenharmony_ci          "%flat_d = OpTypeStruct %int %float",
297fd4e5da5Sopenharmony_ci          "%_pf_flat_d = OpTypePointer Function %flat_d",
298fd4e5da5Sopenharmony_ci          "%int_1 = OpConstant %int 1",
299fd4e5da5Sopenharmony_ci          "%float_1 = OpConstant %float 1",
300fd4e5da5Sopenharmony_ci          "%flat_1 = OpConstantComposite %flat %int_1 %float_1",
301fd4e5da5Sopenharmony_ci          "%flat_d_1 = OpConstantComposite %flat_d %int_1 %float_1",
302fd4e5da5Sopenharmony_ci          // clang-format on
303fd4e5da5Sopenharmony_ci      })
304fd4e5da5Sopenharmony_ci      .AppendInMain({
305fd4e5da5Sopenharmony_ci          "%flat_var = OpVariable %_pf_flat Function",
306fd4e5da5Sopenharmony_ci          "OpStore %flat_var %flat_1",
307fd4e5da5Sopenharmony_ci          "%flat_d_var = OpVariable %_pf_flat_d Function",
308fd4e5da5Sopenharmony_ci          "OpStore %flat_d_var %flat_d_1",
309fd4e5da5Sopenharmony_ci      })
310fd4e5da5Sopenharmony_ci      .AppendNames({
311fd4e5da5Sopenharmony_ci          "OpName %flat_1 \"flat_1_dup\"",
312fd4e5da5Sopenharmony_ci          "OpName %flat_d_1 \"flat_d_1_dup\"",
313fd4e5da5Sopenharmony_ci      });
314fd4e5da5Sopenharmony_ci
315fd4e5da5Sopenharmony_ci  Check(expected_builder, test_builder);
316fd4e5da5Sopenharmony_ci}
317fd4e5da5Sopenharmony_ci
318fd4e5da5Sopenharmony_cistruct UnifyConstantTestCase {
319fd4e5da5Sopenharmony_ci  // preserved constants.
320fd4e5da5Sopenharmony_ci  std::vector<std::string> preserved_consts;
321fd4e5da5Sopenharmony_ci  // expected uses of the preserved constants.
322fd4e5da5Sopenharmony_ci  std::vector<std::string> use_preserved_consts;
323fd4e5da5Sopenharmony_ci  // duplicated constants of the preserved constants.
324fd4e5da5Sopenharmony_ci  std::vector<std::string> duplicate_consts;
325fd4e5da5Sopenharmony_ci  // uses of the duplicated constants, expected to be updated to use the
326fd4e5da5Sopenharmony_ci  // preserved constants.
327fd4e5da5Sopenharmony_ci  std::vector<std::string> use_duplicate_consts;
328fd4e5da5Sopenharmony_ci  // The updated OpName instructions that originally refer to duplicated
329fd4e5da5Sopenharmony_ci  // constants.
330fd4e5da5Sopenharmony_ci  std::vector<std::string> remapped_names;
331fd4e5da5Sopenharmony_ci};
332fd4e5da5Sopenharmony_ci
333fd4e5da5Sopenharmony_ciusing UnifyFrontEndConstantParamTest = UnifyConstantTest<
334fd4e5da5Sopenharmony_ci    PassTest<::testing::TestWithParam<UnifyConstantTestCase>>>;
335fd4e5da5Sopenharmony_ci
336fd4e5da5Sopenharmony_ciTEST_P(UnifyFrontEndConstantParamTest, TestCase) {
337fd4e5da5Sopenharmony_ci  auto& tc = GetParam();
338fd4e5da5Sopenharmony_ci  AssemblyBuilder test_builder;
339fd4e5da5Sopenharmony_ci  AssemblyBuilder expected_builder;
340fd4e5da5Sopenharmony_ci  test_builder.AppendTypesConstantsGlobals(CommonTypes());
341fd4e5da5Sopenharmony_ci  expected_builder.AppendTypesConstantsGlobals(CommonTypes());
342fd4e5da5Sopenharmony_ci
343fd4e5da5Sopenharmony_ci  test_builder.AppendTypesConstantsGlobals(tc.preserved_consts)
344fd4e5da5Sopenharmony_ci      .AppendTypesConstantsGlobals(tc.duplicate_consts)
345fd4e5da5Sopenharmony_ci      .AppendInMain(tc.use_duplicate_consts);
346fd4e5da5Sopenharmony_ci
347fd4e5da5Sopenharmony_ci  // Duplicated constants are killed in the expected output, and the debug
348fd4e5da5Sopenharmony_ci  // instructions attached to those duplicated instructions will be migrated to
349fd4e5da5Sopenharmony_ci  // the corresponding preserved constants.
350fd4e5da5Sopenharmony_ci  expected_builder.AppendTypesConstantsGlobals(tc.preserved_consts)
351fd4e5da5Sopenharmony_ci      .AppendInMain(tc.use_preserved_consts)
352fd4e5da5Sopenharmony_ci      .AppendNames(tc.remapped_names);
353fd4e5da5Sopenharmony_ci
354fd4e5da5Sopenharmony_ci  Check(expected_builder, test_builder);
355fd4e5da5Sopenharmony_ci}
356fd4e5da5Sopenharmony_ci
357fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
358fd4e5da5Sopenharmony_ci    Case, UnifyFrontEndConstantParamTest,
359fd4e5da5Sopenharmony_ci    ::
360fd4e5da5Sopenharmony_ci        testing::
361fd4e5da5Sopenharmony_ci            ValuesIn(
362fd4e5da5Sopenharmony_ci                std::
363fd4e5da5Sopenharmony_ci                    vector<UnifyConstantTestCase>(
364fd4e5da5Sopenharmony_ci                        {
365fd4e5da5Sopenharmony_ci                            // clang-format off
366fd4e5da5Sopenharmony_ci        // basic tests for scalar constants
367fd4e5da5Sopenharmony_ci        {
368fd4e5da5Sopenharmony_ci          // preserved constants
369fd4e5da5Sopenharmony_ci          {
370fd4e5da5Sopenharmony_ci            "%bool_true = OpConstantTrue %bool",
371fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
372fd4e5da5Sopenharmony_ci            "%signed_minus_1 = OpConstant %int64 -1",
373fd4e5da5Sopenharmony_ci            "%unsigned_max = OpConstant %uint64 18446744073709551615",
374fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
375fd4e5da5Sopenharmony_ci            "%double_1 = OpConstant %double 1",
376fd4e5da5Sopenharmony_ci          },
377fd4e5da5Sopenharmony_ci          // use preserved constants in main
378fd4e5da5Sopenharmony_ci          {
379fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
380fd4e5da5Sopenharmony_ci            "OpStore %bool_var %bool_true",
381fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
382fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_1",
383fd4e5da5Sopenharmony_ci            "%int64_var = OpVariable %_pf_int64 Function",
384fd4e5da5Sopenharmony_ci            "OpStore %int64_var %signed_minus_1",
385fd4e5da5Sopenharmony_ci            "%uint64_var = OpVariable %_pf_uint64 Function",
386fd4e5da5Sopenharmony_ci            "OpStore %uint64_var %unsigned_max",
387fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
388fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_1",
389fd4e5da5Sopenharmony_ci            "%double_var = OpVariable %_pf_double Function",
390fd4e5da5Sopenharmony_ci            "OpStore %double_var %double_1",
391fd4e5da5Sopenharmony_ci          },
392fd4e5da5Sopenharmony_ci          // duplicated constants
393fd4e5da5Sopenharmony_ci          {
394fd4e5da5Sopenharmony_ci            "%bool_true_duplicate = OpConstantTrue %bool",
395fd4e5da5Sopenharmony_ci            "%signed_1_duplicate = OpConstant %int 1",
396fd4e5da5Sopenharmony_ci            "%signed_minus_1_duplicate = OpConstant %int64 -1",
397fd4e5da5Sopenharmony_ci            "%unsigned_max_duplicate = OpConstant %uint64 18446744073709551615",
398fd4e5da5Sopenharmony_ci            "%float_1_duplicate = OpConstant %float 1",
399fd4e5da5Sopenharmony_ci            "%double_1_duplicate = OpConstant %double 1",
400fd4e5da5Sopenharmony_ci          },
401fd4e5da5Sopenharmony_ci          // use duplicated constants in main
402fd4e5da5Sopenharmony_ci          {
403fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
404fd4e5da5Sopenharmony_ci            "OpStore %bool_var %bool_true_duplicate",
405fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
406fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_1_duplicate",
407fd4e5da5Sopenharmony_ci            "%int64_var = OpVariable %_pf_int64 Function",
408fd4e5da5Sopenharmony_ci            "OpStore %int64_var %signed_minus_1_duplicate",
409fd4e5da5Sopenharmony_ci            "%uint64_var = OpVariable %_pf_uint64 Function",
410fd4e5da5Sopenharmony_ci            "OpStore %uint64_var %unsigned_max_duplicate",
411fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
412fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_1_duplicate",
413fd4e5da5Sopenharmony_ci            "%double_var = OpVariable %_pf_double Function",
414fd4e5da5Sopenharmony_ci            "OpStore %double_var %double_1_duplicate",
415fd4e5da5Sopenharmony_ci          },
416fd4e5da5Sopenharmony_ci          // remapped names
417fd4e5da5Sopenharmony_ci          {
418fd4e5da5Sopenharmony_ci            "OpName %bool_true \"bool_true_duplicate\"",
419fd4e5da5Sopenharmony_ci            "OpName %signed_1 \"signed_1_duplicate\"",
420fd4e5da5Sopenharmony_ci            "OpName %signed_minus_1 \"signed_minus_1_duplicate\"",
421fd4e5da5Sopenharmony_ci            "OpName %unsigned_max \"unsigned_max_duplicate\"",
422fd4e5da5Sopenharmony_ci            "OpName %float_1 \"float_1_duplicate\"",
423fd4e5da5Sopenharmony_ci            "OpName %double_1 \"double_1_duplicate\"",
424fd4e5da5Sopenharmony_ci          },
425fd4e5da5Sopenharmony_ci        },
426fd4e5da5Sopenharmony_ci        // NaN in different bit patterns should not be unified, but the ones
427fd4e5da5Sopenharmony_ci        // using same bit pattern should be unified.
428fd4e5da5Sopenharmony_ci        {
429fd4e5da5Sopenharmony_ci          // preserved constants
430fd4e5da5Sopenharmony_ci          {
431fd4e5da5Sopenharmony_ci            "%float_nan_1 = OpConstant %float 0x1.8p+128", // !2143289344, 7FC00000
432fd4e5da5Sopenharmony_ci            "%float_nan_2 = OpConstant %float 0x1.800002p+128",// !2143289345 7FC00001
433fd4e5da5Sopenharmony_ci          },
434fd4e5da5Sopenharmony_ci          // use preserved constants in main
435fd4e5da5Sopenharmony_ci          {
436fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
437fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_nan_1",
438fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_nan_2",
439fd4e5da5Sopenharmony_ci          },
440fd4e5da5Sopenharmony_ci          // duplicated constants
441fd4e5da5Sopenharmony_ci          {
442fd4e5da5Sopenharmony_ci            "%float_nan_1_duplicate = OpConstant %float 0x1.8p+128", // !2143289344, 7FC00000
443fd4e5da5Sopenharmony_ci            "%float_nan_2_duplicate = OpConstant %float 0x1.800002p+128",// !2143289345, 7FC00001
444fd4e5da5Sopenharmony_ci          },
445fd4e5da5Sopenharmony_ci          // use duplicated constants in main
446fd4e5da5Sopenharmony_ci          {
447fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
448fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_nan_1_duplicate",
449fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_nan_2_duplicate",
450fd4e5da5Sopenharmony_ci          },
451fd4e5da5Sopenharmony_ci          // remapped names
452fd4e5da5Sopenharmony_ci          {
453fd4e5da5Sopenharmony_ci            "OpName %float_nan_1 \"float_nan_1_duplicate\"",
454fd4e5da5Sopenharmony_ci            "OpName %float_nan_2 \"float_nan_2_duplicate\"",
455fd4e5da5Sopenharmony_ci          },
456fd4e5da5Sopenharmony_ci        },
457fd4e5da5Sopenharmony_ci        // null values
458fd4e5da5Sopenharmony_ci        {
459fd4e5da5Sopenharmony_ci          // preserved constants
460fd4e5da5Sopenharmony_ci          {
461fd4e5da5Sopenharmony_ci            "%bool_null = OpConstantNull %bool",
462fd4e5da5Sopenharmony_ci            "%signed_null = OpConstantNull %int",
463fd4e5da5Sopenharmony_ci            "%signed_64_null = OpConstantNull %int64",
464fd4e5da5Sopenharmony_ci            "%float_null = OpConstantNull %float",
465fd4e5da5Sopenharmony_ci            "%double_null = OpConstantNull %double",
466fd4e5da5Sopenharmony_ci            // zero-valued constants will not be unified with the equivalent
467fd4e5da5Sopenharmony_ci            // null constants.
468fd4e5da5Sopenharmony_ci            "%signed_zero = OpConstant %int 0",
469fd4e5da5Sopenharmony_ci          },
470fd4e5da5Sopenharmony_ci          // use preserved constants in main
471fd4e5da5Sopenharmony_ci          {
472fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
473fd4e5da5Sopenharmony_ci            "OpStore %bool_var %bool_null",
474fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
475fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_null",
476fd4e5da5Sopenharmony_ci            "%int64_var = OpVariable %_pf_int64 Function",
477fd4e5da5Sopenharmony_ci            "OpStore %int64_var %signed_64_null",
478fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
479fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_null",
480fd4e5da5Sopenharmony_ci            "%double_var = OpVariable %_pf_double Function",
481fd4e5da5Sopenharmony_ci            "OpStore %double_var %double_null",
482fd4e5da5Sopenharmony_ci          },
483fd4e5da5Sopenharmony_ci          // duplicated constants
484fd4e5da5Sopenharmony_ci          {
485fd4e5da5Sopenharmony_ci            "%bool_null_duplicate = OpConstantNull %bool",
486fd4e5da5Sopenharmony_ci            "%signed_null_duplicate = OpConstantNull %int",
487fd4e5da5Sopenharmony_ci            "%signed_64_null_duplicate = OpConstantNull %int64",
488fd4e5da5Sopenharmony_ci            "%float_null_duplicate = OpConstantNull %float",
489fd4e5da5Sopenharmony_ci            "%double_null_duplicate = OpConstantNull %double",
490fd4e5da5Sopenharmony_ci          },
491fd4e5da5Sopenharmony_ci          // use duplicated constants in main
492fd4e5da5Sopenharmony_ci          {
493fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
494fd4e5da5Sopenharmony_ci            "OpStore %bool_var %bool_null_duplicate",
495fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
496fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_null_duplicate",
497fd4e5da5Sopenharmony_ci            "%int64_var = OpVariable %_pf_int64 Function",
498fd4e5da5Sopenharmony_ci            "OpStore %int64_var %signed_64_null_duplicate",
499fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
500fd4e5da5Sopenharmony_ci            "OpStore %float_var %float_null_duplicate",
501fd4e5da5Sopenharmony_ci            "%double_var = OpVariable %_pf_double Function",
502fd4e5da5Sopenharmony_ci            "OpStore %double_var %double_null_duplicate",
503fd4e5da5Sopenharmony_ci          },
504fd4e5da5Sopenharmony_ci          // remapped names
505fd4e5da5Sopenharmony_ci          {
506fd4e5da5Sopenharmony_ci            "OpName %bool_null \"bool_null_duplicate\"",
507fd4e5da5Sopenharmony_ci            "OpName %signed_null \"signed_null_duplicate\"",
508fd4e5da5Sopenharmony_ci            "OpName %signed_64_null \"signed_64_null_duplicate\"",
509fd4e5da5Sopenharmony_ci            "OpName %float_null \"float_null_duplicate\"",
510fd4e5da5Sopenharmony_ci            "OpName %double_null \"double_null_duplicate\"",
511fd4e5da5Sopenharmony_ci          },
512fd4e5da5Sopenharmony_ci        },
513fd4e5da5Sopenharmony_ci        // constant sampler
514fd4e5da5Sopenharmony_ci        {
515fd4e5da5Sopenharmony_ci          // preserved constants
516fd4e5da5Sopenharmony_ci          {
517fd4e5da5Sopenharmony_ci            "%sampler = OpTypeSampler",
518fd4e5da5Sopenharmony_ci            "%_pf_sampler = OpTypePointer Function %sampler",
519fd4e5da5Sopenharmony_ci            "%sampler_1 = OpConstantSampler %sampler Repeat 0 Linear",
520fd4e5da5Sopenharmony_ci          },
521fd4e5da5Sopenharmony_ci          // use preserved constants in main
522fd4e5da5Sopenharmony_ci          {
523fd4e5da5Sopenharmony_ci            "%sampler_var = OpVariable %_pf_sampler Function",
524fd4e5da5Sopenharmony_ci            "OpStore %sampler_var %sampler_1",
525fd4e5da5Sopenharmony_ci          },
526fd4e5da5Sopenharmony_ci          // duplicated constants
527fd4e5da5Sopenharmony_ci          {
528fd4e5da5Sopenharmony_ci            "%sampler_1_duplicate = OpConstantSampler %sampler Repeat 0 Linear",
529fd4e5da5Sopenharmony_ci          },
530fd4e5da5Sopenharmony_ci          // use duplicated constants in main
531fd4e5da5Sopenharmony_ci          {
532fd4e5da5Sopenharmony_ci            "%sampler_var = OpVariable %_pf_sampler Function",
533fd4e5da5Sopenharmony_ci            "OpStore %sampler_var %sampler_1_duplicate",
534fd4e5da5Sopenharmony_ci          },
535fd4e5da5Sopenharmony_ci          // remapped names
536fd4e5da5Sopenharmony_ci          {
537fd4e5da5Sopenharmony_ci            "OpName %sampler_1 \"sampler_1_duplicate\"",
538fd4e5da5Sopenharmony_ci          },
539fd4e5da5Sopenharmony_ci        },
540fd4e5da5Sopenharmony_ci        // duplicate vector built from same ids.
541fd4e5da5Sopenharmony_ci        {
542fd4e5da5Sopenharmony_ci          // preserved constants
543fd4e5da5Sopenharmony_ci          {
544fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
545fd4e5da5Sopenharmony_ci            "%signed_2 = OpConstant %int 2",
546fd4e5da5Sopenharmony_ci            "%signed_3 = OpConstant %int 3",
547fd4e5da5Sopenharmony_ci            "%signed_4 = OpConstant %int 4",
548fd4e5da5Sopenharmony_ci            "%vec = OpConstantComposite %v4int %signed_1 %signed_2 %signed_3 %signed_4",
549fd4e5da5Sopenharmony_ci          },
550fd4e5da5Sopenharmony_ci          // use preserved constants in main
551fd4e5da5Sopenharmony_ci          {
552fd4e5da5Sopenharmony_ci            "%vec_var = OpVariable %_pf_v4int Function",
553fd4e5da5Sopenharmony_ci            "OpStore %vec_var %vec",
554fd4e5da5Sopenharmony_ci          },
555fd4e5da5Sopenharmony_ci          // duplicated constants
556fd4e5da5Sopenharmony_ci          {
557fd4e5da5Sopenharmony_ci            "%vec_duplicate = OpConstantComposite %v4int %signed_1 %signed_2 %signed_3 %signed_4",
558fd4e5da5Sopenharmony_ci          },
559fd4e5da5Sopenharmony_ci          // use duplicated constants in main
560fd4e5da5Sopenharmony_ci          {
561fd4e5da5Sopenharmony_ci            "%vec_var = OpVariable %_pf_v4int Function",
562fd4e5da5Sopenharmony_ci            "OpStore %vec_var %vec_duplicate",
563fd4e5da5Sopenharmony_ci          },
564fd4e5da5Sopenharmony_ci          // remapped names
565fd4e5da5Sopenharmony_ci          {
566fd4e5da5Sopenharmony_ci            "OpName %vec \"vec_duplicate\"",
567fd4e5da5Sopenharmony_ci          }
568fd4e5da5Sopenharmony_ci        },
569fd4e5da5Sopenharmony_ci        // duplicate vector built from duplicated ids.
570fd4e5da5Sopenharmony_ci        {
571fd4e5da5Sopenharmony_ci          // preserved constants
572fd4e5da5Sopenharmony_ci          {
573fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
574fd4e5da5Sopenharmony_ci            "%signed_2 = OpConstant %int 2",
575fd4e5da5Sopenharmony_ci            "%signed_3 = OpConstant %int 3",
576fd4e5da5Sopenharmony_ci            "%signed_4 = OpConstant %int 4",
577fd4e5da5Sopenharmony_ci            "%vec = OpConstantComposite %v4int %signed_1 %signed_2 %signed_3 %signed_4",
578fd4e5da5Sopenharmony_ci          },
579fd4e5da5Sopenharmony_ci          // use preserved constants in main
580fd4e5da5Sopenharmony_ci          {
581fd4e5da5Sopenharmony_ci            "%vec_var = OpVariable %_pf_v4int Function",
582fd4e5da5Sopenharmony_ci            "OpStore %vec_var %vec",
583fd4e5da5Sopenharmony_ci          },
584fd4e5da5Sopenharmony_ci          // duplicated constants
585fd4e5da5Sopenharmony_ci          {
586fd4e5da5Sopenharmony_ci            "%signed_3_duplicate = OpConstant %int 3",
587fd4e5da5Sopenharmony_ci            "%signed_4_duplicate = OpConstant %int 4",
588fd4e5da5Sopenharmony_ci            "%vec_duplicate = OpConstantComposite %v4int %signed_1 %signed_2 %signed_3_duplicate %signed_4_duplicate",
589fd4e5da5Sopenharmony_ci          },
590fd4e5da5Sopenharmony_ci          // use duplicated constants in main
591fd4e5da5Sopenharmony_ci          {
592fd4e5da5Sopenharmony_ci            "%vec_var = OpVariable %_pf_v4int Function",
593fd4e5da5Sopenharmony_ci            "OpStore %vec_var %vec_duplicate",
594fd4e5da5Sopenharmony_ci          },
595fd4e5da5Sopenharmony_ci          // remapped names
596fd4e5da5Sopenharmony_ci          {
597fd4e5da5Sopenharmony_ci            "OpName %signed_3 \"signed_3_duplicate\"",
598fd4e5da5Sopenharmony_ci            "OpName %signed_4 \"signed_4_duplicate\"",
599fd4e5da5Sopenharmony_ci            "OpName %vec \"vec_duplicate\"",
600fd4e5da5Sopenharmony_ci          },
601fd4e5da5Sopenharmony_ci        },
602fd4e5da5Sopenharmony_ci        // flat struct
603fd4e5da5Sopenharmony_ci        {
604fd4e5da5Sopenharmony_ci          // preserved constants
605fd4e5da5Sopenharmony_ci          {
606fd4e5da5Sopenharmony_ci            "%bool_true = OpConstantTrue %bool",
607fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
608fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
609fd4e5da5Sopenharmony_ci            "%double_1 = OpConstant %double 1",
610fd4e5da5Sopenharmony_ci            "%s = OpConstantComposite %flat_struct %bool_true %signed_1 %float_1 %double_1",
611fd4e5da5Sopenharmony_ci          },
612fd4e5da5Sopenharmony_ci          // use preserved constants in main
613fd4e5da5Sopenharmony_ci          {
614fd4e5da5Sopenharmony_ci            "%s_var = OpVariable %_pf_flat_struct Function",
615fd4e5da5Sopenharmony_ci            "OpStore %s_var %s",
616fd4e5da5Sopenharmony_ci          },
617fd4e5da5Sopenharmony_ci          // duplicated constants
618fd4e5da5Sopenharmony_ci          {
619fd4e5da5Sopenharmony_ci            "%float_1_duplicate = OpConstant %float 1",
620fd4e5da5Sopenharmony_ci            "%double_1_duplicate = OpConstant %double 1",
621fd4e5da5Sopenharmony_ci            "%s_duplicate = OpConstantComposite %flat_struct %bool_true %signed_1 %float_1_duplicate %double_1_duplicate",
622fd4e5da5Sopenharmony_ci          },
623fd4e5da5Sopenharmony_ci          // use duplicated constants in main
624fd4e5da5Sopenharmony_ci          {
625fd4e5da5Sopenharmony_ci            "%s_var = OpVariable %_pf_flat_struct Function",
626fd4e5da5Sopenharmony_ci            "OpStore %s_var %s_duplicate",
627fd4e5da5Sopenharmony_ci          },
628fd4e5da5Sopenharmony_ci          // remapped names
629fd4e5da5Sopenharmony_ci          {
630fd4e5da5Sopenharmony_ci            "OpName %float_1 \"float_1_duplicate\"",
631fd4e5da5Sopenharmony_ci            "OpName %double_1 \"double_1_duplicate\"",
632fd4e5da5Sopenharmony_ci            "OpName %s \"s_duplicate\"",
633fd4e5da5Sopenharmony_ci          },
634fd4e5da5Sopenharmony_ci        },
635fd4e5da5Sopenharmony_ci        // nested struct
636fd4e5da5Sopenharmony_ci        {
637fd4e5da5Sopenharmony_ci          // preserved constants
638fd4e5da5Sopenharmony_ci          {
639fd4e5da5Sopenharmony_ci            "%bool_true = OpConstantTrue %bool",
640fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
641fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
642fd4e5da5Sopenharmony_ci            "%double_1 = OpConstant %double 1",
643fd4e5da5Sopenharmony_ci            "%inner = OpConstantComposite %inner_struct %bool_true %float_1",
644fd4e5da5Sopenharmony_ci            "%outer = OpConstantComposite %outer_struct %inner %signed_1 %double_1",
645fd4e5da5Sopenharmony_ci          },
646fd4e5da5Sopenharmony_ci          // use preserved constants in main
647fd4e5da5Sopenharmony_ci          {
648fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
649fd4e5da5Sopenharmony_ci            "OpStore %outer_var %outer",
650fd4e5da5Sopenharmony_ci          },
651fd4e5da5Sopenharmony_ci          // duplicated constants
652fd4e5da5Sopenharmony_ci          {
653fd4e5da5Sopenharmony_ci            "%float_1_duplicate = OpConstant %float 1",
654fd4e5da5Sopenharmony_ci            "%double_1_duplicate = OpConstant %double 1",
655fd4e5da5Sopenharmony_ci            "%inner_duplicate = OpConstantComposite %inner_struct %bool_true %float_1_duplicate",
656fd4e5da5Sopenharmony_ci            "%outer_duplicate = OpConstantComposite %outer_struct %inner_duplicate %signed_1 %double_1_duplicate",
657fd4e5da5Sopenharmony_ci          },
658fd4e5da5Sopenharmony_ci          // use duplicated constants in main
659fd4e5da5Sopenharmony_ci          {
660fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
661fd4e5da5Sopenharmony_ci            "OpStore %outer_var %outer_duplicate",
662fd4e5da5Sopenharmony_ci          },
663fd4e5da5Sopenharmony_ci          // remapped names
664fd4e5da5Sopenharmony_ci          {
665fd4e5da5Sopenharmony_ci            "OpName %float_1 \"float_1_duplicate\"",
666fd4e5da5Sopenharmony_ci            "OpName %double_1 \"double_1_duplicate\"",
667fd4e5da5Sopenharmony_ci            "OpName %inner \"inner_duplicate\"",
668fd4e5da5Sopenharmony_ci            "OpName %outer \"outer_duplicate\"",
669fd4e5da5Sopenharmony_ci          },
670fd4e5da5Sopenharmony_ci        },
671fd4e5da5Sopenharmony_ci        // composite type null constants. Null constants and zero-valued
672fd4e5da5Sopenharmony_ci        // constants should not be used to replace each other.
673fd4e5da5Sopenharmony_ci        {
674fd4e5da5Sopenharmony_ci          // preserved constants
675fd4e5da5Sopenharmony_ci          {
676fd4e5da5Sopenharmony_ci            "%bool_zero = OpConstantFalse %bool",
677fd4e5da5Sopenharmony_ci            "%float_zero = OpConstant %float 0",
678fd4e5da5Sopenharmony_ci            "%int_null = OpConstantNull %int",
679fd4e5da5Sopenharmony_ci            "%double_null = OpConstantNull %double",
680fd4e5da5Sopenharmony_ci            // inner_struct type null constant.
681fd4e5da5Sopenharmony_ci            "%null_inner = OpConstantNull %inner_struct",
682fd4e5da5Sopenharmony_ci            // zero-valued composite constant built from zero-valued constant
683fd4e5da5Sopenharmony_ci            // component. inner_zero should not be replace by null_inner.
684fd4e5da5Sopenharmony_ci            "%inner_zero = OpConstantComposite %inner_struct %bool_zero %float_zero",
685fd4e5da5Sopenharmony_ci            // zero-valued composite constant built from zero-valued constants
686fd4e5da5Sopenharmony_ci            // and null constants.
687fd4e5da5Sopenharmony_ci            "%outer_zero = OpConstantComposite %outer_struct %inner_zero %int_null %double_null",
688fd4e5da5Sopenharmony_ci            // outer_struct type null constant, it should not be replaced by
689fd4e5da5Sopenharmony_ci            // outer_zero.
690fd4e5da5Sopenharmony_ci            "%null_outer = OpConstantNull %outer_struct",
691fd4e5da5Sopenharmony_ci          },
692fd4e5da5Sopenharmony_ci          // use preserved constants in main
693fd4e5da5Sopenharmony_ci          {
694fd4e5da5Sopenharmony_ci            "%inner_var = OpVariable %_pf_inner_struct Function",
695fd4e5da5Sopenharmony_ci            "OpStore %inner_var %inner_zero",
696fd4e5da5Sopenharmony_ci            "OpStore %inner_var %null_inner",
697fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
698fd4e5da5Sopenharmony_ci            "OpStore %outer_var %outer_zero",
699fd4e5da5Sopenharmony_ci            "OpStore %outer_var %null_outer",
700fd4e5da5Sopenharmony_ci          },
701fd4e5da5Sopenharmony_ci          // duplicated constants
702fd4e5da5Sopenharmony_ci          {
703fd4e5da5Sopenharmony_ci            "%null_inner_dup = OpConstantNull %inner_struct",
704fd4e5da5Sopenharmony_ci            "%null_outer_dup = OpConstantNull %outer_struct",
705fd4e5da5Sopenharmony_ci            "%inner_zero_dup = OpConstantComposite %inner_struct %bool_zero %float_zero",
706fd4e5da5Sopenharmony_ci            "%outer_zero_dup = OpConstantComposite %outer_struct %inner_zero_dup %int_null %double_null",
707fd4e5da5Sopenharmony_ci          },
708fd4e5da5Sopenharmony_ci          // use duplicated constants in main
709fd4e5da5Sopenharmony_ci          {
710fd4e5da5Sopenharmony_ci            "%inner_var = OpVariable %_pf_inner_struct Function",
711fd4e5da5Sopenharmony_ci            "OpStore %inner_var %inner_zero_dup",
712fd4e5da5Sopenharmony_ci            "OpStore %inner_var %null_inner_dup",
713fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
714fd4e5da5Sopenharmony_ci            "OpStore %outer_var %outer_zero_dup",
715fd4e5da5Sopenharmony_ci            "OpStore %outer_var %null_outer_dup",
716fd4e5da5Sopenharmony_ci          },
717fd4e5da5Sopenharmony_ci          // remapped names
718fd4e5da5Sopenharmony_ci          {
719fd4e5da5Sopenharmony_ci            "OpName %null_inner \"null_inner_dup\"",
720fd4e5da5Sopenharmony_ci            "OpName %null_outer \"null_outer_dup\"",
721fd4e5da5Sopenharmony_ci            "OpName %inner_zero \"inner_zero_dup\"",
722fd4e5da5Sopenharmony_ci            "OpName %outer_zero \"outer_zero_dup\"",
723fd4e5da5Sopenharmony_ci          },
724fd4e5da5Sopenharmony_ci        },
725fd4e5da5Sopenharmony_ci        // Spec Constants with SpecId decoration should be skipped.
726fd4e5da5Sopenharmony_ci        {
727fd4e5da5Sopenharmony_ci          // preserved constants
728fd4e5da5Sopenharmony_ci          {
729fd4e5da5Sopenharmony_ci            // Assembly builder will add OpDecorate SpecId instruction for the
730fd4e5da5Sopenharmony_ci            // following spec constant instructions automatically.
731fd4e5da5Sopenharmony_ci            "%spec_bool_1 = OpSpecConstantTrue %bool",
732fd4e5da5Sopenharmony_ci            "%spec_bool_2 = OpSpecConstantTrue %bool",
733fd4e5da5Sopenharmony_ci            "%spec_int_1 = OpSpecConstant %int 1",
734fd4e5da5Sopenharmony_ci            "%spec_int_2 = OpSpecConstant %int 1",
735fd4e5da5Sopenharmony_ci          },
736fd4e5da5Sopenharmony_ci          // use preserved constants in main
737fd4e5da5Sopenharmony_ci          {
738fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
739fd4e5da5Sopenharmony_ci            "OpStore %bool_var %spec_bool_1",
740fd4e5da5Sopenharmony_ci            "OpStore %bool_var %spec_bool_2",
741fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
742fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_int_1",
743fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_int_2",
744fd4e5da5Sopenharmony_ci          },
745fd4e5da5Sopenharmony_ci          // duplicated constants. No duplicated instruction to remove in this
746fd4e5da5Sopenharmony_ci          // case.
747fd4e5da5Sopenharmony_ci          {},
748fd4e5da5Sopenharmony_ci          // use duplicated constants in main. Same as the above 'use preserved
749fd4e5da5Sopenharmony_ci          // constants in main' defined above, as no instruction should be
750fd4e5da5Sopenharmony_ci          // removed in this case.
751fd4e5da5Sopenharmony_ci          {
752fd4e5da5Sopenharmony_ci            "%bool_var = OpVariable %_pf_bool Function",
753fd4e5da5Sopenharmony_ci            "OpStore %bool_var %spec_bool_1",
754fd4e5da5Sopenharmony_ci            "OpStore %bool_var %spec_bool_2",
755fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
756fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_int_1",
757fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_int_2",
758fd4e5da5Sopenharmony_ci          },
759fd4e5da5Sopenharmony_ci          // remapped names. No duplicated instruction removed, so this is
760fd4e5da5Sopenharmony_ci          // empty.
761fd4e5da5Sopenharmony_ci          {}
762fd4e5da5Sopenharmony_ci        },
763fd4e5da5Sopenharmony_ci        // spec constant composite
764fd4e5da5Sopenharmony_ci        {
765fd4e5da5Sopenharmony_ci          // preserved constants
766fd4e5da5Sopenharmony_ci          {
767fd4e5da5Sopenharmony_ci            "%spec_bool_true = OpSpecConstantTrue %bool",
768fd4e5da5Sopenharmony_ci            "%spec_signed_1 = OpSpecConstant %int 1",
769fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
770fd4e5da5Sopenharmony_ci            "%double_1 = OpConstant %double 1",
771fd4e5da5Sopenharmony_ci            "%spec_inner = OpSpecConstantComposite %inner_struct %spec_bool_true %float_1",
772fd4e5da5Sopenharmony_ci            "%spec_outer = OpSpecConstantComposite %outer_struct %spec_inner %spec_signed_1 %double_1",
773fd4e5da5Sopenharmony_ci            "%spec_vec2 = OpSpecConstantComposite %v2float %float_1 %float_1",
774fd4e5da5Sopenharmony_ci          },
775fd4e5da5Sopenharmony_ci          // use preserved constants in main
776fd4e5da5Sopenharmony_ci          {
777fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
778fd4e5da5Sopenharmony_ci            "OpStore %outer_var %spec_outer",
779fd4e5da5Sopenharmony_ci            "%v2float_var = OpVariable %_pf_v2float Function",
780fd4e5da5Sopenharmony_ci            "OpStore %v2float_var %spec_vec2",
781fd4e5da5Sopenharmony_ci          },
782fd4e5da5Sopenharmony_ci          // duplicated constants
783fd4e5da5Sopenharmony_ci          {
784fd4e5da5Sopenharmony_ci            "%float_1_duplicate = OpConstant %float 1",
785fd4e5da5Sopenharmony_ci            "%double_1_duplicate = OpConstant %double 1",
786fd4e5da5Sopenharmony_ci            "%spec_inner_duplicate = OpSpecConstantComposite %inner_struct %spec_bool_true %float_1_duplicate",
787fd4e5da5Sopenharmony_ci            "%spec_outer_duplicate = OpSpecConstantComposite %outer_struct %spec_inner_duplicate %spec_signed_1 %double_1_duplicate",
788fd4e5da5Sopenharmony_ci            "%spec_vec2_duplicate = OpSpecConstantComposite %v2float %float_1 %float_1_duplicate",
789fd4e5da5Sopenharmony_ci          },
790fd4e5da5Sopenharmony_ci          // use duplicated constants in main
791fd4e5da5Sopenharmony_ci          {
792fd4e5da5Sopenharmony_ci            "%outer_var = OpVariable %_pf_outer_struct Function",
793fd4e5da5Sopenharmony_ci            "OpStore %outer_var %spec_outer_duplicate",
794fd4e5da5Sopenharmony_ci            "%v2float_var = OpVariable %_pf_v2float Function",
795fd4e5da5Sopenharmony_ci            "OpStore %v2float_var %spec_vec2_duplicate",
796fd4e5da5Sopenharmony_ci          },
797fd4e5da5Sopenharmony_ci          // remapped names
798fd4e5da5Sopenharmony_ci          {
799fd4e5da5Sopenharmony_ci            "OpName %float_1 \"float_1_duplicate\"",
800fd4e5da5Sopenharmony_ci            "OpName %double_1 \"double_1_duplicate\"",
801fd4e5da5Sopenharmony_ci            "OpName %spec_inner \"spec_inner_duplicate\"",
802fd4e5da5Sopenharmony_ci            "OpName %spec_outer \"spec_outer_duplicate\"",
803fd4e5da5Sopenharmony_ci            "OpName %spec_vec2 \"spec_vec2_duplicate\"",
804fd4e5da5Sopenharmony_ci          },
805fd4e5da5Sopenharmony_ci        },
806fd4e5da5Sopenharmony_ci        // spec constant op with int scalar
807fd4e5da5Sopenharmony_ci        {
808fd4e5da5Sopenharmony_ci          // preserved constants
809fd4e5da5Sopenharmony_ci          {
810fd4e5da5Sopenharmony_ci            "%spec_signed_1 = OpSpecConstant %int 1",
811fd4e5da5Sopenharmony_ci            "%spec_signed_2 = OpSpecConstant %int 2",
812fd4e5da5Sopenharmony_ci            "%spec_signed_add = OpSpecConstantOp %int IAdd %spec_signed_1 %spec_signed_2",
813fd4e5da5Sopenharmony_ci          },
814fd4e5da5Sopenharmony_ci          // use preserved constants in main
815fd4e5da5Sopenharmony_ci          {
816fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
817fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_signed_add",
818fd4e5da5Sopenharmony_ci          },
819fd4e5da5Sopenharmony_ci          // duplicated constants
820fd4e5da5Sopenharmony_ci          {
821fd4e5da5Sopenharmony_ci            "%spec_signed_add_duplicate = OpSpecConstantOp %int IAdd %spec_signed_1 %spec_signed_2",
822fd4e5da5Sopenharmony_ci          },
823fd4e5da5Sopenharmony_ci          // use duplicated constants in main
824fd4e5da5Sopenharmony_ci          {
825fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
826fd4e5da5Sopenharmony_ci            "OpStore %int_var %spec_signed_add_duplicate",
827fd4e5da5Sopenharmony_ci          },
828fd4e5da5Sopenharmony_ci          // remapped names
829fd4e5da5Sopenharmony_ci          {
830fd4e5da5Sopenharmony_ci            "OpName %spec_signed_add \"spec_signed_add_duplicate\"",
831fd4e5da5Sopenharmony_ci          },
832fd4e5da5Sopenharmony_ci        },
833fd4e5da5Sopenharmony_ci        // spec constant op composite extract
834fd4e5da5Sopenharmony_ci        {
835fd4e5da5Sopenharmony_ci          // preserved constants
836fd4e5da5Sopenharmony_ci          {
837fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
838fd4e5da5Sopenharmony_ci            "%spec_vec2 = OpSpecConstantComposite %v2float %float_1 %float_1",
839fd4e5da5Sopenharmony_ci            "%spec_extract = OpSpecConstantOp %float CompositeExtract %spec_vec2 1",
840fd4e5da5Sopenharmony_ci          },
841fd4e5da5Sopenharmony_ci          // use preserved constants in main
842fd4e5da5Sopenharmony_ci          {
843fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
844fd4e5da5Sopenharmony_ci            "OpStore %float_var %spec_extract",
845fd4e5da5Sopenharmony_ci          },
846fd4e5da5Sopenharmony_ci          // duplicated constants
847fd4e5da5Sopenharmony_ci          {
848fd4e5da5Sopenharmony_ci            "%spec_extract_duplicate = OpSpecConstantOp %float CompositeExtract %spec_vec2 1",
849fd4e5da5Sopenharmony_ci          },
850fd4e5da5Sopenharmony_ci          // use duplicated constants in main
851fd4e5da5Sopenharmony_ci          {
852fd4e5da5Sopenharmony_ci            "%float_var = OpVariable %_pf_float Function",
853fd4e5da5Sopenharmony_ci            "OpStore %float_var %spec_extract_duplicate",
854fd4e5da5Sopenharmony_ci          },
855fd4e5da5Sopenharmony_ci          // remapped names
856fd4e5da5Sopenharmony_ci          {
857fd4e5da5Sopenharmony_ci            "OpName %spec_extract \"spec_extract_duplicate\"",
858fd4e5da5Sopenharmony_ci          },
859fd4e5da5Sopenharmony_ci        },
860fd4e5da5Sopenharmony_ci        // spec constant op vector shuffle
861fd4e5da5Sopenharmony_ci        {
862fd4e5da5Sopenharmony_ci          // preserved constants
863fd4e5da5Sopenharmony_ci          {
864fd4e5da5Sopenharmony_ci            "%float_1 = OpConstant %float 1",
865fd4e5da5Sopenharmony_ci            "%float_2 = OpConstant %float 2",
866fd4e5da5Sopenharmony_ci            "%spec_vec2_1 = OpSpecConstantComposite %v2float %float_1 %float_1",
867fd4e5da5Sopenharmony_ci            "%spec_vec2_2 = OpSpecConstantComposite %v2float %float_2 %float_2",
868fd4e5da5Sopenharmony_ci            "%spec_vector_shuffle = OpSpecConstantOp %v2float VectorShuffle %spec_vec2_1 %spec_vec2_2 1 2",
869fd4e5da5Sopenharmony_ci          },
870fd4e5da5Sopenharmony_ci          // use preserved constants in main
871fd4e5da5Sopenharmony_ci          {
872fd4e5da5Sopenharmony_ci            "%v2float_var = OpVariable %_pf_v2float Function",
873fd4e5da5Sopenharmony_ci            "OpStore %v2float_var %spec_vector_shuffle",
874fd4e5da5Sopenharmony_ci          },
875fd4e5da5Sopenharmony_ci          // duplicated constants
876fd4e5da5Sopenharmony_ci          {
877fd4e5da5Sopenharmony_ci            "%spec_vector_shuffle_duplicate = OpSpecConstantOp %v2float VectorShuffle %spec_vec2_1 %spec_vec2_2 1 2",
878fd4e5da5Sopenharmony_ci          },
879fd4e5da5Sopenharmony_ci          // use duplicated constants in main
880fd4e5da5Sopenharmony_ci          {
881fd4e5da5Sopenharmony_ci            "%v2float_var = OpVariable %_pf_v2float Function",
882fd4e5da5Sopenharmony_ci            "OpStore %v2float_var %spec_vector_shuffle_duplicate",
883fd4e5da5Sopenharmony_ci          },
884fd4e5da5Sopenharmony_ci          // remapped names
885fd4e5da5Sopenharmony_ci          {
886fd4e5da5Sopenharmony_ci            "OpName %spec_vector_shuffle \"spec_vector_shuffle_duplicate\"",
887fd4e5da5Sopenharmony_ci          },
888fd4e5da5Sopenharmony_ci        },
889fd4e5da5Sopenharmony_ci        // long dependency chain
890fd4e5da5Sopenharmony_ci        {
891fd4e5da5Sopenharmony_ci          // preserved constants
892fd4e5da5Sopenharmony_ci          {
893fd4e5da5Sopenharmony_ci            "%array_size = OpConstant %int 4",
894fd4e5da5Sopenharmony_ci            "%type_arr_int_4 = OpTypeArray %int %array_size",
895fd4e5da5Sopenharmony_ci            "%signed_0 = OpConstant %int 100",
896fd4e5da5Sopenharmony_ci            "%signed_1 = OpConstant %int 1",
897fd4e5da5Sopenharmony_ci            "%signed_2 = OpSpecConstantOp %int IAdd %signed_0 %signed_1",
898fd4e5da5Sopenharmony_ci            "%signed_3 = OpSpecConstantOp %int ISub %signed_0 %signed_2",
899fd4e5da5Sopenharmony_ci            "%signed_4 = OpSpecConstantOp %int IAdd %signed_0 %signed_3",
900fd4e5da5Sopenharmony_ci            "%signed_5 = OpSpecConstantOp %int ISub %signed_0 %signed_4",
901fd4e5da5Sopenharmony_ci            "%signed_6 = OpSpecConstantOp %int IAdd %signed_0 %signed_5",
902fd4e5da5Sopenharmony_ci            "%signed_7 = OpSpecConstantOp %int ISub %signed_0 %signed_6",
903fd4e5da5Sopenharmony_ci            "%signed_8 = OpSpecConstantOp %int IAdd %signed_0 %signed_7",
904fd4e5da5Sopenharmony_ci            "%signed_9 = OpSpecConstantOp %int ISub %signed_0 %signed_8",
905fd4e5da5Sopenharmony_ci            "%signed_10 = OpSpecConstantOp %int IAdd %signed_0 %signed_9",
906fd4e5da5Sopenharmony_ci            "%signed_11 = OpSpecConstantOp %int ISub %signed_0 %signed_10",
907fd4e5da5Sopenharmony_ci            "%signed_12 = OpSpecConstantOp %int IAdd %signed_0 %signed_11",
908fd4e5da5Sopenharmony_ci            "%signed_13 = OpSpecConstantOp %int ISub %signed_0 %signed_12",
909fd4e5da5Sopenharmony_ci            "%signed_14 = OpSpecConstantOp %int IAdd %signed_0 %signed_13",
910fd4e5da5Sopenharmony_ci            "%signed_15 = OpSpecConstantOp %int ISub %signed_0 %signed_14",
911fd4e5da5Sopenharmony_ci            "%signed_16 = OpSpecConstantOp %int ISub %signed_0 %signed_15",
912fd4e5da5Sopenharmony_ci            "%signed_17 = OpSpecConstantOp %int IAdd %signed_0 %signed_16",
913fd4e5da5Sopenharmony_ci            "%signed_18 = OpSpecConstantOp %int ISub %signed_0 %signed_17",
914fd4e5da5Sopenharmony_ci            "%signed_19 = OpSpecConstantOp %int IAdd %signed_0 %signed_18",
915fd4e5da5Sopenharmony_ci            "%signed_20 = OpSpecConstantOp %int ISub %signed_0 %signed_19",
916fd4e5da5Sopenharmony_ci            "%signed_vec_a = OpSpecConstantComposite %v2int %signed_18 %signed_19",
917fd4e5da5Sopenharmony_ci            "%signed_vec_b = OpSpecConstantOp %v2int IMul %signed_vec_a %signed_vec_a",
918fd4e5da5Sopenharmony_ci            "%signed_21 = OpSpecConstantOp %int CompositeExtract %signed_vec_b 0",
919fd4e5da5Sopenharmony_ci            "%signed_array = OpConstantComposite %type_arr_int_4 %signed_20 %signed_20 %signed_21 %signed_21",
920fd4e5da5Sopenharmony_ci            "%signed_22 = OpSpecConstantOp %int CompositeExtract %signed_array 0",
921fd4e5da5Sopenharmony_ci          },
922fd4e5da5Sopenharmony_ci          // use preserved constants in main
923fd4e5da5Sopenharmony_ci          {
924fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
925fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_22",
926fd4e5da5Sopenharmony_ci          },
927fd4e5da5Sopenharmony_ci          // duplicated constants
928fd4e5da5Sopenharmony_ci          {
929fd4e5da5Sopenharmony_ci            "%signed_0_dup = OpConstant %int 100",
930fd4e5da5Sopenharmony_ci            "%signed_1_dup = OpConstant %int 1",
931fd4e5da5Sopenharmony_ci            "%signed_2_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_1_dup",
932fd4e5da5Sopenharmony_ci            "%signed_3_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_2_dup",
933fd4e5da5Sopenharmony_ci            "%signed_4_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_3_dup",
934fd4e5da5Sopenharmony_ci            "%signed_5_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_4_dup",
935fd4e5da5Sopenharmony_ci            "%signed_6_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_5_dup",
936fd4e5da5Sopenharmony_ci            "%signed_7_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_6_dup",
937fd4e5da5Sopenharmony_ci            "%signed_8_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_7_dup",
938fd4e5da5Sopenharmony_ci            "%signed_9_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_8_dup",
939fd4e5da5Sopenharmony_ci            "%signed_10_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_9_dup",
940fd4e5da5Sopenharmony_ci            "%signed_11_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_10_dup",
941fd4e5da5Sopenharmony_ci            "%signed_12_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_11_dup",
942fd4e5da5Sopenharmony_ci            "%signed_13_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_12_dup",
943fd4e5da5Sopenharmony_ci            "%signed_14_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_13_dup",
944fd4e5da5Sopenharmony_ci            "%signed_15_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_14_dup",
945fd4e5da5Sopenharmony_ci            "%signed_16_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_15_dup",
946fd4e5da5Sopenharmony_ci            "%signed_17_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_16_dup",
947fd4e5da5Sopenharmony_ci            "%signed_18_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_17_dup",
948fd4e5da5Sopenharmony_ci            "%signed_19_dup = OpSpecConstantOp %int IAdd %signed_0_dup %signed_18_dup",
949fd4e5da5Sopenharmony_ci            "%signed_20_dup = OpSpecConstantOp %int ISub %signed_0_dup %signed_19_dup",
950fd4e5da5Sopenharmony_ci            "%signed_vec_a_dup = OpSpecConstantComposite %v2int %signed_18_dup %signed_19_dup",
951fd4e5da5Sopenharmony_ci            "%signed_vec_b_dup = OpSpecConstantOp %v2int IMul %signed_vec_a_dup %signed_vec_a_dup",
952fd4e5da5Sopenharmony_ci            "%signed_21_dup = OpSpecConstantOp %int CompositeExtract %signed_vec_b_dup 0",
953fd4e5da5Sopenharmony_ci            "%signed_array_dup = OpConstantComposite %type_arr_int_4 %signed_20_dup %signed_20_dup %signed_21_dup %signed_21_dup",
954fd4e5da5Sopenharmony_ci            "%signed_22_dup = OpSpecConstantOp %int CompositeExtract %signed_array_dup 0",
955fd4e5da5Sopenharmony_ci          },
956fd4e5da5Sopenharmony_ci          // use duplicated constants in main
957fd4e5da5Sopenharmony_ci          {
958fd4e5da5Sopenharmony_ci            "%int_var = OpVariable %_pf_int Function",
959fd4e5da5Sopenharmony_ci            "OpStore %int_var %signed_22_dup",
960fd4e5da5Sopenharmony_ci          },
961fd4e5da5Sopenharmony_ci          // remapped names
962fd4e5da5Sopenharmony_ci          {
963fd4e5da5Sopenharmony_ci            "OpName %signed_0 \"signed_0_dup\"",
964fd4e5da5Sopenharmony_ci            "OpName %signed_1 \"signed_1_dup\"",
965fd4e5da5Sopenharmony_ci            "OpName %signed_2 \"signed_2_dup\"",
966fd4e5da5Sopenharmony_ci            "OpName %signed_3 \"signed_3_dup\"",
967fd4e5da5Sopenharmony_ci            "OpName %signed_4 \"signed_4_dup\"",
968fd4e5da5Sopenharmony_ci            "OpName %signed_5 \"signed_5_dup\"",
969fd4e5da5Sopenharmony_ci            "OpName %signed_6 \"signed_6_dup\"",
970fd4e5da5Sopenharmony_ci            "OpName %signed_7 \"signed_7_dup\"",
971fd4e5da5Sopenharmony_ci            "OpName %signed_8 \"signed_8_dup\"",
972fd4e5da5Sopenharmony_ci            "OpName %signed_9 \"signed_9_dup\"",
973fd4e5da5Sopenharmony_ci            "OpName %signed_10 \"signed_10_dup\"",
974fd4e5da5Sopenharmony_ci            "OpName %signed_11 \"signed_11_dup\"",
975fd4e5da5Sopenharmony_ci            "OpName %signed_12 \"signed_12_dup\"",
976fd4e5da5Sopenharmony_ci            "OpName %signed_13 \"signed_13_dup\"",
977fd4e5da5Sopenharmony_ci            "OpName %signed_14 \"signed_14_dup\"",
978fd4e5da5Sopenharmony_ci            "OpName %signed_15 \"signed_15_dup\"",
979fd4e5da5Sopenharmony_ci            "OpName %signed_16 \"signed_16_dup\"",
980fd4e5da5Sopenharmony_ci            "OpName %signed_17 \"signed_17_dup\"",
981fd4e5da5Sopenharmony_ci            "OpName %signed_18 \"signed_18_dup\"",
982fd4e5da5Sopenharmony_ci            "OpName %signed_19 \"signed_19_dup\"",
983fd4e5da5Sopenharmony_ci            "OpName %signed_20 \"signed_20_dup\"",
984fd4e5da5Sopenharmony_ci            "OpName %signed_vec_a \"signed_vec_a_dup\"",
985fd4e5da5Sopenharmony_ci            "OpName %signed_vec_b \"signed_vec_b_dup\"",
986fd4e5da5Sopenharmony_ci            "OpName %signed_21 \"signed_21_dup\"",
987fd4e5da5Sopenharmony_ci            "OpName %signed_array \"signed_array_dup\"",
988fd4e5da5Sopenharmony_ci            "OpName %signed_22 \"signed_22_dup\"",
989fd4e5da5Sopenharmony_ci          },
990fd4e5da5Sopenharmony_ci        },
991fd4e5da5Sopenharmony_ci                            // clang-format on
992fd4e5da5Sopenharmony_ci                        })));
993fd4e5da5Sopenharmony_ci
994fd4e5da5Sopenharmony_ci}  // namespace
995fd4e5da5Sopenharmony_ci}  // namespace opt
996fd4e5da5Sopenharmony_ci}  // namespace spvtools
997