[LIR] Add support for instanceof.

This also migrates ifstatements, instancevariable and interfaceinlining
example tests.

Bug: b/167145686
Change-Id: Iefbc2d5304cf449a2136e62dce9fac26a7a6627a
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
index 680ace0..9834a17 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
@@ -18,6 +18,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 java.util.Set;
 
 public class InstanceOf extends Instruction {
@@ -135,4 +136,9 @@
   void internalRegisterUse(UseRegistry<?> registry, DexClassAndMethod context) {
     registry.registerInstanceOf(type);
   }
+
+  @Override
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    builder.addInstanceOf(type, value());
+  }
 }
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 6dcfe40..0583876 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -35,6 +35,7 @@
 import com.android.tools.r8.ir.code.If;
 import com.android.tools.r8.ir.code.IfType;
 import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.InstanceOf;
 import com.android.tools.r8.ir.code.InstancePut;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.InvokeDirect;
@@ -588,6 +589,12 @@
     }
 
     @Override
+    public void onInstanceOf(DexType type, EV value) {
+      Value dest = getOutValueForNextInstruction(TypeElement.getInt());
+      addInstruction(new InstanceOf(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 1239c11..54bdd09 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -401,6 +401,11 @@
         LirOpcodes.CHECKCAST, 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));
+  }
+
   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 8d81728..fa36ce6 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -372,6 +372,10 @@
     onInstruction();
   }
 
+  public void onInstanceOf(DexType type, EV value) {
+    onInstruction();
+  }
+
   public void onDebugPosition() {
     onInstruction();
   }
@@ -938,6 +942,13 @@
           onCheckCast(type, value);
           return;
         }
+      case LirOpcodes.INSTANCEOF:
+        {
+          DexType type = getNextDexTypeOperand(view);
+          EV value = getNextValueOperand(view);
+          onInstanceOf(type, value);
+          return;
+        }
       case LirOpcodes.DEBUGPOS:
         {
           onDebugPosition();
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 58ac9b2..c3c06b1 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -304,6 +304,13 @@
   }
 
   @Override
+  public void onInstanceOf(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/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index d63d66c..418dad3 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -26,9 +26,7 @@
   public static Collection<String[]> data() {
     String[] tests = {
         "arithmetic.Arithmetic",
-        "ifstatements.IfStatements",
         "inlining.Inlining",
-        "instancevariable.InstanceVariable",
         "instanceofstring.InstanceofString",
         "invoke.Invoke",
         "invokeempty.InvokeEmpty",
@@ -65,7 +63,6 @@
         "minification.Minification",
         "enclosingmethod.Main",
         "enclosingmethod_proguarded.Main",
-        "interfaceinlining.Main",
         "switchmaps.Switches",
         "uninitializedfinal.UninitializedFinalFieldLeak",
     };
diff --git a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
index 577eb22..fe9bed4 100644
--- a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
@@ -60,16 +60,6 @@
   }
 
   @Test
-  public void testIfStatements() throws Exception {
-    testDebugging("ifstatements", "IfStatements");
-  }
-
-  @Test
-  public void testInstanceVariable() throws Exception {
-    testDebugging("instancevariable", "InstanceVariable");
-  }
-
-  @Test
   public void testInstanceofString() throws Exception {
     testDebugging("instanceofstring", "InstanceofString");
   }
@@ -252,11 +242,6 @@
   }
 
   @Test
-  public void testInterfaceinlining() throws Exception {
-    testDebugging("interfaceinlining", "Main");
-  }
-
-  @Test
   public void testSwitchmaps() throws Exception {
     // TODO(b/79671093): D8 has different line number info during stepping.
     testDebuggingJvmOnly("switchmaps", "Switches");
diff --git a/src/test/examples/ifstatements/IfStatements.java b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
similarity index 96%
rename from src/test/examples/ifstatements/IfStatements.java
rename to src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
index 5d340ab..41183af 100644
--- a/src/test/examples/ifstatements/IfStatements.java
+++ b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatements.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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 ifstatements;
+package com.android.tools.r8.examples.ifstatements;
 
 class IfStatements {
 
diff --git a/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java
new file mode 100644
index 0000000..9106b03
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/ifstatements/IfStatementsTestRunner.java
@@ -0,0 +1,72 @@
+// 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.ifstatements;
+
+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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class IfStatementsTestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public IfStatementsTestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return IfStatements.class;
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines(
+        "sisnotnull",
+        "sisnull",
+        "ifCond x != 0",
+        "ifCond x < 0",
+        "ifCond x <= 0",
+        "ifCond x == 0",
+        "ifCond x >= 0",
+        "ifCond x <= 0",
+        "ifCond x != 0",
+        "ifCond x >= 0",
+        "ifCond x > 0",
+        "ifIcmp x != y",
+        "ifIcmp x < y",
+        "ifIcmp x <= y",
+        "ifIcmp x == y",
+        "ifIcmp x >= y",
+        "ifIcmp x <= y",
+        "ifIcmp x != y",
+        "ifIcmp x >= y",
+        "ifIcmp x > y",
+        "ifAcmp a == b",
+        "ifAcmp a != b");
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    runTestDesugaring();
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runTestR8();
+  }
+
+  @Test
+  public void testDebug() throws Exception {
+    runTestDebugComparator();
+  }
+}
diff --git a/src/test/examples/instancevariable/InstanceVariable.java b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
similarity index 93%
rename from src/test/examples/instancevariable/InstanceVariable.java
rename to src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
index 88768f1..fdad644 100644
--- a/src/test/examples/instancevariable/InstanceVariable.java
+++ b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariable.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, 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 instancevariable;
+package com.android.tools.r8.examples.instancevariable;
 
 class InstanceVariable {
   public int foo = 42;
diff --git a/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java
new file mode 100644
index 0000000..95b20d4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/instancevariable/InstanceVariableTestRunner.java
@@ -0,0 +1,50 @@
+// 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.instancevariable;
+
+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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class InstanceVariableTestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public InstanceVariableTestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return InstanceVariable.class;
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("144=144");
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    runTestDesugaring();
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runTestR8();
+  }
+
+  @Test
+  public void testDebug() throws Exception {
+    runTestDebugComparator();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java b/src/test/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java
new file mode 100644
index 0000000..05138f2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/interfaceinlining/InterfaceInliningTestRunner.java
@@ -0,0 +1,56 @@
+// 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.interfaceinlining;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.examples.ExamplesTestBase;
+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 InterfaceInliningTestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public InterfaceInliningTestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Main.class;
+  }
+
+  @Override
+  public List<Class<?>> getTestClasses() {
+    return ImmutableList.of(Main.class, Main.Data.class, Main.DataI.class);
+  }
+
+  @Override
+  public String getExpected() {
+    return "true";
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    runTestDesugaring();
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runTestR8();
+  }
+
+  @Test
+  public void testDebug() throws Exception {
+    runTestDebugComparator();
+  }
+}
diff --git a/src/test/examples/interfaceinlining/Main.java b/src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.java
similarity index 93%
rename from src/test/examples/interfaceinlining/Main.java
rename to src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.java
index 865fa14..2c23c4d 100644
--- a/src/test/examples/interfaceinlining/Main.java
+++ b/src/test/java/com/android/tools/r8/examples/interfaceinlining/Main.java
@@ -1,7 +1,7 @@
 // Copyright (c) 2017, 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 interfaceinlining;
+package com.android.tools.r8.examples.interfaceinlining;
 
 // This test ensures a check cast instruction is inserted IFF
 // the expression "((DataI) other).field()" is inlined.