1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 import jdk.incubator.code.Reflect;
 25 
 26 import java.util.List;
 27 import java.util.function.Supplier;
 28 
 29 /*
 30  * @test
 31  * @summary Smoke test for code reflection with boxing conversions.
 32  * @modules jdk.incubator.code
 33  * @build BoxingConversionTest
 34  * @build CodeReflectionTester
 35  * @run main CodeReflectionTester BoxingConversionTest
 36  */
 37 
 38 public class BoxingConversionTest {
 39     @Reflect
 40     @IR("""
 41             func @"test1" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
 42                 %1 : java.type:"long" = constant @1;
 43                 %2 : java.type:"java.lang.Long" = invoke %1 @java.ref:"java.lang.Long::valueOf(long):java.lang.Long";
 44                 %3 : Var<java.type:"java.lang.Long"> = var %2 @"x";
 45                 return;
 46             };
 47             """)
 48     void test1() {
 49         Long x = 1L;
 50     }
 51 
 52     @Reflect
 53     @IR("""
 54             func @"test2" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"java.lang.Long")java.type:"void" -> {
 55                 %2 : Var<java.type:"java.lang.Long"> = var %1 @"L";
 56                 %3 : java.type:"java.lang.Long" = var.load %2;
 57                 %4 : java.type:"long" = invoke %3 @java.ref:"java.lang.Long::longValue():long";
 58                 %5 : Var<java.type:"long"> = var %4 @"l";
 59                 return;
 60             };
 61             """)
 62     void test2(Long L) {
 63         long l = L;
 64     }
 65 
 66     @Reflect
 67     @IR("""
 68             func @"test3" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
 69                 %1 : java.type:"long" = constant @0;
 70                 %2 : java.type:"java.lang.Long" = invoke %1 @java.ref:"java.lang.Long::valueOf(long):java.lang.Long";
 71                 %3 : Var<java.type:"java.lang.Object"> = var %2 @"o";
 72                 return;
 73             };
 74             """)
 75     void test3() {
 76         Object o = 0L;
 77     }
 78 
 79     @Reflect
 80     @IR("""
 81             func @"test4" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"java.lang.Object")java.type:"void" -> {
 82                 %2 : Var<java.type:"java.lang.Object"> = var %1 @"o";
 83                 %3 : java.type:"java.lang.Object" = var.load %2;
 84                 %4 : java.type:"java.lang.Long" = cast %3 @java.type:"java.lang.Long";
 85                 %5 : java.type:"long" = invoke %4 @java.ref:"java.lang.Long::longValue():long";
 86                 %6 : Var<java.type:"long"> = var %5 @"l";
 87                 return;
 88             };
 89             """)
 90     void test4(Object o) {
 91         long l = (long)o;
 92     }
 93 
 94     @Reflect
 95     @IR("""
 96             func @"test5" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"java.lang.Integer")java.type:"void" -> {
 97                 %2 : Var<java.type:"java.lang.Integer"> = var %1 @"i2";
 98                 %3 : java.type:"java.lang.Integer" = var.load %2;
 99                 %4 : java.type:"int" = constant @1;
100                 %5 : java.type:"int" = invoke %3 @java.ref:"java.lang.Integer::intValue():int";
101                 %6 : java.type:"int" = add %5 %4;
102                 %7 : java.type:"java.lang.Integer" = invoke %6 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
103                 var.store %2 %7;
104                 return;
105             };
106             """)
107     void test5(Integer i2) {
108         i2++;
109     }
110 
111     @Reflect
112     @IR("""
113             func @"test6" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"java.lang.Integer")java.type:"void" -> {
114                 %2 : Var<java.type:"java.lang.Integer"> = var %1 @"i2";
115                 %3 : java.type:"java.lang.Integer" = var.load %2;
116                 %4 : java.type:"int" = constant @3;
117                 %5 : java.type:"int" = invoke %3 @java.ref:"java.lang.Integer::intValue():int";
118                 %6 : java.type:"int" = add %5 %4;
119                 %7 : java.type:"java.lang.Integer" = invoke %6 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
120                 var.store %2 %7;
121                 return;
122             };
123             """)
124     void test6(Integer i2) {
125         i2 += 3;
126     }
127 
128     static class Box {
129         Integer i;
130     }
131 
132     @Reflect
133     @IR("""
134             func @"test7" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
135                 %1 : java.type:"BoxingConversionTest$Box" = new @java.ref:"BoxingConversionTest$Box::()";
136                 %2 : java.type:"java.lang.Integer" = field.load %1 @java.ref:"BoxingConversionTest$Box::i:java.lang.Integer";
137                 %3 : java.type:"int" = constant @1;
138                 %4 : java.type:"int" = invoke %2 @java.ref:"java.lang.Integer::intValue():int";
139                 %5 : java.type:"int" = add %4 %3;
140                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
141                 field.store %1 %6 @java.ref:"BoxingConversionTest$Box::i:java.lang.Integer";
142                 return;
143             };
144             """)
145     void test7() {
146         new Box().i++;
147     }
148 
149     @Reflect
150     @IR("""
151             func @"test8" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
152                 %1 : java.type:"BoxingConversionTest$Box" = new @java.ref:"BoxingConversionTest$Box::()";
153                 %2 : java.type:"java.lang.Integer" = field.load %1 @java.ref:"BoxingConversionTest$Box::i:java.lang.Integer";
154                 %3 : java.type:"int" = constant @3;
155                 %4 : java.type:"int" = invoke %2 @java.ref:"java.lang.Integer::intValue():int";
156                 %5 : java.type:"int" = add %4 %3;
157                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
158                 field.store %1 %6 @java.ref:"BoxingConversionTest$Box::i:java.lang.Integer";
159                 return;
160             };
161             """)
162     void test8() {
163         new Box().i += 3;
164     }
165 
166     @Reflect
167     @IR("""
168             func @"test9" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int[]", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
169                 %3 : Var<java.type:"int[]"> = var %1 @"ia";
170                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"i";
171                 %5 : java.type:"int[]" = var.load %3;
172                 %6 : java.type:"int" = constant @0;
173                 %7 : java.type:"int" = array.load %5 %6;
174                 %8 : java.type:"java.lang.Integer" = var.load %4;
175                 %9 : java.type:"int" = invoke %8 @java.ref:"java.lang.Integer::intValue():int";
176                 %10 : java.type:"int" = add %7 %9;
177                 array.store %5 %6 %10;
178                 return;
179             };
180             """)
181     void test9(int[] ia, Integer i) {
182         ia[0] += i;
183     }
184 
185     @Reflect
186     @IR("""
187             func @"test10" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"boolean", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
188                 %3 : Var<java.type:"boolean"> = var %1 @"cond";
189                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
190                 %5 : java.type:"int" = java.cexpression
191                     ()java.type:"boolean" -> {
192                         %6 : java.type:"boolean" = var.load %3;
193                         yield %6;
194                     }
195                     ()java.type:"int" -> {
196                         %7 : java.type:"java.lang.Integer" = var.load %4;
197                         %8 : java.type:"int" = invoke %7 @java.ref:"java.lang.Integer::intValue():int";
198                         yield %8;
199                     }
200                     ()java.type:"int" -> {
201                         %9 : java.type:"int" = constant @2;
202                         yield %9;
203                     };
204                 %10 : Var<java.type:"int"> = var %5 @"res";
205                 return;
206             };
207             """)
208     void test10(boolean cond, Integer I) {
209         int res = cond ? I : 2;
210     }
211 
212     @Reflect
213     @IR("""
214             func @"test11" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"boolean", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
215                 %3 : Var<java.type:"boolean"> = var %1 @"cond";
216                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
217                 %5 : java.type:"int" = java.cexpression
218                     ()java.type:"boolean" -> {
219                         %6 : java.type:"boolean" = var.load %3;
220                         yield %6;
221                     }
222                     ()java.type:"int" -> {
223                         %7 : java.type:"int" = constant @2;
224                         yield %7;
225                     }
226                     ()java.type:"int" -> {
227                         %8 : java.type:"java.lang.Integer" = var.load %4;
228                         %9 : java.type:"int" = invoke %8 @java.ref:"java.lang.Integer::intValue():int";
229                         yield %9;
230                     };
231                 %10 : Var<java.type:"int"> = var %5 @"res";
232                 return;
233             };
234             """)
235     void test11(boolean cond, Integer I) {
236         int res = cond ? 2 : I;
237     }
238 
239     @Reflect
240     @IR("""
241             func @"test12" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"boolean")java.type:"void" -> {
242                 %2 : Var<java.type:"boolean"> = var %1 @"cond";
243                 %3 : java.type:"int" = java.cexpression
244                     ()java.type:"boolean" -> {
245                         %4 : java.type:"boolean" = var.load %2;
246                         yield %4;
247                     }
248                     ()java.type:"int" -> {
249                         %5 : java.type:"int" = constant @1;
250                         yield %5;
251                     }
252                     ()java.type:"int" -> {
253                         %6 : java.type:"int" = constant @2;
254                         yield %6;
255                     };
256                 %7 : java.type:"java.lang.Integer" = invoke %3 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
257                 %8 : Var<java.type:"java.lang.Integer"> = var %7 @"x";
258                 return;
259             };
260             """)
261     void test12(boolean cond) {
262         Integer x = cond ? 1 : 2;
263     }
264 
265     @Reflect
266     @IR("""
267             func @"test13" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
268                 %1 : java.type:"java.util.function.Supplier<java.lang.Integer>" = lambda @lambda.isQuotable=true ()java.type:"java.lang.Integer" -> {
269                     %2 : java.type:"int" = constant @1;
270                     %3 : java.type:"java.lang.Integer" = invoke %2 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
271                     return %3;
272                 };
273                 %4 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %1 @"s";
274                 return;
275             };
276             """)
277     void test13() {
278         Supplier<Integer> s = () -> { return 1; };
279     }
280 
281     @Reflect
282     @IR("""
283             func @"test14" (%0 : java.type:"BoxingConversionTest")java.type:"void" -> {
284                 %1 : java.type:"java.util.function.Supplier<java.lang.Integer>" = lambda @lambda.isQuotable=true ()java.type:"java.lang.Integer" -> {
285                     %2 : java.type:"int" = constant @1;
286                     %3 : java.type:"java.lang.Integer" = invoke %2 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
287                     return %3;
288                 };
289                 %4 : Var<java.type:"java.util.function.Supplier<java.lang.Integer>"> = var %1 @"s";
290                 return;
291             };
292             """)
293     void test14() {
294         Supplier<Integer> s = () -> 1;
295     }
296 
297     @Reflect
298     @IR("""
299             func @"test15" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
300                 %3 : Var<java.type:"int"> = var %1 @"i";
301                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
302                 %5 : java.type:"int" = var.load %3;
303                 %6 : java.type:"int" = java.switch.expression %5
304                     (%7 : java.type:"int")java.type:"boolean" -> {
305                         %8 : java.type:"int" = constant @1;
306                         %9 : java.type:"boolean" = eq %7 %8;
307                         yield %9;
308                     }
309                     ()java.type:"int" -> {
310                         %10 : java.type:"java.lang.Integer" = var.load %4;
311                         %11 : java.type:"int" = invoke %10 @java.ref:"java.lang.Integer::intValue():int";
312                         yield %11;
313                     }
314                     ()java.type:"boolean" -> {
315                         %12 : java.type:"boolean" = constant @true;
316                         yield %12;
317                     }
318                     ()java.type:"int" -> {
319                         %13 : java.type:"int" = constant @0;
320                         yield %13;
321                     };
322                 %14 : Var<java.type:"int"> = var %6 @"x";
323                 return;
324             };
325             """)
326     void test15(int i, Integer I) {
327         int x = switch (i) {
328             case 1 -> I;
329             default -> 0;
330         };
331     }
332 
333     @Reflect
334     @IR("""
335             func @"test16" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
336                 %3 : Var<java.type:"int"> = var %1 @"i";
337                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
338                 %5 : java.type:"int" = var.load %3;
339                 %6 : java.type:"int" = java.switch.expression %5
340                     (%7 : java.type:"int")java.type:"boolean" -> {
341                         %8 : java.type:"int" = constant @1;
342                         %9 : java.type:"boolean" = eq %7 %8;
343                         yield %9;
344                     }
345                     ()java.type:"int" -> {
346                         %10 : java.type:"int" = constant @1;
347                         yield %10;
348                     }
349                     ()java.type:"boolean" -> {
350                         %11 : java.type:"boolean" = constant @true;
351                         yield %11;
352                     }
353                     ()java.type:"int" -> {
354                         %12 : java.type:"java.lang.Integer" = var.load %4;
355                         %13 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
356                         yield %13;
357                     };
358                 %14 : Var<java.type:"int"> = var %6 @"x";
359                 return;
360             };
361             """)
362     void test16(int i, Integer I) {
363         int x = switch (i) {
364             case 1 -> 1;
365             default -> I;
366         };
367     }
368 
369     @Reflect
370     @IR("""
371             func @"test17" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
372                 %2 : Var<java.type:"int"> = var %1 @"i";
373                 %3 : java.type:"int" = var.load %2;
374                 %4 : java.type:"java.lang.Integer" = java.switch.expression %3
375                     (%5 : java.type:"int")java.type:"boolean" -> {
376                         %6 : java.type:"int" = constant @1;
377                         %7 : java.type:"boolean" = eq %5 %6;
378                         yield %7;
379                     }
380                     ()java.type:"java.lang.Integer" -> {
381                         %8 : java.type:"int" = constant @1;
382                         %9 : java.type:"java.lang.Integer" = invoke %8 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
383                         yield %9;
384                     }
385                     ()java.type:"boolean" -> {
386                         %10 : java.type:"boolean" = constant @true;
387                         yield %10;
388                     }
389                     ()java.type:"java.lang.Integer" -> {
390                         %11 : java.type:"int" = constant @0;
391                         %12 : java.type:"java.lang.Integer" = invoke %11 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
392                         yield %12;
393                     };
394                 %13 : Var<java.type:"java.lang.Integer"> = var %4 @"x";
395                 return;
396             };
397             """)
398     void test17(int i) {
399         Integer x = switch (i) {
400             case 1 -> 1;
401             default -> 0;
402         };
403     }
404 
405     @Reflect
406     @IR("""
407             func @"test18" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
408                 %3 : Var<java.type:"int"> = var %1 @"i";
409                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
410                 %5 : java.type:"int" = var.load %3;
411                 %6 : java.type:"int" = java.switch.expression %5
412                     (%7 : java.type:"int")java.type:"boolean" -> {
413                         %8 : java.type:"int" = constant @1;
414                         %9 : java.type:"boolean" = eq %7 %8;
415                         yield %9;
416                     }
417                     ()java.type:"int" -> {
418                         %10 : java.type:"java.lang.Integer" = var.load %4;
419                         %11 : java.type:"int" = invoke %10 @java.ref:"java.lang.Integer::intValue():int";
420                         java.yield %11;
421                     }
422                     ()java.type:"boolean" -> {
423                         %12 : java.type:"boolean" = constant @true;
424                         yield %12;
425                     }
426                     ()java.type:"int" -> {
427                         %13 : java.type:"int" = constant @0;
428                         java.yield %13;
429                     };
430                 %14 : Var<java.type:"int"> = var %6 @"x";
431                 return;
432             };
433             """)
434     void test18(int i, Integer I) {
435         int x = switch (i) {
436             case 1 -> { yield I; }
437             default -> { yield 0; }
438         };
439     }
440 
441     @Reflect
442     @IR("""
443             func @"test19" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
444                 %3 : Var<java.type:"int"> = var %1 @"i";
445                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
446                 %5 : java.type:"int" = var.load %3;
447                 %6 : java.type:"int" = java.switch.expression %5
448                     (%7 : java.type:"int")java.type:"boolean" -> {
449                         %8 : java.type:"int" = constant @1;
450                         %9 : java.type:"boolean" = eq %7 %8;
451                         yield %9;
452                     }
453                     ()java.type:"int" -> {
454                         %10 : java.type:"int" = constant @1;
455                         java.yield %10;
456                     }
457                     ()java.type:"boolean" -> {
458                         %11 : java.type:"boolean" = constant @true;
459                         yield %11;
460                     }
461                     ()java.type:"int" -> {
462                         %12 : java.type:"java.lang.Integer" = var.load %4;
463                         %13 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
464                         java.yield %13;
465                     };
466                 %14 : Var<java.type:"int"> = var %6 @"x";
467                 return;
468             };
469             """)
470     void test19(int i, Integer I) {
471         int x = switch (i) {
472             case 1 -> { yield 1; }
473             default -> { yield I; }
474         };
475     }
476 
477     @Reflect
478     @IR("""
479             func @"test20" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
480                 %2 : Var<java.type:"int"> = var %1 @"i";
481                 %3 : java.type:"int" = var.load %2;
482                 %4 : java.type:"java.lang.Integer" = java.switch.expression %3
483                     (%5 : java.type:"int")java.type:"boolean" -> {
484                         %6 : java.type:"int" = constant @1;
485                         %7 : java.type:"boolean" = eq %5 %6;
486                         yield %7;
487                     }
488                     ()java.type:"java.lang.Integer" -> {
489                         %8 : java.type:"int" = constant @1;
490                         %9 : java.type:"java.lang.Integer" = invoke %8 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
491                         java.yield %9;
492                     }
493                     ()java.type:"boolean" -> {
494                         %10 : java.type:"boolean" = constant @true;
495                         yield %10;
496                     }
497                     ()java.type:"java.lang.Integer" -> {
498                         %11 : java.type:"int" = constant @0;
499                         %12 : java.type:"java.lang.Integer" = invoke %11 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
500                         java.yield %12;
501                     };
502                 %13 : Var<java.type:"java.lang.Integer"> = var %4 @"x";
503                 return;
504             };
505             """)
506     void test20(int i) {
507         Integer x = switch (i) {
508             case 1 -> { yield 1; }
509             default -> { yield 0; }
510         };
511     }
512 
513     @Reflect
514     @IR("""
515             func @"test21" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int", %2 : java.type:"java.lang.Integer")java.type:"void" -> {
516                 %3 : Var<java.type:"int"> = var %1 @"i";
517                 %4 : Var<java.type:"java.lang.Integer"> = var %2 @"I";
518                 %5 : java.type:"int" = var.load %3;
519                 %6 : java.type:"java.lang.Integer" = var.load %4;
520                 %7 : java.type:"int" = invoke %6 @java.ref:"java.lang.Integer::intValue():int";
521                 %8 : java.type:"int" = add %5 %7;
522                 %9 : Var<java.type:"int"> = var %8 @"l";
523                 return;
524             };
525             """)
526     void test21(int i, Integer I) {
527         int l = i + I;
528     }
529 
530     void m(Integer I) { }
531 
532     @Reflect
533     @IR("""
534             func @"test22" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
535                 %2 : Var<java.type:"int"> = var %1 @"i";
536                 %3 : java.type:"int" = var.load %2;
537                 %4 : java.type:"java.lang.Integer" = invoke %3 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
538                 invoke %0 %4 @java.ref:"BoxingConversionTest::m(java.lang.Integer):void";
539                 return;
540             };
541             """)
542     void test22(int i) {
543         m(i);
544     }
545 
546     void m(int i1, int i2, Integer... I) { }
547 
548     @Reflect
549     @IR("""
550             func @"test23" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
551                 %2 : Var<java.type:"int"> = var %1 @"i";
552                 %3 : java.type:"int" = var.load %2;
553                 %4 : java.type:"int" = var.load %2;
554                 invoke %0 %3 %4 @java.ref:"BoxingConversionTest::m(int, int, java.lang.Integer[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
555                 return;
556             };
557             """)
558     void test23(int i) {
559         m(i, i);
560     }
561 
562     @Reflect
563     @IR("""
564             func @"test24" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
565                 %2 : Var<java.type:"int"> = var %1 @"i";
566                 %3 : java.type:"int" = var.load %2;
567                 %4 : java.type:"int" = var.load %2;
568                 %5 : java.type:"int" = var.load %2;
569                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
570                 invoke %0 %3 %4 %6 @java.ref:"BoxingConversionTest::m(int, int, java.lang.Integer[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
571                 return;
572             };
573             """)
574     void test24(int i) {
575         m(i, i, i);
576     }
577 
578     @Reflect
579     @IR("""
580             func @"test25" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
581                 %2 : Var<java.type:"int"> = var %1 @"i";
582                 %3 : java.type:"int" = var.load %2;
583                 %4 : java.type:"int" = var.load %2;
584                 %5 : java.type:"int" = var.load %2;
585                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
586                 %7 : java.type:"int" = var.load %2;
587                 %8 : java.type:"java.lang.Integer" = invoke %7 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
588                 invoke %0 %3 %4 %6 %8 @java.ref:"BoxingConversionTest::m(int, int, java.lang.Integer[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
589                 return;
590             };
591             """)
592     void test25(int i) {
593         m(i, i, i, i);
594     }
595 
596     static class Box2 {
597         Box2(Integer I) { }
598         Box2(int i1, int i2, Integer... Is) { }
599     }
600 
601     @Reflect
602     @IR("""
603             func @"test26" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
604                 %2 : Var<java.type:"int"> = var %1 @"i";
605                 %3 : java.type:"int" = var.load %2;
606                 %4 : java.type:"java.lang.Integer" = invoke %3 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
607                 %5 : java.type:"BoxingConversionTest$Box2" = new %4 @java.ref:"BoxingConversionTest$Box2::(java.lang.Integer)";
608                 return;
609             };
610             """)
611     void test26(int i) {
612         new Box2(i);
613     }
614 
615     @Reflect
616     @IR("""
617             func @"test27" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
618                 %2 : Var<java.type:"int"> = var %1 @"i";
619                 %3 : java.type:"int" = var.load %2;
620                 %4 : java.type:"int" = var.load %2;
621                 %5 : java.type:"BoxingConversionTest$Box2" = new %3 %4 @java.ref:"BoxingConversionTest$Box2::(int, int, java.lang.Integer[])" @new.varargs=true;
622                 return;
623             };
624             """)
625     void test27(int i) {
626         new Box2(i, i);
627     }
628 
629     @Reflect
630     @IR("""
631             func @"test28" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
632                 %2 : Var<java.type:"int"> = var %1 @"i";
633                 %3 : java.type:"int" = var.load %2;
634                 %4 : java.type:"int" = var.load %2;
635                 %5 : java.type:"int" = var.load %2;
636                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
637                 %7 : java.type:"BoxingConversionTest$Box2" = new %3 %4 %6 @java.ref:"BoxingConversionTest$Box2::(int, int, java.lang.Integer[])" @new.varargs=true;
638                 return;
639             };
640             """)
641     void test28(int i) {
642         new Box2(i, i, i);
643     }
644 
645     @Reflect
646     @IR("""
647             func @"test29" (%0 : java.type:"BoxingConversionTest", %1 : java.type:"int")java.type:"void" -> {
648                 %2 : Var<java.type:"int"> = var %1 @"i";
649                 %3 : java.type:"int" = var.load %2;
650                 %4 : java.type:"int" = var.load %2;
651                 %5 : java.type:"int" = var.load %2;
652                 %6 : java.type:"java.lang.Integer" = invoke %5 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
653                 %7 : java.type:"int" = var.load %2;
654                 %8 : java.type:"java.lang.Integer" = invoke %7 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
655                 %9 : java.type:"BoxingConversionTest$Box2" = new %3 %4 %6 %8 @java.ref:"BoxingConversionTest$Box2::(int, int, java.lang.Integer[])" @new.varargs=true;
656                 return;
657             };
658             """)
659     void test29(int i) {
660         new Box2(i, i, i, i);
661     }
662 
663     @Reflect
664     @IR("""
665             func @"test30" (%0 : java.type:"java.lang.Integer")java.type:"void" -> {
666                 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
667                 %2 : java.type:"java.lang.Integer" = var.load %1;
668                 %3 : java.type:"int" = invoke %2 @java.ref:"java.lang.Integer::intValue():int";
669                 %4 : java.type:"int" = neg %3;
670                 %5 : Var<java.type:"int"> = var %4 @"j";
671                 return;
672             };
673             """)
674     static void test30(Integer i) {
675         int j = -i;
676     }
677 
678     @Reflect
679     @IR("""
680             func @"test31" (%0 : java.type:"int")java.type:"void" -> {
681                 %1 : Var<java.type:"int"> = var %0 @"i";
682                 %2 : java.type:"int" = var.load %1;
683                 %3 : java.type:"int" = neg %2;
684                 %4 : java.type:"java.lang.Integer" = invoke %3 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
685                 %5 : Var<java.type:"java.lang.Integer"> = var %4 @"j";
686                 return;
687             };
688             """)
689     static void test31(int i) {
690         Integer j = -i;
691     }
692 
693     @Reflect
694     @IR("""
695             func @"test32" (%0 : java.type:"boolean")java.type:"void" -> {
696                 %1 : Var<java.type:"boolean"> = var %0 @"i";
697                 %2 : java.type:"boolean" = var.load %1;
698                 %3 : java.type:"boolean" = not %2;
699                 %4 : java.type:"java.lang.Boolean" = invoke %3 @java.ref:"java.lang.Boolean::valueOf(boolean):java.lang.Boolean";
700                 %5 : Var<java.type:"java.lang.Boolean"> = var %4 @"j";
701                 return;
702             };
703             """)
704     static void test32(boolean i) {
705         Boolean j = !i;
706     }
707 
708     @Reflect
709     @IR("""
710             func @"test33" (%0 : java.type:"java.lang.Boolean")java.type:"void" -> {
711                 %1 : Var<java.type:"java.lang.Boolean"> = var %0 @"i";
712                 %2 : java.type:"java.lang.Boolean" = var.load %1;
713                 %3 : java.type:"boolean" = invoke %2 @java.ref:"java.lang.Boolean::booleanValue():boolean";
714                 %4 : java.type:"boolean" = not %3;
715                 %5 : Var<java.type:"boolean"> = var %4 @"j";
716                 return;
717             };
718             """)
719     static void test33(Boolean i) {
720         boolean j = !i;
721     }
722 
723     @Reflect
724     @IR("""
725             func @"unboxForEachList" (%0 : java.type:"java.util.List<java.lang.Integer>")java.type:"int" -> {
726                 %1 : Var<java.type:"java.util.List<java.lang.Integer>"> = var %0 @"li";
727                 %2 : java.type:"int" = constant @0;
728                 %3 : Var<java.type:"int"> = var %2 @"j";
729                 java.enhancedFor
730                     ()java.type:"java.util.List<java.lang.Integer>" -> {
731                         %4 : java.type:"java.util.List<java.lang.Integer>" = var.load %1;
732                         yield %4;
733                     }
734                     (%5 : java.type:"java.lang.Integer")Var<java.type:"int"> -> {
735                         %6 : java.type:"int" = invoke %5 @java.ref:"java.lang.Integer::intValue():int";
736                         %7 : Var<java.type:"int"> = var %6 @"i";
737                         yield %7;
738                     }
739                     (%8 : Var<java.type:"int">)java.type:"void" -> {
740                         %9 : java.type:"int" = var.load %3;
741                         %10 : java.type:"int" = var.load %8;
742                         %11 : java.type:"int" = add %9 %10;
743                         var.store %3 %11;
744                         java.continue;
745                     };
746                 %12 : java.type:"int" = var.load %3;
747                 return %12;
748             };
749             """)
750     static int unboxForEachList(List<Integer> li) {
751         int j = 0;
752         for (int i : li) {
753             j += i;
754         }
755         return j;
756     }
757 
758     @Reflect
759     @IR("""
760             func @"unboxForEachArray" (%0 : java.type:"java.lang.Integer[]")java.type:"int" -> {
761                 %1 : Var<java.type:"java.lang.Integer[]"> = var %0 @"is";
762                 %2 : java.type:"int" = constant @0;
763                 %3 : Var<java.type:"int"> = var %2 @"j";
764                 java.enhancedFor
765                     ()java.type:"java.lang.Integer[]" -> {
766                         %4 : java.type:"java.lang.Integer[]" = var.load %1;
767                         yield %4;
768                     }
769                     (%5 : java.type:"java.lang.Integer")Var<java.type:"int"> -> {
770                         %6 : java.type:"int" = invoke %5 @java.ref:"java.lang.Integer::intValue():int";
771                         %7 : Var<java.type:"int"> = var %6 @"i";
772                         yield %7;
773                     }
774                     (%8 : Var<java.type:"int">)java.type:"void" -> {
775                         %9 : java.type:"int" = var.load %3;
776                         %10 : java.type:"int" = var.load %8;
777                         %11 : java.type:"int" = add %9 %10;
778                         var.store %3 %11;
779                         java.continue;
780                     };
781                 %12 : java.type:"int" = var.load %3;
782                 return %12;
783             };
784             """)
785     static int unboxForEachArray(Integer[] is) {
786         int j = 0;
787         for (int i : is) {
788             j += i;
789         }
790         return j;
791     }
792 
793     @Reflect
794     @IR("""
795             func @"unboxListRaw" (%0 : java.type:"java.util.List")java.type:"int" -> {
796                 %1 : Var<java.type:"java.util.List"> = var %0 @"li";
797                 %2 : java.type:"int" = constant @0;
798                 %3 : Var<java.type:"int"> = var %2 @"j";
799                 java.enhancedFor
800                     ()java.type:"java.util.List" -> {
801                         %4 : java.type:"java.util.List" = var.load %1;
802                         yield %4;
803                     }
804                     (%5 : java.type:"java.lang.Object")Var<java.type:"java.lang.Object"> -> {
805                         %6 : Var<java.type:"java.lang.Object"> = var %5 @"i";
806                         yield %6;
807                     }
808                     (%7 : Var<java.type:"java.lang.Object">)java.type:"void" -> {
809                         %8 : java.type:"int" = var.load %3;
810                         %9 : java.type:"java.lang.Object" = var.load %7;
811                         %10 : java.type:"java.lang.Integer" = cast %9 @java.type:"java.lang.Integer";
812                         %11 : java.type:"int" = invoke %10 @java.ref:"java.lang.Integer::intValue():int";
813                         %12 : java.type:"int" = add %8 %11;
814                         var.store %3 %12;
815                         java.continue;
816                     };
817                 %13 : java.type:"int" = var.load %3;
818                 return %13;
819             };
820             """)
821     public static int unboxListRaw(List li) {
822         int j = 0;
823         for (Object i : li) {
824             j += (int)i;
825         }
826         return j;
827     }
828 
829     @Reflect
830     @IR("""
831             func @"unboxListTvar" (%0 : java.type:"java.util.List<&BoxingConversionTest::unboxListTvar(java.util.List):int::<X extends java.lang.Integer>>")java.type:"int" -> {
832                 %1 : Var<java.type:"java.util.List<&BoxingConversionTest::unboxListTvar(java.util.List):int::<X extends java.lang.Integer>>"> = var %0 @"li";
833                 %2 : java.type:"int" = constant @0;
834                 %3 : Var<java.type:"int"> = var %2 @"j";
835                 java.enhancedFor
836                     ()java.type:"java.util.List<&BoxingConversionTest::unboxListTvar(java.util.List):int::<X extends java.lang.Integer>>" -> {
837                         %4 : java.type:"java.util.List<&BoxingConversionTest::unboxListTvar(java.util.List):int::<X extends java.lang.Integer>>" = var.load %1;
838                         yield %4;
839                     }
840                     (%5 : java.type:"&BoxingConversionTest::unboxListTvar(java.util.List):int::<X extends java.lang.Integer>")Var<java.type:"int"> -> {
841                         %6 : java.type:"java.lang.Integer" = cast %5 @java.type:"java.lang.Integer";
842                         %7 : java.type:"int" = invoke %6 @java.ref:"java.lang.Integer::intValue():int";
843                         %8 : Var<java.type:"int"> = var %7 @"i";
844                         yield %8;
845                     }
846                     (%9 : Var<java.type:"int">)java.type:"void" -> {
847                         %10 : java.type:"int" = var.load %3;
848                         %11 : java.type:"int" = var.load %9;
849                         %12 : java.type:"int" = add %10 %11;
850                         var.store %3 %12;
851                         java.continue;
852                     };
853                 %13 : java.type:"int" = var.load %3;
854                 return %13;
855             };
856             """)
857     public static <X extends Integer> int unboxListTvar(List<X> li) {
858         int j = 0;
859         for (int i : li) {
860             j += i;
861         }
862         return j;
863     }
864 }