Version 1.0.18.

R=sgjesse@google.com

Merge: Spill a valid register when no valid register candidate can be found.
CL: https://r8-review.googlesource.com/c/r8/+/17860
Change-Id: I0ac96a83a2a2068683bbfda99a146c0df848e7d6
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 907f840..8badad0 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 = "v1.0.17";
+  public static final String LABEL = "v1.0.18";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index f67aade..15c1396 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -1282,10 +1282,17 @@
     // free position.
     int candidate = getLargestValidCandidate(
         unhandledInterval, registerConstraint, needsRegisterPair, freePositions, Type.ANY);
-    assert candidate != REGISTER_CANDIDATE_NOT_FOUND;
-    int largestFreePosition = freePositions.get(candidate);
-    if (needsRegisterPair) {
-      largestFreePosition = Math.min(largestFreePosition, freePositions.get(candidate + 1));
+
+    // It is not always possible to find a largest valid candidate. If none of the usable register
+    // are free we typically get the last candidate. However, if that candidate has to be
+    // discarded in order to workaround bugs we get REGISTER_CANDIDATE_NOT_FOUND. In both cases
+    // we need to spill a valid candidate. That path is triggered when largestFreePosition is 0.
+    int largestFreePosition = 0;
+    if (candidate != REGISTER_CANDIDATE_NOT_FOUND) {
+      largestFreePosition = freePositions.get(candidate);
+      if (needsRegisterPair) {
+        largestFreePosition = Math.min(largestFreePosition, freePositions.get(candidate + 1));
+      }
     }
 
     // Determine what to do based on how long the selected candidate is free.
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 42ff1d7..f3fb918 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -145,10 +145,6 @@
           .put("974-verify-interface-super", AndroidApiLevel.N.getLevel())
           // Desugaring of interface private methods is not yet supported.
           .put("975-iface-private", AndroidApiLevel.N.getLevel())
-          // The extended check for overlapping long registers cause this to run out of registers.
-          .put("421-large-frame", AndroidApiLevel.N.getLevel())
-          // The extended check for overlapping long registers cause this to run out of registers.
-          .put("551-checker-shifter-operand", AndroidApiLevel.N.getLevel())
           .build();
 
   // Tests that timeout when run with Art.
@@ -839,9 +835,6 @@
           .put("973-default-multidex", beforeAndroidN) // --min-sdk = 24
           .put("974-verify-interface-super", beforeAndroidN) // --min-sdk = 24
           .put("975-iface-private", beforeAndroidN) // --min-sdk = 24
-          // These tests have min-api set to N.
-          .put("421-large-frame", beforeAndroidN) // --min-sdk = 24
-          .put("551-checker-shifter-operand", beforeAndroidN) // --min-sdk = 24
           // Uses dex file version 37 and therefore only runs on Android N and above.
           .put("972-iface-super-multidex",
               TestCondition.match(TestCondition.tools(DexTool.JACK, DexTool.DX),