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 @switch.handle.nulls=true
 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     @IR("""
 436             func @"caseConstantNullAndDefault" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 437                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 438                 %2 : java.type:"java.lang.String" = constant @"";
 439                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 440                 %4 : java.type:"java.lang.String" = var.load %1;
 441                 java.switch.statement %4 @switch.handle.nulls=true
 442                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
 443                         %6 : java.type:"java.lang.String" = constant @"abc";
 444                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 445                         yield %7;
 446                     }
 447                     ()java.type:"void" -> {
 448                         %8 : java.type:"java.lang.String" = var.load %3;
 449                         %9 : java.type:"java.lang.String" = constant @"alphabet";
 450                         %10 : java.type:"java.lang.String" = concat %8 %9;
 451                         var.store %3 %10;
 452                         yield;
 453                     }
 454                     ()java.type:"boolean" -> {
 455                         %11 : java.type:"boolean" = constant @true;
 456                         yield %11;
 457                     }
 458                     ()java.type:"void" -> {
 459                         %12 : java.type:"java.lang.String" = var.load %3;
 460                         %13 : java.type:"java.lang.String" = constant @"null or default";
 461                         %14 : java.type:"java.lang.String" = concat %12 %13;
 462                         var.store %3 %14;
 463                         yield;
 464                     };
 465                 %15 : java.type:"java.lang.String" = var.load %3;
 466                 return %15;
 467             };
 468             """)
 469     @Reflect
 470     private static String caseConstantNullAndDefault(String s) {
 471         String r = "";
 472         switch (s) {
 473             case "abc" -> r += "alphabet";
 474             case null, default -> r += "null or default";
 475         }
 476         return r;
 477     }
 478 
 479     @IR("""
 480             func @"caseConstantFallThrough" (%0 : java.type:"char")java.type:"java.lang.String" -> {
 481                 %1 : Var<java.type:"char"> = var %0 @"c";
 482                 %2 : java.type:"java.lang.String" = constant @"";
 483                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 484                 %4 : java.type:"char" = var.load %1;
 485                 java.switch.statement %4
 486                     (%5 : java.type:"char")java.type:"boolean" -> {
 487                         %6 : java.type:"char" = constant @'A';
 488                         %7 : java.type:"boolean" = eq %5 %6;
 489                         yield %7;
 490                     }
 491                     ()java.type:"void" -> {
 492                         java.switch.fallthrough;
 493                     }
 494                     (%8 : java.type:"char")java.type:"boolean" -> {
 495                         %9 : java.type:"char" = constant @'B';
 496                         %10 : java.type:"boolean" = eq %8 %9;
 497                         yield %10;
 498                     }
 499                     ()java.type:"void" -> {
 500                         %11 : java.type:"java.lang.String" = var.load %3;
 501                         %12 : java.type:"java.lang.String" = constant @"A or B";
 502                         %13 : java.type:"java.lang.String" = concat %11 %12;
 503                         var.store %3 %13;
 504                         java.break;
 505                     }
 506                     ()java.type:"boolean" -> {
 507                         %14 : java.type:"boolean" = constant @true;
 508                         yield %14;
 509                     }
 510                     ()java.type:"void" -> {
 511                         %15 : java.type:"java.lang.String" = var.load %3;
 512                         %16 : java.type:"java.lang.String" = constant @"Neither A nor B";
 513                         %17 : java.type:"java.lang.String" = concat %15 %16;
 514                         var.store %3 %17;
 515                         yield;
 516                     };
 517                 %18 : java.type:"java.lang.String" = var.load %3;
 518                 return %18;
 519             };
 520             """)
 521     @Reflect
 522     private static String caseConstantFallThrough(char c) {
 523         String r = "";
 524         switch (c) {
 525             case 'A':
 526             case 'B':
 527                 r += "A or B";
 528                 break;
 529             default:
 530                 r += "Neither A nor B";
 531         }
 532         return r;
 533     }
 534 
 535     enum Day {
 536         MON, TUE, WED, THU, FRI, SAT, SUN
 537     }
 538     @IR("""
 539             func @"caseConstantEnum" (%0 : java.type:"SwitchStatementTest$Day")java.type:"java.lang.String" -> {
 540                 %1 : Var<java.type:"SwitchStatementTest$Day"> = var %0 @"d";
 541                 %2 : java.type:"java.lang.String" = constant @"";
 542                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 543                 %4 : java.type:"SwitchStatementTest$Day" = var.load %1;
 544                 java.switch.statement %4
 545                     (%5 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 546                         %6 : java.type:"boolean" = java.cor
 547                             ()java.type:"boolean" -> {
 548                                 %7 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::MON:SwitchStatementTest$Day";
 549                                 %8 : java.type:"boolean" = eq %5 %7;
 550                                 yield %8;
 551                             }
 552                             ()java.type:"boolean" -> {
 553                                 %9 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::FRI:SwitchStatementTest$Day";
 554                                 %10 : java.type:"boolean" = eq %5 %9;
 555                                 yield %10;
 556                             }
 557                             ()java.type:"boolean" -> {
 558                                 %11 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::SUN:SwitchStatementTest$Day";
 559                                 %12 : java.type:"boolean" = eq %5 %11;
 560                                 yield %12;
 561                             };
 562                         yield %6;
 563                     }
 564                     ()java.type:"void" -> {
 565                         %13 : java.type:"java.lang.String" = var.load %3;
 566                         %14 : java.type:"int" = constant @6;
 567                         %15 : java.type:"java.lang.String" = concat %13 %14;
 568                         var.store %3 %15;
 569                         yield;
 570                     }
 571                     (%16 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 572                         %17 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::TUE:SwitchStatementTest$Day";
 573                         %18 : java.type:"boolean" = eq %16 %17;
 574                         yield %18;
 575                     }
 576                     ()java.type:"void" -> {
 577                         %19 : java.type:"java.lang.String" = var.load %3;
 578                         %20 : java.type:"int" = constant @7;
 579                         %21 : java.type:"java.lang.String" = concat %19 %20;
 580                         var.store %3 %21;
 581                         yield;
 582                     }
 583                     (%22 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 584                         %23 : java.type:"boolean" = java.cor
 585                             ()java.type:"boolean" -> {
 586                                 %24 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::THU:SwitchStatementTest$Day";
 587                                 %25 : java.type:"boolean" = eq %22 %24;
 588                                 yield %25;
 589                             }
 590                             ()java.type:"boolean" -> {
 591                                 %26 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::SAT:SwitchStatementTest$Day";
 592                                 %27 : java.type:"boolean" = eq %22 %26;
 593                                 yield %27;
 594                             };
 595                         yield %23;
 596                     }
 597                     ()java.type:"void" -> {
 598                         %28 : java.type:"java.lang.String" = var.load %3;
 599                         %29 : java.type:"int" = constant @8;
 600                         %30 : java.type:"java.lang.String" = concat %28 %29;
 601                         var.store %3 %30;
 602                         yield;
 603                     }
 604                     (%31 : java.type:"SwitchStatementTest$Day")java.type:"boolean" -> {
 605                         %32 : java.type:"SwitchStatementTest$Day" = field.load @java.ref:"SwitchStatementTest$Day::WED:SwitchStatementTest$Day";
 606                         %33 : java.type:"boolean" = eq %31 %32;
 607                         yield %33;
 608                     }
 609                     ()java.type:"void" -> {
 610                         %34 : java.type:"java.lang.String" = var.load %3;
 611                         %35 : java.type:"int" = constant @9;
 612                         %36 : java.type:"java.lang.String" = concat %34 %35;
 613                         var.store %3 %36;
 614                         yield;
 615                     };
 616                 %37 : java.type:"java.lang.String" = var.load %3;
 617                 return %37;
 618             };
 619             """)
 620     @Reflect
 621     private static String caseConstantEnum(Day d) {
 622         String r = "";
 623         switch (d) {
 624             case MON, FRI, SUN -> r += 6;
 625             case TUE -> r += 7;
 626             case THU, SAT -> r += 8;
 627             case WED -> r += 9;
 628         }
 629         return r;
 630     }
 631 
 632     static class Constants {
 633         static final int c1 = 12;
 634     }
 635     @IR("""
 636             func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
 637                 %1 : Var<java.type:"int"> = var %0 @"i";
 638                 %2 : java.type:"java.lang.String" = constant @"";
 639                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
 640                 %4 : java.type:"int" = constant @11;
 641                 %5 : Var<java.type:"int"> = var %4 @"eleven";
 642                 %6 : java.type:"int" = var.load %1;
 643                 java.switch.statement %6
 644                     (%7 : java.type:"int")java.type:"boolean" -> {
 645                         %8 : java.type:"int" = constant @1;
 646                         %9 : java.type:"int" = constant @15;
 647                         %10 : java.type:"int" = and %8 %9;
 648                         %11 : java.type:"boolean" = eq %7 %10;
 649                         yield %11;
 650                     }
 651                     ()java.type:"void" -> {
 652                         %12 : java.type:"java.lang.String" = var.load %3;
 653                         %13 : java.type:"int" = constant @1;
 654                         %14 : java.type:"java.lang.String" = concat %12 %13;
 655                         var.store %3 %14;
 656                         yield;
 657                     }
 658                     (%15 : java.type:"int")java.type:"boolean" -> {
 659                         %16 : java.type:"int" = constant @4;
 660                         %17 : java.type:"int" = constant @1;
 661                         %18 : java.type:"int" = ashr %16 %17;
 662                         %19 : java.type:"boolean" = eq %15 %18;
 663                         yield %19;
 664                     }
 665                     ()java.type:"void" -> {
 666                         %20 : java.type:"java.lang.String" = var.load %3;
 667                         %21 : java.type:"java.lang.String" = constant @"2";
 668                         %22 : java.type:"java.lang.String" = concat %20 %21;
 669                         var.store %3 %22;
 670                         yield;
 671                     }
 672                     (%23 : java.type:"int")java.type:"boolean" -> {
 673                         %24 : java.type:"long" = constant @3;
 674                         %25 : java.type:"int" = conv %24;
 675                         %26 : java.type:"boolean" = eq %23 %25;
 676                         yield %26;
 677                     }
 678                     ()java.type:"void" -> {
 679                         %27 : java.type:"java.lang.String" = var.load %3;
 680                         %28 : java.type:"int" = constant @3;
 681                         %29 : java.type:"java.lang.String" = concat %27 %28;
 682                         var.store %3 %29;
 683                         yield;
 684                     }
 685                     (%30 : java.type:"int")java.type:"boolean" -> {
 686                         %31 : java.type:"int" = constant @2;
 687                         %32 : java.type:"int" = constant @1;
 688                         %33 : java.type:"int" = lshl %31 %32;
 689                         %34 : java.type:"boolean" = eq %30 %33;
 690                         yield %34;
 691                     }
 692                     ()java.type:"void" -> {
 693                         %35 : java.type:"java.lang.String" = var.load %3;
 694                         %36 : java.type:"int" = constant @4;
 695                         %37 : java.type:"java.lang.String" = concat %35 %36;
 696                         var.store %3 %37;
 697                         yield;
 698                     }
 699                     (%38 : java.type:"int")java.type:"boolean" -> {
 700                         %39 : java.type:"int" = constant @10;
 701                         %40 : java.type:"int" = constant @2;
 702                         %41 : java.type:"int" = div %39 %40;
 703                         %42 : java.type:"boolean" = eq %38 %41;
 704                         yield %42;
 705                     }
 706                     ()java.type:"void" -> {
 707                         %43 : java.type:"java.lang.String" = var.load %3;
 708                         %44 : java.type:"int" = constant @5;
 709                         %45 : java.type:"java.lang.String" = concat %43 %44;
 710                         var.store %3 %45;
 711                         yield;
 712                     }
 713                     (%46 : java.type:"int")java.type:"boolean" -> {
 714                         %47 : java.type:"int" = constant @12;
 715                         %48 : java.type:"int" = constant @6;
 716                         %49 : java.type:"int" = sub %47 %48;
 717                         %50 : java.type:"boolean" = eq %46 %49;
 718                         yield %50;
 719                     }
 720                     ()java.type:"void" -> {
 721                         %51 : java.type:"java.lang.String" = var.load %3;
 722                         %52 : java.type:"int" = constant @6;
 723                         %53 : java.type:"java.lang.String" = concat %51 %52;
 724                         var.store %3 %53;
 725                         yield;
 726                     }
 727                     (%54 : java.type:"int")java.type:"boolean" -> {
 728                         %55 : java.type:"int" = constant @3;
 729                         %56 : java.type:"int" = constant @4;
 730                         %57 : java.type:"int" = add %55 %56;
 731                         %58 : java.type:"boolean" = eq %54 %57;
 732                         yield %58;
 733                     }
 734                     ()java.type:"void" -> {
 735                         %59 : java.type:"java.lang.String" = var.load %3;
 736                         %60 : java.type:"int" = constant @7;
 737                         %61 : java.type:"java.lang.String" = concat %59 %60;
 738                         var.store %3 %61;
 739                         yield;
 740                     }
 741                     (%62 : java.type:"int")java.type:"boolean" -> {
 742                         %63 : java.type:"int" = constant @2;
 743                         %64 : java.type:"int" = constant @2;
 744                         %65 : java.type:"int" = mul %63 %64;
 745                         %66 : java.type:"int" = constant @2;
 746                         %67 : java.type:"int" = mul %65 %66;
 747                         %68 : java.type:"boolean" = eq %62 %67;
 748                         yield %68;
 749                     }
 750                     ()java.type:"void" -> {
 751                         %69 : java.type:"java.lang.String" = var.load %3;
 752                         %70 : java.type:"int" = constant @8;
 753                         %71 : java.type:"java.lang.String" = concat %69 %70;
 754                         var.store %3 %71;
 755                         yield;
 756                     }
 757                     (%72 : java.type:"int")java.type:"boolean" -> {
 758                         %73 : java.type:"int" = constant @8;
 759                         %74 : java.type:"int" = constant @1;
 760                         %75 : java.type:"int" = or %73 %74;
 761                         %76 : java.type:"boolean" = eq %72 %75;
 762                         yield %76;
 763                     }
 764                     ()java.type:"void" -> {
 765                         %77 : java.type:"java.lang.String" = var.load %3;
 766                         %78 : java.type:"int" = constant @9;
 767                         %79 : java.type:"java.lang.String" = concat %77 %78;
 768                         var.store %3 %79;
 769                         yield;
 770                     }
 771                     (%80 : java.type:"int")java.type:"boolean" -> {
 772                         %81 : java.type:"int" = constant @10;
 773                         %82 : java.type:"boolean" = eq %80 %81;
 774                         yield %82;
 775                     }
 776                     ()java.type:"void" -> {
 777                         %83 : java.type:"java.lang.String" = var.load %3;
 778                         %84 : java.type:"int" = constant @10;
 779                         %85 : java.type:"java.lang.String" = concat %83 %84;
 780                         var.store %3 %85;
 781                         yield;
 782                     }
 783                     (%86 : java.type:"int")java.type:"boolean" -> {
 784                         %87 : java.type:"int" = var.load %5;
 785                         %88 : java.type:"boolean" = eq %86 %87;
 786                         yield %88;
 787                     }
 788                     ()java.type:"void" -> {
 789                         %89 : java.type:"java.lang.String" = var.load %3;
 790                         %90 : java.type:"int" = constant @11;
 791                         %91 : java.type:"java.lang.String" = concat %89 %90;
 792                         var.store %3 %91;
 793                         yield;
 794                     }
 795                     (%92 : java.type:"int")java.type:"boolean" -> {
 796                         %93 : java.type:"int" = field.load @java.ref:"SwitchStatementTest$Constants::c1:int";
 797                         %94 : java.type:"boolean" = eq %92 %93;
 798                         yield %94;
 799                     }
 800                     ()java.type:"void" -> {
 801                         %95 : java.type:"java.lang.String" = var.load %3;
 802                         %96 : java.type:"int" = field.load @java.ref:"SwitchStatementTest$Constants::c1:int";
 803                         %97 : java.type:"java.lang.String" = concat %95 %96;
 804                         var.store %3 %97;
 805                         yield;
 806                     }
 807                     (%98 : java.type:"int")java.type:"boolean" -> {
 808                         %99 : java.type:"int" = java.cexpression
 809                             ()java.type:"boolean" -> {
 810                                 %100 : java.type:"int" = constant @1;
 811                                 %101 : java.type:"int" = constant @0;
 812                                 %102 : java.type:"boolean" = gt %100 %101;
 813                                 yield %102;
 814                             }
 815                             ()java.type:"int" -> {
 816                                 %103 : java.type:"int" = constant @13;
 817                                 yield %103;
 818                             }
 819                             ()java.type:"int" -> {
 820                                 %104 : java.type:"int" = constant @133;
 821                                 yield %104;
 822                             };
 823                         %105 : java.type:"boolean" = eq %98 %99;
 824                         yield %105;
 825                     }
 826                     ()java.type:"void" -> {
 827                         %106 : java.type:"java.lang.String" = var.load %3;
 828                         %107 : java.type:"int" = constant @13;
 829                         %108 : java.type:"java.lang.String" = concat %106 %107;
 830                         var.store %3 %108;
 831                         yield;
 832                     }
 833                     ()java.type:"boolean" -> {
 834                         %109 : java.type:"boolean" = constant @true;
 835                         yield %109;
 836                     }
 837                     ()java.type:"void" -> {
 838                         %110 : java.type:"java.lang.String" = var.load %3;
 839                         %111 : java.type:"java.lang.String" = constant @"an int";
 840                         %112 : java.type:"java.lang.String" = concat %110 %111;
 841                         var.store %3 %112;
 842                         yield;
 843                     };
 844                 %113 : java.type:"java.lang.String" = var.load %3;
 845                 return %113;
 846             };
 847             """)
 848     @Reflect
 849     private static String caseConstantOtherKindsOfExpr(int i) {
 850         String r = "";
 851         final int eleven = 11;
 852         switch (i) {
 853             case 1 & 0xF -> r += 1;
 854             case 4>>1 -> r += "2";
 855             case (int) 3L -> r += 3;
 856             case 2<<1 -> r += 4;
 857             case 10 / 2 -> r += 5;
 858             case 12 - 6 -> r += 6;
 859             case 3 + 4 -> r += 7;
 860             case 2 * 2 * 2 -> r += 8;
 861             case 8 | 1 -> r += 9;
 862             case (10) -> r += 10;
 863             case eleven -> r += 11;
 864             case Constants.c1 -> r += Constants.c1;
 865             case 1 > 0 ? 13 : 133 -> r += 13;
 866             default -> r += "an int";
 867         }
 868         return r;
 869     }
 870 
 871     @IR("""
 872             func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
 873                 %1 : Var<java.type:"short"> = var %0 @"a";
 874                 %2 : java.type:"int" = constant @1;
 875                 %3 : java.type:"short" = conv %2;
 876                 %4 : Var<java.type:"short"> = var %3 @"s";
 877                 %5 : java.type:"int" = constant @2;
 878                 %6 : java.type:"byte" = conv %5;
 879                 %7 : Var<java.type:"byte"> = var %6 @"b";
 880                 %8 : java.type:"java.lang.String" = constant @"";
 881                 %9 : Var<java.type:"java.lang.String"> = var %8 @"r";
 882                 %10 : java.type:"short" = var.load %1;
 883                 java.switch.statement %10
 884                     (%11 : java.type:"short")java.type:"boolean" -> {
 885                         %12 : java.type:"short" = var.load %4;
 886                         %13 : java.type:"boolean" = eq %11 %12;
 887                         yield %13;
 888                     }
 889                     ()java.type:"void" -> {
 890                         %14 : java.type:"java.lang.String" = var.load %9;
 891                         %15 : java.type:"java.lang.String" = constant @"one";
 892                         %16 : java.type:"java.lang.String" = concat %14 %15;
 893                         var.store %9 %16;
 894                         yield;
 895                     }
 896                     (%17 : java.type:"short")java.type:"boolean" -> {
 897                         %18 : java.type:"byte" = var.load %7;
 898                         %19 : java.type:"short" = conv %18;
 899                         %20 : java.type:"boolean" = eq %17 %19;
 900                         yield %20;
 901                     }
 902                     ()java.type:"void" -> {
 903                         %21 : java.type:"java.lang.String" = var.load %9;
 904                         %22 : java.type:"java.lang.String" = constant @"two";
 905                         %23 : java.type:"java.lang.String" = concat %21 %22;
 906                         var.store %9 %23;
 907                         yield;
 908                     }
 909                     (%24 : java.type:"short")java.type:"boolean" -> {
 910                         %25 : java.type:"int" = constant @3;
 911                         %26 : java.type:"short" = conv %25;
 912                         %27 : java.type:"boolean" = eq %24 %26;
 913                         yield %27;
 914                     }
 915                     ()java.type:"void" -> {
 916                         %28 : java.type:"java.lang.String" = var.load %9;
 917                         %29 : java.type:"java.lang.String" = constant @"three";
 918                         %30 : java.type:"java.lang.String" = concat %28 %29;
 919                         var.store %9 %30;
 920                         yield;
 921                     }
 922                     ()java.type:"boolean" -> {
 923                         %31 : java.type:"boolean" = constant @true;
 924                         yield %31;
 925                     }
 926                     ()java.type:"void" -> {
 927                         %32 : java.type:"java.lang.String" = var.load %9;
 928                         %33 : java.type:"java.lang.String" = constant @"else";
 929                         %34 : java.type:"java.lang.String" = concat %32 %33;
 930                         var.store %9 %34;
 931                         yield;
 932                     };
 933                 %35 : java.type:"java.lang.String" = var.load %9;
 934                 return %35;
 935             };
 936             """)
 937     @Reflect
 938     static String caseConstantConv(short a) {
 939         final short s = 1;
 940         final byte b = 2;
 941         String r = "";
 942         switch (a) {
 943             case s -> r += "one"; // identity, short -> short
 944             case b -> r += "two"; // widening primitive conversion, byte -> short
 945             case 3 -> r += "three"; // narrowing primitive conversion, int -> short
 946             default -> r += "else";
 947         }
 948         return r;
 949     }
 950 
 951     @IR("""
 952             func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
 953                 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
 954                 %2 : java.type:"int" = constant @2;
 955                 %3 : java.type:"byte" = conv %2;
 956                 %4 : Var<java.type:"byte"> = var %3 @"b";
 957                 %5 : java.type:"java.lang.String" = constant @"";
 958                 %6 : Var<java.type:"java.lang.String"> = var %5 @"r";
 959                 %7 : java.type:"java.lang.Byte" = var.load %1;
 960                 java.switch.statement %7
 961                     (%8 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 962                         %9 : java.type:"byte" = invoke %8 @java.ref:"java.lang.Byte::byteValue():byte";
 963                         %10 : java.type:"int" = constant @1;
 964                         %11 : java.type:"byte" = conv %10;
 965                         %12 : java.type:"boolean" = eq %9 %11;
 966                         yield %12;
 967                     }
 968                     ()java.type:"void" -> {
 969                         %13 : java.type:"java.lang.String" = var.load %6;
 970                         %14 : java.type:"java.lang.String" = constant @"one";
 971                         %15 : java.type:"java.lang.String" = concat %13 %14;
 972                         var.store %6 %15;
 973                         yield;
 974                     }
 975                     (%16 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 976                         %17 : java.type:"byte" = invoke %16 @java.ref:"java.lang.Byte::byteValue():byte";
 977                         %18 : java.type:"byte" = var.load %4;
 978                         %19 : java.type:"boolean" = eq %17 %18;
 979                         yield %19;
 980                     }
 981                     ()java.type:"void" -> {
 982                         %20 : java.type:"java.lang.String" = var.load %6;
 983                         %21 : java.type:"java.lang.String" = constant @"two";
 984                         %22 : java.type:"java.lang.String" = concat %20 %21;
 985                         var.store %6 %22;
 986                         yield;
 987                     }
 988                     ()java.type:"boolean" -> {
 989                         %23 : java.type:"boolean" = constant @true;
 990                         yield %23;
 991                     }
 992                     ()java.type:"void" -> {
 993                         %24 : java.type:"java.lang.String" = var.load %6;
 994                         %25 : java.type:"java.lang.String" = constant @"default";
 995                         %26 : java.type:"java.lang.String" = concat %24 %25;
 996                         var.store %6 %26;
 997                         yield;
 998                     };
 999                 %27 : java.type:"java.lang.String" = var.load %6;
1000                 return %27;
1001             };
1002             """)
1003     @Reflect
1004     static String caseConstantConv2(Byte a) {
1005         final byte b = 2;
1006         String r = "";
1007         switch (a) {
1008             case 1 -> r+= "one";
1009             case b -> r+= "two";
1010             default -> r+= "default";
1011         }
1012         return r;
1013     }
1014 
1015     @IR("""
1016             func @"nonEnhancedSwStatNoDefault" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1017                 %1 : Var<java.type:"int"> = var %0 @"a";
1018                 %2 : java.type:"java.lang.String" = constant @"";
1019                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1020                 %4 : java.type:"int" = var.load %1;
1021                 java.switch.statement %4
1022                     (%5 : java.type:"int")java.type:"boolean" -> {
1023                         %6 : java.type:"int" = constant @1;
1024                         %7 : java.type:"boolean" = eq %5 %6;
1025                         yield %7;
1026                     }
1027                     ()java.type:"void" -> {
1028                         %8 : java.type:"java.lang.String" = var.load %3;
1029                         %9 : java.type:"java.lang.String" = constant @"1";
1030                         %10 : java.type:"java.lang.String" = concat %8 %9;
1031                         var.store %3 %10;
1032                         yield;
1033                     }
1034                     (%11 : java.type:"int")java.type:"boolean" -> {
1035                         %12 : java.type:"int" = constant @2;
1036                         %13 : java.type:"boolean" = eq %11 %12;
1037                         yield %13;
1038                     }
1039                     ()java.type:"void" -> {
1040                         %14 : java.type:"java.lang.String" = var.load %3;
1041                         %15 : java.type:"int" = constant @2;
1042                         %16 : java.type:"java.lang.String" = concat %14 %15;
1043                         var.store %3 %16;
1044                         yield;
1045                     };
1046                 %17 : java.type:"java.lang.String" = var.load %3;
1047                 return %17;
1048             };
1049             """)
1050     @Reflect
1051     static String nonEnhancedSwStatNoDefault(int a) {
1052         String r = "";
1053         switch (a) {
1054             case 1 -> r += "1";
1055             case 2 -> r += 2;
1056         }
1057         return r;
1058     }
1059 
1060     enum E {A, B}
1061     @IR("""
1062             func @"enhancedSwStatNoDefault1" (%0 : java.type:"SwitchStatementTest$E")java.type:"java.lang.String" -> {
1063                 %1 : Var<java.type:"SwitchStatementTest$E"> = var %0 @"e";
1064                 %2 : java.type:"java.lang.String" = constant @"";
1065                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1066                 %4 : java.type:"SwitchStatementTest$E" = var.load %1;
1067                 java.switch.statement %4 @switch.handle.nulls=true
1068                     (%5 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1069                         %6 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::A:SwitchStatementTest$E";
1070                         %7 : java.type:"boolean" = eq %5 %6;
1071                         yield %7;
1072                     }
1073                     ()java.type:"void" -> {
1074                         %8 : java.type:"java.lang.String" = var.load %3;
1075                         %9 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::A:SwitchStatementTest$E";
1076                         %10 : java.type:"java.lang.String" = concat %8 %9;
1077                         var.store %3 %10;
1078                         yield;
1079                     }
1080                     (%11 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1081                         %12 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::B:SwitchStatementTest$E";
1082                         %13 : java.type:"boolean" = eq %11 %12;
1083                         yield %13;
1084                     }
1085                     ()java.type:"void" -> {
1086                         %14 : java.type:"java.lang.String" = var.load %3;
1087                         %15 : java.type:"SwitchStatementTest$E" = field.load @java.ref:"SwitchStatementTest$E::B:SwitchStatementTest$E";
1088                         %16 : java.type:"java.lang.String" = concat %14 %15;
1089                         var.store %3 %16;
1090                         yield;
1091                     }
1092                     (%17 : java.type:"SwitchStatementTest$E")java.type:"boolean" -> {
1093                         %18 : java.type:"java.lang.Object" = constant @null;
1094                         %19 : java.type:"boolean" = eq %17 %18;
1095                         yield %19;
1096                     }
1097                     ()java.type:"void" -> {
1098                         %20 : java.type:"java.lang.String" = var.load %3;
1099                         %21 : java.type:"java.lang.String" = constant @"null";
1100                         %22 : java.type:"java.lang.String" = concat %20 %21;
1101                         var.store %3 %22;
1102                         yield;
1103                     }
1104                     ()java.type:"boolean" -> {
1105                         %23 : java.type:"boolean" = constant @true;
1106                         yield %23;
1107                     }
1108                     ()java.type:"void" -> {
1109                         %24 : java.type:"java.lang.String" = constant @null;
1110                         %25 : java.type:"java.lang.Throwable" = constant @null;
1111                         %26 : java.type:"java.lang.MatchException" = new %24 %25 @java.ref:"java.lang.MatchException::(java.lang.String, java.lang.Throwable)";
1112                         throw %26;
1113                     };
1114             %27 : java.type:"java.lang.String" = var.load %3;
1115             return %27;
1116             };
1117             """)
1118     @Reflect
1119     static String enhancedSwStatNoDefault1(E e) {
1120         String r = "";
1121         switch (e) {
1122             case A -> r += E.A;
1123             case B -> r += E.B;
1124             case null -> r += "null";
1125         }
1126         return r;
1127     }
1128 
1129     sealed interface I permits K, J {}
1130     record K() implements I {}
1131     static final class J implements I {}
1132     @IR("""
1133             func @"enhancedSwStatNoDefault2" (%0 : java.type:"SwitchStatementTest$I")java.type:"java.lang.String" -> {
1134                 %1 : Var<java.type:"SwitchStatementTest$I"> = var %0 @"i";
1135                 %2 : java.type:"java.lang.String" = constant @"";
1136                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1137                 %4 : java.type:"SwitchStatementTest$I" = var.load %1;
1138                 %5 : java.type:"SwitchStatementTest$K" = constant @null;
1139                 %6 : Var<java.type:"SwitchStatementTest$K"> = var %5 @"k";
1140                 %7 : java.type:"SwitchStatementTest$J" = constant @null;
1141                 %8 : Var<java.type:"SwitchStatementTest$J"> = var %7 @"j";
1142                 java.switch.statement %4
1143                     (%9 : java.type:"SwitchStatementTest$I")java.type:"boolean" -> {
1144                         %10 : java.type:"boolean" = pattern.match %9
1145                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$K>" -> {
1146                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$K>" = pattern.type @"k";
1147                                 yield %11;
1148                             }
1149                             (%12 : java.type:"SwitchStatementTest$K")java.type:"void" -> {
1150                                 var.store %6 %12;
1151                                 yield;
1152                             };
1153                         yield %10;
1154                     }
1155                     ()java.type:"void" -> {
1156                         %13 : java.type:"java.lang.String" = var.load %3;
1157                         %14 : java.type:"java.lang.String" = constant @"K";
1158                         %15 : java.type:"java.lang.String" = concat %13 %14;
1159                         var.store %3 %15;
1160                         yield;
1161                     }
1162                     (%16 : java.type:"SwitchStatementTest$I")java.type:"boolean" -> {
1163                         %17 : java.type:"boolean" = pattern.match %16
1164                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$J>" -> {
1165                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchStatementTest$J>" = pattern.type @"j";
1166                                 yield %18;
1167                             }
1168                             (%19 : java.type:"SwitchStatementTest$J")java.type:"void" -> {
1169                                 var.store %8 %19;
1170                                 yield;
1171                             };
1172                         yield %17;
1173                     }
1174                     ()java.type:"void" -> {
1175                         %20 : java.type:"java.lang.String" = var.load %3;
1176                         %21 : java.type:"java.lang.String" = constant @"J";
1177                         %22 : java.type:"java.lang.String" = concat %20 %21;
1178                         var.store %3 %22;
1179                         yield;
1180                     }
1181                     ()java.type:"boolean" -> {
1182                         %23 : java.type:"boolean" = constant @true;
1183                         yield %23;
1184                     }
1185                     ()java.type:"void" -> {
1186                         %24 : java.type:"java.lang.String" = constant @null;
1187                         %25 : java.type:"java.lang.Throwable" = constant @null;
1188                         %26 : java.type:"java.lang.MatchException" = new %24 %25 @java.ref:"java.lang.MatchException::(java.lang.String, java.lang.Throwable)";
1189                         throw %26;
1190                     };
1191                 %27 : java.type:"java.lang.String" = var.load %3;
1192                 return %27;
1193             };
1194             """)
1195     @Reflect
1196     static String enhancedSwStatNoDefault2(I i) {
1197         String r = "";
1198         switch (i) {
1199             case K k -> r += "K";
1200             case J j -> r += "J";
1201         }
1202         return r;
1203     }
1204 
1205     @IR("""
1206             func @"enhancedSwStatUnconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1207                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1208                 %2 : java.type:"java.lang.String" = constant @"";
1209                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1210                 %4 : java.type:"java.lang.String" = var.load %1;
1211                 %5 : java.type:"java.lang.Object" = constant @null;
1212                 %6 : Var<java.type:"java.lang.Object"> = var %5 @"o";
1213                 java.switch.statement %4
1214                     (%7 : java.type:"java.lang.String")java.type:"boolean" -> {
1215                         %8 : java.type:"java.lang.String" = constant @"A";
1216                         %9 : java.type:"boolean" = invoke %7 %8 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1217                         yield %9;
1218                     }
1219                     ()java.type:"void" -> {
1220                         %10 : java.type:"java.lang.String" = var.load %3;
1221                         %11 : java.type:"java.lang.String" = constant @"A";
1222                         %12 : java.type:"java.lang.String" = concat %10 %11;
1223                         var.store %3 %12;
1224                         yield;
1225                     }
1226                     (%13 : java.type:"java.lang.String")java.type:"boolean" -> {
1227                         %14 : java.type:"boolean" = pattern.match %13
1228                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
1229                                 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
1230                                 yield %15;
1231                             }
1232                             (%16 : java.type:"java.lang.Object")java.type:"void" -> {
1233                                 var.store %6 %16;
1234                                 yield;
1235                             };
1236                         yield %14;
1237                     }
1238                     ()java.type:"void" -> {
1239                         %17 : java.type:"java.lang.String" = var.load %3;
1240                         %18 : java.type:"java.lang.String" = constant @"obj";
1241                         %19 : java.type:"java.lang.String" = concat %17 %18;
1242                         var.store %3 %19;
1243                         yield;
1244                     };
1245                 %20 : java.type:"java.lang.String" = var.load %3;
1246                 return %20;
1247             };
1248             """)
1249     @Reflect
1250     static String enhancedSwStatUnconditionalPattern(String s) {
1251         String r = "";
1252         switch (s) {
1253             case "A" -> r += "A";
1254             case Object o -> r += "obj";
1255         }
1256         return r;
1257     }
1258 
1259     @IR("""
1260             func @"casePatternRuleExpression" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1261                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1262                 %2 : java.type:"java.lang.String" = constant @"";
1263                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1264                 %4 : java.type:"java.lang.Object" = var.load %1;
1265                 %5 : java.type:"java.lang.Integer" = constant @null;
1266                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1267                 %7 : java.type:"java.lang.String" = constant @null;
1268                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1269                 java.switch.statement %4
1270                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1271                         %10 : java.type:"boolean" = pattern.match %9
1272                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1273                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1274                                 yield %11;
1275                             }
1276                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1277                                 var.store %6 %12;
1278                                 yield;
1279                             };
1280                         yield %10;
1281                     }
1282                     ()java.type:"void" -> {
1283                         %13 : java.type:"java.lang.String" = var.load %3;
1284                         %14 : java.type:"java.lang.String" = constant @"integer";
1285                         %15 : java.type:"java.lang.String" = concat %13 %14;
1286                         var.store %3 %15;
1287                         yield;
1288                     }
1289                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1290                         %17 : java.type:"boolean" = pattern.match %16
1291                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1292                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1293                                 yield %18;
1294                             }
1295                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1296                                 var.store %8 %19;
1297                                 yield;
1298                             };
1299                         yield %17;
1300                     }
1301                     ()java.type:"void" -> {
1302                         %20 : java.type:"java.lang.String" = var.load %3;
1303                         %21 : java.type:"java.lang.String" = constant @"string";
1304                         %22 : java.type:"java.lang.String" = concat %20 %21;
1305                         var.store %3 %22;
1306                         yield;
1307                     }
1308                     ()java.type:"boolean" -> {
1309                         %23 : java.type:"boolean" = constant @true;
1310                         yield %23;
1311                     }
1312                     ()java.type:"void" -> {
1313                         %24 : java.type:"java.lang.String" = var.load %3;
1314                         %25 : java.type:"java.lang.String" = constant @"else";
1315                         %26 : java.type:"java.lang.String" = concat %24 %25;
1316                         var.store %3 %26;
1317                         yield;
1318                     };
1319                 %27 : java.type:"java.lang.String" = var.load %3;
1320                 return %27;
1321             };
1322             """)
1323     @Reflect
1324     private static String casePatternRuleExpression(Object o) {
1325         String r = "";
1326         switch (o) {
1327             case Integer i -> r += "integer";
1328             case String s -> r+= "string";
1329             default -> r+= "else";
1330         }
1331         return r;
1332     }
1333 
1334     @IR("""
1335             func @"casePatternRuleBlock" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1336                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1337                 %2 : java.type:"java.lang.String" = constant @"";
1338                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1339                 %4 : java.type:"java.lang.Object" = var.load %1;
1340                 %5 : java.type:"java.lang.Integer" = constant @null;
1341                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1342                 %7 : java.type:"java.lang.String" = constant @null;
1343                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1344                 java.switch.statement %4
1345                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1346                         %10 : java.type:"boolean" = pattern.match %9
1347                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1348                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1349                                 yield %11;
1350                             }
1351                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1352                                 var.store %6 %12;
1353                                 yield;
1354                             };
1355                         yield %10;
1356                     }
1357                     ()java.type:"void" -> {
1358                         %13 : java.type:"java.lang.String" = var.load %3;
1359                         %14 : java.type:"java.lang.String" = constant @"integer";
1360                         %15 : java.type:"java.lang.String" = concat %13 %14;
1361                         var.store %3 %15;
1362                         yield;
1363                     }
1364                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1365                         %17 : java.type:"boolean" = pattern.match %16
1366                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1367                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1368                                 yield %18;
1369                             }
1370                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1371                                 var.store %8 %19;
1372                                 yield;
1373                             };
1374                         yield %17;
1375                     }
1376                     ()java.type:"void" -> {
1377                         %20 : java.type:"java.lang.String" = var.load %3;
1378                         %21 : java.type:"java.lang.String" = constant @"string";
1379                         %22 : java.type:"java.lang.String" = concat %20 %21;
1380                         var.store %3 %22;
1381                         yield;
1382                     }
1383                     ()java.type:"boolean" -> {
1384                         %23 : java.type:"boolean" = constant @true;
1385                         yield %23;
1386                     }
1387                     ()java.type:"void" -> {
1388                         %24 : java.type:"java.lang.String" = var.load %3;
1389                         %25 : java.type:"java.lang.String" = constant @"else";
1390                         %26 : java.type:"java.lang.String" = concat %24 %25;
1391                         var.store %3 %26;
1392                         yield;
1393                     };
1394                 %27 : java.type:"java.lang.String" = var.load %3;
1395                 return %27;
1396             };
1397             """)
1398     @Reflect
1399     private static String casePatternRuleBlock(Object o) {
1400         String r = "";
1401         switch (o) {
1402             case Integer i -> {
1403                 r += "integer";
1404             }
1405             case String s -> {
1406                 r += "string";
1407             }
1408             default -> {
1409                 r += "else";
1410             }
1411         }
1412         return r;
1413     }
1414 
1415     @IR("""
1416             func @"casePatternStatement" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1417                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1418                 %2 : java.type:"java.lang.String" = constant @"";
1419                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1420                 %4 : java.type:"java.lang.Object" = var.load %1;
1421                 %5 : java.type:"java.lang.Integer" = constant @null;
1422                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1423                 %7 : java.type:"java.lang.String" = constant @null;
1424                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1425                 java.switch.statement %4
1426                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1427                         %10 : java.type:"boolean" = pattern.match %9
1428                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1429                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1430                                 yield %11;
1431                             }
1432                             (%12 : java.type:"java.lang.Integer")java.type:"void" -> {
1433                                 var.store %6 %12;
1434                                 yield;
1435                             };
1436                         yield %10;
1437                     }
1438                     ()java.type:"void" -> {
1439                         %13 : java.type:"java.lang.String" = var.load %3;
1440                         %14 : java.type:"java.lang.String" = constant @"integer";
1441                         %15 : java.type:"java.lang.String" = concat %13 %14;
1442                         var.store %3 %15;
1443                         java.break;
1444                     }
1445                     (%16 : java.type:"java.lang.Object")java.type:"boolean" -> {
1446                         %17 : java.type:"boolean" = pattern.match %16
1447                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1448                                 %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1449                                 yield %18;
1450                             }
1451                             (%19 : java.type:"java.lang.String")java.type:"void" -> {
1452                                 var.store %8 %19;
1453                                 yield;
1454                             };
1455                         yield %17;
1456                     }
1457                     ()java.type:"void" -> {
1458                         %20 : java.type:"java.lang.String" = var.load %3;
1459                         %21 : java.type:"java.lang.String" = constant @"string";
1460                         %22 : java.type:"java.lang.String" = concat %20 %21;
1461                         var.store %3 %22;
1462                         java.break;
1463                     }
1464                     ()java.type:"boolean" -> {
1465                         %23 : java.type:"boolean" = constant @true;
1466                         yield %23;
1467                     }
1468                     ()java.type:"void" -> {
1469                         %24 : java.type:"java.lang.String" = var.load %3;
1470                         %25 : java.type:"java.lang.String" = constant @"else";
1471                         %26 : java.type:"java.lang.String" = concat %24 %25;
1472                         var.store %3 %26;
1473                         yield;
1474                     };
1475                 %27 : java.type:"java.lang.String" = var.load %3;
1476                 return %27;
1477             };
1478             """)
1479     @Reflect
1480     private static String casePatternStatement(Object o) {
1481         String r = "";
1482         switch (o) {
1483             case Integer i:
1484                 r += "integer";
1485                 break;
1486             case String s:
1487                 r += "string";
1488                 break;
1489             default:
1490                 r += "else";
1491         }
1492         return r;
1493     }
1494 
1495     @IR("""
1496             func @"casePatternThrow" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1497                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1498                 %2 : java.type:"java.lang.String" = constant @"";
1499                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1500                 %4 : java.type:"java.lang.Object" = var.load %1;
1501                 %5 : java.type:"java.lang.Number" = constant @null;
1502                 %6 : Var<java.type:"java.lang.Number"> = var %5 @"n";
1503                 %7 : java.type:"java.lang.String" = constant @null;
1504                 %8 : Var<java.type:"java.lang.String"> = var %7 @"s";
1505                 java.switch.statement %4
1506                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
1507                         %10 : java.type:"boolean" = pattern.match %9
1508                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" -> {
1509                                 %11 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
1510                                 yield %11;
1511                             }
1512                             (%12 : java.type:"java.lang.Number")java.type:"void" -> {
1513                                 var.store %6 %12;
1514                                 yield;
1515                             };
1516                         yield %10;
1517                     }
1518                     ()java.type:"void" -> {
1519                         %13 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
1520                         throw %13;
1521                     }
1522                     (%14 : java.type:"java.lang.Object")java.type:"boolean" -> {
1523                         %15 : java.type:"boolean" = pattern.match %14
1524                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1525                                 %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
1526                                 yield %16;
1527                             }
1528                             (%17 : java.type:"java.lang.String")java.type:"void" -> {
1529                                 var.store %8 %17;
1530                                 yield;
1531                             };
1532                         yield %15;
1533                     }
1534                     ()java.type:"void" -> {
1535                         %18 : java.type:"java.lang.String" = var.load %3;
1536                         %19 : java.type:"java.lang.String" = constant @"a string";
1537                         %20 : java.type:"java.lang.String" = concat %18 %19;
1538                         var.store %3 %20;
1539                         yield;
1540                     }
1541                     ()java.type:"boolean" -> {
1542                         %21 : java.type:"boolean" = constant @true;
1543                         yield %21;
1544                     }
1545                     ()java.type:"void" -> {
1546                         %22 : java.type:"java.lang.String" = var.load %3;
1547                         %23 : java.type:"java.lang.Object" = var.load %1;
1548                         %24 : java.type:"java.lang.Class<?>" = invoke %23 @java.ref:"java.lang.Object::getClass():java.lang.Class";
1549                         %25 : java.type:"java.lang.String" = invoke %24 @java.ref:"java.lang.Class::getName():java.lang.String";
1550                         %26 : java.type:"java.lang.String" = concat %22 %25;
1551                         var.store %3 %26;
1552                         yield;
1553                     };
1554                 %27 : java.type:"java.lang.String" = var.load %3;
1555                 return %27;
1556             };
1557             """)
1558     @Reflect
1559     private static String casePatternThrow(Object o) {
1560         String r = "";
1561         switch (o) {
1562             case Number n -> throw new IllegalArgumentException();
1563             case String s -> r += "a string";
1564             default -> r += o.getClass().getName();
1565         }
1566         return r;
1567     }
1568 
1569     @IR("""
1570             func @"casePatternMultiLabel" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1571                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1572                 %2 : java.type:"java.lang.String" = constant @"";
1573                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1574                 %4 : java.type:"java.lang.Object" = var.load %1;
1575                 %5 : java.type:"java.lang.Integer" = constant @null;
1576                 %6 : Var<java.type:"java.lang.Integer"> = var %5;
1577                 %7 : java.type:"java.lang.Long" = constant @null;
1578                 %8 : Var<java.type:"java.lang.Long"> = var %7;
1579                 %9 : java.type:"java.lang.Character" = constant @null;
1580                 %10 : Var<java.type:"java.lang.Character"> = var %9;
1581                 %11 : java.type:"java.lang.Byte" = constant @null;
1582                 %12 : Var<java.type:"java.lang.Byte"> = var %11;
1583                 %13 : java.type:"java.lang.Short" = constant @null;
1584                 %14 : Var<java.type:"java.lang.Short"> = var %13;
1585                 java.switch.statement %4
1586                     (%15 : java.type:"java.lang.Object")java.type:"boolean" -> {
1587                         %16 : java.type:"boolean" = java.cor
1588                             ()java.type:"boolean" -> {
1589                                 %17 : java.type:"boolean" = pattern.match %15
1590                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1591                                         %18 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
1592                                         yield %18;
1593                                     }
1594                                     (%19 : java.type:"java.lang.Integer")java.type:"void" -> {
1595                                         var.store %6 %19;
1596                                         yield;
1597                                     };
1598                                 yield %17;
1599                             }
1600                             ()java.type:"boolean" -> {
1601                                 %20 : java.type:"boolean" = pattern.match %15
1602                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" -> {
1603                                         %21 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" = pattern.type;
1604                                         yield %21;
1605                                     }
1606                                     (%22 : java.type:"java.lang.Long")java.type:"void" -> {
1607                                         var.store %8 %22;
1608                                         yield;
1609                                     };
1610                                 yield %20;
1611                             }
1612                             ()java.type:"boolean" -> {
1613                                 %23 : java.type:"boolean" = pattern.match %15
1614                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Character>" -> {
1615                                         %24 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Character>" = pattern.type;
1616                                         yield %24;
1617                                     }
1618                                     (%25 : java.type:"java.lang.Character")java.type:"void" -> {
1619                                         var.store %10 %25;
1620                                         yield;
1621                                     };
1622                                 yield %23;
1623                             }
1624                             ()java.type:"boolean" -> {
1625                                 %26 : java.type:"boolean" = pattern.match %15
1626                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" -> {
1627                                         %27 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" = pattern.type;
1628                                         yield %27;
1629                                     }
1630                                     (%28 : java.type:"java.lang.Byte")java.type:"void" -> {
1631                                         var.store %12 %28;
1632                                         yield;
1633                                     };
1634                                 yield %26;
1635                             }
1636                             ()java.type:"boolean" -> {
1637                                 %29 : java.type:"boolean" = pattern.match %15
1638                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" -> {
1639                                         %30 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" = pattern.type;
1640                                         yield %30;
1641                                     }
1642                                     (%31 : java.type:"java.lang.Short")java.type:"void" -> {
1643                                         var.store %14 %31;
1644                                         yield;
1645                                     };
1646                                 yield %29;
1647                             };
1648                         yield %16;
1649                     }
1650                     ()java.type:"void" -> {
1651                         %32 : java.type:"java.lang.String" = var.load %3;
1652                         %33 : java.type:"java.lang.String" = constant @"integral type";
1653                         %34 : java.type:"java.lang.String" = concat %32 %33;
1654                         var.store %3 %34;
1655                         yield;
1656                     }
1657                     ()java.type:"boolean" -> {
1658                         %35 : java.type:"boolean" = constant @true;
1659                         yield %35;
1660                     }
1661                     ()java.type:"void" -> {
1662                         %36 : java.type:"java.lang.String" = var.load %3;
1663                         %37 : java.type:"java.lang.String" = constant @"non integral type";
1664                         %38 : java.type:"java.lang.String" = concat %36 %37;
1665                         var.store %3 %38;
1666                         yield;
1667                     };
1668                 %39 : java.type:"java.lang.String" = var.load %3;
1669                 return %39;
1670             };
1671             """)
1672     @Reflect
1673     private static String casePatternMultiLabel(Object o) {
1674         String r = "";
1675         switch (o) {
1676             case Integer _, Long _, Character _, Byte _, Short _-> r += "integral type";
1677             default -> r += "non integral type";
1678         }
1679         return r;
1680     }
1681 
1682     @IR("""
1683             func @"casePatternGuardedMultiLabel" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1684                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1685                 %2 : java.type:"java.lang.String" = constant @"";
1686                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1687                 %4 : java.type:"java.lang.Object" = var.load %1;
1688                 %5 : java.type:"java.lang.Integer" = constant @null;
1689                 %6 : Var<java.type:"java.lang.Integer"> = var %5;
1690                 %7 : java.type:"java.lang.Long" = constant @null;
1691                 %8 : Var<java.type:"java.lang.Long"> = var %7;
1692                 %9 : java.type:"java.lang.Byte" = constant @null;
1693                 %10 : Var<java.type:"java.lang.Byte"> = var %9;
1694                 %11 : java.type:"java.lang.Short" = constant @null;
1695                 %12 : Var<java.type:"java.lang.Short"> = var %11;
1696                 java.switch.statement %4
1697                     (%13 : java.type:"java.lang.Object")java.type:"boolean" -> {
1698                         %14 : java.type:"boolean" = java.cand
1699                             ()java.type:"boolean" -> {
1700                                 %15 : java.type:"boolean" = java.cor
1701                                     ()java.type:"boolean" -> {
1702                                         %16 : java.type:"boolean" = pattern.match %13
1703                                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1704                                                 %17 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
1705                                                 yield %17;
1706                                             }
1707                                             (%18 : java.type:"java.lang.Integer")java.type:"void" -> {
1708                                                 var.store %6 %18;
1709                                                 yield;
1710                                             };
1711                                         yield %16;
1712                                     }
1713                                     ()java.type:"boolean" -> {
1714                                         %19 : java.type:"boolean" = pattern.match %13
1715                                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" -> {
1716                                                 %20 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Long>" = pattern.type;
1717                                                 yield %20;
1718                                             }
1719                                             (%21 : java.type:"java.lang.Long")java.type:"void" -> {
1720                                                 var.store %8 %21;
1721                                                 yield;
1722                                             };
1723                                         yield %19;
1724                                     }
1725                                     ()java.type:"boolean" -> {
1726                                         %22 : java.type:"boolean" = pattern.match %13
1727                                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" -> {
1728                                                 %23 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Byte>" = pattern.type;
1729                                                 yield %23;
1730                                             }
1731                                             (%24 : java.type:"java.lang.Byte")java.type:"void" -> {
1732                                                 var.store %10 %24;
1733                                                 yield;
1734                                             };
1735                                         yield %22;
1736                                     }
1737                                     ()java.type:"boolean" -> {
1738                                         %25 : java.type:"boolean" = pattern.match %13
1739                                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" -> {
1740                                                 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Short>" = pattern.type;
1741                                                 yield %26;
1742                                             }
1743                                             (%27 : java.type:"java.lang.Short")java.type:"void" -> {
1744                                                 var.store %12 %27;
1745                                                 yield;
1746                                             };
1747                                         yield %25;
1748                                     };
1749                                 yield %15;
1750                             }
1751                             ()java.type:"boolean" -> {
1752                                 %28 : java.type:"java.lang.Object" = var.load %1;
1753                                 %29 : java.type:"java.lang.Number" = cast %28 @java.type:"java.lang.Number";
1754                                 %30 : java.type:"int" = invoke %29 @java.ref:"java.lang.Number::intValue():int";
1755                                 %31 : java.type:"int" = constant @0;
1756                                 %32 : java.type:"boolean" = gt %30 %31;
1757                                 yield %32;
1758                             };
1759                         yield %14;
1760                     }
1761                     ()java.type:"void" -> {
1762                         %33 : java.type:"java.lang.String" = var.load %3;
1763                         %34 : java.type:"java.lang.String" = constant @"integral type";
1764                         %35 : java.type:"java.lang.String" = concat %33 %34;
1765                         var.store %3 %35;
1766                         yield;
1767                     }
1768                     ()java.type:"boolean" -> {
1769                         %36 : java.type:"boolean" = constant @true;
1770                         yield %36;
1771                     }
1772                     ()java.type:"void" -> {
1773                         %37 : java.type:"java.lang.String" = var.load %3;
1774                         %38 : java.type:"java.lang.String" = constant @"non integral type";
1775                         %39 : java.type:"java.lang.String" = concat %37 %38;
1776                         var.store %3 %39;
1777                         yield;
1778                     };
1779                 %40 : java.type:"java.lang.String" = var.load %3;
1780                 return %40;
1781             };
1782             """)
1783     @Reflect
1784     private static String casePatternGuardedMultiLabel(Object o) {
1785         String r = "";
1786         switch (o) {
1787             case Integer _, Long _, Byte _, Short _ when ((Number)o).intValue() > 0 -> r += "integral type";
1788             default -> r += "non integral type";
1789         }
1790         return r;
1791     }
1792 
1793     @IR("""
1794             func @"casePatternWithCaseConstant" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
1795                 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"a";
1796                 %2 : java.type:"java.lang.String" = constant @"";
1797                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1798                 %4 : java.type:"java.lang.Integer" = var.load %1;
1799                 %5 : java.type:"java.lang.Integer" = constant @null;
1800                 %6 : Var<java.type:"java.lang.Integer"> = var %5 @"i";
1801                 %7 : java.type:"java.lang.Integer" = constant @null;
1802                 %8 : Var<java.type:"java.lang.Integer"> = var %7 @"i";
1803                 java.switch.statement %4
1804                     (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1805                         %10 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1806                         %11 : java.type:"int" = constant @42;
1807                         %12 : java.type:"boolean" = eq %10 %11;
1808                         yield %12;
1809                     }
1810                     ()java.type:"void" -> {
1811                         %13 : java.type:"java.lang.String" = var.load %3;
1812                         %14 : java.type:"java.lang.String" = constant @"forty two";
1813                         %15 : java.type:"java.lang.String" = concat %13 %14;
1814                         var.store %3 %15;
1815                         yield;
1816                     }
1817                     (%16 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1818                         %17 : java.type:"boolean" = java.cand
1819                             ()java.type:"boolean" -> {
1820                                 %18 : java.type:"boolean" = pattern.match %16
1821                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1822                                         %19 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1823                                         yield %19;
1824                                     }
1825                                     (%20 : java.type:"java.lang.Integer")java.type:"void" -> {
1826                                         var.store %6 %20;
1827                                         yield;
1828                                     };
1829                                 yield %18;
1830                             }
1831                             ()java.type:"boolean" -> {
1832                                 %21 : java.type:"java.lang.Integer" = var.load %6;
1833                                 %22 : java.type:"int" = invoke %21 @java.ref:"java.lang.Integer::intValue():int";
1834                                 %23 : java.type:"int" = constant @0;
1835                                 %24 : java.type:"boolean" = gt %22 %23;
1836                                 yield %24;
1837                             };
1838                         yield %17;
1839                     }
1840                     ()java.type:"void" -> {
1841                         %25 : java.type:"java.lang.String" = var.load %3;
1842                         %26 : java.type:"java.lang.String" = constant @"positive int";
1843                         %27 : java.type:"java.lang.String" = concat %25 %26;
1844                         var.store %3 %27;
1845                         yield;
1846                     }
1847                     (%28 : java.type:"java.lang.Integer")java.type:"boolean" -> {
1848                         %29 : java.type:"boolean" = java.cand
1849                             ()java.type:"boolean" -> {
1850                                 %30 : java.type:"boolean" = pattern.match %28
1851                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1852                                         %31 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"i";
1853                                         yield %31;
1854                                     }
1855                                     (%32 : java.type:"java.lang.Integer")java.type:"void" -> {
1856                                         var.store %8 %32;
1857                                         yield;
1858                                     };
1859                                 yield %30;
1860                             }
1861                             ()java.type:"boolean" -> {
1862                                 %33 : java.type:"java.lang.Integer" = var.load %8;
1863                                 %34 : java.type:"int" = invoke %33 @java.ref:"java.lang.Integer::intValue():int";
1864                                 %35 : java.type:"int" = constant @0;
1865                                 %36 : java.type:"boolean" = lt %34 %35;
1866                                 yield %36;
1867                             };
1868                         yield %29;
1869                     }
1870                     ()java.type:"void" -> {
1871                         %37 : java.type:"java.lang.String" = var.load %3;
1872                         %38 : java.type:"java.lang.String" = constant @"negative int";
1873                         %39 : java.type:"java.lang.String" = concat %37 %38;
1874                         var.store %3 %39;
1875                         yield;
1876                     }
1877                     ()java.type:"boolean" -> {
1878                         %40 : java.type:"boolean" = constant @true;
1879                         yield %40;
1880                     }
1881                     ()java.type:"void" -> {
1882                         %41 : java.type:"java.lang.String" = var.load %3;
1883                         %42 : java.type:"java.lang.String" = constant @"zero";
1884                         %43 : java.type:"java.lang.String" = concat %41 %42;
1885                         var.store %3 %43;
1886                         yield;
1887                     };
1888                 %44 : java.type:"java.lang.String" = var.load %3;
1889                 return %44;
1890             };
1891             """)
1892     @Reflect
1893     static String casePatternWithCaseConstant(Integer a) {
1894         String r = "";
1895         switch (a) {
1896             case 42 -> r += "forty two";
1897             case Integer i when i > 0 -> r += "positive int";
1898             case Integer i when i < 0 -> r += "negative int";
1899             default -> r += "zero";
1900         }
1901         return r;
1902     }
1903 
1904     @IR("""
1905             func @"caseTypePattern" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
1906                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
1907                 %2 : java.type:"java.lang.String" = constant @"";
1908                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
1909                 %4 : java.type:"java.lang.Object" = var.load %1;
1910                 %5 : java.type:"java.lang.String" = constant @null;
1911                 %6 : Var<java.type:"java.lang.String"> = var %5;
1912                 %7 : java.type:"java.util.RandomAccess" = constant @null;
1913                 %8 : Var<java.type:"java.util.RandomAccess"> = var %7;
1914                 %9 : java.type:"int[]" = constant @null;
1915                 %10 : Var<java.type:"int[]"> = var %9;
1916                 %11 : java.type:"java.util.Stack[][]" = constant @null;
1917                 %12 : Var<java.type:"java.util.Stack[][]"> = var %11;
1918                 %13 : java.type:"java.util.Collection[][][]" = constant @null;
1919                 %14 : Var<java.type:"java.util.Collection[][][]"> = var %13;
1920                 %15 : java.type:"java.lang.Number" = constant @null;
1921                 %16 : Var<java.type:"java.lang.Number"> = var %15 @"n";
1922                 java.switch.statement %4
1923                     (%17 : java.type:"java.lang.Object")java.type:"boolean" -> {
1924                         %18 : java.type:"boolean" = pattern.match %17
1925                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
1926                                 %19 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type;
1927                                 yield %19;
1928                             }
1929                             (%20 : java.type:"java.lang.String")java.type:"void" -> {
1930                                 var.store %6 %20;
1931                                 yield;
1932                             };
1933                         yield %18;
1934                     }
1935                     ()java.type:"void" -> {
1936                         %21 : java.type:"java.lang.String" = var.load %3;
1937                         %22 : java.type:"java.lang.String" = constant @"String";
1938                         %23 : java.type:"java.lang.String" = concat %21 %22;
1939                         var.store %3 %23;
1940                         yield;
1941                     }
1942                     (%24 : java.type:"java.lang.Object")java.type:"boolean" -> {
1943                         %25 : java.type:"boolean" = pattern.match %24
1944                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.RandomAccess>" -> {
1945                                 %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.RandomAccess>" = pattern.type;
1946                                 yield %26;
1947                             }
1948                             (%27 : java.type:"java.util.RandomAccess")java.type:"void" -> {
1949                                 var.store %8 %27;
1950                                 yield;
1951                             };
1952                         yield %25;
1953                     }
1954                     ()java.type:"void" -> {
1955                         %28 : java.type:"java.lang.String" = var.load %3;
1956                         %29 : java.type:"java.lang.String" = constant @"RandomAccess";
1957                         %30 : java.type:"java.lang.String" = concat %28 %29;
1958                         var.store %3 %30;
1959                         yield;
1960                     }
1961                     (%31 : java.type:"java.lang.Object")java.type:"boolean" -> {
1962                         %32 : java.type:"boolean" = pattern.match %31
1963                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<int[]>" -> {
1964                                 %33 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<int[]>" = pattern.type;
1965                                 yield %33;
1966                             }
1967                             (%34 : java.type:"int[]")java.type:"void" -> {
1968                                 var.store %10 %34;
1969                                 yield;
1970                             };
1971                         yield %32;
1972                     }
1973                     ()java.type:"void" -> {
1974                         %35 : java.type:"java.lang.String" = var.load %3;
1975                         %36 : java.type:"java.lang.String" = constant @"int[]";
1976                         %37 : java.type:"java.lang.String" = concat %35 %36;
1977                         var.store %3 %37;
1978                         yield;
1979                     }
1980                     (%38 : java.type:"java.lang.Object")java.type:"boolean" -> {
1981                         %39 : java.type:"boolean" = pattern.match %38
1982                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Stack[][]>" -> {
1983                                 %40 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Stack[][]>" = pattern.type;
1984                                 yield %40;
1985                             }
1986                             (%41 : java.type:"java.util.Stack[][]")java.type:"void" -> {
1987                                 var.store %12 %41;
1988                                 yield;
1989                             };
1990                         yield %39;
1991                     }
1992                     ()java.type:"void" -> {
1993                         %42 : java.type:"java.lang.String" = var.load %3;
1994                         %43 : java.type:"java.lang.String" = constant @"Stack[][]";
1995                         %44 : java.type:"java.lang.String" = concat %42 %43;
1996                         var.store %3 %44;
1997                         yield;
1998                     }
1999                     (%45 : java.type:"java.lang.Object")java.type:"boolean" -> {
2000                         %46 : java.type:"boolean" = pattern.match %45
2001                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Collection[][][]>" -> {
2002                                 %47 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.util.Collection[][][]>" = pattern.type;
2003                                 yield %47;
2004                             }
2005                             (%48 : java.type:"java.util.Collection[][][]")java.type:"void" -> {
2006                                 var.store %14 %48;
2007                                 yield;
2008                             };
2009                         yield %46;
2010                     }
2011                     ()java.type:"void" -> {
2012                         %49 : java.type:"java.lang.String" = var.load %3;
2013                         %50 : java.type:"java.lang.String" = constant @"Collection[][][]";
2014                         %51 : java.type:"java.lang.String" = concat %49 %50;
2015                         var.store %3 %51;
2016                         yield;
2017                     }
2018                     (%52 : java.type:"java.lang.Object")java.type:"boolean" -> {
2019                         %53 : java.type:"boolean" = pattern.match %52
2020                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" -> {
2021                                 %54 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
2022                                 yield %54;
2023                             }
2024                             (%55 : java.type:"java.lang.Number")java.type:"void" -> {
2025                                 var.store %16 %55;
2026                                 yield;
2027                             };
2028                         yield %53;
2029                     }
2030                     ()java.type:"void" -> {
2031                         %56 : java.type:"java.lang.String" = var.load %3;
2032                         %57 : java.type:"java.lang.String" = constant @"Number";
2033                         %58 : java.type:"java.lang.String" = concat %56 %57;
2034                         var.store %3 %58;
2035                         yield;
2036                     }
2037                     ()java.type:"boolean" -> {
2038                         %59 : java.type:"boolean" = constant @true;
2039                         yield %59;
2040                     }
2041                     ()java.type:"void" -> {
2042                         %60 : java.type:"java.lang.String" = var.load %3;
2043                         %61 : java.type:"java.lang.String" = constant @"something else";
2044                         %62 : java.type:"java.lang.String" = concat %60 %61;
2045                         var.store %3 %62;
2046                         yield;
2047                     };
2048                 %63 : java.type:"java.lang.String" = var.load %3;
2049                 return %63;
2050             };
2051             """)
2052     @Reflect
2053     static String caseTypePattern(Object o) {
2054         String r = "";
2055         switch (o) {
2056             case String _ -> r+= "String"; // class
2057             case RandomAccess _ -> r+= "RandomAccess"; // interface
2058             case int[] _ -> r+= "int[]"; // array primitive
2059             case Stack[][] _ -> r+= "Stack[][]"; // array class
2060             case Collection[][][] _ -> r+= "Collection[][][]"; // array interface
2061             case final Number n -> r+= "Number"; // final modifier
2062             default -> r+= "something else";
2063         }
2064         return r;
2065     }
2066 
2067     record R(Number n) {}
2068     @IR("""
2069             func @"caseRecordPattern" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
2070                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"o";
2071                 %2 : java.type:"java.lang.String" = constant @"";
2072                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2073                 %4 : java.type:"java.lang.Object" = var.load %1;
2074                 %5 : java.type:"java.lang.Number" = constant @null;
2075                 %6 : Var<java.type:"java.lang.Number"> = var %5 @"n";
2076                 java.switch.statement %4
2077                     (%7 : java.type:"java.lang.Object")java.type:"boolean" -> {
2078                         %8 : java.type:"boolean" = pattern.match %7
2079                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" -> {
2080                                 %9 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
2081                                 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" = pattern.record %9 @java.ref:"(java.lang.Number n)SwitchStatementTest$R";
2082                                 yield %10;
2083                             }
2084                             (%11 : java.type:"java.lang.Number")java.type:"void" -> {
2085                                 var.store %6 %11;
2086                                 yield;
2087                             };
2088                         yield %8;
2089                     }
2090                     ()java.type:"void" -> {
2091                         %12 : java.type:"java.lang.String" = var.load %3;
2092                         %13 : java.type:"java.lang.String" = constant @"R(_)";
2093                         %14 : java.type:"java.lang.String" = concat %12 %13;
2094                         var.store %3 %14;
2095                         yield;
2096                     }
2097                     ()java.type:"boolean" -> {
2098                         %15 : java.type:"boolean" = constant @true;
2099                         yield %15;
2100                     }
2101                     ()java.type:"void" -> {
2102                         %16 : java.type:"java.lang.String" = var.load %3;
2103                         %17 : java.type:"java.lang.String" = constant @"else";
2104                         %18 : java.type:"java.lang.String" = concat %16 %17;
2105                         var.store %3 %18;
2106                         yield;
2107                     };
2108                 %19 : java.type:"java.lang.String" = var.load %3;
2109                 return %19;
2110             };
2111             """)
2112     @Reflect
2113     static String caseRecordPattern(Object o) {
2114         String r = "";
2115         switch (o) {
2116             case R(Number n) -> r += "R(_)";
2117             default -> r+= "else";
2118         }
2119         return r;
2120     }
2121 
2122     @IR("""
2123             func @"casePatternGuard" (%0 : java.type:"java.lang.Object")java.type:"java.lang.String" -> {
2124                 %1 : Var<java.type:"java.lang.Object"> = var %0 @"obj";
2125                 %2 : java.type:"java.lang.String" = constant @"";
2126                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2127                 %4 : java.type:"java.lang.Object" = var.load %1;
2128                 %5 : java.type:"java.lang.String" = constant @null;
2129                 %6 : Var<java.type:"java.lang.String"> = var %5 @"s";
2130                 %7 : java.type:"java.lang.Number" = constant @null;
2131                 %8 : Var<java.type:"java.lang.Number"> = var %7 @"n";
2132                 java.switch.statement %4
2133                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
2134                         %10 : java.type:"boolean" = java.cand
2135                             ()java.type:"boolean" -> {
2136                                 %11 : java.type:"boolean" = pattern.match %9
2137                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" -> {
2138                                         %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.String>" = pattern.type @"s";
2139                                         yield %12;
2140                                     }
2141                                     (%13 : java.type:"java.lang.String")java.type:"void" -> {
2142                                         var.store %6 %13;
2143                                         yield;
2144                                     };
2145                                 yield %11;
2146                             }
2147                             ()java.type:"boolean" -> {
2148                                 %14 : java.type:"java.lang.String" = var.load %6;
2149                                 %15 : java.type:"int" = invoke %14 @java.ref:"java.lang.String::length():int";
2150                                 %16 : java.type:"int" = constant @3;
2151                                 %17 : java.type:"boolean" = gt %15 %16;
2152                                 yield %17;
2153                             };
2154                         yield %10;
2155                     }
2156                     ()java.type:"void" -> {
2157                         %18 : java.type:"java.lang.String" = var.load %3;
2158                         %19 : java.type:"java.lang.String" = constant @"str with length > %d";
2159                         %20 : java.type:"java.lang.String" = var.load %6;
2160                         %21 : java.type:"int" = invoke %20 @java.ref:"java.lang.String::length():int";
2161                         %22 : java.type:"java.lang.Integer" = invoke %21 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
2162                         %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;
2163                         %24 : java.type:"java.lang.String" = concat %18 %23;
2164                         var.store %3 %24;
2165                         yield;
2166                     }
2167                     (%25 : java.type:"java.lang.Object")java.type:"boolean" -> {
2168                         %26 : java.type:"boolean" = java.cand
2169                             ()java.type:"boolean" -> {
2170                                 %27 : java.type:"boolean" = pattern.match %25
2171                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" -> {
2172                                         %28 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Number>" = pattern.type @"n";
2173                                         %29 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Record<SwitchStatementTest$R>" = pattern.record %28 @java.ref:"(java.lang.Number n)SwitchStatementTest$R";
2174                                         yield %29;
2175                                     }
2176                                     (%30 : java.type:"java.lang.Number")java.type:"void" -> {
2177                                         var.store %8 %30;
2178                                         yield;
2179                                     };
2180                                 yield %27;
2181                             }
2182                             ()java.type:"boolean" -> {
2183                                 %31 : java.type:"java.lang.Number" = var.load %8;
2184                                 %32 : java.type:"java.lang.Class<? extends java.lang.Number>" = invoke %31 @java.ref:"java.lang.Object::getClass():java.lang.Class";
2185                                 %33 : java.type:"java.lang.Class" = constant @java.type:"java.lang.Double";
2186                                 %34 : java.type:"boolean" = invoke %32 %33 @java.ref:"java.lang.Object::equals(java.lang.Object):boolean";
2187                                 yield %34;
2188                             };
2189                         yield %26;
2190                     }
2191                     ()java.type:"void" -> {
2192                         %35 : java.type:"java.lang.String" = var.load %3;
2193                         %36 : java.type:"java.lang.String" = constant @"R(Double)";
2194                         %37 : java.type:"java.lang.String" = concat %35 %36;
2195                         var.store %3 %37;
2196                         yield;
2197                     }
2198                     ()java.type:"boolean" -> {
2199                         %38 : java.type:"boolean" = constant @true;
2200                         yield %38;
2201                     }
2202                     ()java.type:"void" -> {
2203                         %39 : java.type:"java.lang.String" = var.load %3;
2204                         %40 : java.type:"java.lang.String" = constant @"else";
2205                         %41 : java.type:"java.lang.String" = concat %39 %40;
2206                         var.store %3 %41;
2207                         yield;
2208                     };
2209                 %42 : java.type:"java.lang.String" = var.load %3;
2210                 return %42;
2211             };
2212             """)
2213     @Reflect
2214     static String casePatternGuard(Object obj) {
2215         String r = "";
2216         switch (obj) {
2217             case String s when s.length() > 3 -> r += "str with length > %d".formatted(s.length());
2218             case R(Number n) when n.getClass().equals(Double.class) -> r += "R(Double)";
2219             default -> r += "else";
2220         }
2221         return r;
2222     }
2223 
2224     @IR("""
2225             func @"defaultCaseNotTheLast" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
2226                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
2227                 %2 : java.type:"java.lang.String" = constant @"";
2228                 %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2229                 %4 : java.type:"java.lang.String" = var.load %1;
2230                 java.switch.statement %4
2231                     ()java.type:"boolean" -> {
2232                         %17 : java.type:"boolean" = constant @true;
2233                         yield %17;
2234                     }
2235                     ()java.type:"void" -> {
2236                         %18 : java.type:"java.lang.String" = var.load %3;
2237                         %19 : java.type:"java.lang.String" = constant @"else";
2238                         %20 : java.type:"java.lang.String" = concat %18 %19;
2239                         var.store %3 %20;
2240                         yield;
2241                     }
2242                     (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
2243                         %6 : java.type:"java.lang.String" = constant @"M";
2244                         %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2245                         yield %7;
2246                     }
2247                     ()java.type:"void" -> {
2248                         %8 : java.type:"java.lang.String" = var.load %3;
2249                         %9 : java.type:"java.lang.String" = constant @"Mow";
2250                         %10 : java.type:"java.lang.String" = concat %8 %9;
2251                         var.store %3 %10;
2252                         yield;
2253                     }
2254                     (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
2255                         %12 : java.type:"java.lang.String" = constant @"A";
2256                         %13 : java.type:"boolean" = invoke %11 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2257                         yield %13;
2258                     }
2259                     ()java.type:"void" -> {
2260                         %14 : java.type:"java.lang.String" = var.load %3;
2261                         %15 : java.type:"java.lang.String" = constant @"Aow";
2262                         %16 : java.type:"java.lang.String" = concat %14 %15;
2263                         var.store %3 %16;
2264                         yield;
2265                     };
2266                 %21 : java.type:"java.lang.String" = var.load %3;
2267                 return %21;
2268             };
2269             """)
2270     @Reflect
2271     static String defaultCaseNotTheLast(String s) {
2272         String r = "";
2273         switch (s) {
2274             default -> r += "else";
2275             case "M" -> r += "Mow";
2276             case "A" -> r += "Aow";
2277         }
2278         return r;
2279     }
2280 
2281     @IR("""
2282             func @"f" (%0 : java.type:"int")java.type:"int" -> {
2283                   %1 : Var<java.type:"int"> = var %0 @"i";
2284                   %2 : java.type:"int" = var.load %1;
2285                   java.switch.statement %2
2286                       (%3 : java.type:"int")java.type:"boolean" -> {
2287                           %4 : java.type:"int" = constant @0;
2288                           %5 : java.type:"boolean" = eq %3 %4;
2289                           yield %5;
2290                       }
2291                       ()java.type:"void" -> {
2292                           %6 : java.type:"int" = constant @0;
2293                           return %6;
2294                       };
2295                   %7 : java.type:"int" = constant @0;
2296                   return %7;
2297               };
2298             """)
2299     @Reflect
2300     static int f(int i) {
2301         switch (i) {
2302             case 0 -> {
2303                 return 0;
2304             }
2305         }
2306         return 0;
2307     }
2308 
2309     @IR("""
2310             func @"outOfOrderFallThrought" (%0 : java.type:"int")java.type:"java.lang.String" -> {
2311                   %1 : Var<java.type:"int"> = var %0 @"i";
2312                   %2 : java.type:"java.lang.String" = constant @"";
2313                   %3 : Var<java.type:"java.lang.String"> = var %2 @"ret";
2314                   %4 : java.type:"int" = var.load %1;
2315                   java.switch.statement %4
2316                       ()java.type:"boolean" -> {
2317                           %5 : java.type:"boolean" = constant @true;
2318                           yield %5;
2319                       }
2320                       ()java.type:"void" -> {
2321                           %6 : java.type:"java.lang.String" = var.load %3;
2322                           %7 : java.type:"java.lang.String" = constant @"? ";
2323                           %8 : java.type:"java.lang.String" = concat %6 %7;
2324                           var.store %3 %8;
2325                           java.switch.fallthrough;
2326                       }
2327                       (%9 : java.type:"int")java.type:"boolean" -> {
2328                           %10 : java.type:"int" = constant @4;
2329                           %11 : java.type:"boolean" = eq %9 %10;
2330                           yield %11;
2331                       }
2332                       ()java.type:"void" -> {
2333                           %12 : java.type:"java.lang.String" = var.load %3;
2334                           %13 : java.type:"java.lang.String" = constant @"four ";
2335                           %14 : java.type:"java.lang.String" = concat %12 %13;
2336                           var.store %3 %14;
2337                           java.switch.fallthrough;
2338                       }
2339                       (%15 : java.type:"int")java.type:"boolean" -> {
2340                           %16 : java.type:"int" = constant @2;
2341                           %17 : java.type:"boolean" = eq %15 %16;
2342                           yield %17;
2343                       }
2344                       ()java.type:"void" -> {
2345                           %18 : java.type:"java.lang.String" = var.load %3;
2346                           %19 : java.type:"java.lang.String" = constant @"two ";
2347                           %20 : java.type:"java.lang.String" = concat %18 %19;
2348                           var.store %3 %20;
2349                           java.switch.fallthrough;
2350                       }
2351                       (%21 : java.type:"int")java.type:"boolean" -> {
2352                           %22 : java.type:"int" = constant @3;
2353                           %23 : java.type:"boolean" = eq %21 %22;
2354                           yield %23;
2355                       }
2356                       ()java.type:"void" -> {
2357                           %24 : java.type:"java.lang.String" = var.load %3;
2358                           %25 : java.type:"java.lang.String" = constant @"three ";
2359                           %26 : java.type:"java.lang.String" = concat %24 %25;
2360                           var.store %3 %26;
2361                           java.switch.fallthrough;
2362                       }
2363                       (%27 : java.type:"int")java.type:"boolean" -> {
2364                           %28 : java.type:"int" = constant @1;
2365                           %29 : java.type:"boolean" = eq %27 %28;
2366                           yield %29;
2367                       }
2368                       ()java.type:"void" -> {
2369                           %30 : java.type:"java.lang.String" = var.load %3;
2370                           %31 : java.type:"java.lang.String" = constant @"one";
2371                           %32 : java.type:"java.lang.String" = concat %30 %31;
2372                           var.store %3 %32;
2373                           yield;
2374                       };
2375                   %33 : java.type:"java.lang.String" = var.load %3;
2376                   return %33;
2377               };
2378             """)
2379     @Reflect
2380     static String outOfOrderFallThrought(int i) {
2381         String ret = "";
2382         switch (i) {
2383             default:
2384                 ret += "? ";
2385             case 4:
2386                 ret += "four ";
2387             case 2:
2388                 ret += "two ";
2389             case 3:
2390                 ret += "three ";
2391             case 1:
2392                 ret += "one";
2393         }
2394         return ret;
2395     }
2396 
2397     @IR("""
2398             func @"caseConstantPrimitiveWrapperSelector" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
2399                   %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
2400                   %2 : java.type:"java.lang.String" = constant @"";
2401                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2402                   %4 : java.type:"java.lang.Integer" = var.load %1;
2403                   java.switch.statement %4
2404                       (%5 : java.type:"java.lang.Integer")java.type:"boolean" -> {
2405                           %6 : java.type:"int" = invoke %5 @java.ref:"java.lang.Integer::intValue():int";
2406                           %7 : java.type:"int" = constant @1;
2407                           %8 : java.type:"boolean" = eq %6 %7;
2408                           yield %8;
2409                       }
2410                       ()java.type:"void" -> {
2411                           %9 : java.type:"java.lang.String" = var.load %3;
2412                           %10 : java.type:"java.lang.String" = constant @"one";
2413                           %11 : java.type:"java.lang.String" = concat %9 %10;
2414                           var.store %3 %11;
2415                           yield;
2416                       }
2417                       (%12 : java.type:"java.lang.Integer")java.type:"boolean" -> {
2418                           %13 : java.type:"boolean" = java.cor
2419                               ()java.type:"boolean" -> {
2420                                   %14 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
2421                                   %15 : java.type:"int" = constant @2;
2422                                   %16 : java.type:"boolean" = eq %14 %15;
2423                                   yield %16;
2424                               }
2425                               ()java.type:"boolean" -> {
2426                                   %17 : java.type:"int" = invoke %12 @java.ref:"java.lang.Integer::intValue():int";
2427                                   %18 : java.type:"int" = constant @3;
2428                                   %19 : java.type:"boolean" = eq %17 %18;
2429                                   yield %19;
2430                               };
2431                           yield %13;
2432                       }
2433                       ()java.type:"void" -> {
2434                           %20 : java.type:"java.lang.String" = var.load %3;
2435                           %21 : java.type:"java.lang.String" = constant @"two or three";
2436                           %22 : java.type:"java.lang.String" = concat %20 %21;
2437                           var.store %3 %22;
2438                           yield;
2439                       }
2440                       ()java.type:"boolean" -> {
2441                           %23 : java.type:"boolean" = constant @true;
2442                           yield %23;
2443                       }
2444                       ()java.type:"void" -> {
2445                           %24 : java.type:"java.lang.String" = var.load %3;
2446                           %25 : java.type:"java.lang.String" = constant @"else";
2447                           %26 : java.type:"java.lang.String" = concat %24 %25;
2448                           var.store %3 %26;
2449                           yield;
2450                       };
2451                   %27 : java.type:"java.lang.String" = var.load %3;
2452                   return %27;
2453               };
2454             """)
2455     @Reflect
2456     static String caseConstantPrimitiveWrapperSelector(Integer i) {
2457         String r = "";
2458         switch (i) {
2459             case 1 -> r += "one";
2460             case 2, 3 -> r += "two or three";
2461             default -> r += "else";
2462         };
2463         return r;
2464     }
2465 
2466     @IR("""
2467             func @"constantLabelCasted" (%0 : java.type:"int")java.type:"java.lang.String" -> {
2468                   %1 : Var<java.type:"int"> = var %0 @"i";
2469                   %2 : java.type:"java.lang.String" = constant @"";
2470                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2471                   %4 : java.type:"int" = var.load %1;
2472                   java.switch.statement %4
2473                       (%5 : java.type:"int")java.type:"boolean" -> {
2474                           %6 : java.type:"int" = constant @1;
2475                           %7 : java.type:"byte" = conv %6;
2476                           %8 : java.type:"int" = conv %7;
2477                           %9 : java.type:"boolean" = eq %5 %8;
2478                           yield %9;
2479                       }
2480                       ()java.type:"void" -> {
2481                           %10 : java.type:"java.lang.String" = var.load %3;
2482                           %11 : java.type:"java.lang.String" = constant @"one";
2483                           %12 : java.type:"java.lang.String" = concat %10 %11;
2484                           var.store %3 %12;
2485                           yield;
2486                       }
2487                       ()java.type:"boolean" -> {
2488                           %13 : java.type:"boolean" = constant @true;
2489                           yield %13;
2490                       }
2491                       ()java.type:"void" -> {
2492                           %14 : java.type:"java.lang.String" = var.load %3;
2493                           %15 : java.type:"java.lang.String" = constant @"not one";
2494                           %16 : java.type:"java.lang.String" = concat %14 %15;
2495                           var.store %3 %16;
2496                           yield;
2497                       };
2498                   %17 : java.type:"java.lang.String" = var.load %3;
2499                   return %17;
2500               };
2501             """)
2502     @Reflect
2503     static String constantLabelCasted(int i) {
2504         String r = "";
2505         switch (i) {
2506             case (byte) 1 -> r += "one";
2507             default -> r += "not one";
2508         };
2509         return r;
2510     }
2511 
2512     @IR("""
2513             func @"caseConstantStringLiteral" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
2514                   %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
2515                   %2 : java.type:"java.lang.String" = constant @"";
2516                   %3 : Var<java.type:"java.lang.String"> = var %2 @"r";
2517                   %4 : java.type:"java.lang.String" = var.load %1;
2518                   java.switch.statement %4
2519                       (%5 : java.type:"java.lang.String")java.type:"boolean" -> {
2520                           %6 : java.type:"java.lang.String" = constant @"1";
2521                           %7 : java.type:"boolean" = invoke %5 %6 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2522                           yield %7;
2523                       }
2524                       ()java.type:"void" -> {
2525                           %8 : java.type:"java.lang.String" = var.load %3;
2526                           %9 : java.type:"java.lang.String" = constant @"one";
2527                           %10 : java.type:"java.lang.String" = concat %8 %9;
2528                           var.store %3 %10;
2529                           yield;
2530                       }
2531                       (%11 : java.type:"java.lang.String")java.type:"boolean" -> {
2532                           %12 : java.type:"boolean" = java.cor
2533                               ()java.type:"boolean" -> {
2534                                   %13 : java.type:"java.lang.String" = constant @"2";
2535                                   %14 : java.type:"boolean" = invoke %11 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2536                                   yield %14;
2537                               }
2538                               ()java.type:"boolean" -> {
2539                                   %15 : java.type:"java.lang.String" = constant @"3";
2540                                   %16 : java.type:"boolean" = invoke %11 %15 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
2541                                   yield %16;
2542                               };
2543                           yield %12;
2544                       }
2545                       ()java.type:"void" -> {
2546                           %17 : java.type:"java.lang.String" = var.load %3;
2547                           %18 : java.type:"java.lang.String" = constant @"two or three";
2548                           %19 : java.type:"java.lang.String" = concat %17 %18;
2549                           var.store %3 %19;
2550                           yield;
2551                       }
2552                       ()java.type:"boolean" -> {
2553                           %20 : java.type:"boolean" = constant @true;
2554                           yield %20;
2555                       }
2556                       ()java.type:"void" -> {
2557                           %21 : java.type:"java.lang.String" = var.load %3;
2558                           %22 : java.type:"java.lang.String" = constant @"else";
2559                           %23 : java.type:"java.lang.String" = concat %21 %22;
2560                           var.store %3 %23;
2561                           yield;
2562                       };
2563                   %24 : java.type:"java.lang.String" = var.load %3;
2564                   return %24;
2565               };
2566             """)
2567     @Reflect
2568     static String caseConstantStringLiteral(String s) {
2569         String r = "";
2570         switch (s) {
2571             case "1" -> r += "one";
2572             case "2", "3" -> r+= "two or three";
2573             default -> r += "else";
2574         };
2575         return r;
2576     }
2577 
2578     @IR("""
2579             func @"caseBoxedGuard" (%0 : java.type:"java.lang.Object", %1 : java.type:"java.lang.Boolean")java.type:"java.lang.String" -> {
2580                 %2 : Var<java.type:"java.lang.Object"> = var %0 @"o";
2581                 %3 : Var<java.type:"java.lang.Boolean"> = var %1 @"B";
2582                 %4 : java.type:"java.lang.String" = constant @"";
2583                 %5 : Var<java.type:"java.lang.String"> = var %4 @"r";
2584                 %6 : java.type:"java.lang.Object" = var.load %2;
2585                 %7 : java.type:"java.lang.Object" = constant @null;
2586                 %8 : Var<java.type:"java.lang.Object"> = var %7;
2587                 java.switch.statement %6
2588                     (%9 : java.type:"java.lang.Object")java.type:"boolean" -> {
2589                         %10 : java.type:"boolean" = java.cand
2590                             ()java.type:"boolean" -> {
2591                                 %11 : java.type:"boolean" = pattern.match %9
2592                                     ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
2593                                         %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type;
2594                                         yield %12;
2595                                     }
2596                                     (%13 : java.type:"java.lang.Object")java.type:"void" -> {
2597                                         var.store %8 %13;
2598                                         yield;
2599                                     };
2600                                 yield %11;
2601                             }
2602                             ()java.type:"boolean" -> {
2603                                 %14 : java.type:"java.lang.Boolean" = var.load %3;
2604                                 %15 : java.type:"boolean" = invoke %14 @java.ref:"java.lang.Boolean::booleanValue():boolean";
2605                                 yield %15;
2606                             };
2607                         yield %10;
2608                     }
2609                     ()java.type:"void" -> {
2610                         %16 : java.type:"java.lang.String" = var.load %5;
2611                         %17 : java.type:"java.lang.String" = constant @"match";
2612                         %18 : java.type:"java.lang.String" = concat %16 %17;
2613                         var.store %5 %18;
2614                         yield;
2615                     }
2616                     ()java.type:"boolean" -> {
2617                         %19 : java.type:"boolean" = constant @true;
2618                         yield %19;
2619                     }
2620                     ()java.type:"void" -> {
2621                         %20 : java.type:"java.lang.String" = var.load %5;
2622                         %21 : java.type:"java.lang.String" = constant @"no match";
2623                         %22 : java.type:"java.lang.String" = concat %20 %21;
2624                         var.store %5 %22;
2625                         yield;
2626                     };
2627                 %23 : java.type:"java.lang.String" = var.load %5;
2628                 return %23;
2629             };
2630             """)
2631     @Reflect
2632     private static String caseBoxedGuard(Object o, Boolean B) {
2633         String r = "";
2634         switch (o) {
2635             case Object _ when B -> r += "match";
2636             default -> r += "no match";
2637         }
2638         return r;
2639     }
2640 
2641     @IR("""
2642         func @"caseReassignVar" (%0 : java.type:"int")java.type:"int" -> {
2643             %1 : Var<java.type:"int"> = var %0 @"sel";
2644             %2 : java.type:"int" = var.load %1;
2645             java.switch.statement %2
2646                 (%3 : java.type:"int")java.type:"boolean" -> {
2647                     %4 : java.type:"int" = constant @0;
2648                     %5 : java.type:"boolean" = eq %3 %4;
2649                     yield %5;
2650                 }
2651                 ()java.type:"void" -> {
2652                     %6 : java.type:"int" = constant @1;
2653                     %7 : Var<java.type:"int"> = var %6 @"i";
2654                     %8 : java.type:"int" = var.load %7;
2655                     return %8;
2656                 }
2657                 (%9 : java.type:"int")java.type:"boolean" -> {
2658                     %10 : java.type:"int" = constant @1;
2659                     %11 : java.type:"boolean" = eq %9 %10;
2660                     yield %11;
2661                 }
2662                 ()java.type:"void" -> {
2663                     %12 : Var<java.type:"int"> = var @"i";
2664                     %13 : java.type:"int" = constant @2;
2665                     var.store %12 %13;
2666                     %14 : java.type:"int" = var.load %12;
2667                     return %14;
2668                 }
2669                 ()java.type:"boolean" -> {
2670                     %15 : java.type:"boolean" = constant @true;
2671                     yield %15;
2672                 }
2673                 ()java.type:"void" -> {
2674                     %16 : java.type:"int" = constant @-1;
2675                     return %16;
2676                 };
2677             unreachable;
2678         };
2679         """)
2680     @Reflect
2681     private static int caseReassignVar(int sel) {
2682         switch (sel) {
2683             case 0:
2684                 int i = 1;
2685                 return i;
2686             case 1:
2687                 i = 2;
2688                 return i;
2689             default:
2690                 return -1;
2691         }
2692     }
2693 
2694     @IR("""
2695         func @"caseReassignVarFallThrough" (%0 : java.type:"int")java.type:"int" -> {
2696             %1 : Var<java.type:"int"> = var %0 @"sel";
2697             %2 : java.type:"int" = var.load %1;
2698             java.switch.statement %2
2699                 (%3 : java.type:"int")java.type:"boolean" -> {
2700                     %4 : java.type:"int" = constant @0;
2701                     %5 : java.type:"boolean" = eq %3 %4;
2702                     yield %5;
2703                 }
2704                 ()java.type:"void" -> {
2705                     %6 : java.type:"int" = constant @1;
2706                     %7 : Var<java.type:"int"> = var %6 @"i";
2707                     java.switch.fallthrough;
2708                 }
2709                 (%9 : java.type:"int")java.type:"boolean" -> {
2710                     %10 : java.type:"int" = constant @1;
2711                     %11 : java.type:"boolean" = eq %9 %10;
2712                     yield %11;
2713                 }
2714                 ()java.type:"void" -> {
2715                     %12 : Var<java.type:"int"> = var @"i";
2716                     %13 : java.type:"int" = constant @2;
2717                     var.store %12 %13;
2718                     %14 : java.type:"int" = var.load %12;
2719                     return %14;
2720                 }
2721                 ()java.type:"boolean" -> {
2722                     %15 : java.type:"boolean" = constant @true;
2723                     yield %15;
2724                 }
2725                 ()java.type:"void" -> {
2726                     %16 : java.type:"int" = constant @-1;
2727                     return %16;
2728                 };
2729             unreachable;
2730         };
2731         """)
2732     @Reflect
2733     private static int caseReassignVarFallThrough(int sel) {
2734         switch (sel) {
2735             case 0:
2736                 int i = 1;
2737             case 1:
2738                 i = 2;
2739                 return i;
2740             default:
2741                 return -1;
2742         }
2743     }
2744 
2745     @IR("""
2746         func @"caseReassignVarNested" (%0 : java.type:"int")java.type:"int" -> {
2747             %1 : Var<java.type:"int"> = var %0 @"sel";
2748             %2 : java.type:"int" = var.load %1;
2749             java.switch.statement %2
2750                 (%3 : java.type:"int")java.type:"boolean" -> {
2751                     %4 : java.type:"int" = constant @0;
2752                     %5 : java.type:"boolean" = eq %3 %4;
2753                     yield %5;
2754                 }
2755                 ()java.type:"void" -> {
2756                     %6 : java.type:"int" = constant @1;
2757                     %7 : Var<java.type:"int"> = var %6 @"i";
2758                     %8 : java.type:"int" = var.load %7;
2759                     return %8;
2760                 }
2761                 (%9 : java.type:"int")java.type:"boolean" -> {
2762                     %10 : java.type:"int" = constant @1;
2763                     %11 : java.type:"boolean" = eq %9 %10;
2764                     yield %11;
2765                 }
2766                 ()java.type:"void" -> {
2767                     %12 : Var<java.type:"int"> = var @"i";
2768                     %13 : java.type:"int" = constant @2;
2769                     var.store %12 %13;
2770                     %14 : Var<java.type:"int"> = var %13 @"j";
2771                     %15 : java.type:"int" = var.load %12;
2772                     %16 : java.type:"int" = var.load %14;
2773                     %17 : java.type:"int" = add %15 %16;
2774                     return %17;
2775                 }
2776                 ()java.type:"boolean" -> {
2777                     %18 : java.type:"boolean" = constant @true;
2778                     yield %18;
2779                 }
2780                 ()java.type:"void" -> {
2781                     %19 : java.type:"int" = constant @-1;
2782                     return %19;
2783                 };
2784             unreachable;
2785         };
2786         """)
2787     @Reflect
2788     private static int caseReassignVarNested(int sel) {
2789         switch (sel) {
2790             case 0:
2791                 int i = 1;
2792                 return i;
2793             case 1:
2794                 int j = (i = 2);
2795                 return i + j;
2796             default:
2797                 return -1;
2798         }
2799     }
2800 
2801     @IR("""
2802         func @"caseReassignVarNestedBlock" (%0 : java.type:"int")java.type:"int" -> {
2803             %1 : Var<java.type:"int"> = var %0 @"sel";
2804             %2 : java.type:"int" = var.load %1;
2805             java.switch.statement %2
2806                 (%3 : java.type:"int")java.type:"boolean" -> {
2807                     %4 : java.type:"int" = constant @0;
2808                     %5 : java.type:"boolean" = eq %3 %4;
2809                     yield %5;
2810                 }
2811                 ()java.type:"void" -> {
2812                     %6 : java.type:"int" = constant @1;
2813                     %7 : Var<java.type:"int"> = var %6 @"i";
2814                     %8 : java.type:"int" = var.load %7;
2815                     return %8;
2816                 }
2817                 (%9 : java.type:"int")java.type:"boolean" -> {
2818                     %10 : java.type:"int" = constant @1;
2819                     %11 : java.type:"boolean" = eq %9 %10;
2820                     yield %11;
2821                 }
2822                 ()java.type:"void" -> {
2823                     %12 : Var<java.type:"int"> = var @"i";
2824                     java.block ()java.type:"void" -> {
2825                         %13 : java.type:"int" = constant @2;
2826                         var.store %12 %13;
2827                         yield;
2828                     };
2829                     %14 : java.type:"int" = var.load %12;
2830                     return %14;
2831                 }
2832                 ()java.type:"boolean" -> {
2833                     %15 : java.type:"boolean" = constant @true;
2834                     yield %15;
2835                 }
2836                 ()java.type:"void" -> {
2837                     %16 : java.type:"int" = constant @-1;
2838                     return %16;
2839                 };
2840             unreachable;
2841         };
2842         """)
2843     @Reflect
2844     private static int caseReassignVarNestedBlock(int sel) {
2845         switch (sel) {
2846             case 0:
2847                 int i = 1;
2848                 return i;
2849             case 1:
2850                 {
2851                     i = 2;
2852                 }
2853                 return i;
2854             default:
2855                 return -1;
2856         }
2857     }
2858 
2859     @IR("""
2860         func @"caseReassignVarExpression" (%0 : java.type:"int")java.type:"int" -> {
2861             %1 : Var<java.type:"int"> = var %0 @"sel";
2862             %2 : java.type:"int" = var.load %1;
2863             java.switch.statement %2
2864                 (%3 : java.type:"int")java.type:"boolean" -> {
2865                     %4 : java.type:"int" = constant @0;
2866                     %5 : java.type:"boolean" = eq %3 %4;
2867                     yield %5;
2868                 }
2869                 ()java.type:"void" -> {
2870                     %6 : java.type:"int" = constant @1;
2871                     %7 : Var<java.type:"int"> = var %6 @"i";
2872                     %8 : java.type:"int" = var.load %7;
2873                     return %8;
2874                 }
2875                 (%9 : java.type:"int")java.type:"boolean" -> {
2876                     %10 : java.type:"int" = constant @1;
2877                     %11 : java.type:"boolean" = eq %9 %10;
2878                     yield %11;
2879                 }
2880                 ()java.type:"void" -> {
2881                     %12 : Var<java.type:"int"> = var @"i";
2882                     %13 : java.type:"int" = constant @2;
2883                     var.store %12 %13;
2884                     return %13;
2885                 }
2886                 ()java.type:"boolean" -> {
2887                     %14 : java.type:"boolean" = constant @true;
2888                     yield %14;
2889                 }
2890                 ()java.type:"void" -> {
2891                     %15 : java.type:"int" = constant @-1;
2892                     return %15;
2893                 };
2894             unreachable;
2895         };
2896         """)
2897     @Reflect
2898     private static int caseReassignVarExpression(int sel) {
2899         switch (sel) {
2900             case 0:
2901                 int i = 1;
2902                 return i;
2903             case 1:
2904                 return i = 2;
2905             default:
2906                 return -1;
2907         }
2908     }
2909 }