Version 1.4.23

Merge: Unset optimization info for staticized methods
CL: https://r8-review.googlesource.com/c/r8/+/32880

Bug: 122634266
Change-Id: I8c3f7ddd183e3bd694d96f0408d6aa126e602d86
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index ae09545..e0b2994 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.4.22";
+  public static final String LABEL = "1.4.23";
 
   private Version() {
   }
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 4934336..4db858b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -684,9 +684,7 @@
   public DexEncodedMethod toStaticMethodWithoutThis() {
     checkIfObsolete();
     assert !accessFlags.isStatic();
-    Builder builder = builder(this);
-    builder.setStatic();
-    builder.withoutThisParameter();
+    Builder builder = builder(this).setStatic().unsetOptimizationInfo().withoutThisParameter();
     setObsolete();
     return builder.build();
   }
@@ -1256,17 +1254,24 @@
       this.method = method;
     }
 
-    public void setStatic() {
+    public Builder setStatic() {
       this.accessFlags.setStatic();
+      return this;
     }
 
-    public void withoutThisParameter() {
+    public Builder unsetOptimizationInfo() {
+      optimizationInfo = DefaultOptimizationInfoImpl.DEFAULT_INSTANCE;
+      return this;
+    }
+
+    public Builder withoutThisParameter() {
       assert code != null;
       if (code.isDexCode()) {
         code = code.asDexCode().withoutThisParameter();
       } else {
         throw new Unreachable("Code " + code.getClass().getSimpleName() + " is not supported.");
       }
+      return this;
     }
 
     public void setCode(Code code) {
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 5c1fae1..b1598bc 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
@@ -13,6 +13,7 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -154,6 +155,7 @@
 
   public final IRConverter converter;
   private final AppInfo appInfo;
+  private final AppView<? extends AppInfo> appView;
   private final DexItemFactory dexItemFactory;
   private final Set<DexMethod> libraryMethodsReturningReceiver;
   private final InternalOptions options;
@@ -164,6 +166,7 @@
       InternalOptions options) {
     this.converter = converter;
     this.appInfo = converter.appInfo;
+    this.appView = converter.appView;
     this.options = options;
     this.dexItemFactory = appInfo.dexItemFactory;
     this.libraryMethodsReturningReceiver = libraryMethodsReturningReceiver;
@@ -1570,20 +1573,29 @@
     }
   }
 
-  private boolean checkArgumentType(InvokeMethod invoke, DexMethod target, int argumentIndex) {
-    DexType returnType = invoke.getInvokedMethod().proto.returnType;
+  private boolean checkArgumentType(InvokeMethod invoke, int argumentIndex) {
     // TODO(sgjesse): Insert cast if required.
-    if (invoke.isInvokeStatic()) {
-      return invoke.getInvokedMethod().proto.parameters.values[argumentIndex] == returnType;
+    TypeLatticeElement returnType =
+        TypeLatticeElement.fromDexType(invoke.getInvokedMethod().proto.returnType, false, appInfo);
+    TypeLatticeElement argumentType =
+        TypeLatticeElement.fromDexType(getArgumentType(invoke, argumentIndex), false, appInfo);
+    if (appView != null && appView.enableWholeProgramOptimizations()) {
+      return argumentType.lessThanOrEqual(returnType, appInfo);
     } else {
-      if (argumentIndex == 0) {
-        return invoke.getInvokedMethod().getHolder() == returnType;
-      } else {
-        return invoke.getInvokedMethod().proto.parameters.values[argumentIndex - 1] == returnType;
-      }
+      return argumentType.equals(returnType);
     }
   }
 
+  private DexType getArgumentType(InvokeMethod invoke, int argumentIndex) {
+    if (invoke.isInvokeStatic()) {
+      return invoke.getInvokedMethod().proto.parameters.values[argumentIndex];
+    }
+    if (argumentIndex == 0) {
+      return invoke.getInvokedMethod().getHolder();
+    }
+    return invoke.getInvokedMethod().proto.parameters.values[argumentIndex - 1];
+  }
+
   // Replace result uses for methods where something is known about what is returned.
   public void rewriteMoveResult(IRCode code) {
     if (options.isGeneratingClassFiles()) {
@@ -1599,7 +1611,7 @@
         InvokeMethod invoke = current.asInvokeMethod();
         if (invoke.outValue() != null && !invoke.outValue().hasLocalInfo()) {
           if (libraryMethodsReturningReceiver.contains(invoke.getInvokedMethod())) {
-            if (checkArgumentType(invoke, invoke.getInvokedMethod(), 0)) {
+            if (checkArgumentType(invoke, 0)) {
               invoke.outValue().replaceUsers(invoke.arguments().get(0));
               invoke.setOutValue(null);
             }
@@ -1613,8 +1625,7 @@
               if (definition != null && definition.getOptimizationInfo().returnsArgument()) {
                 int argumentIndex = definition.getOptimizationInfo().getReturnedArgument();
                 // Replace the out value of the invoke with the argument and ignore the out value.
-                if (argumentIndex != -1
-                    && checkArgumentType(invoke, target.method, argumentIndex)) {
+                if (argumentIndex >= 0 && checkArgumentType(invoke, argumentIndex)) {
                   Value argument = invoke.arguments().get(argumentIndex);
                   Value outValue = invoke.outValue();
                   assert outValue.verifyCompatible(argument.outType());