1 /*
   2  * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import jdk.incubator.code.Reflect;
  25 
  26 /*
  27  * @test
  28  * @modules jdk.incubator.code
  29  * @enablePreview
  30  * @build SwitchExpressionTest2
  31  * @build CodeReflectionTester
  32  * @run main CodeReflectionTester SwitchExpressionTest2
  33  */
  34 public class SwitchExpressionTest2 {
  35 
  36     @IR("""
  37             func @"caseConstantRuleExpression" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
  38                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
  39                 %2 : java.type:"java.lang.String" = var.load %1;
  40                 %3 : java.type:"java.lang.String" = java.switch.expression %2
  41                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
  42                         %5 : java.type:"java.lang.String" = constant @"FOO";
  43                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  44                         yield %6;
  45                     }
  46                     ()java.type:"java.lang.String" -> {
  47                         %7 : java.type:"java.lang.String" = constant @"BAR";
  48                         yield %7;
  49                     }
  50                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
  51                         %9 : java.type:"java.lang.String" = constant @"BAR";
  52                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  53                         yield %10;
  54                     }
  55                     ()java.type:"java.lang.String" -> {
  56                         %11 : java.type:"java.lang.String" = constant @"BAZ";
  57                         yield %11;
  58                     }
  59                     (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
  60                         %13 : java.type:"java.lang.String" = constant @"BAZ";
  61                         %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  62                         yield %14;
  63                     }
  64                     ()java.type:"java.lang.String" -> {
  65                         %15 : java.type:"java.lang.String" = constant @"FOO";
  66                         yield %15;
  67                     }
  68                     ()java.type:"boolean" -> {
  69                         %16 : java.type:"boolean" = constant @true;
  70                         yield %16;
  71                     }
  72                     ()java.type:"java.lang.String" -> {
  73                         %17 : java.type:"java.lang.String" = constant @"";
  74                         yield %17;
  75                     };
  76                 return %3;
  77             };
  78             """)
  79     @Reflect
  80     public static String caseConstantRuleExpression(String r) {
  81         return switch (r) {
  82             case "FOO" -> "BAR";
  83             case "BAR" -> "BAZ";
  84             case "BAZ" -> "FOO";
  85             default -> "";
  86         };
  87     }
  88 
  89     @IR("""
  90             func @"caseConstantRuleBlock" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
  91                 %1 : Var<java.type:"java.lang.String"> = var %0 @"r";
  92                 %2 : java.type:"java.lang.String" = var.load %1;
  93                 %3 : java.type:"java.lang.String" = java.switch.expression %2
  94                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
  95                         %5 : java.type:"java.lang.String" = constant @"FOO";
  96                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
  97                         yield %6;
  98                     }
  99                     ()java.type:"java.lang.String" -> {
 100                         %7 : java.type:"java.lang.String" = constant @"BAR";
 101                         java.yield %7;
 102                     }
 103                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
 104                         %9 : java.type:"java.lang.String" = constant @"BAR";
 105                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 106                         yield %10;
 107                     }
 108                     ()java.type:"java.lang.String" -> {
 109                         %11 : java.type:"java.lang.String" = constant @"BAZ";
 110                         java.yield %11;
 111                     }
 112                     (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
 113                         %13 : java.type:"java.lang.String" = constant @"BAZ";
 114                         %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 115                         yield %14;
 116                     }
 117                     ()java.type:"java.lang.String" -> {
 118                         %15 : java.type:"java.lang.String" = constant @"FOO";
 119                         java.yield %15;
 120                     }
 121                     ()java.type:"boolean" -> {
 122                         %16 : java.type:"boolean" = constant @true;
 123                         yield %16;
 124                     }
 125                     ()java.type:"java.lang.String" -> {
 126                         %17 : java.type:"java.lang.String" = constant @"";
 127                         java.yield %17;
 128                     };
 129                 return %3;
 130             };
 131             """)
 132     @Reflect
 133     public static String caseConstantRuleBlock(String r) {
 134         return switch (r) {
 135             case "FOO" -> {
 136                 yield "BAR";
 137             }
 138             case "BAR" -> {
 139                 yield "BAZ";
 140             }
 141             case "BAZ" -> {
 142                 yield "FOO";
 143             }
 144             default -> {
 145                 yield "";
 146             }
 147         };
 148     }
 149 
 150     @IR("""
 151             func @"caseConstantStatement" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 152                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 153                 %2 : java.type:"java.lang.String" = var.load %1;
 154                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 155                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
 156                         %5 : java.type:"java.lang.String" = constant @"FOO";
 157                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 158                         yield %6;
 159                     }
 160                     ()java.type:"java.lang.String" -> {
 161                         %7 : java.type:"java.lang.String" = constant @"BAR";
 162                         java.yield %7;
 163                     }
 164                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
 165                         %9 : java.type:"java.lang.String" = constant @"BAR";
 166                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 167                         yield %10;
 168                     }
 169                     ()java.type:"java.lang.String" -> {
 170                         %11 : java.type:"java.lang.String" = constant @"BAZ";
 171                         java.yield %11;
 172                     }
 173                     (%12 : java.type:"java.lang.String")java.type:"boolean" -> {
 174                         %13 : java.type:"java.lang.String" = constant @"BAZ";
 175                         %14 : java.type:"boolean" = invoke %12 %13 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 176                         yield %14;
 177                     }
 178                     ()java.type:"java.lang.String" -> {
 179                         %15 : java.type:"java.lang.String" = constant @"FOO";
 180                         java.yield %15;
 181                     }
 182                     ()java.type:"boolean" -> {
 183                         %16 : java.type:"boolean" = constant @true;
 184                         yield %16;
 185                     }
 186                     ()java.type:"java.lang.String" -> {
 187                         %17 : java.type:"java.lang.String" = constant @"";
 188                         java.yield %17;
 189                     };
 190                 return %3;
 191             };
 192             """)
 193     @Reflect
 194     private static String caseConstantStatement(String s) {
 195         return switch (s) {
 196             case "FOO": yield "BAR";
 197             case "BAR": yield "BAZ";
 198             case "BAZ": yield "FOO";
 199             default: yield "";
 200         };
 201     }
 202 
 203     @IR("""
 204             func @"caseConstantMultiLabels" (%0 : java.type:"char")java.type:"java.lang.String" -> {
 205                 %1 : Var<java.type:"char"> = var %0 @"c";
 206                 %2 : java.type:"char" = var.load %1;
 207                 %3 : java.type:"char" = invoke %2 @java.ref:"java.lang.Character::toLowerCase(char):char";
 208                 %4 : java.type:"java.lang.String" = java.switch.expression %3
 209                     (%5 : java.type:"char")java.type:"boolean" -> {
 210                         %6 : java.type:"boolean" = java.cor
 211                             ()java.type:"boolean" -> {
 212                                 %7 : java.type:"char" = constant @'a';
 213                                 %8 : java.type:"boolean" = eq %5 %7;
 214                                 yield %8;
 215                             }
 216                             ()java.type:"boolean" -> {
 217                                 %9 : java.type:"char" = constant @'e';
 218                                 %10 : java.type:"boolean" = eq %5 %9;
 219                                 yield %10;
 220                             }
 221                             ()java.type:"boolean" -> {
 222                                 %11 : java.type:"char" = constant @'i';
 223                                 %12 : java.type:"boolean" = eq %5 %11;
 224                                 yield %12;
 225                             }
 226                             ()java.type:"boolean" -> {
 227                                 %13 : java.type:"char" = constant @'o';
 228                                 %14 : java.type:"boolean" = eq %5 %13;
 229                                 yield %14;
 230                             }
 231                             ()java.type:"boolean" -> {
 232                                 %15 : java.type:"char" = constant @'u';
 233                                 %16 : java.type:"boolean" = eq %5 %15;
 234                                 yield %16;
 235                             };
 236                         yield %6;
 237                     }
 238                     ()java.type:"java.lang.String" -> {
 239                         %17 : java.type:"java.lang.String" = constant @"vowel";
 240                         java.yield %17;
 241                     }
 242                     ()java.type:"boolean" -> {
 243                         %18 : java.type:"boolean" = constant @true;
 244                         yield %18;
 245                     }
 246                     ()java.type:"java.lang.String" -> {
 247                         %19 : java.type:"java.lang.String" = constant @"consonant";
 248                         java.yield %19;
 249                     };
 250                 return %4;
 251             };
 252             """)
 253     @Reflect
 254     private static String caseConstantMultiLabels(char c) {
 255         return switch (Character.toLowerCase(c)) {
 256             case 'a', 'e', 'i', 'o', 'u': yield "vowel";
 257             default: yield "consonant";
 258         };
 259     }
 260 
 261     @IR("""
 262             func @"caseConstantThrow" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
 263                 %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
 264                 %2 : java.type:"java.lang.Integer" = var.load %1;
 265                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 266                     (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 267                         %5 : java.type:"int" = invoke %4 @java.ref:"java.lang.Integer::intValue():int";
 268                         %6 : java.type:"int" = constant @8;
 269                         %7 : java.type:"boolean" = eq %5 %6;
 270                         yield %7;
 271                     }
 272                     ()java.type:"java.lang.String" -> {
 273                         %8 : java.type:"java.lang.IllegalArgumentException" = new @java.ref:"java.lang.IllegalArgumentException::()";
 274                         throw %8;
 275                     }
 276                     (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 277                         %10 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
 278                         %11 : java.type:"int" = constant @9;
 279                         %12 : java.type:"boolean" = eq %10 %11;
 280                         yield %12;
 281                     }
 282                     ()java.type:"java.lang.String" -> {
 283                         %13 : java.type:"java.lang.String" = constant @"NINE";
 284                         yield %13;
 285                     }
 286                     ()java.type:"boolean" -> {
 287                         %14 : java.type:"boolean" = constant @true;
 288                         yield %14;
 289                     }
 290                     ()java.type:"java.lang.String" -> {
 291                         %15 : java.type:"java.lang.String" = constant @"An integer";
 292                         yield %15;
 293                     };
 294                 return %3;
 295             };
 296             """)
 297     @Reflect
 298     private static String caseConstantThrow(Integer i) {
 299         return switch (i) {
 300             case 8 -> throw new IllegalArgumentException();
 301             case 9 -> "NINE";
 302             default -> "An integer";
 303         };
 304     }
 305 
 306     @IR("""
 307             func @"caseConstantNullLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 308                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 309                 %2 : java.type:"java.lang.String" = var.load %1;
 310                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 311                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
 312                         %5 : java.type:"java.lang.Object" = constant @null;
 313                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 314                         yield %6;
 315                     }
 316                     ()java.type:"java.lang.String" -> {
 317                         %7 : java.type:"java.lang.String" = constant @"null";
 318                         yield %7;
 319                     }
 320                     ()java.type:"boolean" -> {
 321                         %8 : java.type:"boolean" = constant @true;
 322                         yield %8;
 323                     }
 324                     ()java.type:"java.lang.String" -> {
 325                         %9 : java.type:"java.lang.String" = constant @"non null";
 326                         yield %9;
 327                     };
 328                 return %3;
 329             };
 330             """)
 331     @Reflect
 332     private static String caseConstantNullLabel(String s) {
 333         return switch (s) {
 334             case null -> "null";
 335             default -> "non null";
 336         };
 337     }
 338 
 339     // @Reflect
 340     // compiler code doesn't support case null, default
 341     // @@@ support such as case and test the switch expression lowering for this case
 342     private static String caseConstantNullAndDefault(String s) {
 343         return switch (s) {
 344             case "abc" -> "alphabet";
 345             case null, default -> "null or default";
 346         };
 347     }
 348 
 349     @IR("""
 350             func @"caseConstantFallThrough" (%0 : java.type:"char")java.type:"java.lang.String" -> {
 351                 %1 : Var<java.type:"char"> = var %0 @"c";
 352                 %2 : java.type:"char" = var.load %1;
 353                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 354                     (%4 : java.type:"char")java.type:"boolean" -> {
 355                         %5 : java.type:"char" = constant @'A';
 356                         %6 : java.type:"boolean" = eq %4 %5;
 357                         yield %6;
 358                     }
 359                     ()java.type:"java.lang.String" -> {
 360                         java.switch.fallthrough;
 361                     }
 362                     (%7 : java.type:"char")java.type:"boolean" -> {
 363                         %8 : java.type:"char" = constant @'B';
 364                         %9 : java.type:"boolean" = eq %7 %8;
 365                         yield %9;
 366                     }
 367                     ()java.type:"java.lang.String" -> {
 368                         %10 : java.type:"java.lang.String" = constant @"A or B";
 369                         java.yield %10;
 370                     }
 371                     ()java.type:"boolean" -> {
 372                         %11 : java.type:"boolean" = constant @true;
 373                         yield %11;
 374                     }
 375                     ()java.type:"java.lang.String" -> {
 376                         %12 : java.type:"java.lang.String" = constant @"Neither A nor B";
 377                         java.yield %12;
 378                     };
 379                 return %3;
 380             };
 381             """)
 382     @Reflect
 383     private static String caseConstantFallThrough(char c) {
 384         return switch (c) {
 385             case 'A':
 386             case 'B':
 387                 yield "A or B";
 388             default:
 389                 yield "Neither A nor B";
 390         };
 391     }
 392 
 393     enum Day {
 394         MON, TUE, WED, THU, FRI, SAT, SUN
 395     }
 396     @IR("""
 397             func @"caseConstantEnum" (%0 : java.type:"SwitchExpressionTest2$Day")java.type:"int" -> {
 398                 %1 : Var<java.type:"SwitchExpressionTest2$Day"> = var %0 @"d";
 399                 %2 : java.type:"SwitchExpressionTest2$Day" = var.load %1;
 400                 %3 : java.type:"int" = java.switch.expression %2
 401                     (%4 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
 402                         %5 : java.type:"boolean" = java.cor
 403                             ()java.type:"boolean" -> {
 404                                 %6 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::MON:SwitchExpressionTest2$Day";
 405                                 %7 : java.type:"boolean" = eq %4 %6;
 406                                 yield %7;
 407                             }
 408                             ()java.type:"boolean" -> {
 409                                 %8 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::FRI:SwitchExpressionTest2$Day";
 410                                 %9 : java.type:"boolean" = eq %4 %8;
 411                                 yield %9;
 412                             }
 413                             ()java.type:"boolean" -> {
 414                                 %10 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SUN:SwitchExpressionTest2$Day";
 415                                 %11 : java.type:"boolean" = eq %4 %10;
 416                                 yield %11;
 417                             };
 418                         yield %5;
 419                     }
 420                     ()java.type:"int" -> {
 421                         %12 : java.type:"int" = constant @6;
 422                         yield %12;
 423                     }
 424                     (%13 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
 425                         %14 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::TUE:SwitchExpressionTest2$Day";
 426                         %15 : java.type:"boolean" = eq %13 %14;
 427                         yield %15;
 428                     }
 429                     ()java.type:"int" -> {
 430                         %16 : java.type:"int" = constant @7;
 431                         yield %16;
 432                     }
 433                     (%17 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
 434                         %18 : java.type:"boolean" = java.cor
 435                             ()java.type:"boolean" -> {
 436                                 %19 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::THU:SwitchExpressionTest2$Day";
 437                                 %20 : java.type:"boolean" = eq %17 %19;
 438                                 yield %20;
 439                             }
 440                             ()java.type:"boolean" -> {
 441                                 %21 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::SAT:SwitchExpressionTest2$Day";
 442                                 %22 : java.type:"boolean" = eq %17 %21;
 443                                 yield %22;
 444                             };
 445                         yield %18;
 446                     }
 447                     ()java.type:"int" -> {
 448                         %23 : java.type:"int" = constant @8;
 449                         yield %23;
 450                     }
 451                     (%24 : java.type:"SwitchExpressionTest2$Day")java.type:"boolean" -> {
 452                         %25 : java.type:"SwitchExpressionTest2$Day" = field.load @java.ref:"SwitchExpressionTest2$Day::WED:SwitchExpressionTest2$Day";
 453                         %26 : java.type:"boolean" = eq %24 %25;
 454                         yield %26;
 455                     }
 456                     ()java.type:"int" -> {
 457                         %27 : java.type:"int" = constant @9;
 458                         yield %27;
 459                     }
 460                     ()java.type:"boolean" -> {
 461                         %28 : java.type:"boolean" = constant @true;
 462                         yield %28;
 463                     }
 464                     ()java.type:"int" -> {
 465                         %29 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
 466                         throw %29;
 467                     };
 468                 return %3;
 469             };
 470             """)
 471     @Reflect
 472     private static int caseConstantEnum(Day d) {
 473         return switch (d) {
 474             case MON, FRI, SUN -> 6;
 475             case TUE -> 7;
 476             case THU, SAT -> 8;
 477             case WED -> 9;
 478         };
 479     }
 480 
 481     static class Constants {
 482         static final int c1 = 12;
 483     }
 484     @IR("""
 485             func @"caseConstantOtherKindsOfExpr" (%0 : java.type:"int")java.type:"java.lang.String" -> {
 486                 %1 : Var<java.type:"int"> = var %0 @"i";
 487                 %2 : java.type:"int" = constant @11;
 488                 %3 : Var<java.type:"int"> = var %2 @"eleven";
 489                 %4 : java.type:"int" = var.load %1;
 490                 %5 : java.type:"java.lang.String" = java.switch.expression %4
 491                     (%6 : java.type:"int")java.type:"boolean" -> {
 492                         %7 : java.type:"int" = constant @1;
 493                         %8 : java.type:"int" = constant @15;
 494                         %9 : java.type:"int" = and %7 %8;
 495                         %10 : java.type:"boolean" = eq %6 %9;
 496                         yield %10;
 497                     }
 498                     ()java.type:"java.lang.String" -> {
 499                         %11 : java.type:"java.lang.String" = constant @"1";
 500                         yield %11;
 501                     }
 502                     (%12 : java.type:"int")java.type:"boolean" -> {
 503                         %13 : java.type:"int" = constant @4;
 504                         %14 : java.type:"int" = constant @1;
 505                         %15 : java.type:"int" = ashr %13 %14;
 506                         %16 : java.type:"boolean" = eq %12 %15;
 507                         yield %16;
 508                     }
 509                     ()java.type:"java.lang.String" -> {
 510                         %17 : java.type:"java.lang.String" = constant @"2";
 511                         yield %17;
 512                     }
 513                     (%18 : java.type:"int")java.type:"boolean" -> {
 514                         %19 : java.type:"long" = constant @3;
 515                         %20 : java.type:"int" = conv %19;
 516                         %21 : java.type:"boolean" = eq %18 %20;
 517                         yield %21;
 518                     }
 519                     ()java.type:"java.lang.String" -> {
 520                         %22 : java.type:"java.lang.String" = constant @"3";
 521                         yield %22;
 522                     }
 523                     (%23 : java.type:"int")java.type:"boolean" -> {
 524                         %24 : java.type:"int" = constant @2;
 525                         %25 : java.type:"int" = constant @1;
 526                         %26 : java.type:"int" = lshl %24 %25;
 527                         %27 : java.type:"boolean" = eq %23 %26;
 528                         yield %27;
 529                     }
 530                     ()java.type:"java.lang.String" -> {
 531                         %28 : java.type:"java.lang.String" = constant @"4";
 532                         yield %28;
 533                     }
 534                     (%29 : java.type:"int")java.type:"boolean" -> {
 535                         %30 : java.type:"int" = constant @10;
 536                         %31 : java.type:"int" = constant @2;
 537                         %32 : java.type:"int" = div %30 %31;
 538                         %33 : java.type:"boolean" = eq %29 %32;
 539                         yield %33;
 540                     }
 541                     ()java.type:"java.lang.String" -> {
 542                         %34 : java.type:"java.lang.String" = constant @"5";
 543                         yield %34;
 544                     }
 545                     (%35 : java.type:"int")java.type:"boolean" -> {
 546                         %36 : java.type:"int" = constant @12;
 547                         %37 : java.type:"int" = constant @6;
 548                         %38 : java.type:"int" = sub %36 %37;
 549                         %39 : java.type:"boolean" = eq %35 %38;
 550                         yield %39;
 551                     }
 552                     ()java.type:"java.lang.String" -> {
 553                         %40 : java.type:"java.lang.String" = constant @"6";
 554                         yield %40;
 555                     }
 556                     (%41 : java.type:"int")java.type:"boolean" -> {
 557                         %42 : java.type:"int" = constant @3;
 558                         %43 : java.type:"int" = constant @4;
 559                         %44 : java.type:"int" = add %42 %43;
 560                         %45 : java.type:"boolean" = eq %41 %44;
 561                         yield %45;
 562                     }
 563                     ()java.type:"java.lang.String" -> {
 564                         %46 : java.type:"java.lang.String" = constant @"7";
 565                         yield %46;
 566                     }
 567                     (%47 : java.type:"int")java.type:"boolean" -> {
 568                         %48 : java.type:"int" = constant @2;
 569                         %49 : java.type:"int" = constant @2;
 570                         %50 : java.type:"int" = mul %48 %49;
 571                         %51 : java.type:"int" = constant @2;
 572                         %52 : java.type:"int" = mul %50 %51;
 573                         %53 : java.type:"boolean" = eq %47 %52;
 574                         yield %53;
 575                     }
 576                     ()java.type:"java.lang.String" -> {
 577                         %54 : java.type:"java.lang.String" = constant @"8";
 578                         yield %54;
 579                     }
 580                     (%55 : java.type:"int")java.type:"boolean" -> {
 581                         %56 : java.type:"int" = constant @8;
 582                         %57 : java.type:"int" = constant @1;
 583                         %58 : java.type:"int" = or %56 %57;
 584                         %59 : java.type:"boolean" = eq %55 %58;
 585                         yield %59;
 586                     }
 587                     ()java.type:"java.lang.String" -> {
 588                         %60 : java.type:"java.lang.String" = constant @"9";
 589                         yield %60;
 590                     }
 591                     (%61 : java.type:"int")java.type:"boolean" -> {
 592                         %62 : java.type:"int" = constant @10;
 593                         %63 : java.type:"boolean" = eq %61 %62;
 594                         yield %63;
 595                     }
 596                     ()java.type:"java.lang.String" -> {
 597                         %64 : java.type:"java.lang.String" = constant @"10";
 598                         yield %64;
 599                     }
 600                     (%65 : java.type:"int")java.type:"boolean" -> {
 601                         %66 : java.type:"int" = var.load %3;
 602                         %67 : java.type:"boolean" = eq %65 %66;
 603                         yield %67;
 604                     }
 605                     ()java.type:"java.lang.String" -> {
 606                         %68 : java.type:"java.lang.String" = constant @"11";
 607                         yield %68;
 608                     }
 609                     (%69 : java.type:"int")java.type:"boolean" -> {
 610                         %70 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
 611                         %71 : java.type:"boolean" = eq %69 %70;
 612                         yield %71;
 613                     }
 614                     ()java.type:"java.lang.String" -> {
 615                         %72 : java.type:"int" = field.load @java.ref:"SwitchExpressionTest2$Constants::c1:int";
 616                         %73 : java.type:"java.lang.String" = invoke %72 @java.ref:"java.lang.String::valueOf(int):java.lang.String";
 617                         yield %73;
 618                     }
 619                     (%74 : java.type:"int")java.type:"boolean" -> {
 620                         %75 : java.type:"int" = java.cexpression
 621                             ()java.type:"boolean" -> {
 622                                 %76 : java.type:"int" = constant @1;
 623                                 %77 : java.type:"int" = constant @0;
 624                                 %78 : java.type:"boolean" = gt %76 %77;
 625                                 yield %78;
 626                             }
 627                             ()java.type:"int" -> {
 628                                 %79 : java.type:"int" = constant @13;
 629                                 yield %79;
 630                             }
 631                             ()java.type:"int" -> {
 632                                 %80 : java.type:"int" = constant @133;
 633                                 yield %80;
 634                             };
 635                         %81 : java.type:"boolean" = eq %74 %75;
 636                         yield %81;
 637                     }
 638                     ()java.type:"java.lang.String" -> {
 639                         %82 : java.type:"java.lang.String" = constant @"13";
 640                         yield %82;
 641                     }
 642                     ()java.type:"boolean" -> {
 643                         %83 : java.type:"boolean" = constant @true;
 644                         yield %83;
 645                     }
 646                     ()java.type:"java.lang.String" -> {
 647                         %84 : java.type:"java.lang.String" = constant @"an int";
 648                         yield %84;
 649                     };
 650                 return %5;
 651             };
 652             """)
 653     @Reflect
 654     private static String caseConstantOtherKindsOfExpr(int i) {
 655         final int eleven = 11;
 656         return switch (i) {
 657             case 1 & 0xF -> "1";
 658             case 4>>1 -> "2";
 659             case (int) 3L -> "3";
 660             case 2<<1 -> "4";
 661             case 10 / 2 -> "5";
 662             case 12 - 6 -> "6";
 663             case 3 + 4 -> "7";
 664             case 2 * 2 * 2 -> "8";
 665             case 8 | 1 -> "9";
 666             case (10) -> "10";
 667             case eleven -> "11";
 668             case Constants.c1 -> String.valueOf(Constants.c1);
 669             case 1 > 0 ? 13 : 133 -> "13";
 670             default -> "an int";
 671         };
 672     }
 673 
 674     // these are the conversions that applies in switch
 675 
 676     @IR("""
 677             func @"caseConstantConv" (%0 : java.type:"short")java.type:"java.lang.String" -> {
 678                 %1 : Var<java.type:"short"> = var %0 @"a";
 679                 %2 : java.type:"int" = constant @1;
 680                 %3 : java.type:"short" = conv %2;
 681                 %4 : Var<java.type:"short"> = var %3 @"s";
 682                 %5 : java.type:"int" = constant @2;
 683                 %6 : java.type:"byte" = conv %5;
 684                 %7 : Var<java.type:"byte"> = var %6 @"b";
 685                 %8 : java.type:"short" = var.load %1;
 686                 %9 : java.type:"java.lang.String" = java.switch.expression %8
 687                     (%10 : java.type:"short")java.type:"boolean" -> {
 688                         %11 : java.type:"short" = var.load %4;
 689                         %12 : java.type:"boolean" = eq %10 %11;
 690                         yield %12;
 691                     }
 692                     ()java.type:"java.lang.String" -> {
 693                         %13 : java.type:"java.lang.String" = constant @"one";
 694                         yield %13;
 695                     }
 696                     (%14 : java.type:"short")java.type:"boolean" -> {
 697                         %15 : java.type:"byte" = var.load %7;
 698                         %16 : java.type:"short" = conv %15;
 699                         %17 : java.type:"boolean" = eq %14 %16;
 700                         yield %17;
 701                     }
 702                     ()java.type:"java.lang.String" -> {
 703                         %18 : java.type:"java.lang.String" = constant @"three";
 704                         yield %18;
 705                     }
 706                     (%19 : java.type:"short")java.type:"boolean" -> {
 707                         %20 : java.type:"int" = constant @3;
 708                         %21 : java.type:"short" = conv %20;
 709                         %22 : java.type:"boolean" = eq %19 %21;
 710                         yield %22;
 711                     }
 712                     ()java.type:"java.lang.String" -> {
 713                         %23 : java.type:"java.lang.String" = constant @"two";
 714                         yield %23;
 715                     }
 716                     ()java.type:"boolean" -> {
 717                         %24 : java.type:"boolean" = constant @true;
 718                         yield %24;
 719                     }
 720                     ()java.type:"java.lang.String" -> {
 721                         %25 : java.type:"java.lang.String" = constant @"default";
 722                         yield %25;
 723                     };
 724                 return %9;
 725             };
 726             """)
 727     @Reflect
 728     static String caseConstantConv(short a) {
 729         final short s = 1;
 730         final byte b = 2;
 731         return switch (a) {
 732             case s -> "one"; // identity
 733             case b -> "three"; // widening primitive conversion
 734             case 3 -> "two"; // narrowing primitive conversion
 735             default -> "default";
 736         };
 737     }
 738 
 739     @IR("""
 740             func @"caseConstantConv2" (%0 : java.type:"java.lang.Byte")java.type:"java.lang.String" -> {
 741                 %1 : Var<java.type:"java.lang.Byte"> = var %0 @"a";
 742                 %2 : java.type:"int" = constant @2;
 743                 %3 : java.type:"byte" = conv %2;
 744                 %4 : Var<java.type:"byte"> = var %3 @"b";
 745                 %5 : java.type:"java.lang.Byte" = var.load %1;
 746                 %6 : java.type:"java.lang.String" = java.switch.expression %5
 747                     (%7 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 748                         %8 : java.type:"byte" = invoke %7 @java.ref:"java.lang.Byte::byteValue():byte";
 749                         %9 : java.type:"int" = constant @1;
 750                         %10 : java.type:"byte" = conv %9;
 751                         %11 : java.type:"boolean" = eq %8 %10;
 752                         yield %11;
 753                     }
 754                     ()java.type:"java.lang.String" -> {
 755                         %11 : java.type:"java.lang.String" = constant @"one";
 756                         yield %11;
 757                     }
 758                     (%13 : java.type:"java.lang.Byte")java.type:"boolean" -> {
 759                         %14 : java.type:"byte" = invoke %13 @java.ref:"java.lang.Byte::byteValue():byte";
 760                         %15 : java.type:"byte" = var.load %4;
 761                         %16 : java.type:"boolean" = eq %14 %15;
 762                         yield %16;
 763                     }
 764                     ()java.type:"java.lang.String" -> {
 765                         %17 : java.type:"java.lang.String" = constant @"two";
 766                         yield %17;
 767                     }
 768                     ()java.type:"boolean" -> {
 769                         %18 : java.type:"boolean" = constant @true;
 770                         yield %18;
 771                     }
 772                     ()java.type:"java.lang.String" -> {
 773                         %19 : java.type:"java.lang.String" = constant @"default";
 774                         yield %19;
 775                     };
 776                 return %6;
 777             };
 778             """)
 779     @Reflect
 780     static String caseConstantConv2(Byte a) {
 781         final byte b = 2;
 782         return switch (a) {
 783             // narrowing conv is missing in the code model
 784             case 1 -> "one"; // narrowing primitive conversion followed by a boxing conversion
 785             case b -> "two"; // boxing
 786             default -> "default";
 787         };
 788     }
 789 
 790     enum E { F, G }
 791     @IR("""
 792             func @"noDefaultLabelEnum" (%0 : java.type:"SwitchExpressionTest2$E")java.type:"java.lang.String" -> {
 793                 %1 : Var<java.type:"SwitchExpressionTest2$E"> = var %0 @"e";
 794                 %2 : java.type:"SwitchExpressionTest2$E" = var.load %1;
 795                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 796                     (%4 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
 797                         %5 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::F:SwitchExpressionTest2$E";
 798                         %6 : java.type:"boolean" = eq %4 %5;
 799                         yield %6;
 800                     }
 801                     ()java.type:"java.lang.String" -> {
 802                         %7 : java.type:"java.lang.String" = constant @"f";
 803                         yield %7;
 804                     }
 805                     (%8 : java.type:"SwitchExpressionTest2$E")java.type:"boolean" -> {
 806                         %9 : java.type:"SwitchExpressionTest2$E" = field.load @java.ref:"SwitchExpressionTest2$E::G:SwitchExpressionTest2$E";
 807                         %10 : java.type:"boolean" = eq %8 %9;
 808                         yield %10;
 809                     }
 810                     ()java.type:"java.lang.String" -> {
 811                         %11 : java.type:"java.lang.String" = constant @"g";
 812                         yield %11;
 813                     }
 814                     ()java.type:"boolean" -> {
 815                         %12 : java.type:"boolean" = constant @true;
 816                         yield %12;
 817                     }
 818                     ()java.type:"java.lang.String" -> {
 819                         %13 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
 820                         throw %13;
 821                     };
 822                 return %3;
 823             };
 824             """)
 825     @Reflect
 826     static String noDefaultLabelEnum(E e) {
 827         return switch (e) {
 828             case F -> "f";
 829             case G -> "g";
 830         };
 831     }
 832 
 833     @IR("""
 834             func @"unconditionalPattern" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 835                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 836                 %2 : java.type:"java.lang.String" = var.load %1;
 837                 %3 : java.type:"java.lang.Object" = constant @null;
 838                 %4 : Var<java.type:"java.lang.Object"> = var %3 @"o";
 839                 %5 : java.type:"java.lang.String" = java.switch.expression %2
 840                     (%6 : java.type:"java.lang.String")java.type:"boolean" -> {
 841                         %7 : java.type:"java.lang.String" = constant @"A";
 842                         %8 : java.type:"boolean" = invoke %6 %7 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 843                         yield %8;
 844                     }
 845                     ()java.type:"java.lang.String" -> {
 846                         %9 : java.type:"java.lang.String" = constant @"Alphabet";
 847                         yield %9;
 848                     }
 849                     (%10 : java.type:"java.lang.String")java.type:"boolean" -> {
 850                         %11 : java.type:"boolean" = pattern.match %10
 851                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" -> {
 852                                 %12 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Object>" = pattern.type @"o";
 853                                 yield %12;
 854                             }
 855                             (%13 : java.type:"java.lang.Object")java.type:"void" -> {
 856                                 var.store %4 %13;
 857                                 yield;
 858                             };
 859                         yield %11;
 860                     }
 861                     ()java.type:"java.lang.String" -> {
 862                         %14 : java.type:"java.lang.String" = constant @"default";
 863                         yield %14;
 864                     };
 865                 return %5;
 866             };
 867             """)
 868     @Reflect
 869     static String unconditionalPattern(String s) {
 870         return switch (s) {
 871             case "A" -> "Alphabet";
 872             case Object o -> "default";
 873         };
 874     }
 875 
 876     sealed interface A permits B, C {}
 877     record B() implements A {}
 878     final class C implements A {}
 879     @IR("""
 880             func @"noDefault" (%0 : java.type:"SwitchExpressionTest2$A")java.type:"java.lang.String" -> {
 881                 %1 : Var<java.type:"SwitchExpressionTest2$A"> = var %0 @"a";
 882                 %2 : java.type:"SwitchExpressionTest2$A" = var.load %1;
 883                 %3 : java.type:"SwitchExpressionTest2$B" = constant @null;
 884                 %4 : Var<java.type:"SwitchExpressionTest2$B"> = var %3 @"b";
 885                 %5 : java.type:"SwitchExpressionTest2::C" = constant @null;
 886                 %6 : Var<java.type:"SwitchExpressionTest2::C"> = var %5 @"c";
 887                 %7 : java.type:"java.lang.String" = java.switch.expression %2
 888                     (%8 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
 889                         %9 : java.type:"boolean" = pattern.match %8
 890                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" -> {
 891                                 %10 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2$B>" = pattern.type @"b";
 892                                 yield %10;
 893                             }
 894                             (%11 : java.type:"SwitchExpressionTest2$B")java.type:"void" -> {
 895                                 var.store %4 %11;
 896                                 yield;
 897                             };
 898                         yield %9;
 899                     }
 900                     ()java.type:"java.lang.String" -> {
 901                         %12 : java.type:"java.lang.String" = constant @"B";
 902                         yield %12;
 903                     }
 904                     (%13 : java.type:"SwitchExpressionTest2$A")java.type:"boolean" -> {
 905                         %14 : java.type:"boolean" = pattern.match %13
 906                             ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" -> {
 907                                 %15 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<SwitchExpressionTest2::C>" = pattern.type @"c";
 908                                 yield %15;
 909                             }
 910                             (%16 : java.type:"SwitchExpressionTest2::C")java.type:"void" -> {
 911                                 var.store %6 %16;
 912                                 yield;
 913                             };
 914                         yield %14;
 915                     }
 916                     ()java.type:"java.lang.String" -> {
 917                         %17 : java.type:"java.lang.String" = constant @"C";
 918                         yield %17;
 919                     }
 920                     ()java.type:"boolean" -> {
 921                         %18 : java.type:"boolean" = constant @true;
 922                         yield %18;
 923                     }
 924                     ()java.type:"java.lang.String" -> {
 925                         %19 : java.type:"java.lang.MatchException" = new @java.ref:"java.lang.MatchException::()";
 926                         throw %19;
 927                     };
 928                 return %7;
 929             };
 930             """)
 931     @Reflect
 932     static String noDefault(A a) {
 933         return switch (a) {
 934             case B b -> "B";
 935             case C c -> "C";
 936         };
 937     }
 938 
 939     @IR("""
 940             func @"defaultNotTheLastLabel" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
 941                 %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
 942                 %2 : java.type:"java.lang.String" = var.load %1;
 943                 %3 : java.type:"java.lang.String" = java.switch.expression %2
 944                     ()java.type:"boolean" -> {
 945                         %12 : java.type:"boolean" = constant @true;
 946                         yield %12;
 947                     }
 948                     ()java.type:"java.lang.String" -> {
 949                         %13 : java.type:"java.lang.String" = constant @"else";
 950                         yield %13;
 951                     }
 952                     (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
 953                         %5 : java.type:"java.lang.String" = constant @"M";
 954                         %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 955                         yield %6;
 956                     }
 957                     ()java.type:"java.lang.String" -> {
 958                         %7 : java.type:"java.lang.String" = constant @"Mow";
 959                         yield %7;
 960                     }
 961                     (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
 962                         %9 : java.type:"java.lang.String" = constant @"A";
 963                         %10 : java.type:"boolean" = invoke %8 %9 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
 964                         yield %10;
 965                     }
 966                     ()java.type:"java.lang.String" -> {
 967                         %11 : java.type:"java.lang.String" = constant @"Aow";
 968                         yield %11;
 969                     };
 970                 return %3;
 971             };
 972             """)
 973     @Reflect
 974     static String defaultNotTheLastLabel(String s) {
 975         return switch (s) {
 976             default -> "else";
 977             case "M" -> "Mow";
 978             case "A" -> "Aow";
 979         };
 980     }
 981 
 982     @IR("""
 983             func @"caseConstantPrimitiveWrapperSelector" (%0 : java.type:"java.lang.Integer")java.type:"java.lang.String" -> {
 984                   %1 : Var<java.type:"java.lang.Integer"> = var %0 @"i";
 985                   %2 : java.type:"java.lang.Integer" = var.load %1;
 986                   %3 : java.type:"java.lang.String" = java.switch.expression %2
 987                       (%4 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 988                           %5 : java.type:"int" = invoke %4 @java.ref:"java.lang.Integer::intValue():int";
 989                           %6 : java.type:"int" = constant @1;
 990                           %7 : java.type:"boolean" = eq %5 %6;
 991                           yield %7;
 992                       }
 993                       ()java.type:"java.lang.String" -> {
 994                           %8 : java.type:"java.lang.String" = constant @"one";
 995                           yield %8;
 996                       }
 997                       (%9 : java.type:"java.lang.Integer")java.type:"boolean" -> {
 998                           %10 : java.type:"boolean" = java.cor
 999                               ()java.type:"boolean" -> {
1000                                   %11 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1001                                   %12 : java.type:"int" = constant @2;
1002                                   %13 : java.type:"boolean" = eq %11 %12;
1003                                   yield %13;
1004                               }
1005                               ()java.type:"boolean" -> {
1006                                   %14 : java.type:"int" = invoke %9 @java.ref:"java.lang.Integer::intValue():int";
1007                                   %15 : java.type:"int" = constant @3;
1008                                   %16 : java.type:"boolean" = eq %14 %15;
1009                                   yield %16;
1010                               };
1011                           yield %10;
1012                       }
1013                       ()java.type:"java.lang.String" -> {
1014                           %17 : java.type:"java.lang.String" = constant @"two or three";
1015                           yield %17;
1016                       }
1017                       ()java.type:"boolean" -> {
1018                           %18 : java.type:"boolean" = constant @true;
1019                           yield %18;
1020                       }
1021                       ()java.type:"java.lang.String" -> {
1022                           %19 : java.type:"java.lang.String" = constant @"else";
1023                           yield %19;
1024                       };
1025                   return %3;
1026             };
1027             """)
1028     @Reflect
1029     static String caseConstantPrimitiveWrapperSelector(Integer i) {
1030         return switch (i) {
1031             case 1 -> "one";
1032             case 2, 3 -> "two or three";
1033             default -> "else";
1034         };
1035     }
1036 
1037     @IR("""
1038             func @"constantLabelCasted" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1039                   %1 : Var<java.type:"int"> = var %0 @"i";
1040                   %2 : java.type:"int" = var.load %1;
1041                   %3 : java.type:"java.lang.String" = java.switch.expression %2
1042                       (%4 : java.type:"int")java.type:"boolean" -> {
1043                           %5 : java.type:"int" = constant @1;
1044                           %6 : java.type:"byte" = conv %5;
1045                           %7 : java.type:"int" = conv %6;
1046                           %8 : java.type:"boolean" = eq %4 %7;
1047                           yield %8;
1048                       }
1049                       ()java.type:"java.lang.String" -> {
1050                           %9 : java.type:"java.lang.String" = constant @"one";
1051                           yield %9;
1052                       }
1053                       ()java.type:"boolean" -> {
1054                           %10 : java.type:"boolean" = constant @true;
1055                           yield %10;
1056                       }
1057                       ()java.type:"java.lang.String" -> {
1058                           %11 : java.type:"java.lang.String" = constant @"not one";
1059                           yield %11;
1060                       };
1061                   return %3;
1062               };
1063             """)
1064     @Reflect
1065     static String constantLabelCasted(int i) {
1066         return switch (i) {
1067             case (byte) 1 -> "one";
1068             default -> "not one";
1069         };
1070     }
1071 
1072     @IR("""
1073             func @"caseConstantStringLiteral" (%0 : java.type:"java.lang.String")java.type:"java.lang.String" -> {
1074                   %1 : Var<java.type:"java.lang.String"> = var %0 @"s";
1075                   %2 : java.type:"java.lang.String" = var.load %1;
1076                   %3 : java.type:"java.lang.String" = java.switch.expression %2
1077                       (%4 : java.type:"java.lang.String")java.type:"boolean" -> {
1078                           %5 : java.type:"java.lang.String" = constant @"1";
1079                           %6 : java.type:"boolean" = invoke %4 %5 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1080                           yield %6;
1081                       }
1082                       ()java.type:"java.lang.String" -> {
1083                           %7 : java.type:"java.lang.String" = constant @"one";
1084                           yield %7;
1085                       }
1086                       (%8 : java.type:"java.lang.String")java.type:"boolean" -> {
1087                           %9 : java.type:"boolean" = java.cor
1088                               ()java.type:"boolean" -> {
1089                                   %10 : java.type:"java.lang.String" = constant @"2";
1090                                   %11 : java.type:"boolean" = invoke %8 %10 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1091                                   yield %11;
1092                               }
1093                               ()java.type:"boolean" -> {
1094                                   %12 : java.type:"java.lang.String" = constant @"3";
1095                                   %13 : java.type:"boolean" = invoke %8 %12 @java.ref:"java.util.Objects::equals(java.lang.Object, java.lang.Object):boolean";
1096                                   yield %13;
1097                               };
1098                           yield %9;
1099                       }
1100                       ()java.type:"java.lang.String" -> {
1101                           %14 : java.type:"java.lang.String" = constant @"two or three";
1102                           yield %14;
1103                       }
1104                       ()java.type:"boolean" -> {
1105                           %15 : java.type:"boolean" = constant @true;
1106                           yield %15;
1107                       }
1108                       ()java.type:"java.lang.String" -> {
1109                           %16 : java.type:"java.lang.String" = constant @"else";
1110                           yield %16;
1111                       };
1112                   return %3;
1113               };
1114             """)
1115     @Reflect
1116     static String caseConstantStringLiteral(String s) {
1117         return switch (s) {
1118             case "1" -> "one";
1119             case "2", "3" -> "two or three";
1120             default -> "else";
1121         };
1122     }
1123 
1124     @IR("""
1125             func @"casePatternWithCaseConstant" (%0 : java.type:"int")java.type:"java.lang.String" -> {
1126                   %1 : Var<java.type:"int"> = var %0 @"i";
1127                   %2 : java.type:"int" = var.load %1;
1128                   %3 : java.type:"java.lang.Integer" = constant @null;
1129                   %4 : Var<java.type:"java.lang.Integer"> = var %3 @"j";
1130                   %5 : java.type:"java.lang.Integer" = constant @null;
1131                   %6 : Var<java.type:"java.lang.Integer"> = var %5;
1132                   %7 : java.type:"java.lang.String" = java.switch.expression %2
1133                       (%8 : java.type:"int")java.type:"boolean" -> {
1134                           %9 : java.type:"int" = constant @0;
1135                           %10 : java.type:"boolean" = eq %8 %9;
1136                           yield %10;
1137                       }
1138                       ()java.type:"java.lang.String" -> {
1139                           %11 : java.type:"java.lang.String" = constant @"zero";
1140                           yield %11;
1141                       }
1142                       (%12 : java.type:"int")java.type:"boolean" -> {
1143                           %13 : java.type:"boolean" = java.cand
1144                               ()java.type:"boolean" -> {
1145                                   %14 : java.type:"java.lang.Integer" = invoke %12 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1146                                   %15 : java.type:"boolean" = pattern.match %14
1147                                       ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1148                                           %16 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type @"j";
1149                                           yield %16;
1150                                       }
1151                                       (%17 : java.type:"java.lang.Integer")java.type:"void" -> {
1152                                           var.store %4 %17;
1153                                           yield;
1154                                       };
1155                                   yield %15;
1156                               }
1157                               ()java.type:"boolean" -> {
1158                                   %18 : java.type:"java.lang.Integer" = var.load %4;
1159                                   %19 : java.type:"int" = invoke %18 @java.ref:"java.lang.Integer::intValue():int";
1160                                   %20 : java.type:"int" = constant @0;
1161                                   %21 : java.type:"boolean" = gt %19 %20;
1162                                   yield %21;
1163                               };
1164                           yield %13;
1165                       }
1166                       ()java.type:"java.lang.String" -> {
1167                           %22 : java.type:"java.lang.String" = constant @"positive";
1168                           yield %22;
1169                       }
1170                       (%23 : java.type:"int")java.type:"boolean" -> {
1171                           %24 : java.type:"java.lang.Integer" = invoke %23 @java.ref:"java.lang.Integer::valueOf(int):java.lang.Integer";
1172                           %25 : java.type:"boolean" = pattern.match %24
1173                               ()java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" -> {
1174                                   %26 : java.type:"jdk.incubator.code.dialect.java.JavaOp$Pattern$Type<java.lang.Integer>" = pattern.type;
1175                                   yield %26;
1176                               }
1177                               (%27 : java.type:"java.lang.Integer")java.type:"void" -> {
1178                                   var.store %6 %27;
1179                                   yield;
1180                               };
1181                           yield %25;
1182                       }
1183                       ()java.type:"java.lang.String" -> {
1184                           %28 : java.type:"java.lang.String" = constant @"negative";
1185                           yield %28;
1186                       };
1187                   return %7;
1188               };
1189             """)
1190     @Reflect
1191     static String casePatternWithCaseConstant(int i) {
1192         return switch (i) {
1193             case 0 -> "zero";
1194             case Integer j when j > 0 -> "positive";
1195             case Integer _ -> "negative";
1196         };
1197     }
1198 }