Allow (improved) changes of dynamic return type of methods.

Bug: 139246447
Change-Id: Id28c272a81d175a3838986c108e7b85ba7f25ac3
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index cb8d7be..acbce17 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1610,7 +1610,8 @@
     @Override
     public void markReturnsConstantNumber(long value) {
       assert !returnsConstantString;
-      assert !returnsConstantNumber || returnedConstantNumber == value;
+      assert !returnsConstantNumber || returnedConstantNumber == value
+          : "return constant number changed from " + returnedConstantNumber + " to " + value;
       returnsConstantNumber = true;
       returnedConstantNumber = value;
     }
@@ -1618,15 +1619,21 @@
     @Override
     public void markReturnsConstantString(DexString value) {
       assert !returnsConstantNumber;
-      assert !returnsConstantString || returnedConstantString == value;
+      assert !returnsConstantString || returnedConstantString == value
+          : "return constant string changed from " + returnedConstantString + " to " + value;
       returnsConstantString = true;
       returnedConstantString = value;
     }
 
     @Override
-    public void markReturnsObjectOfType(TypeLatticeElement type) {
+    public void markReturnsObjectOfType(AppView<?> appView, TypeLatticeElement type) {
       assert type != null;
-      assert returnsObjectOfType == UNKNOWN_TYPE || returnsObjectOfType == type;
+      // We may get more precise type information if the method is reprocessed (e.g., due to
+      // optimization info collected from all call sites), and hence the `returnsObjectOfType` is
+      // allowed to become more precise.
+      assert returnsObjectOfType == UNKNOWN_TYPE
+          || type.lessThanOrEqual(returnsObjectOfType, appView)
+          : "return type changed from " + returnsObjectOfType + " to " + type;
       returnsObjectOfType = type;
     }
 
diff --git a/src/main/java/com/android/tools/r8/graph/UpdatableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/graph/UpdatableMethodOptimizationInfo.java
index c8e7f32..601bc7b 100644
--- a/src/main/java/com/android/tools/r8/graph/UpdatableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/UpdatableMethodOptimizationInfo.java
@@ -24,7 +24,7 @@
 
   void markReturnsConstantString(DexString value);
 
-  void markReturnsObjectOfType(TypeLatticeElement type);
+  void markReturnsObjectOfType(AppView<?> appView, TypeLatticeElement type);
 
   void markAsPropagated();
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index ee9d779..1ba87f9 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1392,7 +1392,7 @@
       // If the dynamic return type is not more precise than the static return type there is no need
       // to record it.
       if (dynamicReturnType.strictlyLessThan(staticReturnType, appView)) {
-        feedback.methodReturnsObjectOfType(method, dynamicReturnType);
+        feedback.methodReturnsObjectOfType(method, appView, dynamicReturnType);
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedback.java b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedback.java
index ce519e5..c5bff88 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedback.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedback.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.conversion;
 
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
 import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer;
@@ -28,7 +29,8 @@
 
   void methodReturnsConstantString(DexEncodedMethod method, DexString value);
 
-  void methodReturnsObjectOfType(DexEncodedMethod method, TypeLatticeElement type);
+  void methodReturnsObjectOfType(
+      DexEncodedMethod method, AppView<?> appView, TypeLatticeElement type);
 
   void methodMayNotHaveSideEffects(DexEncodedMethod method);
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackDelayed.java b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackDelayed.java
index 9652598..5b900d2 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackDelayed.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackDelayed.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.conversion;
 
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
 import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer;
@@ -65,8 +66,8 @@
 
   @Override
   public synchronized void methodReturnsObjectOfType(
-      DexEncodedMethod method, TypeLatticeElement type) {
-    getOptimizationInfoForUpdating(method).markReturnsObjectOfType(type);
+      DexEncodedMethod method, AppView<?> appView, TypeLatticeElement type) {
+    getOptimizationInfoForUpdating(method).markReturnsObjectOfType(appView, type);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackIgnore.java b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackIgnore.java
index d20f34b..a2d7387 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackIgnore.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackIgnore.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.conversion;
 
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
 import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer;
@@ -42,7 +43,8 @@
   public void methodReturnsConstantString(DexEncodedMethod method, DexString value) {}
 
   @Override
-  public void methodReturnsObjectOfType(DexEncodedMethod method, TypeLatticeElement type) {}
+  public void methodReturnsObjectOfType(
+      DexEncodedMethod method, AppView<?> appView, TypeLatticeElement type) {}
 
   @Override
   public void methodMayNotHaveSideEffects(DexEncodedMethod method) {}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackSimple.java b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackSimple.java
index 60df80c..024c815 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackSimple.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/OptimizationFeedbackSimple.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.conversion;
 
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
 import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer;
@@ -44,7 +45,8 @@
   }
 
   @Override
-  public void methodReturnsObjectOfType(DexEncodedMethod method, TypeLatticeElement type) {
+  public void methodReturnsObjectOfType(
+      DexEncodedMethod method, AppView<?> appView, TypeLatticeElement type) {
     // Ignored.
   }