Merge "Correct type lattice conversion in NumberConversion."
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/PrimitiveTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/PrimitiveTypeLatticeElement.java
index 2bfe88d..2eb732d 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/PrimitiveTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/PrimitiveTypeLatticeElement.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.InternalCompilerError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.code.NumericType;
/**
* A {@link TypeLatticeElement} that abstracts primitive types.
@@ -57,6 +58,24 @@
}
}
+ public static PrimitiveTypeLatticeElement fromNumericType(NumericType numericType) {
+ switch(numericType) {
+ case BYTE:
+ case CHAR:
+ case SHORT:
+ case INT:
+ return IntTypeLatticeElement.getInstance();
+ case FLOAT:
+ return FloatTypeLatticeElement.getInstance();
+ case LONG:
+ return LongTypeLatticeElement.getInstance();
+ case DOUBLE:
+ return DoubleTypeLatticeElement.getInstance();
+ default:
+ throw new Unreachable("Invalid numeric type '" + numericType + "'");
+ }
+ }
+
public static TypeLatticeElement join(
PrimitiveTypeLatticeElement t1, PrimitiveTypeLatticeElement t2) {
if (t1 == t2) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
index f1c0049..d676216 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
@@ -20,6 +20,9 @@
import com.android.tools.r8.code.LongToFloat;
import com.android.tools.r8.code.LongToInt;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.ir.analysis.type.PrimitiveTypeLatticeElement;
+import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -146,6 +149,11 @@
}
@Override
+ public TypeLatticeElement evaluate(AppInfo appInfo) {
+ return PrimitiveTypeLatticeElement.fromNumericType(to);
+ }
+
+ @Override
public void buildCf(CfBuilder builder) {
builder.add(new CfNumberConversion(from, to));
}
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index fdb86a1..a2f8d3e 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.ir.code.InvokeNewArray;
import com.android.tools.r8.ir.code.NewArrayEmpty;
import com.android.tools.r8.ir.code.NewInstance;
+import com.android.tools.r8.ir.code.NumberConversion;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
@@ -60,6 +61,7 @@
private static final TypeLatticeElement NULL = NullLatticeElement.getInstance();
private static final TypeLatticeElement SINGLE = SingleTypeLatticeElement.getInstance();
private static final TypeLatticeElement INT = IntTypeLatticeElement.getInstance();
+ private static final TypeLatticeElement LONG = LongTypeLatticeElement.getInstance();
private final String dirName;
private final String smaliFileName;
@@ -287,7 +289,18 @@
method.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, method);
analysis.widening(method, irCode);
- forEachOutValue(irCode, (v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
+ forEachOutValue(irCode, (v, l) -> {
+ verifyTypeEnvironment(expectedLattices, v, l);
+ // There are double-to-int, long-to-int, and int-to-long conversions in this example.
+ if (v.definition != null && v.definition.isNumberConversion()) {
+ NumberConversion instr = v.definition.asNumberConversion();
+ if (instr.to.isWide()) {
+ assertEquals(LONG, l);
+ } else {
+ assertEquals(INT, l);
+ }
+ }
+ });
}
// One more complicated example.