Revert "Disable redundant load elimination in debug mode"

This reverts commit 68afbc60e854be93182435d71cd56d1710bff0d3.

Bug: 218282718
Reason for revert: Significantly regresses memory benchmark

Change-Id: I7aafc3f768babe8703aaf0e7832e0b9af7dddc2d
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
index bcef49c..94c2bed 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadAndStoreElimination.java
@@ -40,7 +40,6 @@
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
 import com.android.tools.r8.ir.optimize.info.initializer.InstanceInitializerInfo;
-import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.collect.Sets;
 import it.unimi.dsi.fastutil.objects.Reference2IntMap;
 import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
@@ -92,9 +91,7 @@
   }
 
   public static boolean shouldRun(AppView<?> appView, IRCode code) {
-    InternalOptions options = appView.options();
-    return options.enableRedundantFieldLoadElimination
-        && !options.debug
+    return appView.options().enableRedundantFieldLoadElimination
         && (code.metadata().mayHaveArrayGet()
             || code.metadata().mayHaveFieldInstruction()
             || code.metadata().mayHaveInitClass());
@@ -556,6 +553,17 @@
   }
 
   private void handleArrayGet(InstructionListIterator it, ArrayGet arrayGet) {
+    if (arrayGet.array().hasLocalInfo()) {
+      // The array may be modified through the debugger. Therefore subsequent reads of the same
+      // array slot may not read this local.
+      return;
+    }
+    if (arrayGet.outValue().hasLocalInfo()) {
+      // This local may be modified through the debugger. Therefore subsequent reads of the same
+      // array slot may not read this local.
+      return;
+    }
+
     Value array = arrayGet.array().getAliasedValue();
     Value index = arrayGet.index().getAliasedValue();
     ArraySlot arraySlot = ArraySlot.create(array, index, arrayGet.getMemberType());
@@ -593,6 +601,11 @@
       InstanceGet instanceGet,
       DexClassAndField field,
       AssumeRemover assumeRemover) {
+    if (instanceGet.outValue().hasLocalInfo()) {
+      clearMostRecentInstanceFieldWrite(instanceGet, field);
+      return;
+    }
+
     Value object = instanceGet.object().getAliasedValue();
     FieldAndObject fieldAndObject = new FieldAndObject(field.getReference(), object);
     FieldValue replacement = activeState.getInstanceFieldValue(fieldAndObject);
@@ -686,6 +699,12 @@
       AssumeRemover assumeRemover) {
     markClassAsInitialized(field.getHolderType());
 
+    if (staticGet.outValue().hasLocalInfo()) {
+      killNonFinalActiveFields(staticGet);
+      clearMostRecentStaticFieldWrite(staticGet, field);
+      return;
+    }
+
     FieldValue replacement = activeState.getStaticFieldValue(field.getReference());
     if (replacement != null) {
       markAssumeDynamicTypeUsersForRemoval(staticGet, replacement, assumeRemover);
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NarrowingWithoutSubtypingTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NarrowingWithoutSubtypingTest.java
index b78279e..403372c 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NarrowingWithoutSubtypingTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NarrowingWithoutSubtypingTest.java
@@ -4,6 +4,12 @@
 
 package com.android.tools.r8.ir.analysis.type;
 
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThrows;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.D8TestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -32,17 +38,32 @@
 
   @Test
   public void test() throws Exception {
-    testForD8()
-        .addInnerClasses(NarrowingWithoutSubtypingTest.class)
-        .addOptionsModification(
-            options -> {
-              options.testing.readInputStackMaps = readStackMap;
-              options.testing.enableNarrowAndWideningingChecksInD8 = true;
-              options.testing.noLocalsTableOnInput = true;
-            })
-        .setMinApi(parameters.getApiLevel())
-        .run(parameters.getRuntime(), TestClass.class)
-        .assertSuccessWithOutputLines("Hello world!");
+    D8TestBuilder d8TestBuilder =
+        testForD8()
+            .addInnerClasses(NarrowingWithoutSubtypingTest.class)
+            .addOptionsModification(
+                options -> {
+                  options.testing.readInputStackMaps = readStackMap;
+                  options.testing.enableNarrowAndWideningingChecksInD8 = true;
+                  options.testing.noLocalsTableOnInput = true;
+                })
+            .setMinApi(parameters.getApiLevel());
+    if (readStackMap) {
+      d8TestBuilder
+          .run(parameters.getRuntime(), TestClass.class)
+          .assertSuccessWithOutputLines("Hello world!");
+    } else {
+      // TODO(b/169120386): We should not be narrowing in D8.
+      assertThrows(
+          CompilationFailedException.class,
+          () -> {
+            d8TestBuilder.compileWithExpectedDiagnostics(
+                diagnostics ->
+                    diagnostics.assertAllErrorsMatch(
+                        diagnosticMessage(
+                            containsString("java.lang.AssertionError: During NARROWING"))));
+          });
+    }
   }
 
   static class TestClass {