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.