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