Check for compare when shorting live ranges for instance-get

Bug: b/251015885
Change-Id: Ia914ba6c4cc1e54686299cc2ce50bb06d1ee2718
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 4d31397..6099074 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
@@ -1980,8 +1980,13 @@
       Map<BasicBlock, LinkedHashMap<Value, Instruction>> addConstantInBlock,
       Predicate<Instruction> selector) {
     InstructionListIterator iterator = block.listIterator(code);
+    boolean seenCompareExit = false;
     while (iterator.hasNext()) {
       Instruction instruction = iterator.next();
+      if (options.canHaveCmpIfFloatBug() && instruction.isCmp()) {
+        seenCompareExit = true;
+      }
+
       if (instruction.hasUnusedOutValue() || instruction.outValue().hasLocalInfo()) {
         continue;
       }
@@ -2008,6 +2013,7 @@
         Instruction uniqueUse = instruction.outValue().singleUniqueUser();
         Instruction next = iterator.next();
         if (uniqueUse == next) {
+          iterator.previous();
           continue;
         }
         if (next.hasOutValue()
@@ -2017,6 +2023,7 @@
           Instruction nextNext = iterator.peekNext();
           Instruction uniqueUseNext = next.outValue().singleUniqueUser();
           if (uniqueUse == nextNext && uniqueUseNext == nextNext) {
+            iterator.previous();
             continue;
           }
         }
@@ -2053,6 +2060,14 @@
         }
       }
 
+      // If the dominator block has a potential compare exit we will chose that as the insertion
+      // point. Uniquely for instructions having invalues this can be before the definition of them.
+      // Bail-out when this is the case. See b/251015885 for more information.
+      if (seenCompareExit
+          && Iterables.any(instruction.inValues(), x -> x.getBlock() == dominator)) {
+        continue;
+      }
+
       Instruction copy;
       switch (instruction.opcode()) {
         case CONST_CLASS:
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/InstanceGetOnCheckCastCompareLongTest.java b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/InstanceGetOnCheckCastCompareLongTest.java
index c2721f1..f94bba3 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/InstanceGetOnCheckCastCompareLongTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/InstanceGetOnCheckCastCompareLongTest.java
@@ -4,16 +4,10 @@
 
 package com.android.tools.r8.ir.optimize.canonicalization;
 
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThrows;
-
-import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.AndroidApiLevel;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -49,29 +43,15 @@
     // For R8 we will try to shorten the live range and we have a bailout to find an insertion
     // point if we see a cmp instruction and the api is lower than 23. The receiver of the instance
     // get is not defined on the insertion point which is why this regression test was made.
-    R8FullTestBuilder r8FullTestBuilder =
-        testForR8(parameters.getBackend())
-            .addProgramClasses(I.class, Main.class)
-            .addProgramClassFileData(getTestClassWithRewrittenLongCompareToLCmp())
-            .addKeepMainRule(Main.class)
-            .addKeepClassRules(I.class)
-            .setMinApi(parameters.getApiLevel())
-            .enableInliningAnnotations();
-    if (parameters.getApiLevel().isLessThan(AndroidApiLevel.M)) {
-      // TODO(b/251015885). We should not fail compilation.
-      assertThrows(
-          CompilationFailedException.class,
-          () ->
-              r8FullTestBuilder.compileWithExpectedDiagnostics(
-                  diagnostics ->
-                      diagnostics.assertErrorMessageThatMatches(
-                          containsString("Unexpected values live at entry to first block"))));
-
-    } else {
-      r8FullTestBuilder
-          .run(parameters.getRuntime(), Main.class)
-          .assertSuccessWithOutputLines(EXPECTED);
-    }
+    testForR8(parameters.getBackend())
+        .addProgramClasses(I.class, Main.class)
+        .addProgramClassFileData(getTestClassWithRewrittenLongCompareToLCmp())
+        .addKeepMainRule(Main.class)
+        .addKeepClassRules(I.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableInliningAnnotations()
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines(EXPECTED);
   }
 
   private byte[] getTestClassWithRewrittenLongCompareToLCmp() throws Exception {