1 /*
  2  * Copyright (c) 2025, 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.*;
 25 import jdk.incubator.code.dialect.core.CoreOp;
 26 import jdk.incubator.code.dialect.java.JavaOp;
 27 
 28 import java.lang.invoke.MethodHandles;
 29 import java.util.function.IntConsumer;
 30 import java.util.function.Predicate;
 31 
 32 /*
 33  * @test
 34  * @modules jdk.incubator.code
 35  * @build TestPE
 36  * @build CodeReflectionTester
 37  * @run main CodeReflectionTester TestPE
 38  * @enablePreview
 39  */
 40 
 41 public class TestPE {
 42 
 43     public static MethodHandles.Lookup lookup() {
 44         return MethodHandles.lookup();
 45     }
 46 
 47     public static Predicate<Op> opConstants() {
 48         return op -> switch (op) {
 49             case CoreOp.ConstantOp _ -> true;
 50             case JavaOp.InvokeOp _ -> false;
 51             case CoreOp.ReturnOp _ -> false;
 52             default -> op.result() != null;
 53         };
 54     }
 55 
 56     @CodeReflection
 57     @EvaluatedModel("""
 58             func @"ifStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
 59                 %2 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
 60                 %3 : java.type:"java.util.function.IntConsumer" = var.load %2;
 61                 %4 : java.type:"int" = constant @1;
 62                 invoke %3 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 63                 return;
 64             };
 65             """)
 66     @EvaluatedModel(value = """
 67             func @"ifStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
 68                 %2 : java.type:"int" = constant @1;
 69                 invoke %1 %2 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 70                 return;
 71             };
 72             """,
 73             ssa = true
 74     )
 75     void ifStatement(IntConsumer c) {
 76         if (true) {
 77             c.accept(1);
 78         } else {
 79             c.accept(2);
 80         }
 81     }
 82 
 83     @CodeReflection
 84     @EvaluatedModel("""
 85             func @"forStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
 86                 %2 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
 87                 %3 : java.type:"java.util.function.IntConsumer" = var.load %2;
 88                 %4 : java.type:"int" = constant @0;
 89                 invoke %3 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 90                 %5 : java.type:"java.util.function.IntConsumer" = var.load %2;
 91                 %6 : java.type:"int" = constant @2;
 92                 invoke %5 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 93                 %7 : java.type:"java.util.function.IntConsumer" = var.load %2;
 94                 %8 : java.type:"int" = constant @-4;
 95                 invoke %7 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 96                 %9 : java.type:"java.util.function.IntConsumer" = var.load %2;
 97                 %10 : java.type:"int" = constant @6;
 98                 invoke %9 %10 @java.ref:"java.util.function.IntConsumer::accept(int):void";
 99                 %11 : java.type:"java.util.function.IntConsumer" = var.load %2;
100                 %12 : java.type:"int" = constant @-8;
101                 invoke %11 %12 @java.ref:"java.util.function.IntConsumer::accept(int):void";
102                 return;
103             };
104             """)
105     @EvaluatedModel(value = """
106             func @"forStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
107                 %2 : java.type:"int" = constant @0;
108                 invoke %1 %2 @java.ref:"java.util.function.IntConsumer::accept(int):void";
109                 %3 : java.type:"int" = constant @2;
110                 invoke %1 %3 @java.ref:"java.util.function.IntConsumer::accept(int):void";
111                 %4 : java.type:"int" = constant @-4;
112                 invoke %1 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
113                 %5 : java.type:"int" = constant @6;
114                 invoke %1 %5 @java.ref:"java.util.function.IntConsumer::accept(int):void";
115                 %6 : java.type:"int" = constant @-8;
116                 invoke %1 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
117                 return;
118             };
119             """,
120             ssa = true
121     )
122     void forStatement(IntConsumer c) {
123         for (int i = 0; i < 5; i++) {
124             int v;
125             if (i % 2 == 0) {
126                 v = -i * 2;
127             } else {
128                 v = i * 2;
129             }
130             c.accept(v);
131         }
132     }
133 //
134     @CodeReflection
135     @EvaluatedModel(value = """
136             func @"forStatementNonConstant" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
137                 %3 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
138                 %4 : Var<java.type:"int"> = var %2 @"n";
139                 %5 : java.type:"int" = constant @0;
140                 %6 : java.type:"int" = var.load %4;
141                 %7 : java.type:"boolean" = lt %5 %6;
142                 cbranch %7 ^block_1 ^block_4;
143 
144               ^block_1:
145                 %8 : java.type:"java.util.function.IntConsumer" = var.load %3;
146                 %9 : java.type:"int" = constant @2;
147                 invoke %8 %9 @java.ref:"java.util.function.IntConsumer::accept(int):void";
148                 branch ^block_2;
149 
150               ^block_2:
151                 %10 : java.type:"int" = constant @1;
152                 %11 : java.type:"int" = var.load %4;
153                 %12 : java.type:"boolean" = lt %10 %11;
154                 cbranch %12 ^block_3 ^block_4;
155 
156               ^block_3:
157                 %13 : java.type:"java.util.function.IntConsumer" = var.load %3;
158                 %14 : java.type:"int" = constant @2;
159                 invoke %13 %14 @java.ref:"java.util.function.IntConsumer::accept(int):void";
160                 branch ^block_2;
161 
162               ^block_4:
163                 return;
164             };
165             """,
166             ssa = false
167     )
168     @EvaluatedModel(value = """
169             func @"forStatementNonConstant" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
170                 %3 : java.type:"int" = constant @0;
171                 %4 : java.type:"boolean" = lt %3 %2;
172                 cbranch %4 ^block_1 ^block_4;
173 
174               ^block_1:
175                 %5 : java.type:"int" = constant @2;
176                 invoke %1 %5 @java.ref:"java.util.function.IntConsumer::accept(int):void";
177                 %6 : java.type:"int" = constant @1;
178                 branch ^block_2(%6);
179 
180               ^block_2(%7 : java.type:"int"):
181                 %8 : java.type:"boolean" = lt %7 %2;
182                 cbranch %8 ^block_3 ^block_4;
183 
184               ^block_3:
185                 %9 : java.type:"int" = constant @2;
186                 invoke %1 %9 @java.ref:"java.util.function.IntConsumer::accept(int):void";
187                 %10 : java.type:"int" = constant @1;
188                 %11 : java.type:"int" = add %7 %10;
189                 branch ^block_2(%11);
190 
191               ^block_4:
192                 return;
193             };
194             """,
195             ssa = true
196     )
197     void forStatementNonConstant(IntConsumer c, int n) {
198         for (int i = 0; i < n; i++) {
199             int v;
200             if (false) {
201                 v = -1;
202             } else {
203                 v = 2;
204             }
205             c.accept(v);
206         }
207     }
208 
209     boolean b = true;
210     int[] x = new int[10];
211 
212     @CodeReflection
213     @EvaluatedModel("""
214             func @"f" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
215                  %2 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
216                  %3 : java.type:"java.util.function.IntConsumer" = var.load %2;
217                  %4 : java.type:"int" = constant @1;
218                  invoke %3 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
219                  %5 : java.type:"java.util.function.IntConsumer" = var.load %2;
220                  %6 : java.type:"int" = constant @3;
221                  invoke %5 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
222                  %7 : java.type:"boolean" = field.load %0 @java.ref:"TestPE::b:boolean";
223                  cbranch %7 ^block_1 ^block_2;
224 
225                ^block_1:
226                  %8 : java.type:"java.util.function.IntConsumer" = var.load %2;
227                  %9 : java.type:"int" = constant @5;
228                  invoke %8 %9 @java.ref:"java.util.function.IntConsumer::accept(int):void";
229                  %10 : java.type:"java.util.function.IntConsumer" = var.load %2;
230                  %11 : java.type:"int" = constant @0;
231                  invoke %10 %11 @java.ref:"java.util.function.IntConsumer::accept(int):void";
232                  %12 : java.type:"java.util.function.IntConsumer" = var.load %2;
233                  %13 : java.type:"int" = constant @6;
234                  invoke %12 %13 @java.ref:"java.util.function.IntConsumer::accept(int):void";
235                  %14 : java.type:"java.util.function.IntConsumer" = var.load %2;
236                  %15 : java.type:"int" = constant @1;
237                  invoke %14 %15 @java.ref:"java.util.function.IntConsumer::accept(int):void";
238                  %16 : java.type:"java.util.function.IntConsumer" = var.load %2;
239                  %17 : java.type:"int" = constant @0;
240                  %18 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
241                  %19 : java.type:"int" = constant @0;
242                  %20 : java.type:"int" = array.load %18 %19;
243                  %21 : java.type:"int" = add %17 %20;
244                  invoke %16 %21 @java.ref:"java.util.function.IntConsumer::accept(int):void";
245                  %22 : java.type:"java.util.function.IntConsumer" = var.load %2;
246                  %23 : java.type:"int" = constant @1;
247                  invoke %22 %23 @java.ref:"java.util.function.IntConsumer::accept(int):void";
248                  %24 : java.type:"java.util.function.IntConsumer" = var.load %2;
249                  %25 : java.type:"int" = constant @7;
250                  invoke %24 %25 @java.ref:"java.util.function.IntConsumer::accept(int):void";
251                  %26 : java.type:"java.util.function.IntConsumer" = var.load %2;
252                  %27 : java.type:"int" = constant @2;
253                  invoke %26 %27 @java.ref:"java.util.function.IntConsumer::accept(int):void";
254                  %28 : java.type:"java.util.function.IntConsumer" = var.load %2;
255                  %29 : java.type:"int" = constant @1;
256                  %30 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
257                  %31 : java.type:"int" = constant @1;
258                  %32 : java.type:"int" = array.load %30 %31;
259                  %33 : java.type:"int" = add %29 %32;
260                  invoke %28 %33 @java.ref:"java.util.function.IntConsumer::accept(int):void";
261                  %34 : java.type:"java.util.function.IntConsumer" = var.load %2;
262                  %35 : java.type:"int" = constant @2;
263                  invoke %34 %35 @java.ref:"java.util.function.IntConsumer::accept(int):void";
264                  %36 : java.type:"java.util.function.IntConsumer" = var.load %2;
265                  %37 : java.type:"int" = constant @7;
266                  invoke %36 %37 @java.ref:"java.util.function.IntConsumer::accept(int):void";
267                  %38 : java.type:"java.util.function.IntConsumer" = var.load %2;
268                  %39 : java.type:"int" = constant @2;
269                  invoke %38 %39 @java.ref:"java.util.function.IntConsumer::accept(int):void";
270                  %40 : java.type:"java.util.function.IntConsumer" = var.load %2;
271                  %41 : java.type:"int" = constant @2;
272                  %42 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
273                  %43 : java.type:"int" = constant @2;
274                  %44 : java.type:"int" = array.load %42 %43;
275                  %45 : java.type:"int" = add %41 %44;
276                  invoke %40 %45 @java.ref:"java.util.function.IntConsumer::accept(int):void";
277                  %46 : java.type:"java.util.function.IntConsumer" = var.load %2;
278                  %47 : java.type:"int" = constant @8;
279                  invoke %46 %47 @java.ref:"java.util.function.IntConsumer::accept(int):void";
280                  branch ^block_3;
281 
282                ^block_2:
283                  branch ^block_3;
284 
285                ^block_3:
286                  %48 : java.type:"java.util.function.IntConsumer" = var.load %2;
287                  %49 : java.type:"int" = constant @9;
288                  invoke %48 %49 @java.ref:"java.util.function.IntConsumer::accept(int):void";
289                  return;
290              };
291             """)
292     @EvaluatedModel(value = """
293             func @"f" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
294                    %2 : java.type:"int" = constant @1;
295                    invoke %1 %2 @java.ref:"java.util.function.IntConsumer::accept(int):void";
296                    %3 : java.type:"int" = constant @3;
297                    invoke %1 %3 @java.ref:"java.util.function.IntConsumer::accept(int):void";
298                    %4 : java.type:"boolean" = field.load %0 @java.ref:"TestPE::b:boolean";
299                    cbranch %4 ^block_1 ^block_2;
300 
301                  ^block_1:
302                    %5 : java.type:"int" = constant @5;
303                    invoke %1 %5 @java.ref:"java.util.function.IntConsumer::accept(int):void";
304                    %6 : java.type:"int" = constant @0;
305                    invoke %1 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
306                    %7 : java.type:"int" = constant @6;
307                    invoke %1 %7 @java.ref:"java.util.function.IntConsumer::accept(int):void";
308                    %8 : java.type:"int" = constant @1;
309                    invoke %1 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
310                    %9 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
311                    %10 : java.type:"int" = array.load %9 %6;
312                    %11 : java.type:"int" = add %6 %10;
313                    invoke %1 %11 @java.ref:"java.util.function.IntConsumer::accept(int):void";
314                    %12 : java.type:"int" = constant @1;
315                    invoke %1 %12 @java.ref:"java.util.function.IntConsumer::accept(int):void";
316                    %13 : java.type:"int" = constant @7;
317                    invoke %1 %13 @java.ref:"java.util.function.IntConsumer::accept(int):void";
318                    %14 : java.type:"int" = constant @2;
319                    invoke %1 %14 @java.ref:"java.util.function.IntConsumer::accept(int):void";
320                    %15 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
321                    %16 : java.type:"int" = array.load %15 %12;
322                    %17 : java.type:"int" = add %12 %16;
323                    invoke %1 %17 @java.ref:"java.util.function.IntConsumer::accept(int):void";
324                    %18 : java.type:"int" = constant @2;
325                    invoke %1 %18 @java.ref:"java.util.function.IntConsumer::accept(int):void";
326                    %19 : java.type:"int" = constant @7;
327                    invoke %1 %19 @java.ref:"java.util.function.IntConsumer::accept(int):void";
328                    %20 : java.type:"int" = constant @2;
329                    invoke %1 %20 @java.ref:"java.util.function.IntConsumer::accept(int):void";
330                    %21 : java.type:"int[]" = field.load %0 @java.ref:"TestPE::x:int[]";
331                    %22 : java.type:"int" = array.load %21 %18;
332                    %23 : java.type:"int" = add %18 %22;
333                    invoke %1 %23 @java.ref:"java.util.function.IntConsumer::accept(int):void";
334                    %24 : java.type:"int" = constant @8;
335                    invoke %1 %24 @java.ref:"java.util.function.IntConsumer::accept(int):void";
336                    branch ^block_3;
337 
338                  ^block_2:
339                    branch ^block_3;
340 
341                  ^block_3:
342                    %25 : java.type:"int" = constant @9;
343                    invoke %1 %25 @java.ref:"java.util.function.IntConsumer::accept(int):void";
344                    return;
345                };
346             """,
347             ssa = true
348     )
349     void f(IntConsumer c) {
350         c.accept(1);
351 
352         if (false) {
353             c.accept(2);
354         } else if (true) {
355             c.accept(3);
356         } else {
357             c.accept(4);
358         }
359 
360         if (b) {
361             c.accept(5);
362             for (int i = 0; i < 3; i++) {
363                 c.accept(i);
364                 int v;
365                 if (i == 0) {
366                     c.accept(6);
367                     v = 1;
368                 } else {
369                     c.accept(7);
370                     v = 2;
371                 }
372                 c.accept(v);
373                 c.accept(i + x[i]);
374             }
375 
376             c.accept(8);
377         }
378 
379         c.accept(9);
380     }
381 
382     @CodeReflection
383     @EvaluatedModel("""
384             func @"constantsInBranches" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
385                 %3 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
386                 %4 : Var<java.type:"int"> = var %2 @"arg";
387                 %5 : java.type:"int" = var.load %4;
388                 %6 : Var<java.type:"int"> = var %5 @"x";
389                 %7 : java.type:"int" = var.load %6;
390                 %8 : java.type:"int" = constant @0;
391                 %9 : java.type:"boolean" = eq %7 %8;
392                 cbranch %9 ^block_1 ^block_2;
393 
394               ^block_1:
395                 %10 : java.type:"int" = constant @1;
396                 var.store %6 %10;
397                 branch ^block_3;
398 
399               ^block_2:
400                 %11 : java.type:"int" = constant @2;
401                 var.store %6 %11;
402                 branch ^block_3;
403 
404               ^block_3:
405                 %12 : java.type:"java.util.function.IntConsumer" = var.load %3;
406                 %13 : java.type:"int" = var.load %6;
407                 invoke %12 %13 @java.ref:"java.util.function.IntConsumer::accept(int):void";
408                 return;
409             };
410             """)
411     @EvaluatedModel(value = """
412             func @"constantsInBranches" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
413                 %3 : java.type:"int" = constant @0;
414                 %4 : java.type:"boolean" = eq %2 %3;
415                 cbranch %4 ^block_1 ^block_2;
416 
417               ^block_1:
418                 %5 : java.type:"int" = constant @1;
419                 branch ^block_3(%5);
420 
421               ^block_2:
422                 %6 : java.type:"int" = constant @2;
423                 branch ^block_3(%6);
424 
425               ^block_3(%7 : java.type:"int"):
426                 invoke %1 %7 @java.ref:"java.util.function.IntConsumer::accept(int):void";
427                 return;
428             };
429             """,
430             ssa = true
431     )
432     void constantsInBranches(IntConsumer c, int arg) {
433         var x = arg;
434         if (x == 0) {
435             x = 1;
436         } else {
437             x = 2;
438         }
439         c.accept(x);
440     }
441 
442     @CodeReflection
443     @EvaluatedModel("""
444             func @"nestedForStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
445                 %2 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
446                 %3 : java.type:"java.util.function.IntConsumer" = var.load %2;
447                 %4 : java.type:"int" = constant @0;
448                 invoke %3 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
449                 %5 : java.type:"java.util.function.IntConsumer" = var.load %2;
450                 %6 : java.type:"int" = constant @1;
451                 invoke %5 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
452                 %7 : java.type:"java.util.function.IntConsumer" = var.load %2;
453                 %8 : java.type:"int" = constant @2;
454                 invoke %7 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
455                 %9 : java.type:"java.util.function.IntConsumer" = var.load %2;
456                 %10 : java.type:"int" = constant @1;
457                 invoke %9 %10 @java.ref:"java.util.function.IntConsumer::accept(int):void";
458                 %11 : java.type:"java.util.function.IntConsumer" = var.load %2;
459                 %12 : java.type:"int" = constant @2;
460                 invoke %11 %12 @java.ref:"java.util.function.IntConsumer::accept(int):void";
461                 %13 : java.type:"java.util.function.IntConsumer" = var.load %2;
462                 %14 : java.type:"int" = constant @3;
463                 invoke %13 %14 @java.ref:"java.util.function.IntConsumer::accept(int):void";
464                 %15 : java.type:"java.util.function.IntConsumer" = var.load %2;
465                 %16 : java.type:"int" = constant @2;
466                 invoke %15 %16 @java.ref:"java.util.function.IntConsumer::accept(int):void";
467                 %17 : java.type:"java.util.function.IntConsumer" = var.load %2;
468                 %18 : java.type:"int" = constant @3;
469                 invoke %17 %18 @java.ref:"java.util.function.IntConsumer::accept(int):void";
470                 %19 : java.type:"java.util.function.IntConsumer" = var.load %2;
471                 %20 : java.type:"int" = constant @4;
472                 invoke %19 %20 @java.ref:"java.util.function.IntConsumer::accept(int):void";
473                 return;
474             };
475             """)
476     @EvaluatedModel(value = """
477             func @"nestedForStatement" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer")java.type:"void" -> {
478                 %2 : java.type:"int" = constant @0;
479                 invoke %1 %2 @java.ref:"java.util.function.IntConsumer::accept(int):void";
480                 %3 : java.type:"int" = constant @1;
481                 invoke %1 %3 @java.ref:"java.util.function.IntConsumer::accept(int):void";
482                 %4 : java.type:"int" = constant @2;
483                 invoke %1 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
484                 %5 : java.type:"int" = constant @1;
485                 invoke %1 %5 @java.ref:"java.util.function.IntConsumer::accept(int):void";
486                 %6 : java.type:"int" = constant @2;
487                 invoke %1 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
488                 %7 : java.type:"int" = constant @3;
489                 invoke %1 %7 @java.ref:"java.util.function.IntConsumer::accept(int):void";
490                 %8 : java.type:"int" = constant @2;
491                 invoke %1 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
492                 %9 : java.type:"int" = constant @3;
493                 invoke %1 %9 @java.ref:"java.util.function.IntConsumer::accept(int):void";
494                 %10 : java.type:"int" = constant @4;
495                 invoke %1 %10 @java.ref:"java.util.function.IntConsumer::accept(int):void";
496                 return;
497             };
498             """,
499             ssa = true
500     )
501     void nestedForStatement(IntConsumer c) {
502         for (int i = 0; i < 3; i++) {
503             for (int j = 0; j < 3; j++) {
504                 c.accept(i + j);
505             }
506         }
507     }
508 
509 
510     @CodeReflection
511     @EvaluatedModel("""
512             func @"whileWithBreak" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
513                 %3 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
514                 %4 : Var<java.type:"int"> = var %2 @"n";
515                 %5 : java.type:"java.util.function.IntConsumer" = var.load %3;
516                 %6 : java.type:"int" = constant @0;
517                 invoke %5 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
518                 %7 : java.type:"java.util.function.IntConsumer" = var.load %3;
519                 %8 : java.type:"int" = constant @1;
520                 invoke %7 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
521                 %9 : java.type:"int" = constant @2;
522                 %10 : java.type:"int" = var.load %4;
523                 %11 : java.type:"boolean" = ge %9 %10;
524                 cbranch %11 ^block_3 ^block_1;
525 
526               ^block_1:
527                 %12 : java.type:"java.util.function.IntConsumer" = var.load %3;
528                 %13 : java.type:"int" = constant @2;
529                 invoke %12 %13 @java.ref:"java.util.function.IntConsumer::accept(int):void";
530                 branch ^block_2;
531 
532               ^block_2:
533                 %14 : java.type:"int" = constant @3;
534                 %15 : java.type:"int" = var.load %4;
535                 %16 : java.type:"boolean" = ge %14 %15;
536                 cbranch %16 ^block_3 ^block_4;
537 
538               ^block_3:
539                 %17 : java.type:"java.util.function.IntConsumer" = var.load %3;
540                 %18 : java.type:"int" = constant @-1;
541                 invoke %17 %18 @java.ref:"java.util.function.IntConsumer::accept(int):void";
542                 return;
543 
544               ^block_4:
545                 %19 : java.type:"java.util.function.IntConsumer" = var.load %3;
546                 %20 : java.type:"int" = constant @3;
547                 invoke %19 %20 @java.ref:"java.util.function.IntConsumer::accept(int):void";
548                 branch ^block_2;
549             };
550             """)
551     @EvaluatedModel(value = """
552             func @"whileWithBreak" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
553                 %3 : java.type:"int" = constant @0;
554                 invoke %1 %3 @java.ref:"java.util.function.IntConsumer::accept(int):void";
555                 %4 : java.type:"int" = constant @1;
556                 invoke %1 %4 @java.ref:"java.util.function.IntConsumer::accept(int):void";
557                 %5 : java.type:"int" = constant @2;
558                 %6 : java.type:"boolean" = ge %5 %2;
559                 cbranch %6 ^block_4 ^block_1;
560 
561               ^block_1:
562                 invoke %1 %5 @java.ref:"java.util.function.IntConsumer::accept(int):void";
563                 %7 : java.type:"int" = constant @3;
564                 branch ^block_2(%7);
565 
566               ^block_2(%8 : java.type:"int"):
567                 %9 : java.type:"int" = constant @2;
568                 %10 : java.type:"boolean" = ge %8 %9;
569                 cbranch %10 ^block_3 ^block_6;
570 
571               ^block_3:
572                 %11 : java.type:"boolean" = ge %8 %2;
573                 cbranch %11 ^block_4 ^block_5;
574 
575               ^block_4:
576                 %12 : java.type:"int" = constant @-1;
577                 invoke %1 %12 @java.ref:"java.util.function.IntConsumer::accept(int):void";
578                 return;
579 
580               ^block_5:
581                 branch ^block_7;
582 
583               ^block_6:
584                 branch ^block_7;
585 
586               ^block_7:
587                 invoke %1 %8 @java.ref:"java.util.function.IntConsumer::accept(int):void";
588                 %13 : java.type:"int" = constant @1;
589                 %14 : java.type:"int" = add %8 %13;
590                 branch ^block_2(%14);
591             };
592             """,
593             ssa = true
594     )
595     void whileWithBreak(IntConsumer c, int n) {
596         int i = 0;
597         while (true) {
598             if (i >= 2) {
599                 if (i >= n) {
600                     break;
601                 }
602             }
603             c.accept(i);
604             i += 1;
605         }
606         c.accept(-1);
607     }
608 
609     @CodeReflection
610     @EvaluatedModel("""
611             func @"whileWithBreakAndContinue" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
612                 %3 : Var<java.type:"java.util.function.IntConsumer"> = var %1 @"c";
613                 %4 : Var<java.type:"int"> = var %2 @"n";
614                 %5 : java.type:"int" = constant @2;
615                 %6 : java.type:"int" = var.load %4;
616                 %7 : java.type:"boolean" = ge %5 %6;
617                 cbranch %7 ^block_3 ^block_1;
618 
619               ^block_1:
620                 branch ^block_2;
621 
622               ^block_2:
623                 %8 : java.type:"int" = constant @4;
624                 %9 : java.type:"int" = var.load %4;
625                 %10 : java.type:"boolean" = ge %8 %9;
626                 cbranch %10 ^block_3 ^block_4;
627 
628               ^block_3:
629                 %11 : java.type:"java.util.function.IntConsumer" = var.load %3;
630                 %12 : java.type:"int" = constant @-1;
631                 invoke %11 %12 @java.ref:"java.util.function.IntConsumer::accept(int):void";
632                 return;
633 
634               ^block_4:
635                 branch ^block_2;
636             };
637             """)
638     @EvaluatedModel(value = """
639             func @"whileWithBreakAndContinue" (%0 : java.type:"TestPE", %1 : java.type:"java.util.function.IntConsumer", %2 : java.type:"int")java.type:"void" -> {
640                 %3 : java.type:"int" = constant @2;
641                 %4 : java.type:"boolean" = ge %3 %2;
642                 cbranch %4 ^block_4 ^block_1;
643 
644               ^block_1:
645                 %5 : java.type:"int" = constant @4;
646                 branch ^block_2(%5);
647 
648               ^block_2(%6 : java.type:"int"):
649                 %7 : java.type:"int" = constant @2;
650                 %8 : java.type:"boolean" = ge %6 %7;
651                 cbranch %8 ^block_3 ^block_6;
652 
653               ^block_3:
654                 %9 : java.type:"boolean" = ge %6 %2;
655                 cbranch %9 ^block_4 ^block_5;
656 
657               ^block_4:
658                 %10 : java.type:"int" = constant @-1;
659                 invoke %1 %10 @java.ref:"java.util.function.IntConsumer::accept(int):void";
660                 return;
661 
662               ^block_5:
663                 branch ^block_7;
664 
665               ^block_6:
666                 branch ^block_7;
667 
668               ^block_7:
669                 %11 : java.type:"int" = constant @5;
670                 %12 : java.type:"boolean" = lt %6 %11;
671                 cbranch %12 ^block_8 ^block_9;
672 
673               ^block_8:
674                 %13 : java.type:"int" = constant @2;
675                 %14 : java.type:"int" = add %6 %13;
676                 branch ^block_2(%14);
677 
678               ^block_9:
679                 invoke %1 %6 @java.ref:"java.util.function.IntConsumer::accept(int):void";
680                 %15 : java.type:"int" = constant @1;
681                 %16 : java.type:"int" = add %6 %15;
682                 branch ^block_2(%16);
683             };
684             """,
685             ssa = true
686     )
687     void whileWithBreakAndContinue(IntConsumer c, int n) {
688         int i = 0;
689         while (true) {
690             if (i >= 2) {
691                 if (i >= n) {
692                     break;
693                 }
694             }
695             if (i < 5) {
696                 i += 2;
697                 continue;
698             }
699             c.accept(i);
700             i += 1;
701         }
702         c.accept(-1);
703     }
704 
705 }