Enable CF for MoveStringConstantsTest.

Change-Id: Ifab557e812e5cf62e6b9c6d11575e69d6ee7b93c
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 2d951fa..596fa74 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -533,6 +533,25 @@
     return result.stdout;
   }
 
+  /** Run application on Java with the specified main class and provided arguments. */
+  protected String runOnJava(AndroidApp app, Class mainClass, String... args) throws IOException {
+    return runOnJava(app, mainClass, Arrays.asList(args));
+  }
+
+  /** Run application on Java with the specified main class and provided arguments. */
+  protected String runOnJava(AndroidApp app, Class mainClass, List<String> args)
+      throws IOException {
+    return runOnJava(app, mainClass.getCanonicalName(), args);
+  }
+
+  /** Run application on Java with the specified main class and provided arguments. */
+  protected String runOnJava(AndroidApp app, String mainClass, List<String> args)
+      throws IOException {
+    Path out = File.createTempFile("junit", ".zip", temp.getRoot()).toPath();
+    app.writeToZip(out, OutputMode.ClassFile);
+    return ToolHelper.runJava(out, mainClass).stdout;
+  }
+
   protected ProcessResult runOnJavaRaw(String main, byte[]... classes) throws IOException {
     return runOnJavaRaw(main, Arrays.asList(classes));
   }
diff --git a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
index 60e9d08..3d6309d 100644
--- a/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
+++ b/src/test/java/com/android/tools/r8/movestringconstants/MoveStringConstantsTest.java
@@ -6,6 +6,7 @@
 
 import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.ClassFileConsumer;
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.DexIndexedConsumer;
 import com.android.tools.r8.R8Command;
@@ -13,23 +14,46 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.dexinspector.CfInstructionSubject;
 import com.android.tools.r8.utils.dexinspector.ClassSubject;
 import com.android.tools.r8.utils.dexinspector.DexInspector;
 import com.android.tools.r8.utils.dexinspector.InstructionSubject;
 import com.android.tools.r8.utils.dexinspector.InstructionSubject.JumboStringMode;
 import com.android.tools.r8.utils.dexinspector.MethodSubject;
 import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class MoveStringConstantsTest extends TestBase {
+
+  private Backend backend;
+
+  @Parameters(name = "Backend: {0}")
+  public static Collection<Backend> data() {
+    return Arrays.asList(Backend.values());
+  }
+
   private void runTest(Consumer<DexInspector> inspection) throws Exception {
     R8Command.Builder builder = R8Command.builder();
     builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class));
     builder.addProgramFiles(ToolHelper.getClassFileForTestClass(Utils.class));
-    builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+    builder.addLibraryFiles(
+        backend == Backend.DEX
+            ? ToolHelper.getDefaultAndroidJar()
+            : ToolHelper.getJava8RuntimeJar());
+    assert (backend == Backend.CF || backend == Backend.DEX);
+    builder.setProgramConsumer(
+        backend == Backend.DEX
+            ? DexIndexedConsumer.emptyConsumer()
+            : ClassFileConsumer.emptyConsumer());
     builder.setMode(CompilationMode.RELEASE);
     builder.addProguardConfiguration(
         ImmutableList.of(
@@ -38,11 +62,32 @@
             "-allowaccessmodification"
         ),
         Origin.unknown());
-    AndroidApp app = ToolHelper.runR8(builder.build());
-    inspection.accept(new DexInspector(app));
+    AndroidApp app =
+        ToolHelper.runR8(
+            builder.build(),
+            options -> {
+              // This test relies on that TestClass.java/Utils.check will be inlined.
+              // Its size must fit into the inlining instruction limit. For CF, the default
+              // setting (5) is just too small.
+              options.inliningInstructionLimit = 10;
+            });
+    inspection.accept(
+        new DexInspector(
+            app,
+            options -> {
+              options.enableCfFrontend = true;
+            }));
 
-    // Run on Art to check generated code against verifier.
-    runOnArt(app, TestClass.class);
+    if (backend == Backend.DEX) {
+      // Run on Art to check generated code against verifier.
+      runOnArt(app, TestClass.class);
+    } else {
+      runOnJava(app, TestClass.class);
+    }
+  }
+
+  public MoveStringConstantsTest(Backend backend) {
+    this.backend = backend;
   }
 
   private void validate(DexInspector inspector) {
@@ -54,10 +99,15 @@
         clazz.method("void", "foo", ImmutableList.of(
             "java.lang.String", "java.lang.String", "java.lang.String", "java.lang.String"));
     assertTrue(methodThrowToBeInlined.isPresent());
+    assert (backend == Backend.DEX || backend == Backend.CF);
+    Predicate<InstructionSubject> nullCheck =
+        backend == Backend.DEX
+            ? InstructionSubject::isIfEqz
+            : insn -> ((CfInstructionSubject) insn).isIfNull();
     validateSequence(
         methodThrowToBeInlined.iterateInstructions(),
         // 'if' with "foo#1" is flipped.
-        InstructionSubject::isIfEqz,
+        nullCheck,
 
         // 'if' with "foo#2" is removed along with the constant.
 
@@ -69,12 +119,12 @@
         // 'if's with "foo#4" and "foo#5" are flipped, but their throwing branches
         // are not moved to the end of the code (area for improvement?).
         insn -> insn.isConstString("StringConstants::foo#4", JumboStringMode.DISALLOW),
-        InstructionSubject::isIfEqz, // Flipped if
+        nullCheck, // Flipped if
         InstructionSubject::isGoto, // Jump around throwing branch.
         InstructionSubject::isInvokeStatic, // Throwing branch.
         InstructionSubject::isThrow,
         insn -> insn.isConstString("StringConstants::foo#5", JumboStringMode.DISALLOW),
-        InstructionSubject::isIfEqz, // Flipped if
+        nullCheck, // Flipped if
         InstructionSubject::isReturnVoid, // Final return statement.
         InstructionSubject::isInvokeStatic, // Throwing branch.
         InstructionSubject::isThrow,
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
index 377f4d6..3e74981 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
@@ -116,4 +116,8 @@
   public boolean isPosition() {
     return instruction instanceof CfPosition;
   }
+
+  public boolean isIfNull() {
+    return instruction instanceof CfIf && ((CfIf) instruction).getOpcode() == Opcodes.IFNULL;
+  }
 }