Update null cyclic phis when rewriting always throwing instructions
Bug: b/250634405
Change-Id: I3a26861b028c553e8bb5c66ae30f335d19bc40c4
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java b/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
index 0ccf414..89e78e5 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/DestructivePhiTypeUpdater.java
@@ -60,7 +60,7 @@
worklist.addAll(affectedPhis);
while (!worklist.isEmpty()) {
Phi phi = worklist.poll();
- TypeElement newType = phi.computePhiType(appView);
+ TypeElement newType = phi.getDynamicUpperBoundType(appView);
if (!phi.getType().equals(newType)) {
assert !newType.isBottom();
phi.setType(newType);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index a2cd8e8..dbd19bd 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AccessControl;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
@@ -3367,6 +3368,28 @@
ListIterator<BasicBlock> blockIterator = code.listIterator();
ProgramMethod context = code.context();
boolean hasUnlinkedCatchHandlers = false;
+ // For cyclic phis we sometimes do not propagate the dynamic upper type after rewritings.
+ // The inValue.isAlwaysNull(appView) check below will not recompute the dynamic type of phi's
+ // so we recompute all phis here if they are always null.
+ AppView<AppInfoWithClassHierarchy> appViewWithClassHierarchy =
+ appView.hasClassHierarchy() ? appView.withClassHierarchy() : null;
+ if (appViewWithClassHierarchy != null) {
+ code.blocks.forEach(
+ block ->
+ block
+ .getPhis()
+ .forEach(
+ phi -> {
+ if (!phi.getType().isDefinitelyNull()) {
+ TypeElement dynamicUpperBoundType =
+ phi.getDynamicUpperBoundType(appViewWithClassHierarchy);
+ if (dynamicUpperBoundType.isDefinitelyNull()) {
+ affectedValues.add(phi);
+ phi.setType(dynamicUpperBoundType);
+ }
+ }
+ }));
+ }
while (blockIterator.hasNext()) {
BasicBlock block = blockIterator.next();
if (block.getNumber() != 0 && block.getPredecessors().isEmpty()) {