1 /*
   2  * Copyright (c) 2024, 2026, 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 import java.util.Collection;
  26 import java.util.RandomAccess;
  27 import java.util.Stack;
  28 
  29 /*
  30  * @test
  31  * @modules jdk.incubator.code
  32  * @build SwitchStatementTest
  33  * @build CodeReflectionTester
  34  * @run main CodeReflectionTester SwitchStatementTest
  35  */
  36 public class SwitchStatementTest {
  37 
  38     @IR("""
  39             func @"caseConstantRuleExpression" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
  40                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
  41                 %2 : java.type:"java.lang.String" = constant @"";
  42                 %3 : Var<java.type:"java.lang.String"> = var %2 @"s";
  43                 %4 : java.type:"java.lang.String" = var.load %1;
  44                 java.switch.statement %4
  45                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
  46                         %6 : java.type:"java.lang.String" = constant @"FOO";
  47                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  48                         yield %7;
  49                     }
  50                     ()java.type:"void" -> {
  51                         %8 : java.type:"java.lang.String" = var.load %3;
  52                         %9 : java.type:"java.lang.String" = constant @"BAR";
  53                         %10 : java.type:"java.lang.String" = concat %8 %9;
  54                         var.store %3 %10;
  55                         yield;
  56                     }
  57                     (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
  58                         %12 : java.type:"java.lang.String" = constant @"BAR";
  59                         %13 : java.type:"boolean" = invoke %11 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  60                         yield %13;
  61                     }
  62                     ()java.type:"void" -> {
  63                         %14 : java.type:"java.lang.String" = var.load %3;
  64                         %15 : java.type:"java.lang.String" = constant @"BAZ";
  65                         %16 : java.type:"java.lang.String" = concat %14 %15;
  66                         var.store %3 %16;
  67                         yield;
  68                     }
  69                     (%17 : java.type:"java.lang.String")java.type:"boolean" -> {
  70                         %18 : java.type:"java.lang.String" = constant @"BAZ";
  71                         %19 : java.type:"boolean" = invoke %17 %18 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  72                         yield %19;
  73                     }
  74                     ()java.type:"void" -> {
  75                         %20 : java.type:"java.lang.String" = var.load %3;
  76                         %21 : java.type:"java.lang.String" = constant @"FOO";
  77                         %22 : java.type:"java.lang.String" = concat %20 %21;
  78                         var.store %3 %22;
  79                         yield;
  80                     }
  81                     ()java.type:"boolean" -> {
  82                         %23 : java.type:"boolean" = constant @true;
  83                         yield %23;
  84                     }
  85                     ()java.type:"void" -> {
  86                         %24 : java.type:"java.lang.String" = var.load %3;
  87                         %25 : java.type:"java.lang.String" = constant @"else";
  88                         %26 : java.type:"java.lang.String" = concat %24 %25;
  89                         var.store %3 %26;
  90                         yield;
  91                     };
  92                 %27 : java.type:"java.lang.String" = var.load %3;
  93                 return %27;
  94             };
  95             """)
  96     @Reflect
  97     public static String caseConstantRuleExpression(String r) {
  98         String s = "";
  99         switch (r) {
 100             case "FOO" -> s += "BAR";
 101             case "BAR" -> s += "BAZ";
 102             case "BAZ" -> s += "FOO";
 103             default -> s += "else";
 104         }
 105         return s;
 106     }
 107 
 108     @IR("""
 109             func @"caseConstantRuleBlock" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 110                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
 111                 %2 : java.type:"java.lang.String" = constant @"";
 112                 %3 : Var<java.type:"java.lang.String"> = var %2 @"s";
 113                 %4 : java.type:"java.lang.String" = var.load %1;
 114                 java.switch.statement %4
 115                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
 116                         %6 : java.type:"java.lang.String" = constant @"FOO";
 117                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 118                         yield %7;
 119                     }
 120                     ()java.type:"void" -> {
 121                         %8 : java.type:"java.lang.String" = var.load %3;
 122                         %9 : java.type:"java.lang.String" = constant @"BAR";
 123                         %10 : java.type:"java.lang.String" = concat %8 %9;
 124                         var.store %3 %10;
 125                         yield;
 126                     }
 127                     (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
 128                         %12 : java.type:"java.lang.String" = constant @"BAR";
 129                         %13 : java.type:"boolean" = invoke %11 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 130                         yield %13;
 131                     }
 132                     ()java.type:"void" -> {
 133                         %14 : java.type:"java.lang.String" = var.load %3;
 134                         %15 : java.type:"java.lang.String" = constant @"BAZ";
 135                         %16 : java.type:"java.lang.String" = concat %14 %15;
 136                         var.store %3 %16;
 137                         yield;
 138                     }
 139                     (%17 : java.type:"java.lang.String")java.type:"boolean" -> {
 140                         %18 : java.type:"java.lang.String" = constant @"BAZ";
 141                         %19 : java.type:"boolean" = invoke %17 %18 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 142                         yield %19;
 143                     }
 144                     ()java.type:"void" -> {
 145                         %20 : java.type:"java.lang.String" = var.load %3;
 146                         %21 : java.type:"java.lang.String" = constant @"FOO";
 147                         %22 : java.type:"java.lang.String" = concat %20 %21;
 148                         var.store %3 %22;
 149                         yield;
 150                     }
 151                     ()java.type:"boolean" -> {
 152                         %23 : java.type:"boolean" = constant @true;
 153                         yield %23;
 154                     }
 155                     ()java.type:"void" -> {
 156                         %24 : java.type:"java.lang.String" = var.load %3;
 157                         %25 : java.type:"java.lang.String" = constant @"else";
 158                         %26 : java.type:"java.lang.String" = concat %24 %25;
 159                         var.store %3 %26;
 160                         yield;
 161                     };
 162                 %27 : java.type:"java.lang.String" = var.load %3;
 163                 return %27;
 164             };
 165             """)
 166     @Reflect
 167     public static String caseConstantRuleBlock(String r) {
 168         String s = "";
 169         switch (r) {
 170             case "FOO" -> {
 171                 s += "BAR";
 172             }
 173             case "BAR" -> {
 174                 s += "BAZ";
 175             }
 176             case "BAZ" -> {
 177                 s += "FOO";
 178             }
 179             default -> {
 180                 s += "else";
 181             }
 182         }
 183         return s;
 184     }
 185 
 186     @IR("""
 187             func @"caseConstantStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 188                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 189                 %2 : java.type:"java.lang.String" = constant @"";
 190                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 191                 %4 : java.type:"java.lang.String" = var.load %1;
 192                 java.switch.statement %4
 193                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
 194                         %6 : java.type:"java.lang.String" = constant @"FOO";
 195                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 196                         yield %7;
 197                     }
 198                     ()java.type:"void" -> {
 199                         %8 : java.type:"java.lang.String" = var.load %3;
 200                         %9 : java.type:"java.lang.String" = constant @"BAR";
 201                         %10 : java.type:"java.lang.String" = concat %8 %9;
 202                         var.store %3 %10;
 203                         java.break;
 204                     }
 205                     (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
 206                         %12 : java.type:"java.lang.String" = constant @"BAR";
 207                         %13 : java.type:"boolean" = invoke %11 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 208                         yield %13;
 209                     }
 210                     ()java.type:"void" -> {
 211                         %14 : java.type:"java.lang.String" = var.load %3;
 212                         %15 : java.type:"java.lang.String" = constant @"BAZ";
 213                         %16 : java.type:"java.lang.String" = concat %14 %15;
 214                         var.store %3 %16;
 215                         java.break;
 216                     }
 217                     (%17 : java.type:"java.lang.String")java.type:"boolean" -> {
 218                         %18 : java.type:"java.lang.String" = constant @"BAZ";
 219                         %19 : java.type:"boolean" = invoke %17 %18 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 220                         yield %19;
 221                     }
 222                     ()java.type:"void" -> {
 223                         %20 : java.type:"java.lang.String" = var.load %3;
 224                         %21 : java.type:"java.lang.String" = constant @"FOO";
 225                         %22 : java.type:"java.lang.String" = concat %20 %21;
 226                         var.store %3 %22;
 227                         java.break;
 228                     }
 229                     ()java.type:"boolean" -> {
 230                         %23 : java.type:"boolean" = constant @true;
 231                         yield %23;
 232                     }
 233                     ()java.type:"void" -> {
 234                         %24 : java.type:"java.lang.String" = var.load %3;
 235                         %25 : java.type:"java.lang.String" = constant @"else";
 236                         %26 : java.type:"java.lang.String" = concat %24 %25;
 237                         var.store %3 %26;
 238                         yield;
 239                     };
 240                 %27 : java.type:"java.lang.String" = var.load %3;
 241                 return %27;
 242             };
 243             """)
 244     @Reflect
 245     private static String caseConstantStatement(String s) {
 246         String r = "";
 247         switch (s) {
 248             case "FOO":
 249                 r += "BAR";
 250                 break;
 251             case "BAR":
 252                 r += "BAZ";
 253                 break;
 254             case "BAZ":
 255                 r += "FOO";
 256                 break;
 257             default:
 258                 r += "else";
 259         }
 260         return r;
 261     }
 262 
 263     @IR("""
 264             func @"caseConstantMultiLabels" (%0 : java.type:"char")java.type:"java.lang.String" -> {
 265                 %1 : Var<java.type:"char"> = var %0 @"c";
 266                 %2 : java.type:"java.lang.String" = constant @"";
 267                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 268                 %4 : java.type:"char" = var.load %1;
 269                 %5 : java.type:"char" = invoke %4 @java.ref:"java.lang.Character::toLowerCase(char):char";
 270                 java.switch.statement %5
 271                     (%6 : java.type:"char")java.type:"boolean" -> {
 272                         %7 : java.type:"boolean" = java.cor
 273                             ()java.type:"boolean" -> {
 274                                 %8 : java.type:"char" = constant @'a';
 275                                 %9 : java.type:"boolean" = eq %6 %8;
 276                                 yield %9;
 277                             }
 278                             ()java.type:"boolean" -> {
 279                                 %10 : java.type:"char" = constant @'e';
 280                                 %11 : java.type:"boolean" = eq %6 %10;
 281                                 yield %11;
 282                             }
 283                             ()java.type:"boolean" -> {
 284                                 %12 : java.type:"char" = constant @'i';
 285                                 %13 : java.type:"boolean" = eq %6 %12;
 286                                 yield %13;
 287                             }
 288                             ()java.type:"boolean" -> {
 289                                 %14 : java.type:"char" = constant @'o';
 290                                 %15 : java.type:"boolean" = eq %6 %14;
 291                                 yield %15;
 292                             }
 293                             ()java.type:"boolean" -> {
 294                                 %16 : java.type:"char" = constant @'u';
 295                                 %17 : java.type:"boolean" = eq %6 %16;
 296                                 yield %17;
 297                             };
 298                         yield %7;
 299                     }
 300                     ()java.type:"void" -> {
 301                         %18 : java.type:"java.lang.String" = var.load %3;
 302                         %19 : java.type:"java.lang.String" = constant @"vowel";
 303                         %20 : java.type:"java.lang.String" = concat %18 %19;
 304                         var.store %3 %20;
 305                         java.break;
 306                     }
 307                     ()java.type:"boolean" -> {
 308                         %21 : java.type:"boolean" = constant @true;
 309                         yield %21;
 310                     }
 311                     ()java.type:"void" -> {
 312                         %22 : java.type:"java.lang.String" = var.load %3;
 313                         %23 : java.type:"java.lang.String" = constant @"consonant";
 314                         %24 : java.type:"java.lang.String" = concat %22 %23;
 315                         var.store %3 %24;
 316                         yield;
 317                     };
 318                 %25 : java.type:"java.lang.String" = var.load %3;
 319                 return %25;
 320             };
 321             """)
 322     @Reflect
 323     private static String caseConstantMultiLabels(char c) {
 324         String r = "";
 325         switch (Character.toLowerCase(c)) {
 326             case 'a', 'e', 'i', 'o', 'u':
 327                 r += "vowel";
 328                 break;
 329             default:
 330                 r += "consonant";
 331         }
 332         return r;
 333     }
 334 
 335     @IR("""
 336             func @"caseConstantThrow" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
 337                 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
 338                 %2 : java.type:"java.lang.String" = constant @"";
 339                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 340                 %4 : java.type:"java.lang.Integer" = var.load %1;
 341                 java.switch.statement %4
 342                     (%5 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 343                         %6 : java.type:"int" = invoke %5 @java.ref:"java.lang.Integer::intValue():int";
 344                         %7 : java.type:"int" = constant @8;
 345                         %8 : java.type:"boolean" = eq %6 %7;
 346                         yield %8;
 347                     }
 348                     ()java.type:"void" -> {
 349                         %9 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
 350                         throw %9;
 351                     }
 352                     (%10 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 353                         %11 : java.type:"int" = invoke %10 @java.ref:"java.lang.Integer::intValue():int";
 354                         %12 : java.type:"int" = constant @9;
 355                         %13 : java.type:"boolean" = eq %11 %12;
 356                         yield %13;
 357                     }
 358                     ()java.type:"void" -> {
 359                         %14 : java.type:"java.lang.String" = var.load %3;
 360                         %15 : java.type:"java.lang.String" = constant @"Nine";
 361                         %16 : java.type:"java.lang.String" = concat %14 %15;
 362                         var.store %3 %16;
 363                         yield;
 364                     }
 365                     ()java.type:"boolean" -> {
 366                         %17 : java.type:"boolean" = constant @true;
 367                         yield %17;
 368                     }
 369                     ()java.type:"void" -> {
 370                         %18 : java.type:"java.lang.String" = var.load %3;
 371                         %19 : java.type:"java.lang.String" = constant @"An integer";
 372                         %20 : java.type:"java.lang.String" = concat %18 %19;
 373                         var.store %3 %20;
 374                         yield;
 375                     };
 376                 %21 : java.type:"java.lang.String" = var.load %3;
 377                 return %21;
 378             };
 379             """)
 380     @Reflect
 381     private static String caseConstantThrow(Integer i) {
 382         String r = "";
 383         switch (i) {
 384             case 8 -> throw new IllegalArgumentException();
 385             case 9 -> r += "Nine";
 386             default -> r += "An integer";
 387         }
 388         return r;
 389     }
 390 
 391     @IR("""
 392             func @"caseConstantNullLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 393                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 394                 %2 : java.type:"java.lang.String" = constant @"";
 395                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 396                 %4 : java.type:"java.lang.String" = var.load %1;
 397                 java.switch.statement %4
 398                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
 399                         %6 : java.type:"java.lang.Object" = constant @null;
 400                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 401                         yield %7;
 402                     }
 403                     ()java.type:"void" -> {
 404                         %8 : java.type:"java.lang.String" = var.load %3;
 405                         %9 : java.type:"java.lang.String" = constant @"null";
 406                         %10 : java.type:"java.lang.String" = concat %8 %9;
 407                         var.store %3 %10;
 408                         yield;
 409                     }
 410                     ()java.type:"boolean" -> {
 411                         %11 : java.type:"boolean" = constant @true;
 412                         yield %11;
 413                     }
 414                     ()java.type:"void" -> {
 415                         %12 : java.type:"java.lang.String" = var.load %3;
 416                         %13 : java.type:"java.lang.String" = constant @"non null";
 417                         %14 : java.type:"java.lang.String" = concat %12 %13;
 418                         var.store %3 %14;
 419                         yield;
 420                     };
 421                 %15 : java.type:"java.lang.String" = var.load %3;
 422                 return %15;
 423             };
 424             """)
 425     @Reflect
 426     private static String caseConstantNullLabel(String s) {
 427         String r = "";
 428         switch (s) {
 429             case null -> r += "null";
 430             default -> r += "non null";
 431         }
 432         return r;
 433     }
 434 
 435 //    @Reflect
 436 //    @@@ not supported
 437     private static String caseConstantNullAndDefault(String s) {
 438         String r = "";
 439         switch (s) {
 440             case "abc" -> r += "alphabet";
 441             case null, default -> r += "null or default";
 442         }
 443         return r;
 444     }
 445 
 446     @IR("""
 447             func @"caseConstantFallThrough" (%0 : java.type:"char")java.type:"java.lang.String" -> {
 448                 %1 : Var<java.type:"char"> = var %0 @"c";
 449                 %2 : java.type:"java.lang.String" = constant @"";
 450                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 451                 %4 : java.type:"char" = var.load %1;
 452                 java.switch.statement %4
 453                     (%5 : java.type:"char")java.type:"boolean" -> {
 454                         %6 : java.type:"char" = constant @'A';
 455                         %7 : java.type:"boolean" = eq %5 %6;
 456                         yield %7;
 457                     }
 458                     ()java.type:"void" -> {
 459                         java.switch.fallthrough;
 460                     }
 461                     (%8 : java.type:"char")java.type:"boolean" -> {
 462                         %9 : java.type:"char" = constant @'B';
 463                         %10 : java.type:"boolean" = eq %8 %9;
 464                         yield %10;
 465                     }
 466                     ()java.type:"void" -> {
 467                         %11 : java.type:"java.lang.String" = var.load %3;
 468                         %12 : java.type:"java.lang.String" = constant @"A or B";
 469                         %13 : java.type:"java.lang.String" = concat %11 %12;
 470                         var.store %3 %13;
 471                         java.break;
 472                     }
 473                     ()java.type:"boolean" -> {
 474                         %14 : java.type:"boolean" = constant @true;
 475                         yield %14;
 476                     }
 477                     ()java.type:"void" -> {
 478                         %15 : java.type:"java.lang.String" = var.load %3;
 479                         %16 : java.type:"java.lang.String" = constant @"Neither A nor B";
 480                         %17 : java.type:"java.lang.String" = concat %15 %16;
 481                         var.store %3 %17;
 482                         yield;
 483                     };
 484                 %18 : java.type:"java.lang.String" = var.load %3;
 485                 return %18;
 486             };
 487             """)
 488     @Reflect
 489     private static String caseConstantFallThrough(char c) {
 490         String r = "";
 491         switch (c) {
 492             case 'A':
 493             case 'B':
 494                 r += "A or B";
 495                 break;
 496             default:
 497                 r += "Neither A nor B";
 498         }
 499         return r;
 500     }
 501 
 502     enum Day {
 503         MON, TUE, WED, THU, FRI, SAT, SUN
 504     }
 505     @IR("""
 506             func @"caseConstantEnum" (%0 : java.type:"SwitchStatementTest$Day")java.type:"java.lang.String" -> {
 507                 %1 : Var<java.type:"SwitchStatementTest$Day"> = var %0 @"d";
 508                 %2 : java.type:"java.lang.String" = constant @"";
 509                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 510                 %4 : java.type:"SwitchStatementTest$Day" = var.load %1;
 511                 java.switch.statement %4
 512                     (%5 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 513                         %6 : java.type:"boolean" = java.cor
 514                             ()java.type:"boolean" -> {
 515                                 %7 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::MON:SwitchStatementTest$Day";
 516                                 %8 : java.type:"boolean" = eq %5 %7;
 517                                 yield %8;
 518                             }
 519                             ()java.type:"boolean" -> {
 520                                 %9 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::FRI:SwitchStatementTest$Day";
 521                                 %10 : java.type:"boolean" = eq %5 %9;
 522                                 yield %10;
 523                             }
 524                             ()java.type:"boolean" -> {
 525                                 %11 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::SUN:SwitchStatementTest$Day";
 526                                 %12 : java.type:"boolean" = eq %5 %11;
 527                                 yield %12;
 528                             };
 529                         yield %6;
 530                     }
 531                     ()java.type:"void" -> {
 532                         %13 : java.type:"java.lang.String" = var.load %3;
 533                         %14 : java.type:"int" = constant @6;
 534                         %15 : java.type:"java.lang.String" = concat %13 %14;
 535                         var.store %3 %15;
 536                         yield;
 537                     }
 538                     (%16 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 539                         %17 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::TUE:SwitchStatementTest$Day";
 540                         %18 : java.type:"boolean" = eq %16 %17;
 541                         yield %18;
 542                     }
 543                     ()java.type:"void" -> {
 544                         %19 : java.type:"java.lang.String" = var.load %3;
 545                         %20 : java.type:"int" = constant @7;
 546                         %21 : java.type:"java.lang.String" = concat %19 %20;
 547                         var.store %3 %21;
 548                         yield;
 549                     }
 550                     (%22 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 551                         %23 : java.type:"boolean" = java.cor
 552                             ()java.type:"boolean" -> {
 553                                 %24 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::THU:SwitchStatementTest$Day";
 554                                 %25 : java.type:"boolean" = eq %22 %24;
 555                                 yield %25;
 556                             }
 557                             ()java.type:"boolean" -> {
 558                                 %26 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::SAT:SwitchStatementTest$Day";
 559                                 %27 : java.type:"boolean" = eq %22 %26;
 560                                 yield %27;
 561                             };
 562                         yield %23;
 563                     }
 564                     ()java.type:"void" -> {
 565                         %28 : java.type:"java.lang.String" = var.load %3;
 566                         %29 : java.type:"int" = constant @8;
 567                         %30 : java.type:"java.lang.String" = concat %28 %29;
 568                         var.store %3 %30;
 569                         yield;
 570                     }
 571                     (%31 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 572                         %32 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::WED:SwitchStatementTest$Day";
 573                         %33 : java.type:"boolean" = eq %31 %32;
 574                         yield %33;
 575                     }
 576                     ()java.type:"void" -> {
 577                         %34 : java.type:"java.lang.String" = var.load %3;
 578                         %35 : java.type:"int" = constant @9;
 579                         %36 : java.type:"java.lang.String" = concat %34 %35;
 580                         var.store %3 %36;
 581                         yield;
 582                     };
 583                 %37 : java.type:"java.lang.String" = var.load %3;
 584                 return %37;
 585             };
 586             """)
 587     @Reflect
 588     private static String caseConstantEnum(Day d) {
 589         String r = "";
 590         switch (d) {
 591             case MON, FRI, SUN -> r += 6;
 592             case TUE -> r += 7;
 593             case THU, SAT -> r += 8;
 594             case WED -> r += 9;
 595         }
 596         return r;
 597     }
 598 
 599     static class Constants {
 600         static final int c1 = 12;
 601     }
 602     @IR("""
 603             func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
 604                 %1 : Var<java.type:"int"> = var %0 @"i";
 605                 %2 : java.type:"java.lang.String" = constant @"";
 606                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 607                 %4 : java.type:"int" = constant @11;
 608                 %5 : Var<java.type:"int"> = var %4 @"eleven";
 609                 %6 : java.type:"int" = var.load %1;
 610                 java.switch.statement %6
 611                     (%7 : java.type:"int")java.type:"boolean" -> {
 612                         %8 : java.type:"int" = constant @1;
 613                         %9 : java.type:"int" = constant @15;
 614                         %10 : java.type:"int" = and %8 %9;
 615                         %11 : java.type:"boolean" = eq %7 %10;
 616                         yield %11;
 617                     }
 618                     ()java.type:"void" -> {
 619                         %12 : java.type:"java.lang.String" = var.load %3;
 620                         %13 : java.type:"int" = constant @1;
 621                         %14 : java.type:"java.lang.String" = concat %12 %13;
 622                         var.store %3 %14;
 623                         yield;
 624                     }
 625                     (%15 : java.type:"int")java.type:"boolean" -> {
 626                         %16 : java.type:"int" = constant @4;
 627                         %17 : java.type:"int" = constant @1;
 628                         %18 : java.type:"int" = ashr %16 %17;
 629                         %19 : java.type:"boolean" = eq %15 %18;
 630                         yield %19;
 631                     }
 632                     ()java.type:"void" -> {
 633                         %20 : java.type:"java.lang.String" = var.load %3;
 634                         %21 : java.type:"java.lang.String" = constant @"2";
 635                         %22 : java.type:"java.lang.String" = concat %20 %21;
 636                         var.store %3 %22;
 637                         yield;
 638                     }
 639                     (%23 : java.type:"int")java.type:"boolean" -> {
 640                         %24 : java.type:"long" = constant @3;
 641                         %25 : java.type:"int" = conv %24;
 642                         %26 : java.type:"boolean" = eq %23 %25;
 643                         yield %26;
 644                     }
 645                     ()java.type:"void" -> {
 646                         %27 : java.type:"java.lang.String" = var.load %3;
 647                         %28 : java.type:"int" = constant @3;
 648                         %29 : java.type:"java.lang.String" = concat %27 %28;
 649                         var.store %3 %29;
 650                         yield;
 651                     }
 652                     (%30 : java.type:"int")java.type:"boolean" -> {
 653                         %31 : java.type:"int" = constant @2;
 654                         %32 : java.type:"int" = constant @1;
 655                         %33 : java.type:"int" = lshl %31 %32;
 656                         %34 : java.type:"boolean" = eq %30 %33;
 657                         yield %34;
 658                     }
 659                     ()java.type:"void" -> {
 660                         %35 : java.type:"java.lang.String" = var.load %3;
 661                         %36 : java.type:"int" = constant @4;
 662                         %37 : java.type:"java.lang.String" = concat %35 %36;
 663                         var.store %3 %37;
 664                         yield;
 665                     }
 666                     (%38 : java.type:"int")java.type:"boolean" -> {
 667                         %39 : java.type:"int" = constant @10;
 668                         %40 : java.type:"int" = constant @2;
 669                         %41 : java.type:"int" = div %39 %40;
 670                         %42 : java.type:"boolean" = eq %38 %41;
 671                         yield %42;
 672                     }
 673                     ()java.type:"void" -> {
 674                         %43 : java.type:"java.lang.String" = var.load %3;
 675                         %44 : java.type:"int" = constant @5;
 676                         %45 : java.type:"java.lang.String" = concat %43 %44;
 677                         var.store %3 %45;
 678                         yield;
 679                     }
 680                     (%46 : java.type:"int")java.type:"boolean" -> {
 681                         %47 : java.type:"int" = constant @12;
 682                         %48 : java.type:"int" = constant @6;
 683                         %49 : java.type:"int" = sub %47 %48;
 684                         %50 : java.type:"boolean" = eq %46 %49;
 685                         yield %50;
 686                     }
 687                     ()java.type:"void" -> {
 688                         %51 : java.type:"java.lang.String" = var.load %3;
 689                         %52 : java.type:"int" = constant @6;
 690                         %53 : java.type:"java.lang.String" = concat %51 %52;
 691                         var.store %3 %53;
 692                         yield;
 693                     }
 694                     (%54 : java.type:"int")java.type:"boolean" -> {
 695                         %55 : java.type:"int" = constant @3;
 696                         %56 : java.type:"int" = constant @4;
 697                         %57 : java.type:"int" = add %55 %56;
 698                         %58 : java.type:"boolean" = eq %54 %57;
 699                         yield %58;
 700                     }
 701                     ()java.type:"void" -> {
 702                         %59 : java.type:"java.lang.String" = var.load %3;
 703                         %60 : java.type:"int" = constant @7;
 704                         %61 : java.type:"java.lang.String" = concat %59 %60;
 705                         var.store %3 %61;
 706                         yield;
 707                     }
 708                     (%62 : java.type:"int")java.type:"boolean" -> {
 709                         %63 : java.type:"int" = constant @2;
 710                         %64 : java.type:"int" = constant @2;
 711                         %65 : java.type:"int" = mul %63 %64;
 712                         %66 : java.type:"int" = constant @2;
 713                         %67 : java.type:"int" = mul %65 %66;
 714                         %68 : java.type:"boolean" = eq %62 %67;
 715                         yield %68;
 716                     }
 717                     ()java.type:"void" -> {
 718                         %69 : java.type:"java.lang.String" = var.load %3;
 719                         %70 : java.type:"int" = constant @8;
 720                         %71 : java.type:"java.lang.String" = concat %69 %70;
 721                         var.store %3 %71;
 722                         yield;
 723                     }
 724                     (%72 : java.type:"int")java.type:"boolean" -> {
 725                         %73 : java.type:"int" = constant @8;
 726                         %74 : java.type:"int" = constant @1;
 727                         %75 : java.type:"int" = or %73 %74;
 728                         %76 : java.type:"boolean" = eq %72 %75;
 729                         yield %76;
 730                     }
 731                     ()java.type:"void" -> {
 732                         %77 : java.type:"java.lang.String" = var.load %3;
 733                         %78 : java.type:"int" = constant @9;
 734                         %79 : java.type:"java.lang.String" = concat %77 %78;
 735                         var.store %3 %79;
 736                         yield;
 737                     }
 738                     (%80 : java.type:"int")java.type:"boolean" -> {
 739                         %81 : java.type:"int" = constant @10;
 740                         %82 : java.type:"boolean" = eq %80 %81;
 741                         yield %82;
 742                     }
 743                     ()java.type:"void" -> {
 744                         %83 : java.type:"java.lang.String" = var.load %3;
 745                         %84 : java.type:"int" = constant @10;
 746                         %85 : java.type:"java.lang.String" = concat %83 %84;
 747                         var.store %3 %85;
 748                         yield;
 749                     }
 750                     (%86 : java.type:"int")java.type:"boolean" -> {
 751                         %87 : java.type:"int" = var.load %5;
 752                         %88 : java.type:"boolean" = eq %86 %87;
 753                         yield %88;
 754                     }
 755                     ()java.type:"void" -> {
 756                         %89 : java.type:"java.lang.String" = var.load %3;
 757                         %90 : java.type:"int" = constant @11;
 758                         %91 : java.type:"java.lang.String" = concat %89 %90;
 759                         var.store %3 %91;
 760                         yield;
 761                     }
 762                     (%92 : java.type:"int")java.type:"boolean" -> {
 763                         %93 : java.type:"int" = field.load @java.ref:"SwitchStatementTest$Constants::c1:int";
 764                         %94 : java.type:"boolean" = eq %92 %93;
 765                         yield %94;
 766                     }
 767                     ()java.type:"void" -> {
 768                         %95 : java.type:"java.lang.String" = var.load %3;
 769                         %96 : java.type:"int" = field.load @java.ref:"SwitchStatementTest$Constants::c1:int";
 770                         %97 : java.type:"java.lang.String" = concat %95 %96;
 771                         var.store %3 %97;
 772                         yield;
 773                     }
 774                     (%98 : java.type:"int")java.type:"boolean" -> {
 775                         %99 : java.type:"int" = java.cexpression
 776                             ()java.type:"boolean" -> {
 777                                 %100 : java.type:"int" = constant @1;
 778                                 %101 : java.type:"int" = constant @0;
 779                                 %102 : java.type:"boolean" = gt %100 %101;
 780                                 yield %102;
 781                             }
 782                             ()java.type:"int" -> {
 783                                 %103 : java.type:"int" = constant @13;
 784                                 yield %103;
 785                             }
 786                             ()java.type:"int" -> {
 787                                 %104 : java.type:"int" = constant @133;
 788                                 yield %104;
 789                             };
 790                         %105 : java.type:"boolean" = eq %98 %99;
 791                         yield %105;
 792                     }
 793                     ()java.type:"void" -> {
 794                         %106 : java.type:"java.lang.String" = var.load %3;
 795                         %107 : java.type:"int" = constant @13;
 796                         %108 : java.type:"java.lang.String" = concat %106 %107;
 797                         var.store %3 %108;
 798                         yield;
 799                     }
 800                     ()java.type:"boolean" -> {
 801                         %109 : java.type:"boolean" = constant @true;
 802                         yield %109;
 803                     }
 804                     ()java.type:"void" -> {
 805                         %110 : java.type:"java.lang.String" = var.load %3;
 806                         %111 : java.type:"java.lang.String" = constant @"an int";
 807                         %112 : java.type:"java.lang.String" = concat %110 %111;
 808                         var.store %3 %112;
 809                         yield;
 810                     };
 811                 %113 : java.type:"java.lang.String" = var.load %3;
 812                 return %113;
 813             };
 814             """)
 815     @Reflect
 816     private static String caseConstantOtherKindsOfExpr(int i) {
 817         String r = "";
 818         final int eleven = 11;
 819         switch (i) {
 820             case 1 & 0xF -> r += 1;
 821             case 4>>1 -> r += "2";
 822             case (int) 3L -> r += 3;
 823             case 2<<1 -> r += 4;
 824             case 10 / 2 -> r += 5;
 825             case 12 - 6 -> r += 6;
 826             case 3 + 4 -> r += 7;
 827             case 2 * 2 * 2 -> r += 8;
 828             case 8 | 1 -> r += 9;
 829             case (10) -> r += 10;
 830             case eleven -> r += 11;
 831             case Constants.c1 -> r += Constants.c1;
 832             case 1 > 0 ? 13 : 133 -> r += 13;
 833             default -> r += "an int";
 834         }
 835         return r;
 836     }
 837 
 838     @IR("""
 839             func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
 840                 %1 : Var<java.type:"short"> = var %0 @"a";
 841                 %2 : java.type:"int" = constant @1;
 842                 %3 : java.type:"short" = conv %2;
 843                 %4 : Var<java.type:"short"> = var %3 @"s";
 844                 %5 : java.type:"int" = constant @2;
 845                 %6 : java.type:"byte" = conv %5;
 846                 %7 : Var<java.type:"byte"> = var %6 @"b";
 847                 %8 : java.type:"java.lang.String" = constant @"";
 848                 %9 : Var<java.type:"java.lang.String"> = var %8 @"r";
 849                 %10 : java.type:"short" = var.load %1;
 850                 java.switch.statement %10
 851                     (%11 : java.type:"short")java.type:"boolean" -> {
 852                         %12 : java.type:"short" = var.load %4;
 853                         %13 : java.type:"boolean" = eq %11 %12;
 854                         yield %13;
 855                     }
 856                     ()java.type:"void" -> {
 857                         %14 : java.type:"java.lang.String" = var.load %9;
 858                         %15 : java.type:"java.lang.String" = constant @"one";
 859                         %16 : java.type:"java.lang.String" = concat %14 %15;
 860                         var.store %9 %16;
 861                         yield;
 862                     }
 863                     (%17 : java.type:"short")java.type:"boolean" -> {
 864                         %18 : java.type:"byte" = var.load %7;
 865                         %19 : java.type:"short" = conv %18;
 866                         %20 : java.type:"boolean" = eq %17 %19;
 867                         yield %20;
 868                     }
 869                     ()java.type:"void" -> {
 870                         %21 : java.type:"java.lang.String" = var.load %9;
 871                         %22 : java.type:"java.lang.String" = constant @"two";
 872                         %23 : java.type:"java.lang.String" = concat %21 %22;
 873                         var.store %9 %23;
 874                         yield;
 875                     }
 876                     (%24 : java.type:"short")java.type:"boolean" -> {
 877                         %25 : java.type:"int" = constant @3;
 878                         %26 : java.type:"short" = conv %25;
 879                         %27 : java.type:"boolean" = eq %24 %26;
 880                         yield %27;
 881                     }
 882                     ()java.type:"void" -> {
 883                         %28 : java.type:"java.lang.String" = var.load %9;
 884                         %29 : java.type:"java.lang.String" = constant @"three";
 885                         %30 : java.type:"java.lang.String" = concat %28 %29;
 886                         var.store %9 %30;
 887                         yield;
 888                     }
 889                     ()java.type:"boolean" -> {
 890                         %31 : java.type:"boolean" = constant @true;
 891                         yield %31;
 892                     }
 893                     ()java.type:"void" -> {
 894                         %32 : java.type:"java.lang.String" = var.load %9;
 895                         %33 : java.type:"java.lang.String" = constant @"else";
 896                         %34 : java.type:"java.lang.String" = concat %32 %33;
 897                         var.store %9 %34;
 898                         yield;
 899                     };
 900                 %35 : java.type:"java.lang.String" = var.load %9;
 901                 return %35;
 902             };
 903             """)
 904     @Reflect
 905     static String caseConstantConv(short a) {
 906         final short s = 1;
 907         final byte b = 2;
 908         String r = "";
 909         switch (a) {
 910             case s -> r += "one"; // identity, short -> short
 911             case b -> r += "two"; // widening primitive conversion, byte -> short
 912             case 3 -> r += "three"; // narrowing primitive conversion, int -> short
 913             default -> r += "else";
 914         }
 915         return r;
 916     }
 917 
 918     @IR("""
 919             func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
 920                 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
 921                 %2 : java.type:"int" = constant @2;
 922                 %3 : java.type:"byte" = conv %2;
 923                 %4 : Var<java.type:"byte"> = var %3 @"b";
 924                 %5 : java.type:"java.lang.String" = constant @"";
 925                 %6 : Var<java.type:"java.lang.String"> = var %5 @"r";
 926                 %7 : java.type:"java.lang.Byte" = var.load %1;
 927                 java.switch.statement %7
 928                     (%8 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 929                         %9 : java.type:"byte" = invoke %8 @java.ref:"java.lang.Byte::byteValue():byte";
 930                         %10 : java.type:"int" = constant @1;
 931                         %11 : java.type:"byte" = conv %10;
 932                         %12 : java.type:"boolean" = eq %9 %11;
 933                         yield %12;
 934                     }
 935                     ()java.type:"void" -> {
 936                         %13 : java.type:"java.lang.String" = var.load %6;
 937                         %14 : java.type:"java.lang.String" = constant @"one";
 938                         %15 : java.type:"java.lang.String" = concat %13 %14;
 939                         var.store %6 %15;
 940                         yield;
 941                     }
 942                     (%16 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 943                         %17 : java.type:"byte" = invoke %16 @java.ref:"java.lang.Byte::byteValue():byte";
 944                         %18 : java.type:"byte" = var.load %4;
 945                         %19 : java.type:"boolean" = eq %17 %18;
 946                         yield %19;
 947                     }
 948                     ()java.type:"void" -> {
 949                         %20 : java.type:"java.lang.String" = var.load %6;
 950                         %21 : java.type:"java.lang.String" = constant @"two";
 951                         %22 : java.type:"java.lang.String" = concat %20 %21;
 952                         var.store %6 %22;
 953                         yield;
 954                     }
 955                     ()java.type:"boolean" -> {
 956                         %23 : java.type:"boolean" = constant @true;
 957                         yield %23;
 958                     }
 959                     ()java.type:"void" -> {
 960                         %24 : java.type:"java.lang.String" = var.load %6;
 961                         %25 : java.type:"java.lang.String" = constant @"default";
 962                         %26 : java.type:"java.lang.String" = concat %24 %25;
 963                         var.store %6 %26;
 964                         yield;
 965                     };
 966                 %27 : java.type:"java.lang.String" = var.load %6;
 967                 return %27;
 968             };
 969             """)
 970     @Reflect
 971     static String caseConstantConv2(Byte a) {
 972         final byte b = 2;
 973         String r = "";
 974         switch (a) {
 975             case 1 -> r+= "one";
 976             case b -> r+= "two";
 977             default -> r+= "default";
 978         }
 979         return r;
 980     }
 981 
 982     @IR("""
 983             func @"nonEnhancedSwStatNoDefault" (%0 : java.type:"int")java.type:"java.lang.String" -> {
 984                 %1 : Var<java.type:"int"> = var %0 @"a";
 985                 %2 : java.type:"java.lang.String" = constant @"";
 986                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 987                 %4 : java.type:"int" = var.load %1;
 988                 java.switch.statement %4
 989                     (%5 : java.type:"int")java.type:"boolean" -> {
 990                         %6 : java.type:"int" = constant @1;
 991                         %7 : java.type:"boolean" = eq %5 %6;
 992                         yield %7;
 993                     }
 994                     ()java.type:"void" -> {
 995                         %8 : java.type:"java.lang.String" = var.load %3;
 996                         %9 : java.type:"java.lang.String" = constant @"1";
 997                         %10 : java.type:"java.lang.String" = concat %8 %9;
 998                         var.store %3 %10;
 999                         yield;
1000                     }
1001                     (%11 : java.type:"int")java.type:"boolean" -> {
1002                         %12 : java.type:"int" = constant @2;
1003                         %13 : java.type:"boolean" = eq %11 %12;
1004                         yield %13;
1005                     }
1006                     ()java.type:"void" -> {
1007                         %14 : java.type:"java.lang.String" = var.load %3;
1008                         %15 : java.type:"int" = constant @2;
1009                         %16 : java.type:"java.lang.String" = concat %14 %15;
1010                         var.store %3 %16;
1011                         yield;
1012                     };
1013                 %17 : java.type:"java.lang.String" = var.load %3;
1014                 return %17;
1015             };
1016             """)
1017     @Reflect
1018     static String nonEnhancedSwStatNoDefault(int a) {
1019         String r = "";
1020         switch (a) {
1021             case 1 -> r += "1";
1022             case 2 -> r += 2;
1023         }
1024         return r;
1025     }
1026 
1027     enum E {A, B}
1028     @IR("""
1029             func @"enhancedSwStatNoDefault1" (%0 : java.type:"SwitchStatementTest$E")java.type:"java.lang.String" -> {
1030                 %1 : Var<java.type:"SwitchStatementTest$E"> = var %0 @"e";
1031                 %2 : java.type:"java.lang.String" = constant @"";
1032                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1033                 %4 : java.type:"SwitchStatementTest$E" = var.load %1;
1034                 java.switch.statement %4
1035                     (%5 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1036                         %6 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::A:SwitchStatementTest$E";
1037                         %7 : java.type:"boolean" = eq %5 %6;
1038                         yield %7;
1039                     }
1040                     ()java.type:"void" -> {
1041                         %8 : java.type:"java.lang.String" = var.load %3;
1042                         %9 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::A:SwitchStatementTest$E";
1043                         %10 : java.type:"java.lang.String" = cast %9 @java.type:"java.lang.String";
1044                         %11 : java.type:"java.lang.String" = concat %8 %10;
1045                         var.store %3 %11;
1046                         yield;
1047                     }
1048                     (%12 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1049                         %13 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::B:SwitchStatementTest$E";
1050                         %14 : java.type:"boolean" = eq %12 %13;
1051                         yield %14;
1052                     }
1053                     ()java.type:"void" -> {
1054                         %15 : java.type:"java.lang.String" = var.load %3;
1055                         %16 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::B:SwitchStatementTest$E";
1056                         %17 : java.type:"java.lang.String" = cast %16 @java.type:"java.lang.String";
1057                         %18 : java.type:"java.lang.String" = concat %15 %17;
1058                         var.store %3 %18;
1059                         yield;
1060                     }
1061                     (%19 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1062                         %20 : java.type:"java.lang.Object" = constant @null;
1063                         %21 : java.type:"boolean" = eq %19 %20;
1064                         yield %21;
1065                     }
1066                     ()java.type:"void" -> {
1067                         %22 : java.type:"java.lang.String" = var.load %3;
1068                         %23 : java.type:"java.lang.String" = constant @"null";
1069                         %24 : java.type:"java.lang.String" = concat %22 %23;
1070                         var.store %3 %24;
1071                         yield;
1072                     }
1073                     ()java.type:"boolean" -> {
1074                         %25 : java.type:"boolean" = constant @true;
1075                         yield %25;
1076                     }
1077                     ()java.type:"void" -> {
1078                         %26 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
1079                         throw %26;
1080                     };
1081                 %27 : java.type:"java.lang.String" = var.load %3;
1082                 return %27;
1083             };
1084             """)
1085     @Reflect
1086     static String enhancedSwStatNoDefault1(E e) {
1087         String r = "";
1088         switch (e) {
1089             case A -> r += E.A;
1090             case B -> r += E.B;
1091             case null -> r += "null";
1092         }
1093         return r;
1094     }
1095 
1096     sealed interface I permits K, J {}
1097     record K() implements I {}
1098     static final class J implements I {}
1099     @IR("""
1100             func @"enhancedSwStatNoDefault2" (%0 : java.type:"SwitchStatementTest$I")java.type:"java.lang.String" -> {
1101                 %1 : Var<java.type:"SwitchStatementTest$I"> = var %0 @"i";
1102                 %2 : java.type:"java.lang.String" = constant @"";
1103                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1104                 %4 : java.type:"SwitchStatementTest$I" = var.load %1;
1105                 %5 : java.type:"SwitchStatementTest$K" = constant @null;
1106                 %6 : Var<java.type:"SwitchStatementTest$K"> = var %5 @"k";
1107                 %7 : java.type:"SwitchStatementTest$J" = constant @null;
1108                 %8 : Var<java.type:"SwitchStatementTest$J"> = var %7 @"j";
1109                 java.switch.statement %4
1110                     (%9 : java.type:"SwitchStatementTest$I")java.type:"boolean" -> {
1111                         %10 : java.type:"boolean" = pattern.match %9
1112                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$K>" -> {
1113                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$K>" = pattern.type @"k";
1114                                 yield %11;
1115                             }
1116                             (%12 : java.type:"SwitchStatementTest$K")java.type:"void" -> {
1117                                 var.store %6 %12;
1118                                 yield;
1119                             };
1120                         yield %10;
1121                     }
1122                     ()java.type:"void" -> {
1123                         %13 : java.type:"java.lang.String" = var.load %3;
1124                         %14 : java.type:"java.lang.String" = constant @"K";
1125                         %15 : java.type:"java.lang.String" = concat %13 %14;
1126                         var.store %3 %15;
1127                         yield;
1128                     }
1129                     (%16 : java.type:"SwitchStatementTest$I")java.type:"boolean" -> {
1130                         %17 : java.type:"boolean" = pattern.match %16
1131                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$J>" -> {
1132                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$J>" = pattern.type @"j";
1133                                 yield %18;
1134                             }
1135                             (%19 : java.type:"SwitchStatementTest$J")java.type:"void" -> {
1136                                 var.store %8 %19;
1137                                 yield;
1138                             };
1139                         yield %17;
1140                     }
1141                     ()java.type:"void" -> {
1142                         %20 : java.type:"java.lang.String" = var.load %3;
1143                         %21 : java.type:"java.lang.String" = constant @"J";
1144                         %22 : java.type:"java.lang.String" = concat %20 %21;
1145                         var.store %3 %22;
1146                         yield;
1147                     }
1148                     ()java.type:"boolean" -> {
1149                         %23 : java.type:"boolean" = constant @true;
1150                         yield %23;
1151                     }
1152                     ()java.type:"void" -> {
1153                         %24 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
1154                         throw %24;
1155                     };
1156                 %25 : java.type:"java.lang.String" = var.load %3;
1157                 return %25;
1158             };
1159             """)
1160     @Reflect
1161     static String enhancedSwStatNoDefault2(I i) {
1162         String r = "";
1163         switch (i) {
1164             case K k -> r += "K";
1165             case J j -> r += "J";
1166         }
1167         return r;
1168     }
1169 
1170     @IR("""
1171             func @"enhancedSwStatUnconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1172                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1173                 %2 : java.type:"java.lang.String" = constant @"";
1174                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1175                 %4 : java.type:"java.lang.String" = var.load %1;
1176                 %5 : java.type:"java.lang.Object" = constant @null;
1177                 %6 : Var<java.type:"java.lang.Object"> = var %5 @"o";
1178                 java.switch.statement %4
1179                     (%7 : java.type:"java.lang.String")java.type:"boolean" -> {
1180                         %8 : java.type:"java.lang.String" = constant @"A";
1181                         %9 : java.type:"boolean" = invoke %7 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1182                         yield %9;
1183                     }
1184                     ()java.type:"void" -> {
1185                         %10 : java.type:"java.lang.String" = var.load %3;
1186                         %11 : java.type:"java.lang.String" = constant @"A";
1187                         %12 : java.type:"java.lang.String" = concat %10 %11;
1188                         var.store %3 %12;
1189                         yield;
1190                     }
1191                     (%13 : java.type:"java.lang.String")java.type:"boolean" -> {
1192                         %14 : java.type:"boolean" = pattern.match %13
1193                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
1194                                 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
1195                                 yield %15;
1196                             }
1197                             (%16 : java.type:"java.lang.Object")java.type:"void" -> {
1198                                 var.store %6 %16;
1199                                 yield;
1200                             };
1201                         yield %14;
1202                     }
1203                     ()java.type:"void" -> {
1204                         %17 : java.type:"java.lang.String" = var.load %3;
1205                         %18 : java.type:"java.lang.String" = constant @"obj";
1206                         %19 : java.type:"java.lang.String" = concat %17 %18;
1207                         var.store %3 %19;
1208                         yield;
1209                     };
1210                 %20 : java.type:"java.lang.String" = var.load %3;
1211                 return %20;
1212             };
1213             """)
1214     @Reflect
1215     static String enhancedSwStatUnconditionalPattern(String s) {
1216         String r = "";
1217         switch (s) {
1218             case "A" -> r += "A";
1219             case Object o -> r += "obj";
1220         }
1221         return r;
1222     }
1223 
1224     @IR("""
1225             func @"casePatternRuleExpression" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1226                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1227                 %2 : java.type:"java.lang.String" = constant @"";
1228                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1229                 %4 : java.type:"java.lang.Object" = var.load %1;
1230                 %5 : java.type:"java.lang.Integer" = constant @null;
1231                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1232                 %7 : java.type:"java.lang.String" = constant @null;
1233                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1234                 java.switch.statement %4
1235                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1236                         %10 : java.type:"boolean" = pattern.match %9
1237                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1238                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1239                                 yield %11;
1240                             }
1241                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1242                                 var.store %6 %12;
1243                                 yield;
1244                             };
1245                         yield %10;
1246                     }
1247                     ()java.type:"void" -> {
1248                         %13 : java.type:"java.lang.String" = var.load %3;
1249                         %14 : java.type:"java.lang.String" = constant @"integer";
1250                         %15 : java.type:"java.lang.String" = concat %13 %14;
1251                         var.store %3 %15;
1252                         yield;
1253                     }
1254                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1255                         %17 : java.type:"boolean" = pattern.match %16
1256                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1257                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1258                                 yield %18;
1259                             }
1260                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1261                                 var.store %8 %19;
1262                                 yield;
1263                             };
1264                         yield %17;
1265                     }
1266                     ()java.type:"void" -> {
1267                         %20 : java.type:"java.lang.String" = var.load %3;
1268                         %21 : java.type:"java.lang.String" = constant @"string";
1269                         %22 : java.type:"java.lang.String" = concat %20 %21;
1270                         var.store %3 %22;
1271                         yield;
1272                     }
1273                     ()java.type:"boolean" -> {
1274                         %23 : java.type:"boolean" = constant @true;
1275                         yield %23;
1276                     }
1277                     ()java.type:"void" -> {
1278                         %24 : java.type:"java.lang.String" = var.load %3;
1279                         %25 : java.type:"java.lang.String" = constant @"else";
1280                         %26 : java.type:"java.lang.String" = concat %24 %25;
1281                         var.store %3 %26;
1282                         yield;
1283                     };
1284                 %27 : java.type:"java.lang.String" = var.load %3;
1285                 return %27;
1286             };
1287             """)
1288     @Reflect
1289     private static String casePatternRuleExpression(Object o) {
1290         String r = "";
1291         switch (o) {
1292             case Integer i -> r += "integer";
1293             case String s -> r+= "string";
1294             default -> r+= "else";
1295         }
1296         return r;
1297     }
1298 
1299     @IR("""
1300             func @"casePatternRuleBlock" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1301                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1302                 %2 : java.type:"java.lang.String" = constant @"";
1303                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1304                 %4 : java.type:"java.lang.Object" = var.load %1;
1305                 %5 : java.type:"java.lang.Integer" = constant @null;
1306                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1307                 %7 : java.type:"java.lang.String" = constant @null;
1308                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1309                 java.switch.statement %4
1310                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1311                         %10 : java.type:"boolean" = pattern.match %9
1312                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1313                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1314                                 yield %11;
1315                             }
1316                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1317                                 var.store %6 %12;
1318                                 yield;
1319                             };
1320                         yield %10;
1321                     }
1322                     ()java.type:"void" -> {
1323                         %13 : java.type:"java.lang.String" = var.load %3;
1324                         %14 : java.type:"java.lang.String" = constant @"integer";
1325                         %15 : java.type:"java.lang.String" = concat %13 %14;
1326                         var.store %3 %15;
1327                         yield;
1328                     }
1329                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1330                         %17 : java.type:"boolean" = pattern.match %16
1331                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1332                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1333                                 yield %18;
1334                             }
1335                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1336                                 var.store %8 %19;
1337                                 yield;
1338                             };
1339                         yield %17;
1340                     }
1341                     ()java.type:"void" -> {
1342                         %20 : java.type:"java.lang.String" = var.load %3;
1343                         %21 : java.type:"java.lang.String" = constant @"string";
1344                         %22 : java.type:"java.lang.String" = concat %20 %21;
1345                         var.store %3 %22;
1346                         yield;
1347                     }
1348                     ()java.type:"boolean" -> {
1349                         %23 : java.type:"boolean" = constant @true;
1350                         yield %23;
1351                     }
1352                     ()java.type:"void" -> {
1353                         %24 : java.type:"java.lang.String" = var.load %3;
1354                         %25 : java.type:"java.lang.String" = constant @"else";
1355                         %26 : java.type:"java.lang.String" = concat %24 %25;
1356                         var.store %3 %26;
1357                         yield;
1358                     };
1359                 %27 : java.type:"java.lang.String" = var.load %3;
1360                 return %27;
1361             };
1362             """)
1363     @Reflect
1364     private static String casePatternRuleBlock(Object o) {
1365         String r = "";
1366         switch (o) {
1367             case Integer i -> {
1368                 r += "integer";
1369             }
1370             case String s -> {
1371                 r += "string";
1372             }
1373             default -> {
1374                 r += "else";
1375             }
1376         }
1377         return r;
1378     }
1379 
1380     @IR("""
1381             func @"casePatternStatement" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1382                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1383                 %2 : java.type:"java.lang.String" = constant @"";
1384                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1385                 %4 : java.type:"java.lang.Object" = var.load %1;
1386                 %5 : java.type:"java.lang.Integer" = constant @null;
1387                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1388                 %7 : java.type:"java.lang.String" = constant @null;
1389                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1390                 java.switch.statement %4
1391                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1392                         %10 : java.type:"boolean" = pattern.match %9
1393                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1394                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1395                                 yield %11;
1396                             }
1397                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1398                                 var.store %6 %12;
1399                                 yield;
1400                             };
1401                         yield %10;
1402                     }
1403                     ()java.type:"void" -> {
1404                         %13 : java.type:"java.lang.String" = var.load %3;
1405                         %14 : java.type:"java.lang.String" = constant @"integer";
1406                         %15 : java.type:"java.lang.String" = concat %13 %14;
1407                         var.store %3 %15;
1408                         java.break;
1409                     }
1410                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1411                         %17 : java.type:"boolean" = pattern.match %16
1412                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1413                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1414                                 yield %18;
1415                             }
1416                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1417                                 var.store %8 %19;
1418                                 yield;
1419                             };
1420                         yield %17;
1421                     }
1422                     ()java.type:"void" -> {
1423                         %20 : java.type:"java.lang.String" = var.load %3;
1424                         %21 : java.type:"java.lang.String" = constant @"string";
1425                         %22 : java.type:"java.lang.String" = concat %20 %21;
1426                         var.store %3 %22;
1427                         java.break;
1428                     }
1429                     ()java.type:"boolean" -> {
1430                         %23 : java.type:"boolean" = constant @true;
1431                         yield %23;
1432                     }
1433                     ()java.type:"void" -> {
1434                         %24 : java.type:"java.lang.String" = var.load %3;
1435                         %25 : java.type:"java.lang.String" = constant @"else";
1436                         %26 : java.type:"java.lang.String" = concat %24 %25;
1437                         var.store %3 %26;
1438                         yield;
1439                     };
1440                 %27 : java.type:"java.lang.String" = var.load %3;
1441                 return %27;
1442             };
1443             """)
1444     @Reflect
1445     private static String casePatternStatement(Object o) {
1446         String r = "";
1447         switch (o) {
1448             case Integer i:
1449                 r += "integer";
1450                 break;
1451             case String s:
1452                 r += "string";
1453                 break;
1454             default:
1455                 r += "else";
1456         }
1457         return r;
1458     }
1459 
1460     @IR("""
1461             func @"casePatternThrow" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1462                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1463                 %2 : java.type:"java.lang.String" = constant @"";
1464                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1465                 %4 : java.type:"java.lang.Object" = var.load %1;
1466                 %5 : java.type:"java.lang.Number" = constant @null;
1467                 %6 : Var<java.type:"java.lang.Number"> = var %5 @"n";
1468                 %7 : java.type:"java.lang.String" = constant @null;
1469                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1470                 java.switch.statement %4
1471                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1472                         %10 : java.type:"boolean" = pattern.match %9
1473                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" -> {
1474                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
1475                                 yield %11;
1476                             }
1477                             (%12 : java.type:"java.lang.Number")java.type:"void" -> {
1478                                 var.store %6 %12;
1479                                 yield;
1480                             };
1481                         yield %10;
1482                     }
1483                     ()java.type:"void" -> {
1484                         %13 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
1485                         throw %13;
1486                     }
1487                     (%14 : java.type:"java.lang.Object")java.type:"boolean" -> {
1488                         %15 : java.type:"boolean" = pattern.match %14
1489                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1490                                 %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1491                                 yield %16;
1492                             }
1493                             (%17 : java.type:"java.lang.String")java.type:"void" -> {
1494                                 var.store %8 %17;
1495                                 yield;
1496                             };
1497                         yield %15;
1498                     }
1499                     ()java.type:"void" -> {
1500                         %18 : java.type:"java.lang.String" = var.load %3;
1501                         %19 : java.type:"java.lang.String" = constant @"a string";
1502                         %20 : java.type:"java.lang.String" = concat %18 %19;
1503                         var.store %3 %20;
1504                         yield;
1505                     }
1506                     ()java.type:"boolean" -> {
1507                         %21 : java.type:"boolean" = constant @true;
1508                         yield %21;
1509                     }
1510                     ()java.type:"void" -> {
1511                         %22 : java.type:"java.lang.String" = var.load %3;
1512                         %23 : java.type:"java.lang.Object" = var.load %1;
1513                         %24 : java.type:"java.lang.Class<?>" = invoke %23 @java.ref:"java.lang.Object::getClass():java.lang.Class";
1514                         %25 : java.type:"java.lang.String" = invoke %24 @java.ref:"java.lang.Class::getName():java.lang.String";
1515                         %26 : java.type:"java.lang.String" = concat %22 %25;
1516                         var.store %3 %26;
1517                         yield;
1518                     };
1519                 %27 : java.type:"java.lang.String" = var.load %3;
1520                 return %27;
1521             };
1522             """)
1523     @Reflect
1524     private static String casePatternThrow(Object o) {
1525         String r = "";
1526         switch (o) {
1527             case Number n -> throw new IllegalArgumentException();
1528             case String s -> r += "a string";
1529             default -> r += o.getClass().getName();
1530         }
1531         return r;
1532     }
1533 
1534     // @@@ code model for such as code is not supported
1535 //    @Reflect
1536     private static String casePatternMultiLabel(Object o) {
1537         String r = "";
1538         switch (o) {
1539             case Integer _, Long _, Character _, Byte _, Short _-> r += "integral type";
1540             default -> r += "non integral type";
1541         }
1542         return r;
1543     }
1544 
1545     @IR("""
1546             func @"casePatternWithCaseConstant" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
1547                 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"a";
1548                 %2 : java.type:"java.lang.String" = constant @"";
1549                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1550                 %4 : java.type:"java.lang.Integer" = var.load %1;
1551                 %5 : java.type:"java.lang.Integer" = constant @null;
1552                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1553                 %7 : java.type:"java.lang.Integer" = constant @null;
1554                 %8 : Var<java.type:"java.lang.Integer"> = var %7 @"i";
1555                 java.switch.statement %4
1556                     (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1557                         %10 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1558                         %11 : java.type:"int" = constant @42;
1559                         %12 : java.type:"boolean" = eq %10 %11;
1560                         yield %12;
1561                     }
1562                     ()java.type:"void" -> {
1563                         %13 : java.type:"java.lang.String" = var.load %3;
1564                         %14 : java.type:"java.lang.String" = constant @"forty two";
1565                         %15 : java.type:"java.lang.String" = concat %13 %14;
1566                         var.store %3 %15;
1567                         yield;
1568                     }
1569                     (%16 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1570                         %17 : java.type:"boolean" = java.cand
1571                             ()java.type:"boolean" -> {
1572                                 %18 : java.type:"boolean" = pattern.match %16
1573                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1574                                         %19 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1575                                         yield %19;
1576                                     }
1577                                     (%20 : java.type:"java.lang.Integer")java.type:"void" -> {
1578                                         var.store %6 %20;
1579                                         yield;
1580                                     };
1581                                 yield %18;
1582                             }
1583                             ()java.type:"boolean" -> {
1584                                 %21 : java.type:"java.lang.Integer" = var.load %6;
1585                                 %22 : java.type:"int" = invoke %21 @java.ref:"java.lang.Integer::intValue():int";
1586                                 %23 : java.type:"int" = constant @0;
1587                                 %24 : java.type:"boolean" = gt %22 %23;
1588                                 yield %24;
1589                             };
1590                         yield %17;
1591                     }
1592                     ()java.type:"void" -> {
1593                         %25 : java.type:"java.lang.String" = var.load %3;
1594                         %26 : java.type:"java.lang.String" = constant @"positive int";
1595                         %27 : java.type:"java.lang.String" = concat %25 %26;
1596                         var.store %3 %27;
1597                         yield;
1598                     }
1599                     (%28 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1600                         %29 : java.type:"boolean" = java.cand
1601                             ()java.type:"boolean" -> {
1602                                 %30 : java.type:"boolean" = pattern.match %28
1603                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1604                                         %31 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1605                                         yield %31;
1606                                     }
1607                                     (%32 : java.type:"java.lang.Integer")java.type:"void" -> {
1608                                         var.store %8 %32;
1609                                         yield;
1610                                     };
1611                                 yield %30;
1612                             }
1613                             ()java.type:"boolean" -> {
1614                                 %33 : java.type:"java.lang.Integer" = var.load %8;
1615                                 %34 : java.type:"int" = invoke %33 @java.ref:"java.lang.Integer::intValue():int";
1616                                 %35 : java.type:"int" = constant @0;
1617                                 %36 : java.type:"boolean" = lt %34 %35;
1618                                 yield %36;
1619                             };
1620                         yield %29;
1621                     }
1622                     ()java.type:"void" -> {
1623                         %37 : java.type:"java.lang.String" = var.load %3;
1624                         %38 : java.type:"java.lang.String" = constant @"negative int";
1625                         %39 : java.type:"java.lang.String" = concat %37 %38;
1626                         var.store %3 %39;
1627                         yield;
1628                     }
1629                     ()java.type:"boolean" -> {
1630                         %40 : java.type:"boolean" = constant @true;
1631                         yield %40;
1632                     }
1633                     ()java.type:"void" -> {
1634                         %41 : java.type:"java.lang.String" = var.load %3;
1635                         %42 : java.type:"java.lang.String" = constant @"zero";
1636                         %43 : java.type:"java.lang.String" = concat %41 %42;
1637                         var.store %3 %43;
1638                         yield;
1639                     };
1640                 %44 : java.type:"java.lang.String" = var.load %3;
1641                 return %44;
1642             };
1643             """)
1644     @Reflect
1645     static String casePatternWithCaseConstant(Integer a) {
1646         String r = "";
1647         switch (a) {
1648             case 42 -> r += "forty two";
1649             case Integer i when i > 0 -> r += "positive int";
1650             case Integer i when i < 0 -> r += "negative int";
1651             default -> r += "zero";
1652         }
1653         return r;
1654     }
1655 
1656     @IR("""
1657             func @"caseTypePattern" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1658                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1659                 %2 : java.type:"java.lang.String" = constant @"";
1660                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1661                 %4 : java.type:"java.lang.Object" = var.load %1;
1662                 %5 : java.type:"java.lang.String" = constant @null;
1663                 %6 : Var<java.type:"java.lang.String"> = var %5;
1664                 %7 : java.type:"java.util.RandomAccess" = constant @null;
1665                 %8 : Var<java.type:"java.util.RandomAccess"> = var %7;
1666                 %9 : java.type:"int[]" = constant @null;
1667                 %10 : Var<java.type:"int[]"> = var %9;
1668                 %11 : java.type:"java.util.Stack[][]" = constant @null;
1669                 %12 : Var<java.type:"java.util.Stack[][]"> = var %11;
1670                 %13 : java.type:"java.util.Collection[][][]" = constant @null;
1671                 %14 : Var<java.type:"java.util.Collection[][][]"> = var %13;
1672                 %15 : java.type:"java.lang.Number" = constant @null;
1673                 %16 : Var<java.type:"java.lang.Number"> = var %15 @"n";
1674                 java.switch.statement %4
1675                     (%17 : java.type:"java.lang.Object")java.type:"boolean" -> {
1676                         %18 : java.type:"boolean" = pattern.match %17
1677                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1678                                 %19 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type;
1679                                 yield %19;
1680                             }
1681                             (%20 : java.type:"java.lang.String")java.type:"void" -> {
1682                                 var.store %6 %20;
1683                                 yield;
1684                             };
1685                         yield %18;
1686                     }
1687                     ()java.type:"void" -> {
1688                         %21 : java.type:"java.lang.String" = var.load %3;
1689                         %22 : java.type:"java.lang.String" = constant @"String";
1690                         %23 : java.type:"java.lang.String" = concat %21 %22;
1691                         var.store %3 %23;
1692                         yield;
1693                     }
1694                     (%24 : java.type:"java.lang.Object")java.type:"boolean" -> {
1695                         %25 : java.type:"boolean" = pattern.match %24
1696                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.RandomAccess>" -> {
1697                                 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.RandomAccess>" = pattern.type;
1698                                 yield %26;
1699                             }
1700                             (%27 : java.type:"java.util.RandomAccess")java.type:"void" -> {
1701                                 var.store %8 %27;
1702                                 yield;
1703                             };
1704                         yield %25;
1705                     }
1706                     ()java.type:"void" -> {
1707                         %28 : java.type:"java.lang.String" = var.load %3;
1708                         %29 : java.type:"java.lang.String" = constant @"RandomAccess";
1709                         %30 : java.type:"java.lang.String" = concat %28 %29;
1710                         var.store %3 %30;
1711                         yield;
1712                     }
1713                     (%31 : java.type:"java.lang.Object")java.type:"boolean" -> {
1714                         %32 : java.type:"boolean" = pattern.match %31
1715                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<int[]>" -> {
1716                                 %33 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<int[]>" = pattern.type;
1717                                 yield %33;
1718                             }
1719                             (%34 : java.type:"int[]")java.type:"void" -> {
1720                                 var.store %10 %34;
1721                                 yield;
1722                             };
1723                         yield %32;
1724                     }
1725                     ()java.type:"void" -> {
1726                         %35 : java.type:"java.lang.String" = var.load %3;
1727                         %36 : java.type:"java.lang.String" = constant @"int[]";
1728                         %37 : java.type:"java.lang.String" = concat %35 %36;
1729                         var.store %3 %37;
1730                         yield;
1731                     }
1732                     (%38 : java.type:"java.lang.Object")java.type:"boolean" -> {
1733                         %39 : java.type:"boolean" = pattern.match %38
1734                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Stack[][]>" -> {
1735                                 %40 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Stack[][]>" = pattern.type;
1736                                 yield %40;
1737                             }
1738                             (%41 : java.type:"java.util.Stack[][]")java.type:"void" -> {
1739                                 var.store %12 %41;
1740                                 yield;
1741                             };
1742                         yield %39;
1743                     }
1744                     ()java.type:"void" -> {
1745                         %42 : java.type:"java.lang.String" = var.load %3;
1746                         %43 : java.type:"java.lang.String" = constant @"Stack[][]";
1747                         %44 : java.type:"java.lang.String" = concat %42 %43;
1748                         var.store %3 %44;
1749                         yield;
1750                     }
1751                     (%45 : java.type:"java.lang.Object")java.type:"boolean" -> {
1752                         %46 : java.type:"boolean" = pattern.match %45
1753                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Collection[][][]>" -> {
1754                                 %47 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Collection[][][]>" = pattern.type;
1755                                 yield %47;
1756                             }
1757                             (%48 : java.type:"java.util.Collection[][][]")java.type:"void" -> {
1758                                 var.store %14 %48;
1759                                 yield;
1760                             };
1761                         yield %46;
1762                     }
1763                     ()java.type:"void" -> {
1764                         %49 : java.type:"java.lang.String" = var.load %3;
1765                         %50 : java.type:"java.lang.String" = constant @"Collection[][][]";
1766                         %51 : java.type:"java.lang.String" = concat %49 %50;
1767                         var.store %3 %51;
1768                         yield;
1769                     }
1770                     (%52 : java.type:"java.lang.Object")java.type:"boolean" -> {
1771                         %53 : java.type:"boolean" = pattern.match %52
1772                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" -> {
1773                                 %54 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
1774                                 yield %54;
1775                             }
1776                             (%55 : java.type:"java.lang.Number")java.type:"void" -> {
1777                                 var.store %16 %55;
1778                                 yield;
1779                             };
1780                         yield %53;
1781                     }
1782                     ()java.type:"void" -> {
1783                         %56 : java.type:"java.lang.String" = var.load %3;
1784                         %57 : java.type:"java.lang.String" = constant @"Number";
1785                         %58 : java.type:"java.lang.String" = concat %56 %57;
1786                         var.store %3 %58;
1787                         yield;
1788                     }
1789                     ()java.type:"boolean" -> {
1790                         %59 : java.type:"boolean" = constant @true;
1791                         yield %59;
1792                     }
1793                     ()java.type:"void" -> {
1794                         %60 : java.type:"java.lang.String" = var.load %3;
1795                         %61 : java.type:"java.lang.String" = constant @"something else";
1796                         %62 : java.type:"java.lang.String" = concat %60 %61;
1797                         var.store %3 %62;
1798                         yield;
1799                     };
1800                 %63 : java.type:"java.lang.String" = var.load %3;
1801                 return %63;
1802             };
1803             """)
1804     @Reflect
1805     static String caseTypePattern(Object o) {
1806         String r = "";
1807         switch (o) {
1808             case String _ -> r+= "String"; // class
1809             case RandomAccess _ -> r+= "RandomAccess"; // interface
1810             case int[] _ -> r+= "int[]"; // array primitive
1811             case Stack[][] _ -> r+= "Stack[][]"; // array class
1812             case Collection[][][] _ -> r+= "Collection[][][]"; // array interface
1813             case final Number n -> r+= "Number"; // final modifier
1814             default -> r+= "something else";
1815         }
1816         return r;
1817     }
1818 
1819     record R(Number n) {}
1820     @IR("""
1821             func @"caseRecordPattern" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1822                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1823                 %2 : java.type:"java.lang.String" = constant @"";
1824                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1825                 %4 : java.type:"java.lang.Object" = var.load %1;
1826                 %5 : java.type:"java.lang.Number" = constant @null;
1827                 %6 : Var<java.type:"java.lang.Number"> = var %5 @"n";
1828                 java.switch.statement %4
1829                     (%7 : java.type:"java.lang.Object")java.type:"boolean" -> {
1830                         %8 : java.type:"boolean" = pattern.match %7
1831                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" -> {
1832                                 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
1833                                 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" = pattern.record %9 @java.ref:"(java.lang.Number n)SwitchStatementTest$R";
1834                                 yield %10;
1835                             }
1836                             (%11 : java.type:"java.lang.Number")java.type:"void" -> {
1837                                 var.store %6 %11;
1838                                 yield;
1839                             };
1840                         yield %8;
1841                     }
1842                     ()java.type:"void" -> {
1843                         %12 : java.type:"java.lang.String" = var.load %3;
1844                         %13 : java.type:"java.lang.String" = constant @"R(_)";
1845                         %14 : java.type:"java.lang.String" = concat %12 %13;
1846                         var.store %3 %14;
1847                         yield;
1848                     }
1849                     ()java.type:"boolean" -> {
1850                         %15 : java.type:"boolean" = constant @true;
1851                         yield %15;
1852                     }
1853                     ()java.type:"void" -> {
1854                         %16 : java.type:"java.lang.String" = var.load %3;
1855                         %17 : java.type:"java.lang.String" = constant @"else";
1856                         %18 : java.type:"java.lang.String" = concat %16 %17;
1857                         var.store %3 %18;
1858                         yield;
1859                     };
1860                 %19 : java.type:"java.lang.String" = var.load %3;
1861                 return %19;
1862             };
1863             """)
1864     @Reflect
1865     static String caseRecordPattern(Object o) {
1866         String r = "";
1867         switch (o) {
1868             case R(Number n) -> r += "R(_)";
1869             default -> r+= "else";
1870         }
1871         return r;
1872     }
1873 
1874     @IR("""
1875             func @"casePatternGuard" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1876                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"obj";
1877                 %2 : java.type:"java.lang.String" = constant @"";
1878                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1879                 %4 : java.type:"java.lang.Object" = var.load %1;
1880                 %5 : java.type:"java.lang.String" = constant @null;
1881                 %6 : Var<java.type:"java.lang.String"> = var %5 @"s";
1882                 %7 : java.type:"java.lang.Number" = constant @null;
1883                 %8 : Var<java.type:"java.lang.Number"> = var %7 @"n";
1884                 java.switch.statement %4
1885                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1886                         %10 : java.type:"boolean" = java.cand
1887                             ()java.type:"boolean" -> {
1888                                 %11 : java.type:"boolean" = pattern.match %9
1889                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1890                                         %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1891                                         yield %12;
1892                                     }
1893                                     (%13 : java.type:"java.lang.String")java.type:"void" -> {
1894                                         var.store %6 %13;
1895                                         yield;
1896                                     };
1897                                 yield %11;
1898                             }
1899                             ()java.type:"boolean" -> {
1900                                 %14 : java.type:"java.lang.String" = var.load %6;
1901                                 %15 : java.type:"int" = invoke %14 @java.ref:"java.lang.String::length():int";
1902                                 %16 : java.type:"int" = constant @3;
1903                                 %17 : java.type:"boolean" = gt %15 %16;
1904                                 yield %17;
1905                             };
1906                         yield %10;
1907                     }
1908                     ()java.type:"void" -> {
1909                         %18 : java.type:"java.lang.String" = var.load %3;
1910                         %19 : java.type:"java.lang.String" = constant @"str with length > %d";
1911                         %20 : java.type:"java.lang.String" = var.load %6;
1912                         %21 : java.type:"int" = invoke %20 @java.ref:"java.lang.String::length():int";
1913                         %22 : java.type:"java.lang.Integer" = invoke %21 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1914                         %23 : java.type:"java.lang.String" = invoke %19 %22 @java.ref:"java.lang.String::formatted(java.lang.Object[]):java.lang.String" @invoke.kind="INSTANCE" @invoke.varargs=true;
1915                         %24 : java.type:"java.lang.String" = concat %18 %23;
1916                         var.store %3 %24;
1917                         yield;
1918                     }
1919                     (%25 : java.type:"java.lang.Object")java.type:"boolean" -> {
1920                         %26 : java.type:"boolean" = java.cand
1921                             ()java.type:"boolean" -> {
1922                                 %27 : java.type:"boolean" = pattern.match %25
1923                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" -> {
1924                                         %28 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
1925                                         %29 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" = pattern.record %28 @java.ref:"(java.lang.Number n)SwitchStatementTest$R";
1926                                         yield %29;
1927                                     }
1928                                     (%30 : java.type:"java.lang.Number")java.type:"void" -> {
1929                                         var.store %8 %30;
1930                                         yield;
1931                                     };
1932                                 yield %27;
1933                             }
1934                             ()java.type:"boolean" -> {
1935                                 %31 : java.type:"java.lang.Number" = var.load %8;
1936                                 %32 : java.type:"java.lang.Class<?>" = invoke %31 @java.ref:"java.lang.Object::getClass():java.lang.Class";
1937                                 %33 : java.type:"java.lang.Class" = constant @java.type:"java.lang.Double";
1938                                 %34 : java.type:"boolean" = invoke %32 %33 @java.ref:"java.lang.Object::equals(java.lang.Object):boolean";
1939                                 yield %34;
1940                             };
1941                         yield %26;
1942                     }
1943                     ()java.type:"void" -> {
1944                         %35 : java.type:"java.lang.String" = var.load %3;
1945                         %36 : java.type:"java.lang.String" = constant @"R(Double)";
1946                         %37 : java.type:"java.lang.String" = concat %35 %36;
1947                         var.store %3 %37;
1948                         yield;
1949                     }
1950                     ()java.type:"boolean" -> {
1951                         %38 : java.type:"boolean" = constant @true;
1952                         yield %38;
1953                     }
1954                     ()java.type:"void" -> {
1955                         %39 : java.type:"java.lang.String" = var.load %3;
1956                         %40 : java.type:"java.lang.String" = constant @"else";
1957                         %41 : java.type:"java.lang.String" = concat %39 %40;
1958                         var.store %3 %41;
1959                         yield;
1960                     };
1961                 %42 : java.type:"java.lang.String" = var.load %3;
1962                 return %42;
1963             };
1964             """)
1965     @Reflect
1966     static String casePatternGuard(Object obj) {
1967         String r = "";
1968         switch (obj) {
1969             case String s when s.length() > 3 -> r += "str with length > %d".formatted(s.length());
1970             case R(Number n) when n.getClass().equals(Double.class) -> r += "R(Double)";
1971             default -> r += "else";
1972         }
1973         return r;
1974     }
1975 
1976     @IR("""
1977             func @"defaultCaseNotTheLast" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1978                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1979                 %2 : java.type:"java.lang.String" = constant @"";
1980                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1981                 %4 : java.type:"java.lang.String" = var.load %1;
1982                 java.switch.statement %4
1983                     ()java.type:"boolean" -> {
1984                         %17 : java.type:"boolean" = constant @true;
1985                         yield %17;
1986                     }
1987                     ()java.type:"void" -> {
1988                         %18 : java.type:"java.lang.String" = var.load %3;
1989                         %19 : java.type:"java.lang.String" = constant @"else";
1990                         %20 : java.type:"java.lang.String" = concat %18 %19;
1991                         var.store %3 %20;
1992                         yield;
1993                     }
1994                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
1995                         %6 : java.type:"java.lang.String" = constant @"M";
1996                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1997                         yield %7;
1998                     }
1999                     ()java.type:"void" -> {
2000                         %8 : java.type:"java.lang.String" = var.load %3;
2001                         %9 : java.type:"java.lang.String" = constant @"Mow";
2002                         %10 : java.type:"java.lang.String" = concat %8 %9;
2003                         var.store %3 %10;
2004                         yield;
2005                     }
2006                     (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
2007                         %12 : java.type:"java.lang.String" = constant @"A";
2008                         %13 : java.type:"boolean" = invoke %11 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2009                         yield %13;
2010                     }
2011                     ()java.type:"void" -> {
2012                         %14 : java.type:"java.lang.String" = var.load %3;
2013                         %15 : java.type:"java.lang.String" = constant @"Aow";
2014                         %16 : java.type:"java.lang.String" = concat %14 %15;
2015                         var.store %3 %16;
2016                         yield;
2017                     };
2018                 %21 : java.type:"java.lang.String" = var.load %3;
2019                 return %21;
2020             };
2021             """)
2022     @Reflect
2023     static String defaultCaseNotTheLast(String s) {
2024         String r = "";
2025         switch (s) {
2026             default -> r += "else";
2027             case "M" -> r += "Mow";
2028             case "A" -> r += "Aow";
2029         }
2030         return r;
2031     }
2032 
2033     @IR("""
2034             func @"f" (%0 : java.type:"int")java.type:"int" -> {
2035                   %1 : Var<java.type:"int"> = var %0 @"i";
2036                   %2 : java.type:"int" = var.load %1;
2037                   java.switch.statement %2
2038                       (%3 : java.type:"int")java.type:"boolean" -> {
2039                           %4 : java.type:"int" = constant @0;
2040                           %5 : java.type:"boolean" = eq %3 %4;
2041                           yield %5;
2042                       }
2043                       ()java.type:"void" -> {
2044                           %6 : java.type:"int" = constant @0;
2045                           return %6;
2046                       };
2047                   %7 : java.type:"int" = constant @0;
2048                   return %7;
2049               };
2050             """)
2051     @Reflect
2052     static int f(int i) {
2053         switch (i) {
2054             case 0 -> {
2055                 return 0;
2056             }
2057         }
2058         return 0;
2059     }
2060 
2061     @IR("""
2062             func @"outOfOrderFallThrought" (%0 : java.type:"int")java.type:"java.lang.String" -> {
2063                   %1 : Var<java.type:"int"> = var %0 @"i";
2064                   %2 : java.type:"java.lang.String" = constant @"";
2065                   %3 : Var<java.type:"java.lang.String"> = var %2 @"ret";
2066                   %4 : java.type:"int" = var.load %1;
2067                   java.switch.statement %4
2068                       ()java.type:"boolean" -> {
2069                           %5 : java.type:"boolean" = constant @true;
2070                           yield %5;
2071                       }
2072                       ()java.type:"void" -> {
2073                           %6 : java.type:"java.lang.String" = var.load %3;
2074                           %7 : java.type:"java.lang.String" = constant @"? ";
2075                           %8 : java.type:"java.lang.String" = concat %6 %7;
2076                           var.store %3 %8;
2077                           java.switch.fallthrough;
2078                       }
2079                       (%9 : java.type:"int")java.type:"boolean" -> {
2080                           %10 : java.type:"int" = constant @4;
2081                           %11 : java.type:"boolean" = eq %9 %10;
2082                           yield %11;
2083                       }
2084                       ()java.type:"void" -> {
2085                           %12 : java.type:"java.lang.String" = var.load %3;
2086                           %13 : java.type:"java.lang.String" = constant @"four ";
2087                           %14 : java.type:"java.lang.String" = concat %12 %13;
2088                           var.store %3 %14;
2089                           java.switch.fallthrough;
2090                       }
2091                       (%15 : java.type:"int")java.type:"boolean" -> {
2092                           %16 : java.type:"int" = constant @2;
2093                           %17 : java.type:"boolean" = eq %15 %16;
2094                           yield %17;
2095                       }
2096                       ()java.type:"void" -> {
2097                           %18 : java.type:"java.lang.String" = var.load %3;
2098                           %19 : java.type:"java.lang.String" = constant @"two ";
2099                           %20 : java.type:"java.lang.String" = concat %18 %19;
2100                           var.store %3 %20;
2101                           java.switch.fallthrough;
2102                       }
2103                       (%21 : java.type:"int")java.type:"boolean" -> {
2104                           %22 : java.type:"int" = constant @3;
2105                           %23 : java.type:"boolean" = eq %21 %22;
2106                           yield %23;
2107                       }
2108                       ()java.type:"void" -> {
2109                           %24 : java.type:"java.lang.String" = var.load %3;
2110                           %25 : java.type:"java.lang.String" = constant @"three ";
2111                           %26 : java.type:"java.lang.String" = concat %24 %25;
2112                           var.store %3 %26;
2113                           java.switch.fallthrough;
2114                       }
2115                       (%27 : java.type:"int")java.type:"boolean" -> {
2116                           %28 : java.type:"int" = constant @1;
2117                           %29 : java.type:"boolean" = eq %27 %28;
2118                           yield %29;
2119                       }
2120                       ()java.type:"void" -> {
2121                           %30 : java.type:"java.lang.String" = var.load %3;
2122                           %31 : java.type:"java.lang.String" = constant @"one";
2123                           %32 : java.type:"java.lang.String" = concat %30 %31;
2124                           var.store %3 %32;
2125                           yield;
2126                       };
2127                   %33 : java.type:"java.lang.String" = var.load %3;
2128                   return %33;
2129               };
2130             """)
2131     @Reflect
2132     static String outOfOrderFallThrought(int i) {
2133         String ret = "";
2134         switch (i) {
2135             default:
2136                 ret += "? ";
2137             case 4:
2138                 ret += "four ";
2139             case 2:
2140                 ret += "two ";
2141             case 3:
2142                 ret += "three ";
2143             case 1:
2144                 ret += "one";
2145         }
2146         return ret;
2147     }
2148 
2149     @IR("""
2150             func @"caseConstantPrimitiveWrapperSelector" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
2151                   %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
2152                   %2 : java.type:"java.lang.String" = constant @"";
2153                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2154                   %4 : java.type:"java.lang.Integer" = var.load %1;
2155                   java.switch.statement %4
2156                       (%5 : java.type:"java.lang.Integer")java.type:"boolean" -> {
2157                           %6 : java.type:"int" = invoke %5 @java.ref:"java.lang.Integer::intValue():int";
2158                           %7 : java.type:"int" = constant @1;
2159                           %8 : java.type:"boolean" = eq %6 %7;
2160                           yield %8;
2161                       }
2162                       ()java.type:"void" -> {
2163                           %9 : java.type:"java.lang.String" = var.load %3;
2164                           %10 : java.type:"java.lang.String" = constant @"one";
2165                           %11 : java.type:"java.lang.String" = concat %9 %10;
2166                           var.store %3 %11;
2167                           yield;
2168                       }
2169                       (%12 : java.type:"java.lang.Integer")java.type:"boolean" -> {
2170                           %13 : java.type:"boolean" = java.cor
2171                               ()java.type:"boolean" -> {
2172                                   %14 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
2173                                   %15 : java.type:"int" = constant @2;
2174                                   %16 : java.type:"boolean" = eq %14 %15;
2175                                   yield %16;
2176                               }
2177                               ()java.type:"boolean" -> {
2178                                   %17 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
2179                                   %18 : java.type:"int" = constant @3;
2180                                   %19 : java.type:"boolean" = eq %17 %18;
2181                                   yield %19;
2182                               };
2183                           yield %13;
2184                       }
2185                       ()java.type:"void" -> {
2186                           %20 : java.type:"java.lang.String" = var.load %3;
2187                           %21 : java.type:"java.lang.String" = constant @"two or three";
2188                           %22 : java.type:"java.lang.String" = concat %20 %21;
2189                           var.store %3 %22;
2190                           yield;
2191                       }
2192                       ()java.type:"boolean" -> {
2193                           %23 : java.type:"boolean" = constant @true;
2194                           yield %23;
2195                       }
2196                       ()java.type:"void" -> {
2197                           %24 : java.type:"java.lang.String" = var.load %3;
2198                           %25 : java.type:"java.lang.String" = constant @"else";
2199                           %26 : java.type:"java.lang.String" = concat %24 %25;
2200                           var.store %3 %26;
2201                           yield;
2202                       };
2203                   %27 : java.type:"java.lang.String" = var.load %3;
2204                   return %27;
2205               };
2206             """)
2207     @Reflect
2208     static String caseConstantPrimitiveWrapperSelector(Integer i) {
2209         String r = "";
2210         switch (i) {
2211             case 1 -> r += "one";
2212             case 2, 3 -> r += "two or three";
2213             default -> r += "else";
2214         };
2215         return r;
2216     }
2217 
2218     @IR("""
2219             func @"constantLabelCasted" (%0 : java.type:"int")java.type:"java.lang.String" -> {
2220                   %1 : Var<java.type:"int"> = var %0 @"i";
2221                   %2 : java.type:"java.lang.String" = constant @"";
2222                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2223                   %4 : java.type:"int" = var.load %1;
2224                   java.switch.statement %4
2225                       (%5 : java.type:"int")java.type:"boolean" -> {
2226                           %6 : java.type:"int" = constant @1;
2227                           %7 : java.type:"byte" = conv %6;
2228                           %8 : java.type:"int" = conv %7;
2229                           %9 : java.type:"boolean" = eq %5 %8;
2230                           yield %9;
2231                       }
2232                       ()java.type:"void" -> {
2233                           %10 : java.type:"java.lang.String" = var.load %3;
2234                           %11 : java.type:"java.lang.String" = constant @"one";
2235                           %12 : java.type:"java.lang.String" = concat %10 %11;
2236                           var.store %3 %12;
2237                           yield;
2238                       }
2239                       ()java.type:"boolean" -> {
2240                           %13 : java.type:"boolean" = constant @true;
2241                           yield %13;
2242                       }
2243                       ()java.type:"void" -> {
2244                           %14 : java.type:"java.lang.String" = var.load %3;
2245                           %15 : java.type:"java.lang.String" = constant @"not one";
2246                           %16 : java.type:"java.lang.String" = concat %14 %15;
2247                           var.store %3 %16;
2248                           yield;
2249                       };
2250                   %17 : java.type:"java.lang.String" = var.load %3;
2251                   return %17;
2252               };
2253             """)
2254     @Reflect
2255     static String constantLabelCasted(int i) {
2256         String r = "";
2257         switch (i) {
2258             case (byte) 1 -> r += "one";
2259             default -> r += "not one";
2260         };
2261         return r;
2262     }
2263 
2264     @IR("""
2265             func @"caseConstantStringLiteral" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
2266                   %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
2267                   %2 : java.type:"java.lang.String" = constant @"";
2268                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2269                   %4 : java.type:"java.lang.String" = var.load %1;
2270                   java.switch.statement %4
2271                       (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
2272                           %6 : java.type:"java.lang.String" = constant @"1";
2273                           %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2274                           yield %7;
2275                       }
2276                       ()java.type:"void" -> {
2277                           %8 : java.type:"java.lang.String" = var.load %3;
2278                           %9 : java.type:"java.lang.String" = constant @"one";
2279                           %10 : java.type:"java.lang.String" = concat %8 %9;
2280                           var.store %3 %10;
2281                           yield;
2282                       }
2283                       (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
2284                           %12 : java.type:"boolean" = java.cor
2285                               ()java.type:"boolean" -> {
2286                                   %13 : java.type:"java.lang.String" = constant @"2";
2287                                   %14 : java.type:"boolean" = invoke %11 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2288                                   yield %14;
2289                               }
2290                               ()java.type:"boolean" -> {
2291                                   %15 : java.type:"java.lang.String" = constant @"3";
2292                                   %16 : java.type:"boolean" = invoke %11 %15 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2293                                   yield %16;
2294                               };
2295                           yield %12;
2296                       }
2297                       ()java.type:"void" -> {
2298                           %17 : java.type:"java.lang.String" = var.load %3;
2299                           %18 : java.type:"java.lang.String" = constant @"two or three";
2300                           %19 : java.type:"java.lang.String" = concat %17 %18;
2301                           var.store %3 %19;
2302                           yield;
2303                       }
2304                       ()java.type:"boolean" -> {
2305                           %20 : java.type:"boolean" = constant @true;
2306                           yield %20;
2307                       }
2308                       ()java.type:"void" -> {
2309                           %21 : java.type:"java.lang.String" = var.load %3;
2310                           %22 : java.type:"java.lang.String" = constant @"else";
2311                           %23 : java.type:"java.lang.String" = concat %21 %22;
2312                           var.store %3 %23;
2313                           yield;
2314                       };
2315                   %24 : java.type:"java.lang.String" = var.load %3;
2316                   return %24;
2317               };
2318             """)
2319     @Reflect
2320     static String caseConstantStringLiteral(String s) {
2321         String r = "";
2322         switch (s) {
2323             case "1" -> r += "one";
2324             case "2", "3" -> r+= "two or three";
2325             default -> r += "else";
2326         };
2327         return r;
2328     }
2329 
2330 }