Version 1.4.60

Cherry pick: Make moves from argument registers block moves to argument registers
CL: https://r8-review.googlesource.com/c/r8/+/34880

Bug: 126273993
Change-Id: I2d5715bf42c2ced9eb6b8a66f4ace5e7363a65a8
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 3fe4334..f26dab4 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.59";
+  public static final String LABEL = "1.4.60";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java
index fb681b9..92992e8 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/RegisterMove.java
@@ -25,7 +25,7 @@
   }
 
   public RegisterMove(int dst, TypeLatticeElement type, Instruction definition) {
-    assert definition.isOutConstant() || definition.isArgument();
+    assert definition.isOutConstant();
     this.dst = dst;
     this.src = LiveIntervals.NO_REGISTER;
     this.definition = definition;
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java b/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java
index fa82d2b..698a1e6 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/SpillMoveSet.java
@@ -353,9 +353,18 @@
       // Use rematerialization when possible and otherwise generate moves.
       if (move.from.isSpilledAndRematerializable()) {
         assert allocator.unadjustedRealRegisterFromAllocated(move.to.getRegister()) < 256;
-        scheduler.addMove(
-            new RegisterMove(move.to.getRegister(), move.type, move.from.getValue().definition));
-      } else if (move.to.getRegister() != move.from.getRegister()) {
+        Instruction definition = move.from.getValue().definition;
+        if (definition.isOutConstant()) {
+          scheduler.addMove(new RegisterMove(move.to.getRegister(), move.type, definition));
+          continue;
+        } else {
+          // The src value is an argument, so we must create a register move that has a src
+          // register, using the code below, to ensure that other moves that have the argument
+          // register as dest are blocked by this move.
+          assert definition.isArgument();
+        }
+      }
+      if (move.to.getRegister() != move.from.getRegister()) {
         // In case the runtime might have a bound-check elimination bug we make sure to define all
         // indexing constants with an actual const instruction rather than a move. This appears to
         // avoid a bug where the index variable could end up being uninitialized.