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