Propagate type constraints of trivial phis
Bug: 119401913
Change-Id: Ifac169045eaeb33949692e58a796ae4746772f8c
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 2446b3b..dd0e174 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.TypeChecker;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
+import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.InternalOptions;
@@ -836,10 +837,14 @@
}
public void removeAllTrivialPhis() {
+ removeAllTrivialPhis(null);
+ }
+
+ public void removeAllTrivialPhis(IRBuilder builder) {
for (BasicBlock block : blocks) {
List<Phi> phis = new ArrayList<>(block.getPhis());
for (Phi phi : phis) {
- phi.removeTrivialPhi();
+ phi.removeTrivialPhi(builder);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 617008e..566ab41 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -124,7 +124,7 @@
builder.constrainType(operand, readConstraint);
appendOperand(operand);
}
- removeTrivialPhi();
+ removeTrivialPhi(builder);
recomputeNeverNull();
}
@@ -247,6 +247,10 @@
}
public void removeTrivialPhi() {
+ removeTrivialPhi(null);
+ }
+
+ public void removeTrivialPhi(IRBuilder builder) {
Value same = null;
for (Value op : operands) {
if (op == same || op == this) {
@@ -267,6 +271,10 @@
// leave the phi in there and check at the end that there are no trivial phis.
return;
}
+ // Ensure that the value that replaces this phi is constrained to the type of this phi.
+ if (builder != null && typeLattice.isPreciseType()) {
+ builder.constrainType(same, ValueType.fromTypeLattice(typeLattice));
+ }
// Removing this phi, so get rid of it as a phi user from all of the operands to avoid
// recursively getting back here with the same phi. If the phi has itself as an operand
// that also removes the self-reference.
@@ -292,7 +300,7 @@
replaceUsers(same);
// Try to simplify phi users that might now have become trivial.
for (Phi user : phiUsersToSimplify) {
- user.removeTrivialPhi();
+ user.removeTrivialPhi(builder);
}
}
// Get rid of the phi itself.
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 596de48..c597702 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -596,7 +596,7 @@
block.deduplicatePhis();
}
- ir.removeAllTrivialPhis();
+ ir.removeAllTrivialPhis(this);
ir.removeUnreachableBlocks();
// Constrain all values to precise types.
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeConstraintOnTrivialPhiTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeConstraintOnTrivialPhiTest.java
index da32262..5f6efa2 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeConstraintOnTrivialPhiTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeConstraintOnTrivialPhiTest.java
@@ -19,7 +19,6 @@
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.util.function.Consumer;
-import org.junit.Ignore;
import org.junit.Test;
public class TypeConstraintOnTrivialPhiTest extends TypeAnalysisTestBase {
@@ -88,7 +87,6 @@
}
@Test
- @Ignore("b/119401913")
public void testFloatConstraintOnTrivialPhi() throws Exception {
buildAndCheckIR("floatConstraintOnTrivialPhiTest", testInspector(FLOAT));
}
@@ -99,7 +97,6 @@
}
@Test
- @Ignore("b/119401913")
public void testDoubleConstraintOnTrivialPhi() throws Exception {
buildAndCheckIR("doubleConstraintOnTrivialPhiTest", testInspector(DOUBLE));
}