[LIR] Add support for safe check-cast variant.

Bug: b/225838009
Change-Id: I85370a4b69ab60c536c9e41626598fc3524944ed
diff --git a/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java b/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
index 1aee996..bfb48e6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/SafeCheckCast.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.lightir.LirBuilder;
 
 public class SafeCheckCast extends CheckCast {
 
@@ -28,6 +29,11 @@
   }
 
   @Override
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    builder.addSafeCheckCast(getType(), object());
+  }
+
+  @Override
   DexCheckCast createCheckCast(int register) {
     return new DexSafeCheckCast(register, getType());
   }
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 985b5c2..45e136d 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -79,6 +79,7 @@
 import com.android.tools.r8.ir.code.RecordFieldValues;
 import com.android.tools.r8.ir.code.Rem;
 import com.android.tools.r8.ir.code.Return;
+import com.android.tools.r8.ir.code.SafeCheckCast;
 import com.android.tools.r8.ir.code.Shl;
 import com.android.tools.r8.ir.code.Shr;
 import com.android.tools.r8.ir.code.StaticGet;
@@ -741,6 +742,12 @@
     }
 
     @Override
+    public void onSafeCheckCast(DexType type, EV value) {
+      Value dest = getOutValueForNextInstruction(type.toTypeElement(appView));
+      addInstruction(new SafeCheckCast(dest, getValue(value), type));
+    }
+
+    @Override
     public void onInstanceOf(DexType type, EV value) {
       Value dest = getOutValueForNextInstruction(TypeElement.getInt());
       addInstruction(new InstanceOf(dest, getValue(value), type));
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 0607661..09229fc 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -488,6 +488,13 @@
         LirOpcodes.CHECKCAST, Collections.singletonList(type), Collections.singletonList(value));
   }
 
+  public LirBuilder<V, EV> addSafeCheckCast(DexType type, V value) {
+    return addInstructionTemplate(
+        LirOpcodes.CHECKCAST_SAFE,
+        Collections.singletonList(type),
+        Collections.singletonList(value));
+  }
+
   public LirBuilder<V, EV> addInstanceOf(DexType type, V value) {
     return addInstructionTemplate(
         LirOpcodes.INSTANCEOF, Collections.singletonList(type), Collections.singletonList(value));
diff --git a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
index bd52773..8863892 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
@@ -208,6 +208,7 @@
   int INITCLASS = 221;
   int INVOKEPOLYMORPHIC = 222;
   int RECORDFIELDVALUES = 223;
+  int CHECKCAST_SAFE = 224;
 
   static String toString(int opcode) {
     switch (opcode) {
@@ -540,6 +541,8 @@
         return "INVOKEPOLYMORPHIC";
       case RECORDFIELDVALUES:
         return "RECORDFIELDVALUES";
+      case CHECKCAST_SAFE:
+        return "CHECKCAST_SAFE";
 
       default:
         throw new Unreachable("Unexpected LIR opcode: " + opcode);
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 f4f6e64..73ad12b 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -472,6 +472,10 @@
     onInstruction();
   }
 
+  public void onSafeCheckCast(DexType type, EV value) {
+    onInstruction();
+  }
+
   public void onInstanceOf(DexType type, EV value) {
     onInstruction();
   }
@@ -1109,6 +1113,13 @@
           onCheckCast(type, value);
           return;
         }
+      case LirOpcodes.CHECKCAST_SAFE:
+        {
+          DexType type = getNextDexTypeOperand(view);
+          EV value = getNextValueOperand(view);
+          onSafeCheckCast(type, value);
+          return;
+        }
       case LirOpcodes.INSTANCEOF:
         {
           DexType type = getNextDexTypeOperand(view);
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 b494ecb..5092894 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -350,6 +350,11 @@
   }
 
   @Override
+  public void onSafeCheckCast(DexType type, EV value) {
+    onCheckCast(type, value);
+  }
+
+  @Override
   public void onInstanceOf(DexType type, EV value) {
     appendOutValue();
     appendValueArguments(value);