Add a test for using invoke-range for consecutive arguments

Bug: b/375147913
Change-Id: Ia2033940224ddb3e6ddbf2ebfac05881b754d260
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/InvokeRangeForConsecutiveArgumentsTest.java b/src/test/java/com/android/tools/r8/ir/regalloc/InvokeRangeForConsecutiveArgumentsTest.java
new file mode 100644
index 0000000..642eb7e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/InvokeRangeForConsecutiveArgumentsTest.java
@@ -0,0 +1,65 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.ir.regalloc;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class InvokeRangeForConsecutiveArgumentsTest extends TestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDefaultDexRuntime().withMaximumApiLevel().build();
+  }
+
+  @Test
+  public void testD8() throws Exception {
+    testForD8()
+        .addInnerClasses(getClass())
+        .addOptionsModification(
+            options -> options.getTestingOptions().enableRegisterAllocation8BitRefinement = true)
+        .release()
+        .setMinApi(parameters)
+        .compile()
+        .inspect(
+            inspector -> {
+              MethodSubject testMethodSubject =
+                  inspector.clazz(Main.class).uniqueMethodWithOriginalName("test");
+              assertThat(testMethodSubject, isPresent());
+              assertTrue(
+                  testMethodSubject
+                      .streamInstructions()
+                      .filter(InstructionSubject::isInvokeMethod)
+                      .allMatch(InstructionSubject::isInvokeRange));
+              assertTrue(
+                  testMethodSubject.streamInstructions().noneMatch(InstructionSubject::isMove));
+            });
+  }
+
+  static class Main {
+
+    void test(long a, long b, long c, long d, long e, long f, long g, long h) {
+      test(a, b, c, d, e, f, g, h);
+      testPartial(g, h);
+    }
+
+    static void testPartial(long a, long b) {}
+  }
+}
diff --git a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
index 6cc23c2..aa3e569 100644
--- a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
+++ b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/CfInstructionSubject.java
@@ -140,6 +140,11 @@
   }
 
   @Override
+  public boolean isInvokeRange() {
+    return false;
+  }
+
+  @Override
   public boolean isPop() {
     return instruction instanceof CfStackInstruction
         && ((CfStackInstruction) instruction).getOpcode() == Opcode.Pop;
diff --git a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
index 8c1d4a2..aec79c9 100644
--- a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
+++ b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/DexInstructionSubject.java
@@ -80,6 +80,7 @@
 import com.android.tools.r8.dex.code.DexInvokeDirectRange;
 import com.android.tools.r8.dex.code.DexInvokeInterface;
 import com.android.tools.r8.dex.code.DexInvokeInterfaceRange;
+import com.android.tools.r8.dex.code.DexInvokePolymorphicRange;
 import com.android.tools.r8.dex.code.DexInvokeStatic;
 import com.android.tools.r8.dex.code.DexInvokeStaticRange;
 import com.android.tools.r8.dex.code.DexInvokeSuper;
@@ -317,6 +318,17 @@
   }
 
   @Override
+  public boolean isInvokeRange() {
+    return instruction instanceof DexInvokeCustomRange
+        || instruction instanceof DexInvokeDirectRange
+        || instruction instanceof DexInvokeInterfaceRange
+        || instruction instanceof DexInvokeStaticRange
+        || instruction instanceof DexInvokeSuperRange
+        || instruction instanceof DexInvokeVirtualRange
+        || instruction instanceof DexInvokePolymorphicRange;
+  }
+
+  @Override
   public DexMethod getMethod() {
     assert isInvoke();
     return instruction.getMethod();
diff --git a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
index b23719d..82b9263 100644
--- a/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
+++ b/src/test/testbase/java/com/android/tools/r8/utils/codeinspector/InstructionSubject.java
@@ -51,6 +51,8 @@
 
   boolean isInvokeDynamic();
 
+  boolean isInvokeRange();
+
   default boolean isInvokeSpecialOrDirect() {
     if (isCfInstruction()) {
       return asCfInstruction().isInvokeSpecial();