Disable canonicalization for singleton fields

Bug: 171136616
Change-Id: I42a6046030ae104daf1f4b8a41aaf50b74904889
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
index 36fba35..5585153 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
@@ -11,6 +11,9 @@
 
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.value.AbstractValue;
 import com.android.tools.r8.ir.analysis.value.SingleFieldValue;
@@ -147,13 +150,22 @@
           continue;
         }
         SingleFieldValue singleFieldValue = abstractValue.asSingleFieldValue();
+        DexType fieldHolderType = singleFieldValue.getField().holder;
         if (context.getDefinition().isClassInitializer()
-            && context.getHolderType() == singleFieldValue.getField().holder) {
+            && context.getHolderType() == fieldHolderType) {
           // Avoid that canonicalization inserts a read before the unique write in the class
           // initializer, as that would change the program behavior.
           continue;
         }
-        if (current.instructionMayHaveSideEffects(appView, context)) {
+        DexClass fieldHolder = appView.definitionFor(fieldHolderType);
+        if (fieldHolder == null) {
+          continue;
+        }
+        DexEncodedField field = fieldHolder.lookupField(singleFieldValue.getField());
+        if (field == null
+            || !field.isEnum()
+            || current.instructionMayHaveSideEffects(appView, context)) {
+          // Only allow canonicalization of enums.
           continue;
         }
       }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/EffectivelyFinalFieldCanonicalizationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/EffectivelyFinalFieldCanonicalizationTest.java
index 4e73445..cde89ec 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/EffectivelyFinalFieldCanonicalizationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/EffectivelyFinalFieldCanonicalizationTest.java
@@ -54,7 +54,7 @@
     MethodSubject mainMethodSubject = testClassSubject.mainMethod();
     assertThat(mainMethodSubject, isPresent());
     assertEquals(
-        1, mainMethodSubject.streamInstructions().filter(InstructionSubject::isStaticGet).count());
+        2, mainMethodSubject.streamInstructions().filter(InstructionSubject::isStaticGet).count());
   }
 
   static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/SingletonCanonicalizationWithApiLevelCheckTest.java b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/SingletonCanonicalizationWithApiLevelCheckTest.java
index bbc7245..7b86868 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/SingletonCanonicalizationWithApiLevelCheckTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/SingletonCanonicalizationWithApiLevelCheckTest.java
@@ -63,15 +63,7 @@
         .compile()
         .addRunClasspathFiles(program)
         .run(parameters.getRuntime(), TestClass.class)
-        .apply(
-            runResult -> {
-              if (parameters.isCfRuntime()) {
-                // Constant canonicalization is disabled for CF.
-                runResult.assertSuccessWithOutput("");
-              } else {
-                runResult.assertFailureWithErrorThatThrows(NoClassDefFoundError.class);
-              }
-            });
+        .assertSuccessWithOutput("");
   }
 
   private List<String> getAssumeValuesRule(int version) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
index fc87e9b..885eb25 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
@@ -205,6 +205,7 @@
             "STATIC: SimpleWithThrowingGetter SimpleWithThrowingGetter.getInstance()",
             "STATIC: String TrivialTestClass.next()",
             "SimpleWithThrowingGetter SimpleWithThrowingGetter.INSTANCE",
+            "SimpleWithThrowingGetter SimpleWithThrowingGetter.INSTANCE",
             "VIRTUAL: String SimpleWithThrowingGetter.bar(String)",
             "VIRTUAL: String SimpleWithThrowingGetter.foo()"),
         references(clazz, "testSimpleWithThrowingGetter", "void"));