Workaround instance-of type weakening in verifier
Bug: b/288273207
Change-Id: I9f3ece2f4292fe37e5928876e45f5e22c958a103
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java b/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
index cf59a7e..3a966f1 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRToDexFinalizer.java
@@ -44,6 +44,7 @@
RuntimeWorkaroundCodeRewriter.workaroundNumberConversionRegisterAllocationBug(code, options);
// Workaround massive dex2oat memory use for self-recursive methods.
RuntimeWorkaroundCodeRewriter.workaroundDex2OatInliningIssue(appView, code);
+ RuntimeWorkaroundCodeRewriter.workaroundInstanceOfTypeWeakeningInVerifier(appView, code);
// Workaround MAX_INT switch issue.
RuntimeWorkaroundCodeRewriter.workaroundSwitchMaxIntBug(code, codeRewriter, options);
RuntimeWorkaroundCodeRewriter.workaroundDex2OatLinkedListBug(code, options);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
index afed4c2..e7d2e5c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RuntimeWorkaroundCodeRewriter.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.ir.code.AlwaysMaterializingUser;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.InstanceOf;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.IntSwitch;
@@ -68,6 +69,19 @@
}
}
+ public static void workaroundInstanceOfTypeWeakeningInVerifier(AppView<?> appView, IRCode code) {
+ for (BasicBlock block : code.getBlocks()) {
+ InstructionListIterator instructionIterator = block.listIterator(code);
+ while (instructionIterator.hasNext()) {
+ InstanceOf instanceOf = instructionIterator.nextUntil(Instruction::isInstanceOf);
+ if (instanceOf != null && instanceOf.value().getType().isNullType()) {
+ instructionIterator.replaceCurrentInstructionWithConstFalse(code);
+ }
+ }
+ }
+ assert code.isConsistentSSA(appView);
+ }
+
/**
* For each block, we look to see if the header matches:
*
diff --git a/src/test/java/com/android/tools/r8/workaround/IncorrectTypeRefinementForThrowableTest.java b/src/test/java/com/android/tools/r8/workaround/IncorrectTypeRefinementForThrowableTest.java
index 4ebca46..bf3f43e 100644
--- a/src/test/java/com/android/tools/r8/workaround/IncorrectTypeRefinementForThrowableTest.java
+++ b/src/test/java/com/android/tools/r8/workaround/IncorrectTypeRefinementForThrowableTest.java
@@ -4,13 +4,10 @@
package com.android.tools.r8.workaround;
-import static org.junit.Assume.assumeFalse;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestRunResult;
-import com.android.tools.r8.utils.BooleanUtils;
-import java.util.List;
+import com.android.tools.r8.TestParametersCollection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -21,15 +18,11 @@
public class IncorrectTypeRefinementForThrowableTest extends TestBase {
@Parameter(0)
- public boolean enableCheckCastAndInstanceOfRemoval;
-
- @Parameter(1)
public TestParameters parameters;
- @Parameters(name = "{1}, optimize: {0}")
- public static List<Object[]> data() {
- return buildParameters(
- BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
@Test
@@ -37,23 +30,14 @@
parameters.assumeDexRuntime();
testForD8(parameters.getBackend())
.addInnerClasses(getClass())
- .addOptionsModification(
- options ->
- options.testing.enableCheckCastAndInstanceOfRemoval =
- enableCheckCastAndInstanceOfRemoval)
.release()
.setMinApi(parameters)
.run(parameters.getRuntime(), Main.class)
- // TODO(b/288273207): Should remove the instanceof check.
- .applyIf(
- parameters.getDexRuntimeVersion().isDalvik(),
- TestRunResult::assertSuccessWithEmptyOutput,
- runResult -> runResult.assertFailureWithErrorThatThrows(VerifyError.class));
+ .assertSuccessWithEmptyOutput();
}
@Test
public void testJvm() throws Exception {
- assumeFalse(enableCheckCastAndInstanceOfRemoval);
parameters.assumeJvmTestParameters();
testForJvm(parameters)
.addInnerClasses(getClass())