[LIR] Add support for IOR

Also migrates legacy example regression tests.

Bug: b/225838009
Bug: b/167145686
Change-Id: I154116ff1b3cd53253c1c9ca11e10834121b86a9
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index c33be9f..511c157 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -225,6 +225,11 @@
 
   public abstract void buildCf(CfBuilder builder);
 
+  // TODO(b/225838009): Make this abstract.
+  public void buildLir(LirBuilder<Value, ?> builder) {
+    throw new Unimplemented("Missing impl for " + getClass().getSimpleName());
+  }
+
   public void replaceValue(Value oldValue, Value newValue) {
     for (int i = 0; i < inValues.size(); i++) {
       if (oldValue == inValues.get(i)) {
@@ -1535,10 +1540,6 @@
     return false;
   }
 
-  public void buildLir(LirBuilder<Value, ?> builder) {
-    throw new Unimplemented("Missing impl for " + getClass().getSimpleName());
-  }
-
   public void registerUse(UseRegistry registry, ProgramMethod context) {
     internalRegisterUse(registry, context);
   }
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 3fc7069..2c8b535 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -61,6 +61,7 @@
 import com.android.tools.r8.ir.code.NumberConversion;
 import com.android.tools.r8.ir.code.NumberGenerator;
 import com.android.tools.r8.ir.code.NumericType;
+import com.android.tools.r8.ir.code.Or;
 import com.android.tools.r8.ir.code.Phi;
 import com.android.tools.r8.ir.code.Position;
 import com.android.tools.r8.ir.code.Position.SyntheticPosition;
@@ -437,6 +438,12 @@
     }
 
     @Override
+    public void onOr(NumericType type, EV left, EV right) {
+      Value dest = getOutValueForNextInstruction(valueTypeElement(type));
+      addInstruction(Or.createNonNormalized(type, dest, getValue(left), getValue(right)));
+    }
+
+    @Override
     public void onXor(NumericType type, EV left, EV right) {
       Value dest = getOutValueForNextInstruction(valueTypeElement(type));
       addInstruction(Xor.createNonNormalized(type, dest, getValue(left), getValue(right)));
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 4e14c72..3684dab 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -131,10 +131,18 @@
     onInstruction();
   }
 
-  public void onAdd(NumericType type, EV leftValueIndex, EV rightValueIndex) {
+  public void onBinop(NumericType type, EV left, EV right) {
     onInstruction();
   }
 
+  public void onArithmeticBinop(NumericType type, EV left, EV right) {
+    onBinop(type, left, right);
+  }
+
+  public void onAdd(NumericType type, EV leftValueIndex, EV rightValueIndex) {
+    onArithmeticBinop(type, leftValueIndex, rightValueIndex);
+  }
+
   public void onAddInt(EV leftValueIndex, EV rightValueIndex) {
     onAdd(NumericType.INT, leftValueIndex, rightValueIndex);
   }
@@ -152,7 +160,7 @@
   }
 
   public void onSub(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    onInstruction();
+    onArithmeticBinop(type, leftValueIndex, rightValueIndex);
   }
 
   public void onSubInt(EV leftValueIndex, EV rightValueIndex) {
@@ -172,7 +180,7 @@
   }
 
   public void onMul(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    onInstruction();
+    onArithmeticBinop(type, leftValueIndex, rightValueIndex);
   }
 
   public void onMulInt(EV leftValueIndex, EV rightValueIndex) {
@@ -192,7 +200,7 @@
   }
 
   public void onDiv(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    onInstruction();
+    onArithmeticBinop(type, leftValueIndex, rightValueIndex);
   }
 
   public void onDivInt(EV leftValueIndex, EV rightValueIndex) {
@@ -212,7 +220,7 @@
   }
 
   public void onRem(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    onInstruction();
+    onArithmeticBinop(type, leftValueIndex, rightValueIndex);
   }
 
   public void onRemInt(EV leftValueIndex, EV rightValueIndex) {
@@ -249,7 +257,10 @@
         onAnd(NumericType.INT, left, right);
         return;
       case LirOpcodes.LAND:
+        throw new Unimplemented(LirOpcodes.toString(opcode));
       case LirOpcodes.IOR:
+        onOr(NumericType.INT, left, right);
+        return;
       case LirOpcodes.LOR:
         throw new Unimplemented(LirOpcodes.toString(opcode));
       case LirOpcodes.IXOR:
@@ -263,16 +274,24 @@
     }
   }
 
+  public void onLogicalBinop(NumericType type, EV left, EV right) {
+    onBinop(type, left, right);
+  }
+
   public void onShr(NumericType type, EV left, EV right) {
-    onInstruction();
+    onLogicalBinop(type, left, right);
   }
 
   public void onAnd(NumericType type, EV left, EV right) {
-    onInstruction();
+    onLogicalBinop(type, left, right);
+  }
+
+  public void onOr(NumericType type, EV left, EV right) {
+    onLogicalBinop(type, left, right);
   }
 
   public void onXor(NumericType type, EV left, EV right) {
-    onInstruction();
+    onLogicalBinop(type, left, right);
   }
 
   public void onNumberConversion(int opcode, EV value) {
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 98dd02d..91dd055 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -164,48 +164,12 @@
   }
 
   @Override
-  public void onAdd(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
-  public void onSub(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
-  public void onMul(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
-  public void onDiv(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
-  public void onShr(NumericType type, EV left, EV right) {
+  public void onBinop(NumericType type, EV left, EV right) {
     appendOutValue();
     appendValueArguments(left, right);
   }
 
   @Override
-  public void onAnd(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
-  public void onXor(NumericType type, EV leftValueIndex, EV rightValueIndex) {
-    appendOutValue();
-    appendValueArguments(leftValueIndex, rightValueIndex);
-  }
-
-  @Override
   public void onNumberConversion(int opcode, EV value) {
     appendOutValue();
     appendValueArguments(value);
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index a61b882..9b09a48 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -27,11 +27,6 @@
     String[] tests = {
       "arithmetic.Arithmetic",
       "inlining.Inlining",
-      "regress.Regress",
-      "regress2.Regress2",
-      "regress_37726195.Regress",
-      "regress_37658666.Regress",
-      "regress_37875803.Regress",
       "regress_37955340.Regress",
       "regress_62300145.Regress",
       "regress_64881691.Regress",
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 8274614..81e32d0 100644
--- a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
@@ -60,31 +60,6 @@
   }
 
   @Test
-  public void testRegress() throws Exception {
-    testDebugging("regress", "Regress");
-  }
-
-  @Test
-  public void testRegress2() throws Exception {
-    testDebugging("regress2", "Regress2");
-  }
-
-  @Test
-  public void testRegress37726195() throws Exception {
-    testDebugging("regress_37726195", "Regress");
-  }
-
-  @Test
-  public void testRegress37658666() throws Exception {
-    testDebugging("regress_37658666", "Regress");
-  }
-
-  @Test
-  public void testRegress37875803() throws Exception {
-    testDebugging("regress_37875803", "Regress");
-  }
-
-  @Test
   public void testRegress37955340() throws Exception {
     testDebugging("regress_37955340", "Regress");
   }
diff --git a/src/test/examples/regress/Regress.java b/src/test/java/com/android/tools/r8/examples/regress/Regress.java
similarity index 95%
rename from src/test/examples/regress/Regress.java
rename to src/test/java/com/android/tools/r8/examples/regress/Regress.java
index 4b931b6..8a9107e 100644
--- a/src/test/examples/regress/Regress.java
+++ b/src/test/java/com/android/tools/r8/examples/regress/Regress.java
@@ -5,7 +5,7 @@
 // This code is not run directly. It needs to be compiled to dex code.
 // 'arithmetic.dex' is what is run.
 
-package regress;
+package com.android.tools.r8.examples.regress;
 
 public class Regress {
 
diff --git a/src/test/java/com/android/tools/r8/examples/regress/RegressTestRunner.java b/src/test/java/com/android/tools/r8/examples/regress/RegressTestRunner.java
new file mode 100644
index 0000000..36d5578
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress/RegressTestRunner.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.regress;
+
+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 RegressTestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public RegressTestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Regress.class;
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("LOOP", "LOOP", "LOOP", "LOOP");
+  }
+
+  @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/regress2/Regress2.java b/src/test/java/com/android/tools/r8/examples/regress2/Regress2.java
similarity index 94%
rename from src/test/examples/regress2/Regress2.java
rename to src/test/java/com/android/tools/r8/examples/regress2/Regress2.java
index 151a520..a1c5fcb 100644
--- a/src/test/examples/regress2/Regress2.java
+++ b/src/test/java/com/android/tools/r8/examples/regress2/Regress2.java
@@ -2,7 +2,7 @@
 // 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 regress2;
+package com.android.tools.r8.examples.regress2;
 
 public class Regress2 {
 
diff --git a/src/test/java/com/android/tools/r8/examples/regress2/Regress2TestRunner.java b/src/test/java/com/android/tools/r8/examples/regress2/Regress2TestRunner.java
new file mode 100644
index 0000000..5de6bdf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress2/Regress2TestRunner.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.regress2;
+
+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 Regress2TestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public Regress2TestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Regress2.class;
+  }
+
+  @Override
+  public List<Class<?>> getTestClasses() throws Exception {
+    return ImmutableList.of(getMainClass(), Regress2.X.class);
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("START", "LOOP", "LOOP", "LOOP", "LOOP", "LOOP", "END");
+  }
+
+  @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/regress_37658666/Regress.java b/src/test/java/com/android/tools/r8/examples/regress_37658666/Regress.java
similarity index 90%
rename from src/test/examples/regress_37658666/Regress.java
rename to src/test/java/com/android/tools/r8/examples/regress_37658666/Regress.java
index 4f6019d..9173418 100644
--- a/src/test/examples/regress_37658666/Regress.java
+++ b/src/test/java/com/android/tools/r8/examples/regress_37658666/Regress.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 regress_37658666;
+package com.android.tools.r8.examples.regress_37658666;
 
 class Float {
   int cmp(float a, float b) {
diff --git a/src/test/java/com/android/tools/r8/examples/regress_37658666/Regress37658666TestRunner.java b/src/test/java/com/android/tools/r8/examples/regress_37658666/Regress37658666TestRunner.java
new file mode 100644
index 0000000..55e283a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress_37658666/Regress37658666TestRunner.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.regress_37658666;
+
+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 Regress37658666TestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public Regress37658666TestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Regress.class;
+  }
+
+  @Override
+  public List<Class<?>> getTestClasses() throws Exception {
+    return ImmutableList.of(getMainClass(), Float.class);
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("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/regress_37726195/Regress.java b/src/test/java/com/android/tools/r8/examples/regress_37726195/Regress.java
similarity index 95%
rename from src/test/examples/regress_37726195/Regress.java
rename to src/test/java/com/android/tools/r8/examples/regress_37726195/Regress.java
index ad9781a..6bf7e81 100644
--- a/src/test/examples/regress_37726195/Regress.java
+++ b/src/test/java/com/android/tools/r8/examples/regress_37726195/Regress.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 regress_37726195;
+package com.android.tools.r8.examples.regress_37726195;
 
 public class Regress {
 
diff --git a/src/test/java/com/android/tools/r8/examples/regress_37726195/Regress37726195TestRunner.java b/src/test/java/com/android/tools/r8/examples/regress_37726195/Regress37726195TestRunner.java
new file mode 100644
index 0000000..7a8b0b6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress_37726195/Regress37726195TestRunner.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.regress_37726195;
+
+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 Regress37726195TestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public Regress37726195TestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Regress.class;
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("4", "4.0");
+  }
+
+  @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/regress_37875803/Regress.java b/src/test/java/com/android/tools/r8/examples/regress_37875803/Regress.java
similarity index 97%
rename from src/test/examples/regress_37875803/Regress.java
rename to src/test/java/com/android/tools/r8/examples/regress_37875803/Regress.java
index 9360046..26308cb 100644
--- a/src/test/examples/regress_37875803/Regress.java
+++ b/src/test/java/com/android/tools/r8/examples/regress_37875803/Regress.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 regress_37875803;
+package com.android.tools.r8.examples.regress_37875803;
 
 public class Regress {
 
diff --git a/src/test/java/com/android/tools/r8/examples/regress_37875803/Regress37875803TestRunner.java b/src/test/java/com/android/tools/r8/examples/regress_37875803/Regress37875803TestRunner.java
new file mode 100644
index 0000000..f309514
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress_37875803/Regress37875803TestRunner.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.regress_37875803;
+
+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 Regress37875803TestRunner extends ExamplesTestBase {
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+  }
+
+  public Regress37875803TestRunner(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  public Class<?> getMainClass() {
+    return Regress.class;
+  }
+
+  @Override
+  public String getExpected() {
+    return StringUtils.lines("10", "10", "10", "10", "204", "140", "107", "75");
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    runTestDesugaring();
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    runTestR8();
+  }
+
+  @Test
+  public void testDebug() throws Exception {
+    runTestDebugComparator();
+  }
+}