diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index 8ab2c1a..5bed061 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -6,7 +6,6 @@
 import static com.android.tools.r8.ir.code.IRCode.INSTRUCTION_NUMBER_DELTA;
 
 import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DebugLocalInfo;
 import com.android.tools.r8.graph.DebugLocalInfo.PrintLevel;
 import com.android.tools.r8.graph.DexItemFactory;
@@ -468,7 +467,7 @@
         return instruction;
       }
     }
-    throw new Unreachable();
+    return null;
   }
 
   public void clearUserInfo() {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index c6ba97d..555ddf0 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -46,6 +46,7 @@
 import com.android.tools.r8.ir.optimize.NonNullTracker;
 import com.android.tools.r8.ir.optimize.Outliner;
 import com.android.tools.r8.ir.optimize.PeepholeOptimizer;
+import com.android.tools.r8.ir.optimize.RedundantFieldLoadElimination;
 import com.android.tools.r8.ir.optimize.classinliner.ClassInliner;
 import com.android.tools.r8.ir.optimize.lambda.LambdaMerger;
 import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
@@ -104,6 +105,8 @@
   private final Devirtualizer devirtualizer;
   private final CovariantReturnTypeAnnotationTransformer covariantReturnTypeAnnotationTransformer;
 
+  private final boolean enableWholeProgramOptimizations;
+
   private final OptimizationFeedback ignoreOptimizationFeedback = new OptimizationFeedbackIgnore();
   private DexString highestSortingString;
 
@@ -134,6 +137,7 @@
         options.processCovariantReturnTypeAnnotations
             ? new CovariantReturnTypeAnnotationTransformer(this, appInfo.dexItemFactory)
             : null;
+    this.enableWholeProgramOptimizations = enableWholeProgramOptimizations;
     if (enableWholeProgramOptimizations) {
       assert appInfo.hasLiveness();
       this.nonNullTracker = new NonNullTracker();
@@ -695,6 +699,7 @@
     codeRewriter.rewriteSwitch(code);
     codeRewriter.processMethodsNeverReturningNormally(code);
     codeRewriter.simplifyIf(code, typeEnvironment);
+    new RedundantFieldLoadElimination(appInfo, code, enableWholeProgramOptimizations).run();
 
     if (options.testing.invertConditionals) {
       invertConditionalsForTesting(code);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
new file mode 100644
index 0000000..dee935e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -0,0 +1,222 @@
+// 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.ir.optimize;
+
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.ir.code.BasicBlock;
+import com.android.tools.r8.ir.code.DominatorTree;
+import com.android.tools.r8.ir.code.FieldInstruction;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionListIterator;
+import com.android.tools.r8.ir.code.Phi;
+import com.android.tools.r8.ir.code.Value;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Eliminate redundant field loads.
+ *
+ * <p>Simple algorithm that goes through all blocks in one pass in dominator order and propagates
+ * active field sets across control-flow edges where the target has only one predecessor.
+ */
+// TODO(ager): Evaluate speed/size for computing active field sets in a fixed-point computation.
+public class RedundantFieldLoadElimination {
+
+  private final AppInfo appInfo;
+  private final DexEncodedMethod method;
+  private final IRCode code;
+  private final boolean enableWholeProgramOptimizations;
+  private final DominatorTree dominatorTree;
+
+  // Maps keeping track of fields that have an already loaded value at basic block entry.
+  private final HashMap<BasicBlock, HashMap<FieldAndObject, Instruction>>
+      activeInstanceFieldsAtEntry = new HashMap<>();
+  private final HashMap<BasicBlock, HashMap<DexField, Instruction>> activeStaticFieldsAtEntry =
+      new HashMap<>();
+
+  // Maps keeping track of fields with already loaded values for the current block during
+  // elimination.
+  private HashMap<FieldAndObject, Instruction> activeInstanceFields;
+  private HashMap<DexField, Instruction> activeStaticFields;
+
+  public RedundantFieldLoadElimination(
+      AppInfo appInfo, IRCode code, boolean enableWholeProgramOptimizations) {
+    this.appInfo = appInfo;
+    this.method = code.method;
+    this.code = code;
+    this.enableWholeProgramOptimizations = enableWholeProgramOptimizations;
+    dominatorTree = new DominatorTree(code);
+  }
+
+  private static class FieldAndObject {
+    private final DexField field;
+    private final Value object;
+
+    private FieldAndObject(DexField field, Value receiver) {
+      this.field = field;
+      this.object = receiver;
+    }
+
+    @Override
+    public int hashCode() {
+      return field.hashCode() * 7 + object.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+      if (!(other instanceof FieldAndObject)) {
+        return false;
+      }
+      FieldAndObject o = (FieldAndObject) other;
+      return o.object == object && o.field == field;
+    }
+  }
+
+  private boolean couldBeVolatile(DexField field) {
+    if (!enableWholeProgramOptimizations && field.getHolder() != method.method.getHolder()) {
+      return true;
+    }
+    DexEncodedField definition = appInfo.definitionFor(field);
+    return definition == null || definition.accessFlags.isVolatile();
+  }
+
+  public void run() {
+    for (BasicBlock block : dominatorTree.getSortedBlocks()) {
+      activeInstanceFields =
+          activeInstanceFieldsAtEntry.containsKey(block)
+              ? activeInstanceFieldsAtEntry.get(block)
+              : new HashMap<>();
+      activeStaticFields =
+          activeStaticFieldsAtEntry.containsKey(block)
+              ? activeStaticFieldsAtEntry.get(block)
+              : new HashMap<>();
+      InstructionListIterator it = block.listIterator();
+      while (it.hasNext()) {
+        Instruction instruction = it.next();
+        if (instruction.isFieldInstruction()) {
+          DexField field = instruction.asFieldInstruction().getField();
+          if (instruction.isInstancePut() || instruction.isStaticPut()) {
+            killActiveFields(instruction.asFieldInstruction());
+          } else if (couldBeVolatile(field)) {
+            assert instruction.isInstanceGet() || instruction.isStaticGet();
+            killAllActiveFields();
+          } else {
+            assert instruction.isInstanceGet() || instruction.isStaticGet();
+            assert !couldBeVolatile(field);
+            if (instruction.isInstanceGet() && !instruction.outValue().hasLocalInfo()) {
+              Value object = instruction.asInstanceGet().object();
+              FieldAndObject fieldAndObject = new FieldAndObject(field, object);
+              if (activeInstanceFields.containsKey(fieldAndObject)) {
+                Instruction active = activeInstanceFields.get(fieldAndObject);
+                eliminateRedundantRead(it, instruction, active);
+              } else {
+                activeInstanceFields.put(fieldAndObject, instruction);
+              }
+            } else if (instruction.isStaticGet() && !instruction.outValue().hasLocalInfo()) {
+              if (activeStaticFields.containsKey(field)) {
+                Instruction active = activeStaticFields.get(field);
+                eliminateRedundantRead(it, instruction, active);
+              } else {
+                // A field get on a different class can cause <clinit> to run and change static
+                // field values.
+                killActiveFields(instruction.asFieldInstruction());
+                activeStaticFields.put(field, instruction);
+              }
+            }
+          }
+        }
+        if (instruction.isMonitor() || instruction.isInvokeMethod()) {
+          killAllActiveFields();
+        }
+      }
+      propagateActiveFieldsFrom(block);
+    }
+    assert code.isConsistentSSA();
+  }
+
+  private void propagateActiveFieldsFrom(BasicBlock block) {
+    for (BasicBlock successor : block.getSuccessors()) {
+      // Allow propagation across exceptional edges, just be careful not to propagate if the
+      // throwing instruction is a field instruction.
+      if (successor.getPredecessors().size() == 1) {
+        if (block.hasCatchSuccessor(successor)) {
+          Instruction exceptionalExit = block.exceptionalExit();
+          if (exceptionalExit != null && exceptionalExit.isFieldInstruction()) {
+            killActiveFieldsForExceptionalExit(exceptionalExit.asFieldInstruction());
+          }
+        }
+        assert !activeInstanceFieldsAtEntry.containsKey(successor);
+        activeInstanceFieldsAtEntry.put(successor, new HashMap<>(activeInstanceFields));
+        assert !activeStaticFieldsAtEntry.containsKey(successor);
+        activeStaticFieldsAtEntry.put(successor, new HashMap<>(activeStaticFields));
+      }
+    }
+  }
+
+  private void killAllActiveFields() {
+    activeInstanceFields.clear();
+    activeStaticFields.clear();
+  }
+
+  private void killActiveFields(FieldInstruction instruction) {
+    DexField field = instruction.getField();
+    if (instruction.isInstancePut()) {
+      // Remove all the field/object pairs that refer to this field to make sure
+      // that we are conservative.
+      List<FieldAndObject> keysToRemove = new ArrayList<>();
+      for (FieldAndObject key : activeInstanceFields.keySet()) {
+        if (key.field == field) {
+          keysToRemove.add(key);
+        }
+      }
+      keysToRemove.forEach((k) -> activeInstanceFields.remove(k));
+    } else if (instruction.isInstanceGet()) {
+      Value object = instruction.asInstanceGet().object();
+      FieldAndObject fieldAndObject = new FieldAndObject(field, object);
+      activeInstanceFields.remove(fieldAndObject);
+    } else if (instruction.isStaticPut()) {
+      if (field.clazz != code.method.method.holder) {
+        // Accessing a static field on a different object could cause <clinit> to run which
+        // could modify any static field on any other object.
+        activeStaticFields.clear();
+      } else {
+        activeStaticFields.remove(field);
+      }
+    } else if (instruction.isStaticGet()) {
+      if (field.clazz != code.method.method.holder) {
+        // Accessing a static field on a different object could cause <clinit> to run which
+        // could modify any static field on any other object.
+        activeStaticFields.clear();
+      }
+    }
+  }
+
+  // If a field get instruction throws an exception it did not have an effect on the
+  // value of the field. Therefore, when propagating across exceptional edges for a
+  // field get instruction we have to exclude that field from the set of known
+  // field values.
+  private void killActiveFieldsForExceptionalExit(FieldInstruction instruction) {
+    DexField field = instruction.getField();
+    if (instruction.isInstanceGet()) {
+      Value object = instruction.asInstanceGet().object();
+      FieldAndObject fieldAndObject = new FieldAndObject(field, object);
+      activeInstanceFields.remove(fieldAndObject);
+    } else if (instruction.isStaticGet()) {
+      activeStaticFields.remove(field);
+    }
+  }
+
+  private void eliminateRedundantRead(
+      InstructionListIterator it, Instruction redundant, Instruction active) {
+    redundant.outValue().replaceUsers(active.outValue());
+    it.removeOrReplaceByDebugLocalRead();
+    active.outValue().uniquePhiUsers().forEach(Phi::removeTrivialPhi);
+  }
+}
diff --git a/src/test/examples/uninitializedfinal/UninitializedFinalFieldLeak.java b/src/test/examples/uninitializedfinal/UninitializedFinalFieldLeak.java
new file mode 100644
index 0000000..781d2b4
--- /dev/null
+++ b/src/test/examples/uninitializedfinal/UninitializedFinalFieldLeak.java
@@ -0,0 +1,57 @@
+// 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 uninitializedfinal;
+
+// Test that leaks an instance before its final field has been initialized to a thread that
+// reads that field. This tests that redundant field load elimination does not eliminate
+// field reads (even of final fields) that cross a monitor operation.
+public class UninitializedFinalFieldLeak {
+
+  public static class PollingThread extends Thread {
+    public int result = 0;
+    UninitializedFinalFieldLeak f;
+
+    PollingThread(UninitializedFinalFieldLeak f) {
+      this.f = f;
+    }
+
+    // Read the field a number of times. Then lock on the object to await field initialization.
+    public void run() {
+      result += f.i;
+      result += f.i;
+      result += f.i;
+      f.threadReadsDone = true;
+      synchronized (f) {
+        result += f.i;
+      }
+      // The right result is 42. Reading the uninitialized 0 three times and then
+      // reading the initialized value. It is safe to remove the two redundant loads
+      // before the monitor operation.
+      System.out.println(result);
+    }
+  }
+
+  public final int i;
+  public volatile boolean threadReadsDone = false;
+
+  public UninitializedFinalFieldLeak() throws InterruptedException {
+    // Leak the object to a thread and start the thread with the lock on the object taken.
+    // Then allow the other thread to run and read the uninitialized field.
+    // Finally, initialize the field and release the lock.
+    PollingThread t = new PollingThread(this);
+    synchronized (this) {
+      t.start();
+      while (!threadReadsDone) {
+        Thread.yield();
+      }
+      i = 42;
+    }
+    t.join();
+  }
+
+  public static void main(String[] args) throws InterruptedException {
+    new UninitializedFinalFieldLeak();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
index 36f7594..221d427 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesTest.java
@@ -45,9 +45,11 @@
         "instancevariable.InstanceVariable",
         "instanceofstring.InstanceofString",
         "invoke.Invoke",
+        "invokeempty.InvokeEmpty",
         "jumbostring.JumboString",
         "loadconst.LoadConst",
         "loop.UdpServer",
+        "nestedtrycatches.NestedTryCatches",
         "newarray.NewArray",
         "regalloc.RegAlloc",
         "returns.Returns",
@@ -58,9 +60,7 @@
         "throwing.Throwing",
         "trivial.Trivial",
         "trycatch.TryCatch",
-        "nestedtrycatches.NestedTryCatches",
         "trycatchmany.TryCatchMany",
-        "invokeempty.InvokeEmpty",
         "regress.Regress",
         "regress2.Regress2",
         "regress_37726195.Regress",
@@ -82,6 +82,7 @@
         "enclosingmethod_proguarded.Main",
         "interfaceinlining.Main",
         "switchmaps.Switches",
+        "uninitializedfinal.UninitializedFinalFieldLeak",
     };
 
     List<String[]> fullTestList = new ArrayList<>(tests.length * 2);
diff --git a/src/test/java/com/android/tools/r8/regress/b111250398/B111250398.java b/src/test/java/com/android/tools/r8/regress/b111250398/B111250398.java
new file mode 100644
index 0000000..90fba5f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/regress/b111250398/B111250398.java
@@ -0,0 +1,342 @@
+// 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.regress.b111250398;
+
+import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.code.Iget;
+import com.android.tools.r8.code.IgetObject;
+import com.android.tools.r8.code.Sget;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.android.tools.r8.utils.DexInspector.FieldSubject;
+import com.android.tools.r8.utils.DexInspector.MethodSubject;
+import com.android.tools.r8.utils.InternalOptions;
+import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import org.junit.Test;
+
+// Copy of javax.inject.Provider.
+interface Provider<T> {
+  T get();
+}
+
+// Copy of dagger.internal.SingleClass.
+final class SingleCheck<T> implements Provider<T> {
+  private static final Object UNINITIALIZED = new Object();
+
+  private volatile Provider<T> provider;
+  private volatile Object instance = UNINITIALIZED;
+
+  private SingleCheck(Provider<T> provider) {
+    assert provider != null;
+    this.provider = provider;
+  }
+
+  @SuppressWarnings("unchecked") // cast only happens when result comes from the delegate provider
+  @Override
+  public T get() {
+    Object local = instance;
+    if (local == UNINITIALIZED) {
+      // provider is volatile and might become null after the check, so retrieve the provider first
+      Provider<T> providerReference = provider;
+      if (providerReference == null) {
+        // The provider was null, so the instance must already be set
+        local = instance;
+      } else {
+        local = providerReference.get();
+        instance = local;
+
+        // Null out the reference to the provider. We are never going to need it again, so we can
+        // make it eligible for GC.
+        provider = null;
+      }
+    }
+    return (T) local;
+  }
+
+  // This method is not relevant for the test.
+  /*
+  public static <P extends Provider<T>, T> Provider<T> provider(P provider) {
+    // If a scoped @Binds delegates to a scoped binding, don't cache the value again.
+    if (provider instanceof SingleCheck || provider instanceof DoubleCheck) {
+      return provider;
+    }
+    return new SingleCheck<T>(checkNotNull(provider));
+  }
+  */
+}
+
+// Several field gets on non-volatile and volatile fields on the same class.
+class A {
+  int t;
+  int f;
+  static int sf;
+  volatile int v;
+  static volatile int sv;
+
+  public void mf() {
+    t = f;
+    t = f;
+    t = f;
+    t = f;
+    t = f;
+  }
+
+  public void msf() {
+    t = sf;
+    t = sf;
+    t = sf;
+    t = sf;
+    t = sf;
+  }
+
+  public void mv() {
+    t = v;
+    t = v;
+    t = v;
+    t = v;
+    t = v;
+  }
+
+  public void msv() {
+    t = sv;
+    t = sv;
+    t = sv;
+    t = sv;
+    t = sv;
+  }
+}
+
+// Several field gets on non-volatile and volatile fields on different class.
+class B {
+  int t;
+
+  public void mf(A a) {
+    t = a.f;
+    t = a.f;
+    t = a.f;
+    t = a.f;
+    t = a.f;
+  }
+
+  public void msf() {
+    t = A.sf;
+    t = A.sf;
+    t = A.sf;
+    t = A.sf;
+    t = A.sf;
+  }
+
+  public void mv(A a) {
+    t = a.v;
+    t = a.v;
+    t = a.v;
+    t = a.v;
+    t = a.v;
+  }
+
+  public void msv() {
+    t = A.sv;
+    t = A.sv;
+    t = A.sv;
+    t = A.sv;
+    t = A.sv;
+  }
+}
+
+// Modified sample from http://tutorials.jenkov.com/java-concurrency/volatile.html.
+class C {
+  private int years;
+  private int months;
+  private volatile int days;
+
+  public int totalDays() {
+    int total = this.days;
+    total += months * 30;
+    total += years * 365;
+    return total;
+  }
+
+  public int totalDaysTimes2() {
+    int total = this.days;
+    total += months * 30;
+    total += years * 365;
+    total += this.days;
+    total += months * 30;
+    total += years * 365;
+    return total;
+  }
+
+  public int totalDaysTimes3() {
+    int total = this.days;
+    total += months * 30;
+    total += years * 365;
+    total += this.days;
+    total += months * 30;
+    total += years * 365;
+    total += this.days;
+    total += months * 30;
+    total += years * 365;
+    return total;
+  }
+
+  public void update(int years, int months, int days){
+    this.years  = years;
+    this.months = months;
+    this.days   = days;
+  }
+}
+
+public class B111250398 extends TestBase {
+
+  private void releaseMode(InternalOptions options) {
+    options.debug = false;
+  }
+
+  private long countIget(DexCode code, DexField field) {
+    return Arrays.stream(code.instructions)
+        .filter(instruction -> instruction instanceof Iget)
+        .map(instruction -> (Iget) instruction)
+        .filter(get -> get.getField() == field)
+        .count();
+  }
+
+  private long countSget(DexCode code, DexField field) {
+    return Arrays.stream(code.instructions)
+        .filter(instruction -> instruction instanceof Sget)
+        .map(instruction -> (Sget) instruction)
+        .filter(get -> get.getField() == field)
+        .count();
+  }
+
+  private long countIgetObject(MethodSubject method, FieldSubject field) {
+    return Arrays.stream(method.getMethod().getCode().asDexCode().instructions)
+        .filter(instruction -> instruction instanceof IgetObject)
+        .map(instruction -> (IgetObject) instruction)
+        .filter(get -> get.getField() == field.getField().field)
+        .count();
+  }
+
+  private void check(DexInspector inspector, int mfOnBGets, int msfOnBGets) {
+    ClassSubject classA = inspector.clazz(A.class);
+    assertThat(classA, isPresent());
+    MethodSubject mfOnA = classA.method("void", "mf", ImmutableList.of());
+    assertThat(mfOnA, isPresent());
+    MethodSubject msfOnA = classA.method("void", "msf", ImmutableList.of());
+    assertThat(msfOnA, isPresent());
+    MethodSubject mvOnA = classA.method("void", "mv", ImmutableList.of());
+    assertThat(mvOnA, isPresent());
+    MethodSubject msvOnA = classA.method("void", "msv", ImmutableList.of());
+    assertThat(msvOnA, isPresent());
+    FieldSubject fOnA = classA.field("int", "f");
+    assertThat(fOnA, isPresent());
+    FieldSubject sfOnA = classA.field("int", "sf");
+    assertThat(sfOnA, isPresent());
+    FieldSubject vOnA = classA.field("int", "v");
+    assertThat(vOnA, isPresent());
+    FieldSubject svOnA = classA.field("int", "sv");
+    assertThat(svOnA, isPresent());
+    ClassSubject classB = inspector.clazz(B.class);
+    assertThat(classB, isPresent());
+    MethodSubject mfOnB = classB.method("void", "mf", ImmutableList.of(classA.getOriginalName()));
+    assertThat(mfOnB, isPresent());
+    MethodSubject msfOnB = classB.method("void", "msf", ImmutableList.of());
+    assertThat(msfOnB, isPresent());
+    MethodSubject mvOnB = classB.method("void", "mv", ImmutableList.of(classA.getOriginalName()));
+    assertThat(mvOnB, isPresent());
+    MethodSubject msvOnB = classB.method("void", "msv", ImmutableList.of());
+    assertThat(msvOnB, isPresent());
+    // Field load of volatile fields are never eliminated.
+    assertEquals(5, countIget(mvOnA.getMethod().getCode().asDexCode(), vOnA.getField().field));
+    assertEquals(5, countSget(msvOnA.getMethod().getCode().asDexCode(), svOnA.getField().field));
+    assertEquals(5, countIget(mvOnB.getMethod().getCode().asDexCode(), vOnA.getField().field));
+    assertEquals(5, countSget(msvOnB.getMethod().getCode().asDexCode(), svOnA.getField().field));
+    // For fields on the same class both separate compilation (D8) and whole program
+    // compilation (R8) will eliminate field loads on non-volatile fields.
+    assertEquals(1, countIget(mfOnA.getMethod().getCode().asDexCode(), fOnA.getField().field));
+    assertEquals(1, countSget(msfOnA.getMethod().getCode().asDexCode(), sfOnA.getField().field));
+    // For fields on other class both separate compilation (D8) and whole program
+    // compilation (R8) will differ in the eliminated field loads of non-volatile fields.
+    assertEquals(mfOnBGets,
+        countIget(mfOnB.getMethod().getCode().asDexCode(), fOnA.getField().field));
+    assertEquals(msfOnBGets,
+        countSget(msfOnB.getMethod().getCode().asDexCode(), sfOnA.getField().field));
+  }
+
+  @Test
+  public void testSeparateCompilation() throws Exception {
+    DexInspector inspector =
+        new DexInspector(compileWithD8(readClasses(A.class, B.class), this::releaseMode));
+    check(inspector, 5, 5);
+  }
+
+  @Test
+  public void testWholeProgram() throws Exception {
+    DexInspector inspector =
+        new DexInspector(compileWithR8(readClasses(A.class, B.class), this::releaseMode));
+    // The reason for getting two Igets in B.mf is that the first Iget inserts a NonNull
+    // instruction which creates a new value for the remaining Igets.
+    check(inspector, 2, 1);
+  }
+
+  private void checkMixed(AndroidApp app) throws Exception{
+    DexInspector inspector = new DexInspector(app);
+    ClassSubject classC = inspector.clazz(C.class);
+    assertThat(classC, isPresent());
+    MethodSubject totalDays = classC.method("int", "totalDays", ImmutableList.of());
+    assertThat(totalDays, isPresent());
+    MethodSubject totalDaysTimes2 = classC.method("int", "totalDaysTimes2", ImmutableList.of());
+    assertThat(totalDaysTimes2, isPresent());
+    MethodSubject totalDaysTimes3 = classC.method("int", "totalDaysTimes3", ImmutableList.of());
+    assertThat(totalDaysTimes3, isPresent());
+    FieldSubject years = classC.field("int", "years");
+    assertThat(years, isPresent());
+    FieldSubject months = classC.field("int", "months");
+    assertThat(months, isPresent());
+    FieldSubject days = classC.field("int", "days");
+    assertThat(days, isPresent());
+
+
+    for (FieldSubject field : new FieldSubject[]{years, months, days}) {
+      assertEquals(1,
+          countIget(totalDays.getMethod().getCode().asDexCode(), field.getField().field));
+      assertEquals(2,
+          countIget(totalDaysTimes2.getMethod().getCode().asDexCode(), field.getField().field));
+      assertEquals(3,
+          countIget(totalDaysTimes3.getMethod().getCode().asDexCode(), field.getField().field));
+    }
+  }
+
+  @Test
+  public void testMixedVolatileNonVolatile() throws Exception {
+    AndroidApp app = readClasses(C.class);
+    checkMixed(compileWithD8(app, this::releaseMode));
+    checkMixed(compileWithR8(app, this::releaseMode));
+  }
+
+  private void checkDaggerSingleProviderGet(AndroidApp app) throws Exception {
+    DexInspector inspector = new DexInspector(app);
+    MethodSubject get =
+        inspector.clazz(SingleCheck.class).method("java.lang.Object", "get", ImmutableList.of());
+    assertThat(get, isPresent());
+    FieldSubject instance =
+        inspector.clazz(SingleCheck.class).field("java.lang.Object", "instance");
+    assertEquals(2, countIgetObject(get, instance));
+  }
+
+  @Test
+  public void testDaggerSingleProvider() throws Exception {
+    AndroidApp app = readClasses(Provider.class, SingleCheck.class);
+    checkDaggerSingleProviderGet(compileWithD8(app, this::releaseMode));
+    checkDaggerSingleProviderGet(compileWithR8(app, this::releaseMode));
+  }
+}
