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