Support typeSwitch on primitive types

Change-Id: If3931bcbbe5045ee205fae01f8975bae06c80e48
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 02d0092..6fab82f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -897,6 +897,17 @@
     return syntheticNaming;
   }
 
+  public final Map<String, DexType> primitiveDescriptorToType =
+      ImmutableMap.of(
+          byteDescriptor.toString(), byteType,
+          charDescriptor.toString(), charType,
+          shortDescriptor.toString(), shortType,
+          intDescriptor.toString(), intType,
+          longDescriptor.toString(), longType,
+          floatDescriptor.toString(), floatType,
+          doubleDescriptor.toString(), doubleType,
+          booleanDescriptor.toString(), booleanType);
+
   public final BiMap<DexType, DexType> primitiveToBoxed = HashBiMap.create(
       ImmutableMap.<DexType, DexType>builder()
           .put(booleanType, boxedBooleanType)
@@ -1898,6 +1909,12 @@
             constantBootstrapsType,
             createProto(objectType, methodHandlesLookupType, stringType, classType),
             "getStaticFinal");
+
+    public final DexMethod primitiveClass =
+        createMethod(
+            constantBootstrapsType,
+            createProto(classType, methodHandlesLookupType, stringType, classType),
+            "primitiveClass");
   }
 
   public class BufferMembers {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
index 5c36c18..41873b4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/LibraryConstantDynamic.java
@@ -45,6 +45,25 @@
             constantDynamic.getBootstrapMethodArguments().get(0), methodHandleMethod);
   }
 
+  public static boolean isPrimitiveClassConstantDynamic(
+      ConstantDynamicReference constantDynamic, DexItemFactory factory) {
+    DexMethod bootstrapMethod = factory.constantBootstrapsMembers.primitiveClass;
+    return constantDynamic.getType().isIdenticalTo(factory.classType)
+        && constantDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
+        && constantDynamic.getBootstrapMethodArguments().size() == 0;
+  }
+
+  public static DexType extractPrimitiveClassConstantDynamic(
+      ConstantDynamicReference constantDynamic, DexItemFactory factory, Definition context) {
+    assert isPrimitiveClassConstantDynamic(constantDynamic, factory);
+    String name = constantDynamic.getName().toString();
+    DexType primitiveType = factory.primitiveDescriptorToType.get(name);
+    if (primitiveType == null) {
+      throw throwInvalidLibraryConstantDynamic("Invalid primitive type" + name, context);
+    }
+    return primitiveType;
+  }
+
   public static boolean isBoxedBooleanConstantDynamic(
       ConstantDynamicReference constantDynamic, DexItemFactory factory) {
     DexMethod bootstrapMethod = factory.constantBootstrapsMembers.getStaticFinal;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
index 7934c56..5bf900b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/SwitchHelperGenerator.java
@@ -105,7 +105,7 @@
           () -> {
             DexItemFactory factory = appView.dexItemFactory();
             DexType arg0Type = dexCallSite.methodProto.getParameter(0);
-            if (allowsInlinedIntegerEquality(arg0Type, factory)) {
+            if (arg0Type.isPrimitiveType() || allowsInlinedIntegerEquality(arg0Type, factory)) {
               return;
             }
             intEq = generateIntEqMethod(context, eventConsumer, methodProcessingContext);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
index c0b0146..8961590 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
@@ -6,8 +6,10 @@
 
 import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.dispatchEnumDescConstantDynamic;
 import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.extractBoxedBooleanConstantDynamic;
+import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.extractPrimitiveClassConstantDynamic;
 import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isBoxedBooleanConstantDynamic;
 import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isEnumDescConstantDynamic;
+import static com.android.tools.r8.ir.desugar.constantdynamic.LibraryConstantDynamic.isPrimitiveClassConstantDynamic;
 import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isEnumSwitchCallSite;
 import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isTypeSwitchCallSite;
 
@@ -225,9 +227,14 @@
         if (isBoxedBooleanConstantDynamic(constDynamic, factory)) {
           booleanConsumer.accept(
               extractBoxedBooleanConstantDynamic(constDynamic, factory, context));
-        } else {
-          assert isEnumDescConstantDynamic(constDynamic, factory);
+        } else if (isEnumDescConstantDynamic(constDynamic, factory)) {
           dispatchEnumDescConstantDynamic(constDynamic, factory, context, enumConsumer);
+        } else if (isPrimitiveClassConstantDynamic(constDynamic, factory)) {
+          dexTypeConsumer.accept(
+              extractPrimitiveClassConstantDynamic(constDynamic, factory, context));
+        } else {
+          throw new CompilationError(
+              "Invalid constant dynamic for type switch" + dexValue, context.getOrigin());
         }
       } else if (dexValue.isDexValueNumber()) {
         assert dexValue.isDexValueDouble()
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
index 67e4928..fcea7ca 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.synthetic;
 
+import com.android.tools.r8.cf.code.CfCmp;
 import com.android.tools.r8.cf.code.CfConstNull;
 import com.android.tools.r8.cf.code.CfConstNumber;
 import com.android.tools.r8.cf.code.CfConstString;
@@ -34,7 +35,9 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.DexValue.DexValueNumber;
+import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.IfType;
+import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.code.ValueType;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.IntBox;
@@ -86,19 +89,16 @@
 
   @Override
   public CfCode generateCfCode() {
-    // arg 0: Object obj
+    // arg 0: Object|primitive obj
     // arg 1: int restart
+    boolean isPrimitiveSwitch = arg0Type.isPrimitiveType();
     DexItemFactory factory = appView.dexItemFactory();
     List<CfInstruction> instructions = new ArrayList<>();
 
-    CfFrame frame =
-        CfFrame.builder()
-            .appendLocal(FrameType.initialized(arg0Type))
-            .appendLocal(FrameType.intType())
-            .build();
+    CfFrame frame = computeCfFrame();
 
     // Objects.checkIndex(restart, length + 1);
-    instructions.add(new CfLoad(ValueType.INT, 1));
+    instructions.add(loadArg1());
     instructions.add(new CfConstNumber(bootstrapArgs.size() + 1, ValueType.INT));
     DexMethod checkIndex =
         factory.createMethod(
@@ -108,14 +108,16 @@
     instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, checkIndex, false));
     instructions.add(new CfStackInstruction(Opcode.Pop));
 
-    // if (obj == null) { return -1; }
-    instructions.add(new CfLoad(ValueType.OBJECT, 0));
-    CfLabel nonNull = new CfLabel();
-    instructions.add(new CfIf(IfType.NE, ValueType.OBJECT, nonNull));
-    instructions.add(new CfConstNumber(-1, ValueType.INT));
-    instructions.add(new CfReturn(ValueType.INT));
-    instructions.add(nonNull);
-    instructions.add(frame);
+    if (!isPrimitiveSwitch) {
+      // if (obj == null) { return -1; }
+      instructions.add(loadArg0());
+      CfLabel nonNull = new CfLabel();
+      instructions.add(new CfIf(IfType.NE, ValueType.OBJECT, nonNull));
+      instructions.add(new CfConstNumber(-1, ValueType.INT));
+      instructions.add(new CfReturn(ValueType.INT));
+      instructions.add(nonNull);
+      instructions.add(frame);
+    }
 
     // If no cases, return 0;
     if (bootstrapArgs.isEmpty()) {
@@ -130,7 +132,7 @@
       cfLabels.add(new CfLabel());
     }
     cfLabels.add(defaultLabel);
-    instructions.add(new CfLoad(ValueType.INT, 1));
+    instructions.add(loadArg1());
     instructions.add(new CfSwitch(Kind.TABLE, defaultLabel, new int[] {0}, cfLabels));
 
     IntBox index = new IntBox(0);
@@ -142,18 +144,27 @@
                 dexType -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
-                  instructions.add(new CfInstanceOf(dexType));
-                  instructions.add(
-                      new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  if (!isPrimitiveSwitch) {
+                    instructions.add(loadArg0());
+                    instructions.add(new CfInstanceOf(dexType));
+                    instructions.add(
+                        new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  } else {
+                    // TODO(b/399808482): Investigate primitive downcast, i.e., an int being
+                    //  instanceof a byte, short or char.
+                  }
                   instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
                   instructions.add(new CfReturn(ValueType.INT));
                 },
                 intValue -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
-                  if (allowsInlinedIntegerEquality(arg0Type, factory)) {
+                  instructions.add(loadArg0());
+                  if (isPrimitiveSwitch) {
+                    instructions.add(new CfConstNumber(intValue, ValueType.INT));
+                    instructions.add(
+                        new CfIfCmp(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  } else if (allowsInlinedIntegerEquality(arg0Type, factory)) {
                     instructions.add(
                         new CfInvoke(
                             Opcodes.INVOKEVIRTUAL,
@@ -167,7 +178,7 @@
                     assert intEq != null;
                     instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, intEq, false));
                     instructions.add(
-                        new CfIf(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+                        new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
                   }
                   instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
                   instructions.add(new CfReturn(ValueType.INT));
@@ -175,7 +186,7 @@
                 dexString -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
+                  instructions.add(loadArg0());
                   instructions.add(new CfConstString(dexString));
                   instructions.add(
                       new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
@@ -190,7 +201,7 @@
                   // TODO(b/399808482): In R8 release, we can analyze at compile-time program enum
                   //  and generate a fast check based on the field. But these information are not
                   //  available in Cf instructions.
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
+                  instructions.add(loadArg0());
                   // TODO(b/399808482): Temporary work-around so we can roll to google3.
                   DexField field = getEnumField(enumField, type, appView);
                   if (field == null) {
@@ -229,41 +240,63 @@
                 bool -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
-                  instructions.add(new CfConstNumber(BooleanUtils.intValue(bool), ValueType.INT));
-                  instructions.add(
-                      new CfInvoke(Opcodes.INVOKESTATIC, factory.booleanMembers.valueOf, false));
-                  instructions.add(
-                      new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
-                  instructions.add(
-                      new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  instructions.add(loadArg0());
+                  if (isPrimitiveSwitch) {
+                    instructions.add(
+                        new CfIf(
+                            bool ? IfType.EQ : IfType.NE,
+                            ValueType.INT,
+                            cfLabels.get(index.get() + 1)));
+                  } else {
+                    instructions.add(new CfConstNumber(BooleanUtils.intValue(bool), ValueType.INT));
+                    instructions.add(
+                        new CfInvoke(Opcodes.INVOKESTATIC, factory.booleanMembers.valueOf, false));
+                    instructions.add(
+                        new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
+                    instructions.add(
+                        new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  }
                   instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
                   instructions.add(new CfReturn(ValueType.INT));
                 },
                 dexNumber -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
-                  instructions.add(new CfLoad(ValueType.OBJECT, 0));
+                  instructions.add(loadArg0());
                   if (dexNumber.isDexValueFloat()) {
                     instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.FLOAT));
-                    instructions.add(
-                        new CfInvoke(Opcodes.INVOKESTATIC, factory.floatMembers.valueOf, false));
                   } else if (dexNumber.isDexValueDouble()) {
                     instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.DOUBLE));
-                    instructions.add(
-                        new CfInvoke(Opcodes.INVOKESTATIC, factory.doubleMembers.valueOf, false));
                   } else if (dexNumber.isDexValueLong()) {
                     instructions.add(new CfConstNumber(dexNumber.getRawValue(), ValueType.LONG));
-                    instructions.add(
-                        new CfInvoke(Opcodes.INVOKESTATIC, factory.longMembers.valueOf, false));
                   } else {
                     throw new CompilationError(
                         "Unexpected dexNumber in type switch desugaring " + dexNumber);
                   }
-                  instructions.add(
-                      new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
-                  instructions.add(
-                      new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  if (isPrimitiveSwitch) {
+                    instructions.add(
+                        new CfCmp(
+                            arg0Type.isLongType() ? Bias.NONE : Bias.GT,
+                            NumericType.fromDexType(arg0Type)));
+                    instructions.add(
+                        new CfIf(IfType.NE, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  } else {
+                    if (dexNumber.isDexValueFloat()) {
+                      instructions.add(
+                          new CfInvoke(Opcodes.INVOKESTATIC, factory.floatMembers.valueOf, false));
+                    } else if (dexNumber.isDexValueDouble()) {
+                      instructions.add(
+                          new CfInvoke(Opcodes.INVOKESTATIC, factory.doubleMembers.valueOf, false));
+                    } else {
+                      assert dexNumber.isDexValueLong();
+                      instructions.add(
+                          new CfInvoke(Opcodes.INVOKESTATIC, factory.longMembers.valueOf, false));
+                    }
+                    instructions.add(
+                        new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.equals, false));
+                    instructions.add(
+                        new CfIf(IfType.EQ, ValueType.INT, cfLabels.get(index.get() + 1)));
+                  }
                   instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
                   instructions.add(new CfReturn(ValueType.INT));
                 }));
@@ -292,6 +325,30 @@
     return dexEncodedField.getReference();
   }
 
+  private CfLoad loadArg1() {
+    return new CfLoad(ValueType.INT, arg0Type.isWideType() ? 2 : 1);
+  }
+
+  private CfLoad loadArg0() {
+    return new CfLoad(ValueType.fromDexType(arg0Type), 0);
+  }
+
+  private CfFrame computeCfFrame() {
+    DexType frameType =
+        arg0Type.isByteType()
+                || arg0Type.isShortType()
+                || arg0Type.isCharType()
+                || arg0Type.isBooleanType()
+            ? appView.dexItemFactory().intType
+            : arg0Type;
+    CfFrame frame =
+        CfFrame.builder()
+            .appendLocal(FrameType.initialized(frameType))
+            .appendLocal(FrameType.intType())
+            .build();
+    return frame;
+  }
+
   public static boolean allowsInlinedIntegerEquality(DexType arg0Type, DexItemFactory factory) {
     return arg0Type.isIdenticalTo(factory.boxedByteType)
         || arg0Type.isIdenticalTo(factory.boxedCharType)
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java
new file mode 100644
index 0000000..e85f7fb
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMainDump.java
@@ -0,0 +1,1161 @@
+// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.java23.switchpatternmatching;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ConstantDynamic;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.RecordComponentVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * This is generated as a dump since the Main class has to be javac compiled withg --enable-preview.
+ *
+ * <p>Dump generated from:
+ *
+ * <pre>
+ * package com.android.tools.r8.java23.switchpatternmatching;
+ *
+ * public class DexIntValuePrimitiveSwitchMain {
+ *
+ *     static void booleanSwitch(boolean b) {
+ *         switch (b) {
+ *             case true -> {
+ *                 System.out.println("true");
+ *             }
+ *             default -> {
+ *                 System.out.println("false");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void doubleSwitch(double d) {
+ *         switch (d) {
+ *             case 42.0 -> {
+ *                 System.out.println("42");
+ *             }
+ *             case Double f2 when f2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void floatSwitch(float f) {
+ *         switch (f) {
+ *             case 42.0f -> {
+ *                 System.out.println("42");
+ *             }
+ *             case Float f2 when f2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void longSwitch(long l) {
+ *         switch (l) {
+ *             case 42L -> {
+ *                 System.out.println("42");
+ *             }
+ *             case Long i2 when i2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void intSwitch(int i) {
+ *         switch (i) {
+ *             case 42 -> {
+ *                 System.out.println("42");
+ *             }
+ *             case int i2 when i2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void shortSwitch(short s) {
+ *         switch (s) {
+ *             case 42 -> {
+ *                 System.out.println("42");
+ *             }
+ *             case short s2 when s2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void charSwitch(char c) {
+ *         switch (c) {
+ *             case 'c' -> {
+ *                 System.out.println("c");
+ *             }
+ *             case char c2 when Character.isUpperCase(c2) -> {
+ *                 System.out.println("upper");
+ *             }
+ *             default -> {
+ *                 System.out.println("lower");
+ *             }
+ *         }
+ *     }
+ *
+ *     static void byteSwitch(byte b) {
+ *         switch (b) {
+ *             case 42 -> {
+ *                 System.out.println("42");
+ *             }
+ *             case byte b2 when b2 > 0 -> {
+ *                 System.out.println("positif");
+ *             }
+ *             default -> {
+ *                 System.out.println("negatif");
+ *             }
+ *         }
+ *     }
+ *
+ *     public static void main(String[] args) {
+ *         intSwitch(42);
+ *         intSwitch(12);
+ *         intSwitch(-1);
+ *
+ *         charSwitch('c');
+ *         charSwitch('X');
+ *         charSwitch('x');
+ *
+ *         byteSwitch((byte) 42);
+ *         byteSwitch((byte) 12);
+ *         byteSwitch((byte) -1);
+ *
+ *         shortSwitch((short) 42);
+ *         shortSwitch((short) 12);
+ *         shortSwitch((short) -1);
+ *
+ *         longSwitch(42L);
+ *         longSwitch(12L);
+ *         longSwitch(-1L);
+ *
+ *         floatSwitch(42.0f);
+ *         floatSwitch(12.0f);
+ *         floatSwitch(-1.0f);
+ *
+ *         doubleSwitch(42.0);
+ *         doubleSwitch(12.0);
+ *         doubleSwitch(-1.0);
+ *
+ *         booleanSwitch(true);
+ *         booleanSwitch(false);
+ *     }
+ * }
+ * </pre>
+ */
+public class DexIntValuePrimitiveSwitchMainDump implements Opcodes {
+
+  public static byte[] dump() throws Exception {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    FieldVisitor fieldVisitor;
+    RecordComponentVisitor recordComponentVisitor;
+    MethodVisitor methodVisitor;
+    AnnotationVisitor annotationVisitor0;
+
+    classWriter.visit(
+        -65469,
+        ACC_PUBLIC | ACC_SUPER,
+        "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+        null,
+        "java/lang/Object",
+        null);
+
+    classWriter.visitSource("DexIntValuePrimitiveSwitchMain.java", null);
+
+    classWriter.visitInnerClass(
+        "java/lang/invoke/MethodHandles$Lookup",
+        "java/lang/invoke/MethodHandles",
+        "Lookup",
+        ACC_PUBLIC | ACC_FINAL | ACC_STATIC);
+
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(7, label0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "booleanSwitch", "(Z)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(10, label0);
+      methodVisitor.visitVarInsn(ILOAD, 0);
+      methodVisitor.visitVarInsn(ISTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(ZI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {
+            new ConstantDynamic(
+                "TRUE",
+                "Ljava/lang/Boolean;",
+                new Handle(
+                    Opcodes.H_INVOKESTATIC,
+                    "java/lang/invoke/ConstantBootstraps",
+                    "getStaticFinal",
+                    "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;",
+                    false),
+                new Object[] {})
+          });
+      Label label2 = new Label();
+      Label label3 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label3, new int[] {0}, new Label[] {label2});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(12, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("true");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label4 = new Label();
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(13, label4);
+      Label label5 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label5);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(15, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("false");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(18, label5);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 3);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "doubleSwitch", "(D)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(21, label0);
+      methodVisitor.visitVarInsn(DLOAD, 0);
+      methodVisitor.visitVarInsn(DSTORE, 2);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 4);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.DOUBLE, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(DLOAD, 2);
+      methodVisitor.visitVarInsn(ILOAD, 4);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(DI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {new Double("42.0"), Type.getType("Ljava/lang/Double;")});
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(23, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(24, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(25, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(DLOAD, 2);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
+      methodVisitor.visitVarInsn(ASTORE, 5);
+      methodVisitor.visitVarInsn(ALOAD, 5);
+      methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
+      methodVisitor.visitInsn(DCONST_0);
+      methodVisitor.visitInsn(DCMPL);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 4);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(26, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Double"}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(27, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(29, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(30, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(32, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(4, 6);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "floatSwitch", "(F)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(35, label0);
+      methodVisitor.visitVarInsn(FLOAD, 0);
+      methodVisitor.visitVarInsn(FSTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.FLOAT, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(FLOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(FI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {new Float("42.0"), Type.getType("Ljava/lang/Float;")});
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(37, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(38, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(39, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(FLOAD, 1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
+      methodVisitor.visitVarInsn(ASTORE, 3);
+      methodVisitor.visitVarInsn(ALOAD, 3);
+      methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
+      methodVisitor.visitInsn(FCONST_0);
+      methodVisitor.visitInsn(FCMPL);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(40, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Float"}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(41, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(43, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(44, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(46, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 4);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "longSwitch", "(J)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(49, label0);
+      methodVisitor.visitVarInsn(LLOAD, 0);
+      methodVisitor.visitVarInsn(LSTORE, 2);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 4);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.LONG, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(LLOAD, 2);
+      methodVisitor.visitVarInsn(ILOAD, 4);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(JI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {new Long(42L), Type.getType("Ljava/lang/Long;")});
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(51, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(52, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(53, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(LLOAD, 2);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
+      methodVisitor.visitVarInsn(ASTORE, 5);
+      methodVisitor.visitVarInsn(ALOAD, 5);
+      methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
+      methodVisitor.visitInsn(LCONST_0);
+      methodVisitor.visitInsn(LCMP);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 4);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(54, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/Long"}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(55, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(57, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(58, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(60, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(4, 6);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "intSwitch", "(I)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(63, label0);
+      methodVisitor.visitVarInsn(ILOAD, 0);
+      methodVisitor.visitVarInsn(ISTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(II)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {
+            new Integer(42),
+            new ConstantDynamic(
+                "I",
+                "Ljava/lang/Class;",
+                new Handle(
+                    Opcodes.H_INVOKESTATIC,
+                    "java/lang/invoke/ConstantBootstraps",
+                    "primitiveClass",
+                    "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+                    false),
+                new Object[] {})
+          });
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(65, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(66, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(67, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ISTORE, 3);
+      methodVisitor.visitVarInsn(ILOAD, 3);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(68, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(69, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(71, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(72, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(74, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 4);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "shortSwitch", "(S)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(77, label0);
+      methodVisitor.visitVarInsn(ILOAD, 0);
+      methodVisitor.visitVarInsn(ISTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(SI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {
+            new Integer(42),
+            new ConstantDynamic(
+                "S",
+                "Ljava/lang/Class;",
+                new Handle(
+                    Opcodes.H_INVOKESTATIC,
+                    "java/lang/invoke/ConstantBootstraps",
+                    "primitiveClass",
+                    "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+                    false),
+                new Object[] {})
+          });
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(79, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(80, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(81, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ISTORE, 3);
+      methodVisitor.visitVarInsn(ILOAD, 3);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(82, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(83, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(85, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(86, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(88, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 4);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "charSwitch", "(C)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(91, label0);
+      methodVisitor.visitVarInsn(ILOAD, 0);
+      methodVisitor.visitVarInsn(ISTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(CI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {
+            new Integer(99),
+            new ConstantDynamic(
+                "C",
+                "Ljava/lang/Class;",
+                new Handle(
+                    Opcodes.H_INVOKESTATIC,
+                    "java/lang/invoke/ConstantBootstraps",
+                    "primitiveClass",
+                    "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+                    false),
+                new Object[] {})
+          });
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(93, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("c");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(94, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(95, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ISTORE, 3);
+      methodVisitor.visitVarInsn(ILOAD, 3);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC, "java/lang/Character", "isUpperCase", "(C)Z", false);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFNE, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(96, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("upper");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(97, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(99, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("lower");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(100, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(102, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 4);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "byteSwitch", "(B)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(105, label0);
+      methodVisitor.visitVarInsn(ILOAD, 0);
+      methodVisitor.visitVarInsn(ISTORE, 1);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(
+          Opcodes.F_APPEND, 2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ILOAD, 2);
+      methodVisitor.visitInvokeDynamicInsn(
+          "typeSwitch",
+          "(BI)I",
+          new Handle(
+              Opcodes.H_INVOKESTATIC,
+              "java/lang/runtime/SwitchBootstraps",
+              "typeSwitch",
+              "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
+              false),
+          new Object[] {
+            new Integer(42),
+            new ConstantDynamic(
+                "B",
+                "Ljava/lang/Class;",
+                new Handle(
+                    Opcodes.H_INVOKESTATIC,
+                    "java/lang/invoke/ConstantBootstraps",
+                    "primitiveClass",
+                    "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+                    false),
+                new Object[] {})
+          });
+      Label label2 = new Label();
+      Label label3 = new Label();
+      Label label4 = new Label();
+      methodVisitor.visitLookupSwitchInsn(label4, new int[] {0, 1}, new Label[] {label2, label3});
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(107, label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("42");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(108, label5);
+      Label label6 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(109, label3);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitVarInsn(ILOAD, 1);
+      methodVisitor.visitVarInsn(ISTORE, 3);
+      methodVisitor.visitVarInsn(ILOAD, 3);
+      Label label7 = new Label();
+      methodVisitor.visitJumpInsn(IFGT, label7);
+      methodVisitor.visitInsn(ICONST_2);
+      methodVisitor.visitVarInsn(ISTORE, 2);
+      methodVisitor.visitJumpInsn(GOTO, label1);
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(110, label7);
+      methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("positif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(111, label8);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(113, label4);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("negatif");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(114, label9);
+      methodVisitor.visitJumpInsn(GOTO, label6);
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(116, label6);
+      methodVisitor.visitFrame(Opcodes.F_CHOP, 2, null, 0, null);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 4);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(119, label0);
+      methodVisitor.visitIntInsn(BIPUSH, 42);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "intSwitch",
+          "(I)V",
+          false);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitLineNumber(120, label1);
+      methodVisitor.visitIntInsn(BIPUSH, 12);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "intSwitch",
+          "(I)V",
+          false);
+      Label label2 = new Label();
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(121, label2);
+      methodVisitor.visitInsn(ICONST_M1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "intSwitch",
+          "(I)V",
+          false);
+      Label label3 = new Label();
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(123, label3);
+      methodVisitor.visitIntInsn(BIPUSH, 99);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "charSwitch",
+          "(C)V",
+          false);
+      Label label4 = new Label();
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitLineNumber(124, label4);
+      methodVisitor.visitIntInsn(BIPUSH, 88);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "charSwitch",
+          "(C)V",
+          false);
+      Label label5 = new Label();
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitLineNumber(125, label5);
+      methodVisitor.visitIntInsn(BIPUSH, 120);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "charSwitch",
+          "(C)V",
+          false);
+      Label label6 = new Label();
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(127, label6);
+      methodVisitor.visitIntInsn(BIPUSH, 42);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "byteSwitch",
+          "(B)V",
+          false);
+      Label label7 = new Label();
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(128, label7);
+      methodVisitor.visitIntInsn(BIPUSH, 12);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "byteSwitch",
+          "(B)V",
+          false);
+      Label label8 = new Label();
+      methodVisitor.visitLabel(label8);
+      methodVisitor.visitLineNumber(129, label8);
+      methodVisitor.visitInsn(ICONST_M1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "byteSwitch",
+          "(B)V",
+          false);
+      Label label9 = new Label();
+      methodVisitor.visitLabel(label9);
+      methodVisitor.visitLineNumber(131, label9);
+      methodVisitor.visitIntInsn(BIPUSH, 42);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "shortSwitch",
+          "(S)V",
+          false);
+      Label label10 = new Label();
+      methodVisitor.visitLabel(label10);
+      methodVisitor.visitLineNumber(132, label10);
+      methodVisitor.visitIntInsn(BIPUSH, 12);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "shortSwitch",
+          "(S)V",
+          false);
+      Label label11 = new Label();
+      methodVisitor.visitLabel(label11);
+      methodVisitor.visitLineNumber(133, label11);
+      methodVisitor.visitInsn(ICONST_M1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "shortSwitch",
+          "(S)V",
+          false);
+      Label label12 = new Label();
+      methodVisitor.visitLabel(label12);
+      methodVisitor.visitLineNumber(135, label12);
+      methodVisitor.visitLdcInsn(new Long(42L));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "longSwitch",
+          "(J)V",
+          false);
+      Label label13 = new Label();
+      methodVisitor.visitLabel(label13);
+      methodVisitor.visitLineNumber(136, label13);
+      methodVisitor.visitLdcInsn(new Long(12L));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "longSwitch",
+          "(J)V",
+          false);
+      Label label14 = new Label();
+      methodVisitor.visitLabel(label14);
+      methodVisitor.visitLineNumber(137, label14);
+      methodVisitor.visitLdcInsn(new Long(-1L));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "longSwitch",
+          "(J)V",
+          false);
+      Label label15 = new Label();
+      methodVisitor.visitLabel(label15);
+      methodVisitor.visitLineNumber(139, label15);
+      methodVisitor.visitLdcInsn(new Float("42.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "floatSwitch",
+          "(F)V",
+          false);
+      Label label16 = new Label();
+      methodVisitor.visitLabel(label16);
+      methodVisitor.visitLineNumber(140, label16);
+      methodVisitor.visitLdcInsn(new Float("12.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "floatSwitch",
+          "(F)V",
+          false);
+      Label label17 = new Label();
+      methodVisitor.visitLabel(label17);
+      methodVisitor.visitLineNumber(141, label17);
+      methodVisitor.visitLdcInsn(new Float("-1.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "floatSwitch",
+          "(F)V",
+          false);
+      Label label18 = new Label();
+      methodVisitor.visitLabel(label18);
+      methodVisitor.visitLineNumber(143, label18);
+      methodVisitor.visitLdcInsn(new Double("42.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "doubleSwitch",
+          "(D)V",
+          false);
+      Label label19 = new Label();
+      methodVisitor.visitLabel(label19);
+      methodVisitor.visitLineNumber(144, label19);
+      methodVisitor.visitLdcInsn(new Double("12.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "doubleSwitch",
+          "(D)V",
+          false);
+      Label label20 = new Label();
+      methodVisitor.visitLabel(label20);
+      methodVisitor.visitLineNumber(145, label20);
+      methodVisitor.visitLdcInsn(new Double("-1.0"));
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "doubleSwitch",
+          "(D)V",
+          false);
+      Label label21 = new Label();
+      methodVisitor.visitLabel(label21);
+      methodVisitor.visitLineNumber(147, label21);
+      methodVisitor.visitInsn(ICONST_1);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "booleanSwitch",
+          "(Z)V",
+          false);
+      Label label22 = new Label();
+      methodVisitor.visitLabel(label22);
+      methodVisitor.visitLineNumber(148, label22);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitMethodInsn(
+          INVOKESTATIC,
+          "com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchMain",
+          "booleanSwitch",
+          "(Z)V",
+          false);
+      Label label23 = new Label();
+      methodVisitor.visitLabel(label23);
+      methodVisitor.visitLineNumber(149, label23);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 1);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java
new file mode 100644
index 0000000..9636183
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValuePrimitiveSwitchTest.java
@@ -0,0 +1,76 @@
+// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.java23.switchpatternmatching;
+
+import com.android.tools.r8.JdkClassFileProvider;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.utils.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DexIntValuePrimitiveSwitchTest extends TestBase {
+
+  private static final String MAIN =
+      "com.android.tools.r8.java23.switchpatternmatching.DexIntValuePrimitiveSwitchMain";
+
+  @Parameter public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK23)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public static String EXPECTED_OUTPUT =
+      StringUtils.lines(
+          "42", "positif", "negatif", "c", "upper", "lower", "42", "positif", "negatif", "42",
+          "positif", "negatif", "42", "positif", "negatif", "42", "positif", "negatif", "42",
+          "positif", "negatif", "true", "false");
+
+  @Test
+  public void testJvm() throws Exception {
+    parameters.assumeJvmTestParameters();
+    testForJvm(parameters)
+        .enablePreview()
+        .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testD8() throws Exception {
+    testForD8(parameters.getBackend())
+        .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    parameters.assumeR8TestParameters();
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(DexIntValuePrimitiveSwitchMainDump.dump())
+        .applyIf(
+            parameters.isCfRuntime(),
+            b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+        .setMinApi(parameters)
+        .addKeepMainRule(MAIN)
+        .compile()
+        .applyIf(parameters.isCfRuntime(), b -> b.addVmArguments("--enable-preview"))
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+}
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java
new file mode 100644
index 0000000..3fe7fbb
--- /dev/null
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexIntValueSwitchTest.java
@@ -0,0 +1,173 @@
+// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.java23.switchpatternmatching;
+
+import static com.android.tools.r8.desugar.switchpatternmatching.SwitchTestHelper.hasJdk21TypeSwitch;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.JdkClassFileProvider;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DexIntValueSwitchTest extends TestBase {
+
+  @Parameter public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters()
+        .withCfRuntimesStartingFromIncluding(CfVm.JDK23)
+        .withDexRuntimes()
+        .withAllApiLevelsAlsoForCf()
+        .build();
+  }
+
+  public static String EXPECTED_OUTPUT =
+      StringUtils.lines(
+          "null", "42", "positif", "negatif", "null", "c", "upper", "lower", "null", "42",
+          "positif", "negatif", "null", "42", "positif", "negatif");
+
+  @Test
+  public void testJvm() throws Exception {
+    assumeTrue(parameters.isCfRuntime());
+    CodeInspector inspector = new CodeInspector(ToolHelper.getClassFileForTestClass(Main.class));
+    assertTrue(
+        hasJdk21TypeSwitch(inspector.clazz(Main.class).uniqueMethodWithOriginalName("intSwitch")));
+
+    parameters.assumeJvmTestParameters();
+    testForJvm(parameters)
+        .addInnerClassesAndStrippedOuter(getClass())
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testD8() throws Exception {
+    testForD8(parameters.getBackend())
+        .addInnerClassesAndStrippedOuter(getClass())
+        .setMinApi(parameters)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    parameters.assumeR8TestParameters();
+    testForR8(parameters.getBackend())
+        .addInnerClassesAndStrippedOuter(getClass())
+        .applyIf(
+            parameters.isCfRuntime(),
+            b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+        .setMinApi(parameters)
+        .addKeepMainRule(Main.class)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  static class Main {
+
+    static void intSwitch(Integer i) {
+      switch (i) {
+        case null -> {
+          System.out.println("null");
+        }
+        case 42 -> {
+          System.out.println("42");
+        }
+        case Integer i2 when i2 > 0 -> {
+          System.out.println("positif");
+        }
+        default -> {
+          System.out.println("negatif");
+        }
+      }
+    }
+
+    static void shortSwitch(Short s) {
+      switch (s) {
+        case null -> {
+          System.out.println("null");
+        }
+        case 42 -> {
+          System.out.println("42");
+        }
+        case Short s2 when s2 > 0 -> {
+          System.out.println("positif");
+        }
+        default -> {
+          System.out.println("negatif");
+        }
+      }
+    }
+
+    static void charSwitch(Character c) {
+      switch (c) {
+        case null -> {
+          System.out.println("null");
+        }
+        case 'c' -> {
+          System.out.println("c");
+        }
+        case Character c2 when Character.isUpperCase(c2) -> {
+          System.out.println("upper");
+        }
+        default -> {
+          System.out.println("lower");
+        }
+      }
+    }
+
+    static void byteSwitch(Byte b) {
+      switch (b) {
+        case null -> {
+          System.out.println("null");
+        }
+        case 42 -> {
+          System.out.println("42");
+        }
+        case Byte b2 when b2 > 0 -> {
+          System.out.println("positif");
+        }
+        default -> {
+          System.out.println("negatif");
+        }
+      }
+    }
+
+    public static void main(String[] args) {
+      intSwitch(null);
+      intSwitch(42);
+      intSwitch(12);
+      intSwitch(-1);
+
+      charSwitch(null);
+      charSwitch('c');
+      charSwitch('X');
+      charSwitch('x');
+
+      byteSwitch(null);
+      byteSwitch((byte) 42);
+      byteSwitch((byte) 12);
+      byteSwitch((byte) -1);
+
+      shortSwitch(null);
+      shortSwitch((short) 42);
+      shortSwitch((short) 12);
+      shortSwitch((short) -1);
+    }
+  }
+}