Remove out-value from calls to StringBuilder.append() for dex

Bug: b/224959526
Bug: b/165774951
Change-Id: I242ad2ef7f5be5fe5aac9c2343b0f7e7168b4564
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/StringBuilderMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/StringBuilderMethodOptimizer.java
index 8e03c61..835baa6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/StringBuilderMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/StringBuilderMethodOptimizer.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.ir.code.InvokeMethodWithReceiver;
 import com.android.tools.r8.ir.code.InvokeStatic;
 import com.android.tools.r8.ir.code.InvokeVirtual;
+import com.android.tools.r8.ir.code.Phi;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.conversion.MethodProcessor;
 import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations;
@@ -81,7 +82,6 @@
       InvokeMethodWithReceiver invokeWithReceiver = invoke.asInvokeMethodWithReceiver();
       if (stringBuilderMethods.isAppendMethod(singleTarget.getReference())) {
         optimizeAppend(
-            code,
             instructionIterator,
             invokeWithReceiver,
             singleTarget,
@@ -94,18 +94,30 @@
   }
 
   private void optimizeAppend(
-      IRCode code,
       InstructionListIterator instructionIterator,
       InvokeMethodWithReceiver invoke,
       DexClassAndMethod singleTarget,
       State state,
       MethodProcessingContext methodProcessingContext) {
-    if (!state.isUnusedBuilder(invoke.getReceiver())) {
-      return;
-    }
-    if (invoke.hasOutValue()) {
+    boolean isStringBuilderUnused = state.isUnusedBuilder(invoke.getReceiver());
+    if (invoke.hasOutValue() && (options.isGeneratingDex() || isStringBuilderUnused)) {
       invoke.outValue().replaceUsers(invoke.getReceiver());
+      invoke.getReceiver().uniquePhiUsers().forEach(Phi::removeTrivialPhi);
+      invoke.clearOutValue();
     }
+    if (isStringBuilderUnused) {
+      optimizeAppendOnUnusedStringBuilder(
+          instructionIterator, invoke, singleTarget, state, methodProcessingContext);
+    }
+  }
+
+  private void optimizeAppendOnUnusedStringBuilder(
+      InstructionListIterator instructionIterator,
+      InvokeMethodWithReceiver invoke,
+      DexClassAndMethod singleTarget,
+      State state,
+      MethodProcessingContext methodProcessingContext) {
+    assert !invoke.hasOutValue();
     DexMethod appendMethod = singleTarget.getReference();
     if (stringBuilderMethods.isAppendPrimitiveMethod(appendMethod)
         || stringBuilderMethods.isAppendStringMethod(appendMethod)) {