diff --git a/build.gradle b/build.gradle
index a542ea4..e6432e4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1243,6 +1243,8 @@
     }
 
     dependsOn getJarsFromSupportLibs
+    // R8.jar is required for running bootstrap tests.
+    dependsOn R8
     testLogging.exceptionFormat = 'full'
     if (project.hasProperty('print_test_stdout')) {
         testLogging.showStandardStreams = true
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 4e7f421..67b6e2d 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
@@ -1259,9 +1259,7 @@
                   Value argument = invoke.arguments().get(argumentIndex);
                   assert invoke.outType().verifyCompatible(argument.outType());
                   invoke.outValue().replaceUsers(argument);
-                  if (!options.isGeneratingClassFiles()) {
-                    invoke.setOutValue(null);
-                  }
+                  invoke.setOutValue(null);
                 }
               }
             }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 6aa1853..1a23da1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -252,7 +252,7 @@
         if (target != null) {
           // Remove writes to dead (i.e. never read) fields.
           if (!isFieldRead(target, true)) {
-            iterator.remove();
+            iterator.removeOrReplaceByDebugLocalRead();
           }
         }
       }
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index e34282d..f5eaa25 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -93,7 +93,7 @@
   public static final String SMALI_BUILD_DIR = TESTS_BUILD_DIR + "smali/";
 
   public static final String LINE_SEPARATOR = StringUtils.LINE_SEPARATOR;
-  public final static String PATH_SEPARATOR = File.pathSeparator;
+  public static final String PATH_SEPARATOR = File.pathSeparator;
   public static final String DEFAULT_DEX_FILENAME = "classes.dex";
   public static final String DEFAULT_PROGUARD_MAP_FILE = "proguard.map";
 
@@ -106,6 +106,8 @@
   private static final String PROGUARD6_0_1 = "third_party/proguard/proguard6.0.1/bin/proguard";
   private static final String PROGUARD = PROGUARD5_2_1;
 
+  public static final Path R8_JAR = Paths.get(LIBS_DIR, "r8.jar");
+
   public enum DexVm {
     ART_4_0_4_TARGET(Version.V4_0_4, Kind.TARGET),
     ART_4_0_4_HOST(Version.V4_0_4, Kind.HOST),
@@ -997,7 +999,7 @@
 
   public static ProcessResult forkR8Jar(Path dir, String... args)
       throws IOException, InterruptedException {
-    String r8Jar = Paths.get(LIBS_DIR,  "r8.jar").toAbsolutePath().toString();
+    String r8Jar = R8_JAR.toAbsolutePath().toString();
     return forkJavaWithJar(dir, r8Jar, Arrays.asList(args));
   }
 
diff --git a/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java b/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java
new file mode 100644
index 0000000..02df3d1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java
@@ -0,0 +1,205 @@
+// Copyright (c) 2018, 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.cf;
+
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static com.google.common.io.ByteStreams.toByteArray;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.ArchiveClassFileProvider;
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.codeinspector.ClassHierarchyVerifier;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.base.Charsets;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class BootstrapCurrentEqualityTest extends TestBase {
+
+  private static final String R8_NAME = "com.android.tools.r8.R8";
+  private static final Path MAIN_KEEP = Paths.get("src/main/keep.txt");
+
+  private static final String HELLO_NAME = "hello.Hello";
+  private static final String[] KEEP_HELLO = {
+    "-keep class " + HELLO_NAME + " {", "  public static void main(...);", "}",
+  };
+
+  private class R8Result {
+
+    final ProcessResult processResult;
+    final Path outputJar;
+    final String pgMap;
+
+    R8Result(ProcessResult processResult, Path outputJar, String pgMap) {
+      this.processResult = processResult;
+      this.outputJar = outputJar;
+      this.pgMap = pgMap;
+    }
+
+    @Override
+    public String toString() {
+      return processResult.toString() + "\n\n" + pgMap;
+    }
+  }
+
+  private static Path r8R8Debug;
+  private static Path r8R8Release;
+
+  @ClassRule public static TemporaryFolder testFolder = new TemporaryFolder();
+
+  @BeforeClass
+  public static void beforeAll() throws Exception {
+    r8R8Debug = compileR8(CompilationMode.DEBUG);
+    r8R8Release = compileR8(CompilationMode.RELEASE);
+  }
+
+  private static Path compileR8(CompilationMode mode) throws Exception {
+    // Run R8 on r8.jar.
+    Path output = runR8(ToolHelper.R8_JAR, testFolder.newFolder().toPath(), mode);
+    // Check that all non-abstract classes in the R8'd R8 implement all abstract/interface methods
+    // from their supertypes. This is a sanity check for the tree shaking and minification.
+    AndroidApp app = AndroidApp.builder().addProgramFile(output).build();
+    new ClassHierarchyVerifier(new CodeInspector(app)).run();
+    return output;
+  }
+
+  @Test
+  public void test() throws Exception {
+    Path helloJar = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "hello" + JAR_EXTENSION);
+    ProcessResult runResult = ToolHelper.runJava(helloJar, "hello.Hello");
+    assertEquals(0, runResult.exitCode);
+    compareR8(helloJar, runResult, KEEP_HELLO, "hello.Hello");
+  }
+
+  private void compareR8(Path program, ProcessResult runResult, String[] keep, String... args)
+      throws Exception {
+    R8Result runR8Debug =
+        runExternalR8(ToolHelper.R8_JAR, program, temp.newFolder().toPath(), keep, "--debug");
+    assertEquals(runResult.toString(), ToolHelper.runJava(runR8Debug.outputJar, args).toString());
+    R8Result runR8Release =
+        runExternalR8(ToolHelper.R8_JAR, program, temp.newFolder().toPath(), keep, "--release");
+    assertEquals(runResult.toString(), ToolHelper.runJava(runR8Release.outputJar, args).toString());
+    RunR8AndCheck(r8R8Debug, program, runR8Debug, keep, "--debug");
+    RunR8AndCheck(r8R8Debug, program, runR8Release, keep, "--release");
+    RunR8AndCheck(r8R8Release, program, runR8Debug, keep, "--debug");
+    RunR8AndCheck(r8R8Release, program, runR8Release, keep, "--release");
+  }
+
+  private void RunR8AndCheck(Path r8, Path program, R8Result result, String[] keep, String mode)
+      throws Exception {
+    R8Result runR8R8 = runExternalR8(r8, program, temp.newFolder().toPath(), keep, mode);
+    // Check that the process outputs (exit code, stdout, stderr) are the same.
+    assertEquals(result.toString(), runR8R8.toString());
+    // Check that the output jars are the same.
+    assertProgramsEqual(result.outputJar, runR8R8.outputJar);
+  }
+
+  private static Path runR8(Path inputJar, Path outputPath, CompilationMode mode) throws Exception {
+    Path outputJar = outputPath.resolve("output.jar");
+    ToolHelper.runR8(
+        R8Command.builder()
+            .setMode(mode)
+            .addLibraryFiles(ToolHelper.getJava8RuntimeJar())
+            .setProgramConsumer(new ClassFileConsumer.ArchiveConsumer(outputJar, true))
+            .addProgramFiles(inputJar)
+            .addProguardConfigurationFiles(MAIN_KEEP)
+            .build());
+    return outputJar;
+  }
+
+  private R8Result runExternalR8(
+      Path r8Jar, Path inputJar, Path output, String[] keepRules, String mode) throws Exception {
+    Path pgConfigFile = output.resolve("keep.rules");
+    Path outputJar = output.resolve("output.jar");
+    Path pgMapFile = output.resolve("map.txt");
+    FileUtils.writeTextFile(pgConfigFile, keepRules);
+    ProcessResult processResult =
+        ToolHelper.runJava(
+            r8Jar,
+            R8_NAME,
+            "--lib",
+            ToolHelper.JAVA_8_RUNTIME,
+            "--classfile",
+            inputJar.toString(),
+            "--output",
+            outputJar.toString(),
+            "--pg-conf",
+            pgConfigFile.toString(),
+            mode,
+            "--pg-map-output",
+            pgMapFile.toString());
+    assertEquals(0, processResult.exitCode);
+    String pgMap = FileUtils.readTextFile(pgMapFile, Charsets.UTF_8);
+    return new R8Result(processResult, outputJar, pgMap);
+  }
+
+  private static void assertProgramsEqual(Path expectedJar, Path actualJar) throws Exception {
+    if (filesAreEqual(expectedJar, actualJar)) {
+      return;
+    }
+    ArchiveClassFileProvider expected = new ArchiveClassFileProvider(expectedJar);
+    ArchiveClassFileProvider actual = new ArchiveClassFileProvider(actualJar);
+    assertEquals(getSortedDescriptorList(expected), getSortedDescriptorList(actual));
+    for (String descriptor : expected.getClassDescriptors()) {
+      assertArrayEquals(
+          "Class " + descriptor + " differs",
+          getClassAsBytes(expected, descriptor),
+          getClassAsBytes(actual, descriptor));
+    }
+  }
+
+  private static boolean filesAreEqual(Path file1, Path file2) throws IOException {
+    long size = Files.size(file1);
+    long sizeOther = Files.size(file2);
+    if (size != sizeOther) {
+      return false;
+    }
+    if (size < 4096) {
+      return Arrays.equals(Files.readAllBytes(file1), Files.readAllBytes(file2));
+    }
+    int byteRead1 = 0;
+    int byteRead2 = 0;
+    try (FileInputStream fs1 = new FileInputStream(file1.toString());
+        FileInputStream fs2 = new FileInputStream(file2.toString())) {
+      BufferedInputStream bs1 = new BufferedInputStream(fs1);
+      BufferedInputStream bs2 = new BufferedInputStream(fs2);
+      while (byteRead1 == byteRead2 && byteRead1 != -1) {
+        byteRead1 = bs1.read();
+        byteRead2 = bs2.read();
+      }
+    }
+    return byteRead1 == byteRead2;
+  }
+
+  private static List<String> getSortedDescriptorList(ArchiveClassFileProvider inputJar) {
+    ArrayList<String> descriptorList = new ArrayList<>(inputJar.getClassDescriptors());
+    Collections.sort(descriptorList);
+    return descriptorList;
+  }
+
+  private static byte[] getClassAsBytes(ArchiveClassFileProvider inputJar, String descriptor)
+      throws Exception {
+    return toByteArray(inputJar.getProgramResource(descriptor).getByteStream());
+  }
+}
