[LIR] Add support for not instruction.
Also migrates a legacy example regression test.
Bug: b/225838009
Bug: b/167145686
Change-Id: I8dcc30825cdd7edd9fe8c2b419e17602ed17f576
diff --git a/src/main/java/com/android/tools/r8/ir/code/Not.java b/src/main/java/com/android/tools/r8/ir/code/Not.java
index 097ae22..3c6f4c7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Not.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Not.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
+import com.android.tools.r8.lightir.LirBuilder;
import java.util.function.Function;
public class Not extends Unop {
@@ -105,4 +106,9 @@
// JVM has no Not instruction, they should be replaced by "Load -1, Xor" before building CF.
throw new Unreachable();
}
+
+ @Override
+ public void buildLir(LirBuilder<Value, ?> builder) {
+ builder.addNot(type, source());
+ }
}
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 bfd5625..2244a37 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -59,6 +59,7 @@
import com.android.tools.r8.ir.code.NewArrayFilledData;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.NewUnboxedEnumInstance;
+import com.android.tools.r8.ir.code.Not;
import com.android.tools.r8.ir.code.NumberConversion;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.NumericType;
@@ -435,6 +436,12 @@
}
@Override
+ public void onNot(NumericType type, EV value) {
+ Value dest = getOutValueForNextInstruction(valueTypeElement(type));
+ addInstruction(new Not(type, dest, getValue(value)));
+ }
+
+ @Override
public void onShl(NumericType type, EV left, EV right) {
Value dest = getOutValueForNextInstruction(valueTypeElement(type));
addInstruction(new Shl(type, dest, getValue(left), getValue(right)));
@@ -643,7 +650,8 @@
@Override
public void onInstancePut(DexField field, EV object, EV value) {
- addInstruction(new InstancePut(field, getValue(object), getValue(value)));
+ addInstruction(
+ InstancePut.createPotentiallyInvalid(field, getValue(object), getValue(value)));
}
@Override
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 ef0e769..6f56349 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -389,7 +389,7 @@
return addOneItemInstruction(LirOpcodes.LDC, type);
}
- public LirBuilder<V, EV> addNeg(NumericType type, V source) {
+ public LirBuilder<V, EV> addNeg(NumericType type, V value) {
int opcode;
switch (type) {
case BYTE:
@@ -410,7 +410,25 @@
default:
throw new Unreachable("Unexpected type: " + type);
}
- return addOneValueInstruction(opcode, source);
+ return addOneValueInstruction(opcode, value);
+ }
+
+ public LirBuilder<V, EV> addNot(NumericType type, V value) {
+ int opcode;
+ switch (type) {
+ case BYTE:
+ case CHAR:
+ case SHORT:
+ case INT:
+ opcode = LirOpcodes.INOT;
+ break;
+ case LONG:
+ opcode = LirOpcodes.LNOT;
+ break;
+ default:
+ throw new Unreachable("Unexpected type: " + type);
+ }
+ return addOneValueInstruction(opcode, value);
}
public LirBuilder<V, EV> addDiv(NumericType type, V leftValue, V rightValue) {
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 19179aa..d7ccc91 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirOpcodes.java
@@ -198,6 +198,8 @@
int NEWARRAYFILLEDDATA = 215;
int ITEMBASEDCONSTSTRING = 216;
int NEWUNBOXEDENUMINSTANCE = 217;
+ int INOT = 218;
+ int LNOT = 219;
static String toString(int opcode) {
switch (opcode) {
@@ -518,6 +520,10 @@
return "ITEMBASEDCONSTSTRING";
case NEWUNBOXEDENUMINSTANCE:
return "NEWUNBOXEDENUMINSTANCE";
+ case INOT:
+ return "INOT";
+ case LNOT:
+ return "LNOT";
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 c19f035..3aebb0e 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirParsedInstructionCallback.java
@@ -243,6 +243,10 @@
onInstruction();
}
+ public void onNot(NumericType type, EV value) {
+ onInstruction();
+ }
+
private void onLogicalBinopInternal(int opcode, LirInstructionView view) {
EV left = getNextValueOperand(view);
EV right = getNextValueOperand(view);
@@ -277,7 +281,7 @@
onXor(NumericType.INT, left, right);
return;
case LirOpcodes.LXOR:
- onXor(NumericType.INT, left, right);
+ onXor(NumericType.LONG, left, right);
return;
default:
throw new Unreachable("Unexpected logical binop: " + opcode);
@@ -1137,6 +1141,13 @@
onNewUnboxedEnumInstance(type, ordinal);
return;
}
+ case LirOpcodes.INOT:
+ case LirOpcodes.LNOT:
+ {
+ EV value = getNextValueOperand(view);
+ onNot(opcode == LirOpcodes.INOT ? NumericType.INT : NumericType.LONG, value);
+ return;
+ }
default:
throw new Unimplemented("No dispatch for opcode " + LirOpcodes.toString(opcode));
}
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 b818d6b..d49c90f 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirPrinter.java
@@ -176,6 +176,12 @@
}
@Override
+ public void onNot(NumericType type, EV value) {
+ appendOutValue();
+ appendValueArguments(value);
+ }
+
+ @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 190ef4b..c8e1bca 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -27,7 +27,6 @@
String[] tests = {
"arithmetic.Arithmetic",
"inlining.Inlining",
- "regress_70737019.Test",
"regress_72361252.Test",
"regress_110373181.Regress",
"memberrebinding2.Memberrebinding",
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 1018d03..da84de5 100644
--- a/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ExamplesDebugTest.java
@@ -60,11 +60,6 @@
}
@Test
- public void testRegress70737019() throws Exception {
- testDebugging("regress_70737019", "Test");
- }
-
- @Test
public void testRegress72361252() throws Exception {
testDebugging("regress_72361252", "Test");
}
diff --git a/src/test/java/com/android/tools/r8/examples/regress_70737019/Regress70737019TestRunner.java b/src/test/java/com/android/tools/r8/examples/regress_70737019/Regress70737019TestRunner.java
new file mode 100644
index 0000000..93bb0d4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/examples/regress_70737019/Regress70737019TestRunner.java
@@ -0,0 +1,71 @@
+// 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_70737019;
+
+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 Regress70737019TestRunner extends ExamplesTestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build();
+ }
+
+ public Regress70737019TestRunner(TestParameters parameters) {
+ super(parameters);
+ }
+
+ @Override
+ public Class<?> getMainClass() {
+ return TestClass.class;
+ }
+
+ @Override
+ public List<Class<?>> getTestClasses() throws Exception {
+ String outerClass = typeName(TestClass.class);
+ return ImmutableList.of(
+ getMainClass(),
+ Class.forName(outerClass + "$1"),
+ Class.forName(outerClass + "$X"),
+ Class.forName(outerClass + "$A"),
+ Class.forName(outerClass + "$B"),
+ Class.forName(outerClass + "$C"));
+ }
+
+ @Override
+ public String getExpected() {
+ return StringUtils.lines(
+ "r = NaN",
+ "mZ = false",
+ "mI = 1",
+ "mJ = 0",
+ "mF = NaN",
+ "mD = 0.0",
+ "mArray = [[[[[[[[[[1.0775E8]]]]]]]]]]");
+ }
+
+ @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_70737019/Test.java b/src/test/java/com/android/tools/r8/examples/regress_70737019/TestClass.java
similarity index 96%
rename from src/test/examples/regress_70737019/Test.java
rename to src/test/java/com/android/tools/r8/examples/regress_70737019/TestClass.java
index 59d498e..27fb29e 100644
--- a/src/test/examples/regress_70737019/Test.java
+++ b/src/test/java/com/android/tools/r8/examples/regress_70737019/TestClass.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 regress_70737019;
+package com.android.tools.r8.examples.regress_70737019;
/**
* AOSP JFuzz Tester.
@@ -12,7 +12,7 @@
import java.util.Arrays;
-public class Test {
+public class TestClass {
private interface X {
int x();
@@ -63,7 +63,7 @@
return a && b;
}
- private Test() {
+ private TestClass() {
float a = 107750002.0f;
for (int i0 = 0; i0 < 1; i0++) {
for (int i1 = 0; i1 < 1; i1++) {
@@ -131,7 +131,7 @@
mArray = tmp;
}
}
- mZ &= ((mI != 820389954) ? mZ : (this instanceof Test));
+ mZ &= ((mI != 820389954) ? mZ : (this instanceof TestClass));
break;
}
}
@@ -168,7 +168,7 @@
mI %= (~ 1326172655);
switch (i0) {
case 0: {
- mZ |= (true | ((logicalAnd(mZ, (this instanceof Test))) && mZ));
+ mZ |= (true | ((logicalAnd(mZ, (this instanceof TestClass))) && mZ));
if ((((boolean) new Boolean(true)) || (((boolean) new Boolean((false | (! mZ)))) | (! true)))) {
mI /= ((int)(byte)(int) (((mI / mI) >> 265234301) | 188234363));
{
@@ -193,7 +193,7 @@
}
}
}
- mZ |= (this instanceof Test);
+ mZ |= (this instanceof TestClass);
break;
}
default: {
@@ -232,7 +232,7 @@
public static void nop() {}
public static void main(String[] args) {
- Test t = new Test();
+ TestClass t = new TestClass();
float r = 1457261414.0f;
try {
r = t.testMethod();