[LIR] Move bridge example test and add checkcast.

Bug: b/167145686
Bug: b/225838009
Change-Id: Icececdde6c1a8ad91a008623d88a88475600e277
diff --git a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
index d9a1063..0bb5989 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
@@ -27,6 +27,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import com.android.tools.r8.lightir.LirBuilder;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.InternalOptions;
 
@@ -285,6 +286,11 @@
     registry.registerCheckCast(type, ignoreCompatRules);
   }
 
+  @Override
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    builder.addCheckCast(type, object());
+  }
+
   public static class Builder extends BuilderBase<Builder, CheckCast> {
 
     protected DexType castType;
diff --git a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
index a3e20e6..6d6d497 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -21,6 +21,7 @@
 import com.android.tools.r8.ir.code.ArrayPut;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.CatchHandlers;
+import com.android.tools.r8.ir.code.CheckCast;
 import com.android.tools.r8.ir.code.Cmp;
 import com.android.tools.r8.ir.code.Cmp.Bias;
 import com.android.tools.r8.ir.code.ConstNumber;
@@ -564,6 +565,12 @@
     }
 
     @Override
+    public void onCheckCast(DexType type, EV value) {
+      Value dest = getOutValueForNextInstruction(type.toTypeElement(appView));
+      addInstruction(new CheckCast(dest, getValue(value), type));
+    }
+
+    @Override
     public void onDebugPosition() {
       addInstruction(new DebugPosition());
     }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index 95624bb..8f41773 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -368,6 +368,11 @@
     return addOneValueInstruction(LirOpcodes.ARRAYLENGTH, array);
   }
 
+  public LirBuilder<V, EV> addCheckCast(DexType type, V value) {
+    return addInstructionTemplate(
+        LirOpcodes.CHECKCAST, Collections.singletonList(type), Collections.singletonList(value));
+  }
+
   public LirBuilder<V, EV> addStaticGet(DexField field) {
     return addOneItemInstruction(LirOpcodes.GETSTATIC, field);
   }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
index 6af7bb5..1fca6a6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -51,6 +51,10 @@
     return getActualValueIndex(view.getNextValueOperand());
   }
 
+  private DexType getNextDexTypeOperand(LirInstructionView view) {
+    return (DexType) getConstantItem(view.getNextConstantOperand());
+  }
+
   public void onInstruction() {}
 
   public void onConstNull() {
@@ -347,6 +351,10 @@
     onInstruction();
   }
 
+  public void onCheckCast(DexType type, EV value) {
+    onInstruction();
+  }
+
   public void onDebugPosition() {
     onInstruction();
   }
@@ -868,7 +876,7 @@
         }
       case LirOpcodes.NEWARRAY:
         {
-          DexType type = (DexType) getConstantItem(view.getNextConstantOperand());
+          DexType type = getNextDexTypeOperand(view);
           EV size = getNextValueOperand(view);
           onNewArrayEmpty(type, size);
           return;
@@ -895,6 +903,13 @@
           onArrayLength(getNextValueOperand(view));
           return;
         }
+      case LirOpcodes.CHECKCAST:
+        {
+          DexType type = getNextDexTypeOperand(view);
+          EV value = getNextValueOperand(view);
+          onCheckCast(type, value);
+          return;
+        }
       case LirOpcodes.DEBUGPOS:
         {
           onDebugPosition();
@@ -902,7 +917,7 @@
         }
       case LirOpcodes.PHI:
         {
-          DexType type = (DexType) getConstantItem(view.getNextConstantOperand());
+          DexType type = getNextDexTypeOperand(view);
           List<EV> operands = new ArrayList<>();
           while (view.hasMoreOperands()) {
             operands.add(getNextValueOperand(view));
@@ -917,7 +932,7 @@
         }
       case LirOpcodes.MOVEEXCEPTION:
         {
-          DexType type = (DexType) getConstantItem(view.getNextConstantOperand());
+          DexType type = getNextDexTypeOperand(view);
           onMoveException(type);
           return;
         }
diff --git a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
index 58a00f6..132fc61 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -278,6 +278,13 @@
   }
 
   @Override
+  public void onCheckCast(DexType type, EV value) {
+    appendOutValue();
+    appendValueArguments(value);
+    builder.append(type);
+  }
+
+  @Override
   public void onArrayGetPrimitive(MemberType type, EV array, EV index) {
     appendOutValue();
     appendValueArguments(array, index);
diff --git a/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java b/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
index 95dd9bd..7e10a4c 100644
--- a/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
@@ -46,11 +46,6 @@
   }
 
   @Test
-  public void testBridgeMethod() throws Exception {
-    runTest("bridge.BridgeMethod");
-  }
-
-  @Test
   public void testCommonSubexpressionElimination() throws Exception {
     runTest("cse.CommonSubexpressionElimination");
   }
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index 1cfd1a1..ecb577a 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -26,7 +26,6 @@
   public static Collection<String[]> data() {
     String[] tests = {
         "arithmetic.Arithmetic",
-        "bridge.BridgeMethod",
         "catchhandleroverlap.CatchHandlerOverlap",
         "cse.CommonSubexpressionElimination",
         "constants.Constants",
diff --git a/src/test/java/com/android/tools/r8/examples/ExamplesTestBase.java b/src/test/java/com/android/tools/r8/examples/ExamplesTestBase.java
index 76af63f..cd9e112 100644
--- a/src/test/java/com/android/tools/r8/examples/ExamplesTestBase.java
+++ b/src/test/java/com/android/tools/r8/examples/ExamplesTestBase.java
@@ -53,7 +53,6 @@
         .assertSuccessWithOutput(getExpected());
   }
 
-  @Test
   public void runTestDebugComparator() throws Exception {
     Assume.assumeFalse(ToolHelper.isWindows());
     Assume.assumeFalse(
diff --git a/src/test/examples/bridge/BridgeMethod.java b/src/test/java/com/android/tools/r8/examples/bridge/BridgeMethod.java
similarity index 70%
rename from src/test/examples/bridge/BridgeMethod.java
rename to src/test/java/com/android/tools/r8/examples/bridge/BridgeMethod.java
index 9e82a29..685f885 100644
--- a/src/test/examples/bridge/BridgeMethod.java
+++ b/src/test/java/com/android/tools/r8/examples/bridge/BridgeMethod.java
@@ -1,10 +1,11 @@
-// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// Copyright (c) 2023, 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 bridge;
+package com.android.tools.r8.examples.bridge;
 
 abstract class Super<T> {
   public abstract int method(T t0, T t1);
+
   public abstract int rangeMethod(T t0, T t1, T t2, T t3, T t4, T t5);
 }
 
@@ -27,10 +28,12 @@
   }
 
   public static void main(String[] args) {
+    int i = 0;
     Super<Integer> instance = new BridgeMethod();
-    instance.method(1, 2);
-    instance.method(2, 1);
-    instance.rangeMethod(1, 2, 3, 4, 5, 6);
-    instance.rangeMethod(2, 1, 3, 4, 5, 6);
+    i += instance.method(1, 2);
+    i += instance.method(2, 1);
+    i += instance.rangeMethod(1, 2, 3, 4, 5, 6);
+    i += instance.rangeMethod(2, 1, 3, 4, 5, 6);
+    System.out.println(i);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/examples/bridge/BridgeMethodTestRunner.java b/src/test/java/com/android/tools/r8/examples/bridge/BridgeMethodTestRunner.java
new file mode 100644
index 0000000..47e9945
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/bridge/BridgeMethodTestRunner.java
@@ -0,0 +1,57 @@
+// Copyright (c) 2023, 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.examples.bridge;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.examples.ExamplesTestBase;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class BridgeMethodTestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public BridgeMethodTestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return BridgeMethod.class;
+  }
+
+  @Override
+  public List<Class<?>> getTestClasses() {
+    return ImmutableList.of(BridgeMethod.class, Super.class);
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("26");
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    runTestDesugaring();
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runTestR8();
+  }
+
+  @Test
+  public void testDebug() throws Exception {
+    runTestDebugComparator();
+  }
+}