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