diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index 40756ae..14d7ffb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.ir.code;
 
+import static com.android.tools.r8.optimize.MemberRebindingAnalysis.isVisibleFromOriginalContext;
+
 import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.cf.TypeVerificationHelper;
 import com.android.tools.r8.cf.code.CfFieldInstruction;
@@ -19,6 +21,7 @@
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
@@ -98,6 +101,24 @@
   }
 
   @Override
+  public boolean canBeDeadCode(AppInfo appInfo, IRCode code) {
+    // instance-get can be dead code as long as it cannot have any of the following:
+    // * NoSuchFieldError (resolution failure)
+    // * IllegalAccessError (not visible from the access context)
+    // * NullPointerException (null receiver).
+    // TODO(b/123857022): Should be possible to use definitionFor().
+    DexEncodedField resolvedField = appInfo.resolveFieldOn(getField().getHolder(), getField());
+    if (resolvedField == null) {
+      return false;
+    }
+    if (code == null
+        || !isVisibleFromOriginalContext(appInfo, code.method.method.getHolder(), resolvedField)) {
+      return false;
+    }
+    return object().getTypeLattice().nullability().isDefinitelyNotNull();
+  }
+
+  @Override
   public int maxInValueRegister() {
     return Constants.U4BIT_MAX;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
index b79d076..80e74f3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import static com.android.tools.r8.optimize.MemberRebindingAnalysis.isVisibleFromOriginalContext;
+
 import com.android.tools.r8.cf.LoadStoreHelper;
 import com.android.tools.r8.cf.TypeVerificationHelper;
 import com.android.tools.r8.cf.code.CfFieldInstruction;
@@ -18,6 +20,7 @@
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
@@ -91,6 +94,25 @@
   }
 
   @Override
+  public boolean canBeDeadCode(AppInfo appInfo, IRCode code) {
+    // static-get can be dead as long as it cannot have any of the following:
+    // * NoSuchFieldError (resolution failure)
+    // * IllegalAccessError (not visible from the access context)
+    // * side-effects in <clinit>
+    // TODO(b/123857022): Should be possible to use definitionFor().
+    DexEncodedField resolvedField = appInfo.resolveFieldOn(getField().getHolder(), getField());
+    if (resolvedField == null) {
+      return false;
+    }
+    if (code == null
+        || !isVisibleFromOriginalContext(appInfo, code.method.method.getHolder(), resolvedField)) {
+      return false;
+    }
+    return appInfo.hasSubtyping()
+        && !getField().getHolder().classInitializationMayHaveSideEffects(appInfo);
+  }
+
+  @Override
   public int maxInValueRegister() {
     return Constants.U8BIT_MAX;
   }
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index 608f915..60aec09 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.optimize;
 
+import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -291,14 +292,15 @@
       Set<DexEncodedMethod> contexts = fieldsWithContexts.get(field);
       if (target != null && target.field != field
           && contexts.stream().allMatch(context ->
-              isVisibleFromOriginalContext(context.method.getHolder(), target))) {
+              isVisibleFromOriginalContext(appInfo, context.method.getHolder(), target))) {
         builder.map(field,
             lense.lookupField(validTargetFor(target.field, field, lookupTargetOnClass)));
       }
     }
   }
 
-  private boolean isVisibleFromOriginalContext(DexType context, DexEncodedField field) {
+  public static boolean isVisibleFromOriginalContext(
+      AppInfo appInfo, DexType context, DexEncodedField field) {
     DexType holderType = field.field.getHolder();
     DexClass holder = appInfo.definitionFor(holderType);
     if (holder == null) {
diff --git a/src/test/java/com/android/tools/r8/jasmin/MemberResolutionTest.java b/src/test/java/com/android/tools/r8/jasmin/MemberResolutionTest.java
index 33f28fc..ea8ed0b 100644
--- a/src/test/java/com/android/tools/r8/jasmin/MemberResolutionTest.java
+++ b/src/test/java/com/android/tools/r8/jasmin/MemberResolutionTest.java
@@ -462,7 +462,7 @@
     main.addMainMethod(
         ".limit stack 2",
         ".limit locals 1",
-        "  getstatic Empty/aMethod I",
+        "  getstatic Empty/aField I",
         "  return");
 
     ensureRuntimeException(builder, NoSuchFieldError.class);
diff --git a/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java b/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java
new file mode 100644
index 0000000..ac1fd90
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/FieldReadsJasminTest.java
@@ -0,0 +1,180 @@
+// Copyright (c) 2019, 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.shaking;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tools.r8.jasmin.JasminBuilder;
+import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
+import com.android.tools.r8.jasmin.JasminTestBase;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.util.Iterator;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class FieldReadsJasminTest extends JasminTestBase {
+  private static final String CLS = "Empty";
+  private static final String MAIN = "Main";
+  private final Backend backend;
+
+  @Parameterized.Parameters(name = "Backend: {0}")
+  public static Object[] data() {
+    return Backend.values();
+  }
+
+  public FieldReadsJasminTest(Backend backend) {
+    this.backend = backend;
+  }
+
+  @Test
+  public void testInstanceGet_nonNullReceiver() throws Exception {
+    JasminBuilder builder = new JasminBuilder();
+
+    ClassBuilder empty = builder.addClass(CLS);
+    empty.addField("protected", "aField", "I", null);
+
+    ClassBuilder main = builder.addClass(MAIN);
+    main.addMainMethod(
+        ".limit stack 2",
+        ".limit locals 1",
+        "  new Empty",
+        "  dup",
+        "  invokespecial Empty/<init>()V",
+        "  getfield Empty/aField I",
+        "  return");
+
+    ensureNoFields(builder, empty);
+  }
+
+  @Test
+  public void testStaticGet_noSideEffect() throws Exception {
+    JasminBuilder builder = new JasminBuilder();
+
+    ClassBuilder empty = builder.addClass(CLS);
+    empty.addStaticField("sField", "I");
+
+    ClassBuilder main = builder.addClass(MAIN);
+    main.addMainMethod(
+        ".limit stack 2",
+        ".limit locals 1",
+        "  getstatic Empty/sField I",
+        "  return");
+
+    ensureNoFields(builder, empty);
+  }
+
+  private void ensureNoFields(JasminBuilder app, ClassBuilder clazz) throws Exception {
+    testForR8(backend)
+        .addProgramClassFileData(app.buildClasses())
+        .addKeepRules("-keep class * { <methods>; }")
+        .compile()
+        .inspect(inspector -> {
+          ClassSubject classSubject = inspector.clazz(clazz.name);
+          assertThat(classSubject, isPresent());
+          classSubject.forAllFields(foundFieldSubject -> {
+            fail("Expect not to see any fields.");
+          });
+        });
+  }
+
+  @Test
+  public void testInstanceGet_nullableReceiver() throws Exception {
+    JasminBuilder builder = new JasminBuilder();
+
+    ClassBuilder empty = builder.addClass(CLS);
+    empty.addDefaultConstructor();
+    empty.addField("protected", "aField", "I", null);
+    MethodSignature foo = empty.addStaticMethod("foo", ImmutableList.of("L" + CLS + ";"), "V",
+        ".limit stack 2",
+        ".limit locals 1",
+        "  aload 0",
+        "  getfield Empty/aField I",
+        "  return");
+
+    ClassBuilder main = builder.addClass(MAIN);
+    main.addMainMethod(
+        ".limit stack 2",
+        ".limit locals 1",
+        "  aconst_null",
+        "  invokestatic Empty/foo(L" + CLS + ";)V",
+        "  return");
+
+    ensureFieldExists(builder, empty, foo, "aField");
+  }
+
+  @Test
+  public void testStaticGet_nonTrivialClinit() throws Exception {
+    JasminBuilder builder = new JasminBuilder();
+
+    ClassBuilder empty = builder.addClass(CLS);
+    empty.addDefaultConstructor();
+    empty.addStaticField("sField", "I");
+    empty.addClassInitializer(
+        ".limit stack 3",
+        ".limit locals 1",
+        "  getstatic java/lang/System/out Ljava/io/PrintStream;",
+        "  ldc \"hello\"",
+        "  invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+        "  return");
+
+    ClassBuilder main = builder.addClass(MAIN);
+    MethodSignature mainMethod = main.addMainMethod(
+        ".limit stack 2",
+        ".limit locals 1",
+        "  getstatic Empty/sField I",
+        "  return");
+
+    ensureFieldExists(builder, main, mainMethod, "sField");
+  }
+
+  @Test
+  public void testStaticGet_allocation() throws Exception {
+    JasminBuilder builder = new JasminBuilder();
+
+    ClassBuilder empty = builder.addClass(CLS);
+    empty.addDefaultConstructor();
+    empty.addStaticField("sField", "Ljava/lang/String;", "\"8\"");
+
+    ClassBuilder main = builder.addClass(MAIN);
+    MethodSignature mainMethod = main.addMainMethod(
+        ".limit stack 2",
+        ".limit locals 1",
+        "  getstatic Empty/sField Ljava/lang/String;",
+        "  return");
+
+    ensureFieldExists(builder, main, mainMethod, "sField");
+  }
+
+  private void ensureFieldExists(
+      JasminBuilder app, ClassBuilder clazz, MethodSignature method, String fieldName)
+      throws Exception {
+    testForR8(backend)
+        .addProgramClassFileData(app.buildClasses())
+        .addKeepRules("-keep class * { <methods>; }")
+        .compile()
+        .inspect(inspector -> {
+          ClassSubject classSubject = inspector.clazz(clazz.name);
+          assertThat(classSubject, isPresent());
+          MethodSubject methodSubject = classSubject.uniqueMethodWithName(method.name);
+          assertThat(methodSubject, isPresent());
+          Iterator<InstructionSubject> it =
+              methodSubject.iterateInstructions(InstructionSubject::isFieldAccess);
+          assertTrue(it.hasNext());
+          assertEquals(
+              inspector.clazz(CLS).uniqueFieldWithName(fieldName).getFinalName(),
+              it.next().getField().name.toString());
+        });
+  }
+
+}
