Check for -assumenosideeffects rules in dead code elimination for static-get

Bug: 111763015
Change-Id: Ib399593eb55ec9deb4cd74901af5601055ddc4a8
diff --git a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
index 25a9590..fe5dac4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.analysis.AbstractError;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.Collections;
 import java.util.List;
 
@@ -82,14 +83,23 @@
         return AbstractError.specific(appView.dexItemFactory().npeType);
       }
     }
-    // May trigger <clinit> that may have side effects.
-    if (field.holder.classInitializationMayHaveSideEffects(
-        appView,
-        // Types that are a super type of `context` are guaranteed to be initialized already.
-        type -> appView.isSubtype(context, type).isTrue())) {
-      return AbstractError.top();
+    boolean mayTriggerClassInitialization = isStaticGet() || isStaticPut();
+    if (mayTriggerClassInitialization) {
+      // Only check for class initialization side effects if there is no -assumenosideeffects rule.
+      if (appView.appInfo().hasLiveness()) {
+        AppInfoWithLiveness appInfoWithLiveness = appView.appInfo().withLiveness();
+        if (appInfoWithLiveness.noSideEffects.containsKey(resolvedField.field)) {
+          return AbstractError.bottom();
+        }
+      }
+      // May trigger <clinit> that may have side effects.
+      if (field.holder.classInitializationMayHaveSideEffects(
+          appView,
+          // Types that are a super type of `context` are guaranteed to be initialized already.
+          type -> appView.isSubtype(context, type).isTrue())) {
+        return AbstractError.top();
+      }
     }
-
     return AbstractError.bottom();
   }
 
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/MinSdkMemberValuePropagationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/MinSdkMemberValuePropagationTest.java
index caad10b..76f50e2 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/MinSdkMemberValuePropagationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/MinSdkMemberValuePropagationTest.java
@@ -24,17 +24,20 @@
 
   private final TestParameters parameters;
   private final String rule;
+  private final String value;
 
-  @Parameterized.Parameters(name = "{0}, rule: {1}")
+  @Parameterized.Parameters(name = "{0}, rule: {1}, value: {2}")
   public static List<Object[]> data() {
     return buildParameters(
         getTestParameters().withAllRuntimes().build(),
-        ImmutableList.of("assumenosideeffects", "assumevalues"));
+        ImmutableList.of("assumenosideeffects", "assumevalues"),
+        ImmutableList.of("42", "42..43"));
   }
 
-  public MinSdkMemberValuePropagationTest(TestParameters parameters, String rule) {
+  public MinSdkMemberValuePropagationTest(TestParameters parameters, String rule, String value) {
     this.parameters = parameters;
     this.rule = rule;
+    this.value = value;
   }
 
   @Test
@@ -44,7 +47,7 @@
         .addKeepMainRule(TestClass.class)
         .addKeepRules(
             "-" + rule + " class " + Library.class.getTypeName() + " {",
-            "  static int MIN_SDK return 42;",
+            "  static int MIN_SDK return " + value + ";",
             "}")
         .addLibraryClasses(Library.class)
         .addLibraryFiles(runtimeJar(parameters))
@@ -79,7 +82,7 @@
   static class TestClass {
 
     public static void main(String[] args) {
-      if (Library.MIN_SDK == 42) {
+      if (Library.MIN_SDK >= 42) {
         System.out.println("Hello world!");
       }
     }