• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16//! CHECKER       AOT IR Builder, check String concatenation
17//! SKIP_IF       @architecture == "arm32"
18//! RUN           entry: "ets_string_concat.ETSGLOBAL::main"
19//! RUN_PAOC      options: "--compiler-regex='.*concat[0-9]+' --compiler-inlining=false"
20//!
21//! METHOD        "ets_string_concat.ETSGLOBAL::concat0"
22//! PASS_BEFORE   "BranchElimination"
23//! INST_NOT      /Intrinsic.StdCoreStringConcat/
24//! INST          /StringBuilder::<ctor>/
25//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
26//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
27//! INST_NEXT     /Intrinsic.StdCoreSbToString/
28//! PASS_AFTER    "ChecksElimination"
29//! INST_NOT      /StringBuilder::<ctor>/
30//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
31//! INST_NOT      /Intrinsic.StdCoreSbToString/
32//! INST_COUNT    /Intrinsic.StdCoreStringConcat2/,1
33//!
34//! METHOD        "ets_string_concat.ETSGLOBAL::concat1"
35//! PASS_BEFORE   "BranchElimination"
36//! INST_NOT      /Intrinsic.StdCoreStringConcat/
37//! INST          /StringBuilder::<ctor>/
38//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
39//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
40//! INST_NEXT     /Intrinsic.StdCoreSbToString/
41//! PASS_AFTER    "ChecksElimination"
42//! INST_NOT      /StringBuilder::<ctor>/
43//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
44//! INST_NOT      /Intrinsic.StdCoreSbToString/
45//! INST_COUNT    /Intrinsic.StdCoreStringConcat2/,1
46//!
47//! METHOD        "ets_string_concat.ETSGLOBAL::concat2"
48//! PASS_BEFORE   "BranchElimination"
49//! INST_NOT      /Intrinsic.StdCoreStringConcat/
50//! INST          /StringBuilder::<ctor>/
51//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
52//! INST_NEXT     /Intrinsic.StdCoreSbToString/
53//! PASS_AFTER    "ChecksElimination"
54//! INST_NOT      /Intrinsic.StdCoreStringConcat/
55//! INST          /StringBuilder::<ctor>/
56//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
57//! INST_NEXT     /Intrinsic.StdCoreSbToString/
58//!
59//! METHOD        "ets_string_concat.ETSGLOBAL::concat3"
60//! PASS_BEFORE   "BranchElimination"
61//! INST_NOT      /Intrinsic.StdCoreStringConcat/
62//! INST          /StringBuilder::<ctor>/
63//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
64//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
65//! INST_NEXT     /Intrinsic.StdCoreSbToString/
66//! PASS_AFTER    "ChecksElimination"
67//! INST_NOT      /Intrinsic.StdCoreStringConcat/
68//! INST          /StringBuilder::<ctor>/
69//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
70//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
71//! INST_NEXT     /Intrinsic.StdCoreSbToString/
72//!
73//! METHOD        "ets_string_concat.ETSGLOBAL::concat4"
74//! PASS_BEFORE   "BranchElimination"
75//! INST_NOT      /Intrinsic.StdCoreStringConcat/
76//! INST          /StringBuilder::<ctor>/
77//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,3
78//! INST          /Intrinsic.StdCoreSbToString/
79//! PASS_AFTER    "ChecksElimination"
80//! INST_NOT      /StringBuilder::<ctor>/
81//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
82//! INST_NOT      /Intrinsic.StdCoreSbToString/
83//! INST_COUNT    /Intrinsic.StdCoreStringConcat3/,1
84//!
85//! METHOD        "ets_string_concat.ETSGLOBAL::concat5"
86//! PASS_BEFORE   "BranchElimination"
87//! INST_NOT      /Intrinsic.StdCoreStringConcat/
88//! INST          /StringBuilder::<ctor>/
89//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,4
90//! INST          /Intrinsic.StdCoreSbToString/
91//! PASS_AFTER    "ChecksElimination"
92//! INST_NOT      /StringBuilder::<ctor>/
93//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
94//! INST_NOT      /Intrinsic.StdCoreSbToString/
95//! INST_COUNT    /Intrinsic.StdCoreStringConcat4/,1
96//!
97//! METHOD        "ets_string_concat.ETSGLOBAL::concat8"
98//! PASS_BEFORE   "BranchElimination"
99//! INST_NOT      /Intrinsic.StdCoreStringConcat/
100//! INST          /StringBuilder::<ctor>/
101//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
102//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
103//! INST_NEXT     /Intrinsic.StdCoreSbToString/
104//! PASS_AFTER    "ChecksElimination"
105//! INST_NOT      /Intrinsic.StdCoreStringConcat/
106//! INST          /StringBuilder::<ctor>/
107//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
108//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
109//! INST_NEXT     /Intrinsic.StdCoreSbToString/
110//!
111//! METHOD        "ets_string_concat.ETSGLOBAL::concat10"
112//! PASS_BEFORE   "BranchElimination"
113//! INST_NOT      /Intrinsic.StdCoreStringConcat/
114//! INST          /StringBuilder::<ctor>/
115//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,5
116//! INST          /Intrinsic.StdCoreSbToString/
117//! PASS_AFTER    "ChecksElimination"
118//! INST_NOT      /Intrinsic.StdCoreStringConcat/
119//! INST          /StringBuilder::<ctor>/
120//! INST_COUNT    "Intrinsic.StdCoreSbAppendString4",1
121//! INST_COUNT    "Intrinsic.StdCoreSbAppendString ",1
122//! INST          /Intrinsic.StdCoreSbToString/
123//!
124//! METHOD        "ets_string_concat.ETSGLOBAL::concat11"
125//! PASS_BEFORE   "BranchElimination"
126//! INST_NOT      /Intrinsic.StdCoreStringConcat/
127//! INST          /StringBuilder::<ctor>/
128//! INST_COUNT    /Intrinsic.StdCoreSbAppend/,3
129//! INST          /Intrinsic.StdCoreSbToString/
130//! PASS_AFTER    "ChecksElimination"
131//! INST_NOT      /Intrinsic.StdCoreStringConcat/
132//! INST          /StringBuilder::<ctor>/
133//! INST_COUNT    "Intrinsic.StdCoreSbAppendString2",1
134//! INST_COUNT    "Intrinsic.StdCoreSbAppendInt",1
135//! INST          /Intrinsic.StdCoreSbToString/
136//!
137//! METHOD        "ets_string_concat.ETSGLOBAL::concat13"
138//! PASS_BEFORE   "BranchElimination"
139//! INST_NOT      /Intrinsic.StdCoreStringConcat/
140//! INST          /StringBuilder::<ctor>/
141//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
142//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
143//! INST_NEXT     /Intrinsic.StdCoreSbToString/
144//! PASS_AFTER    "ChecksElimination"
145//! INST_COUNT    /StringBuilder::<ctor>/, 1
146//! INST          /Intrinsic.StdCoreSbAppendString2/
147//! INST_NOT      /Intrinsic.StdCoreStringConcat/
148//! INST_COUNT    /Intrinsic.StdCoreSbToString/, 1
149//!
150//! METHOD        "ets_string_concat.ETSGLOBAL::concat14"
151//! PASS_BEFORE   "BranchElimination"
152//! INST_NOT      /Intrinsic.StdCoreStringConcat/
153//! INST          /StringBuilder::<ctor>/
154//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
155//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
156//! INST_NEXT     /Intrinsic.StdCoreSbToString/
157//! PASS_AFTER    "ChecksElimination"
158//! INST          /StringBuilder::<ctor>/
159//! INST_NOT      /Intrinsic.StdCoreStringConcat/
160//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
161//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
162//! INST_NEXT     /Intrinsic.StdCoreSbToString/
163
164//! CHECKER       JIT IR Builder, check String concatenation
165//! SKIP_IF       @architecture == "arm32"
166//! RUN           force_jit: true, options: "--compiler-regex='.*concat[0-9]+.*' --compiler-inlining=false", entry: "ets_string_concat.ETSGLOBAL::main"
167//!
168//! METHOD        "ets_string_concat.ETSGLOBAL::concat0"
169//! PASS_BEFORE   "BranchElimination"
170//! INST_NOT      /Intrinsic.StdCoreStringConcat/
171//! INST          /StringBuilder::<ctor>/
172//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
173//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
174//! INST_NEXT     /Intrinsic.StdCoreSbToString/
175//! PASS_AFTER    "ChecksElimination"
176//! INST_NOT      /StringBuilder::<ctor>/
177//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
178//! INST_NOT      /Intrinsic.StdCoreSbToString/
179//! INST_COUNT    /Intrinsic.StdCoreStringConcat2/,1
180//!
181//! METHOD        "ets_string_concat.ETSGLOBAL::concat1"
182//! PASS_BEFORE   "BranchElimination"
183//! INST_NOT      /Intrinsic.StdCoreStringConcat/
184//! INST          /StringBuilder::<ctor>/
185//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
186//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
187//! INST_NEXT     /Intrinsic.StdCoreSbToString/
188//! PASS_AFTER    "ChecksElimination"
189//! INST_NOT      /StringBuilder::<ctor>/
190//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
191//! INST_NOT      /Intrinsic.StdCoreSbToString/
192//! INST_COUNT    /Intrinsic.StdCoreStringConcat2/,1
193//!
194//! METHOD        "ets_string_concat.ETSGLOBAL::concat2"
195//! PASS_BEFORE   "BranchElimination"
196//! INST_NOT      /Intrinsic.StdCoreStringConcat/
197//! INST          /StringBuilder::<ctor>/
198//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
199//! INST_NEXT     /Intrinsic.StdCoreSbToString/
200//! PASS_AFTER    "ChecksElimination"
201//! INST_NOT      /Intrinsic.StdCoreStringConcat/
202//! INST          /StringBuilder::<ctor>/
203//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
204//! INST_NEXT     /Intrinsic.StdCoreSbToString/
205//!
206//! METHOD        "ets_string_concat.ETSGLOBAL::concat3"
207//! PASS_BEFORE   "BranchElimination"
208//! INST_NOT      /Intrinsic.StdCoreStringConcat/
209//! INST          /StringBuilder::<ctor>/
210//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
211//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
212//! INST_NEXT     /Intrinsic.StdCoreSbToString/
213//! PASS_AFTER    "ChecksElimination"
214//! INST_NOT      /Intrinsic.StdCoreStringConcat/
215//! INST          /StringBuilder::<ctor>/
216//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
217//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
218//! INST_NEXT     /Intrinsic.StdCoreSbToString/
219//!
220//! METHOD        "ets_string_concat.ETSGLOBAL::concat4"
221//! PASS_BEFORE   "BranchElimination"
222//! INST_NOT      /Intrinsic.StdCoreStringConcat/
223//! INST          /StringBuilder::<ctor>/
224//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,3
225//! INST          /Intrinsic.StdCoreSbToString/
226//! PASS_AFTER    "ChecksElimination"
227//! INST_NOT      /StringBuilder::<ctor>/
228//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
229//! INST_NOT      /Intrinsic.StdCoreSbToString/
230//! INST_COUNT    /Intrinsic.StdCoreStringConcat3/,1
231//!
232//! METHOD        "ets_string_concat.ETSGLOBAL::concat5"
233//! PASS_BEFORE   "BranchElimination"
234//! INST_NOT      /Intrinsic.StdCoreStringConcat/
235//! INST          /StringBuilder::<ctor>/
236//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,4
237//! INST          /Intrinsic.StdCoreSbToString/
238//! PASS_AFTER    "ChecksElimination"
239//! INST_NOT      /StringBuilder::<ctor>/
240//! INST_NOT      /Intrinsic.StdCoreSbAppendString/
241//! INST_NOT      /Intrinsic.StdCoreSbToString/
242//! INST_COUNT    /Intrinsic.StdCoreStringConcat4/,1
243//!
244//! METHOD        "ets_string_concat.ETSGLOBAL::concat8"
245//! PASS_BEFORE   "BranchElimination"
246//! INST_NOT      /Intrinsic.StdCoreStringConcat/
247//! INST          /StringBuilder::<ctor>/
248//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
249//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
250//! INST_NEXT     /Intrinsic.StdCoreSbToString/
251//! PASS_AFTER    "ChecksElimination"
252//! INST_NOT      /Intrinsic.StdCoreStringConcat/
253//! INST          /StringBuilder::<ctor>/
254//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
255//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
256//! INST_NEXT     /Intrinsic.StdCoreSbToString/
257//!
258//! METHOD        "ets_string_concat.ETSGLOBAL::concat10"
259//! PASS_BEFORE   "BranchElimination"
260//! INST_NOT      /Intrinsic.StdCoreStringConcat/
261//! INST          /StringBuilder::<ctor>/
262//! INST_COUNT    /Intrinsic.StdCoreSbAppendString/,5
263//! INST          /Intrinsic.StdCoreSbToString/
264//! PASS_AFTER    "ChecksElimination"
265//! INST_NOT      /Intrinsic.StdCoreStringConcat/
266//! INST          /StringBuilder::<ctor>/
267//! INST_COUNT    "Intrinsic.StdCoreSbAppendString4",1
268//! INST_COUNT    "Intrinsic.StdCoreSbAppendString ",1
269//! INST          /Intrinsic.StdCoreSbToString/
270//!
271//! METHOD        "ets_string_concat.ETSGLOBAL::concat11"
272//! PASS_BEFORE   "BranchElimination"
273//! INST_NOT      /Intrinsic.StdCoreStringConcat/
274//! INST          /StringBuilder::<ctor>/
275//! INST_COUNT    /Intrinsic.StdCoreSbAppend/,3
276//! INST          /Intrinsic.StdCoreSbToString/
277//! PASS_AFTER    "ChecksElimination"
278//! INST_NOT      /Intrinsic.StdCoreStringConcat/
279//! INST          /StringBuilder::<ctor>/
280//! INST_COUNT    "Intrinsic.StdCoreSbAppendString2",1
281//! INST_COUNT    "Intrinsic.StdCoreSbAppendInt",1
282//! INST          /Intrinsic.StdCoreSbToString/
283//!
284//! METHOD        "ets_string_concat.ETSGLOBAL::concat13"
285//! PASS_BEFORE   "BranchElimination"
286//! INST_NOT      /Intrinsic.StdCoreStringConcat/
287//! INST          /StringBuilder::<ctor>/
288//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
289//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
290//! INST_NEXT     /Intrinsic.StdCoreSbToString/
291//! PASS_AFTER    "ChecksElimination"
292//! INST_COUNT    /StringBuilder::<ctor>/, 1
293//! INST          /Intrinsic.StdCoreSbAppendString2/
294//! INST_NOT      /Intrinsic.StdCoreStringConcat/
295//! INST_COUNT    /Intrinsic.StdCoreSbToString/, 1
296//!
297//! METHOD        "ets_string_concat.ETSGLOBAL::concat14"
298//! PASS_BEFORE   "BranchElimination"
299//! INST_NOT      /Intrinsic.StdCoreStringConcat/
300//! INST          /StringBuilder::<ctor>/
301//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
302//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
303//! INST_NEXT     /Intrinsic.StdCoreSbToString/
304//! PASS_AFTER    "ChecksElimination"
305//! INST          /StringBuilder::<ctor>/
306//! INST_NOT      /Intrinsic.StdCoreStringConcat/
307//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
308//! INST_NEXT     /Intrinsic.StdCoreSbAppendString/
309//! INST_NEXT     /Intrinsic.StdCoreSbToString/
310
311function concat0(a: String, b: String): String {
312    return a + b;                                   // applied
313}
314
315function concat1(a: String, b: String): String {
316    let sb = new StringBuilder();
317    sb.append(a);
318    sb.append(b);
319    return sb.toString();                           // applied, IR is equivalent to 'return a + b;'
320}
321
322function concat2(a: String, b: String): String {
323    let sb = new StringBuilder(a);
324    sb.append(b);
325    return sb.toString();                           // not applied, IR is not equivalent to 'return a + b;'
326}
327
328let sb: StringBuilder;
329
330function concat3(a: String, b: String): String {
331    sb = new StringBuilder();                       // the object is a global variable
332    sb.append(a);
333    sb.append(b);
334    return sb.toString();                           // not applied, IR is not equivalent to 'return a + b;'
335}
336
337function concat4(a: String, b: String, c: String): String {
338    return a + b + c;                               // applied
339}
340
341function concat5(a: String, b: String, c: String, d: String): String {
342    return a + b + c + d;                           // applied
343}
344
345function concat8(a: String, b: String): String {
346    let sb = new StringBuilder();
347    sb.append(a);
348    if (b != "")
349        sb.append(b);
350    return sb.toString();                           // not applied, IR is not equivalent to 'return a + b;'
351}
352
353function concat10(a: String, b: String, c: String, d: String, e: String): String {
354    return a + b + c + d + e;                       // not applied, to many args
355}
356
357function concat11(a: String, b: String): String {
358    return a + b + 1;                               // not applied, concatenation with int
359}
360
361function concat13(): string
362{
363    let str = "" + StringBuilder.toString(1);       // partially applied, calls StdCoreToStringInt
364    return str;
365}
366
367function concat14(src: string|undefined): string {
368  let dst: string = "" + src;                       // not applied due to instance used outside
369                                                    // basic block it was created
370  return dst;
371}
372
373function main() {
374    assertEQ(concat0("abc", "de"), "abcde", "Wrong result at concat0")
375    assertEQ(concat1("abc", "de"), "abcde", "Wrong result at concat1")
376    assertEQ(concat2("abc", "de"), "abcde", "Wrong result at concat2")
377    assertEQ(concat3("abc", "de"), "abcde", "Wrong result at concat3")
378    assertEQ(concat4("ab", "c", "de"), "abcde", "Wrong result at concat4")
379    assertEQ(concat5("ab", "c", "d", "e"), "abcde", "Wrong result at concat5")
380    assertEQ(concat8("abc", "de"), "abcde", "Wrong result at concat8")
381    assertEQ(concat10("a", "b", "c", "d", "e"), "abcde", "Wrong result at concat10")
382    assertEQ(concat11("abc", "de"), "abcde1", "Wrong result at concat11")
383    assertEQ(concat13(), "1", "Wrong result at concat13")
384    assertEQ(concat14(undefined), "undefined", "Wrong result at concat14")
385}
386