Revert^4 "Partial Load Store Elimination"

This reverts commit 791df7a161ecfa28eb69862a4bc285282463b960.
This unreverts commit fc1ce4e8be0d977e3d41699f5ec746d68f63c024.
This unreverts commit b8686ce4c93eba7192ed7ef89e7ffd9f3aa6cd07.

We incorrectly failed to include PredicatedInstanceFieldGet in a few
conditions, including a DCHECK. This caused tests to fail under the
read-barrier-table-lookup configuration.

Reason for revert: Fixed 2 incorrect checks

Bug: 67037140
Test: ./art/test/testrunner/run_build_test_target.py -j70 art-gtest-read-barrier-table-lookup

Change-Id: I32b01b29fb32077fb5074e7c77a0226bd1fcaab4
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index f250aa5..a303782 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -64,6 +64,20 @@
   boolean test1 = true;
 }
 
+// Chosen to have different values with (x + 1) * 10 and (x - 1) * 10. This
+// means we can easily make sure that different code is in fact executed on
+// escape and non-escape paths.
+// Negative so that high-bits will be set for all the 64-bit values allowing us
+// to easily check for truncation.
+class TestClass4 {
+  float floatField = -3.0f;
+  double doubleField = -3.0d;
+  short shortField = -3;
+  int intField = -3;
+  byte byteField = -3;
+  long longField = -3l;
+}
+
 class Finalizable {
   static boolean sVisited = false;
   static final int VALUE1 = 0xbeef;
@@ -83,9 +97,20 @@
 }
 
 public class Main {
+  static void $noinline$Escape4(TestClass4 o) {
+    o.floatField += 1.0f;
+    o.doubleField += 1.0d;
+    o.byteField += 1;
+    o.shortField += 1;
+    o.intField += 1;
+    o.longField += 1;
+  }
 
   static Object ESCAPE = null;
   static void $noinline$Escape(TestClass o) {
+    if (o == null) {
+      return;
+    }
     ESCAPE = o;
     o.next.i++;
   }
@@ -3792,6 +3817,248 @@
     return res;
   }
 
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (before)
+  /// CHECK-DAG:     ParameterValue
+  /// CHECK-DAG:     NewInstance
+  /// CHECK-DAG:     InvokeStaticOrDirect
+  /// CHECK-DAG:     InvokeStaticOrDirect
+  /// CHECK-DAG:     InvokeStaticOrDirect
+  /// CHECK-DAG:     InstanceFieldSet
+  /// CHECK-DAG:     InstanceFieldSet
+  /// CHECK-DAG:     InstanceFieldSet
+  /// CHECK-DAG:     InstanceFieldGet
+  /// CHECK-DAG:     InstanceFieldGet
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK-DAG:     ParameterValue
+  /// CHECK-DAG:     NewInstance
+  /// CHECK-DAG:     Phi
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK:         InvokeStaticOrDirect
+  /// CHECK:         InvokeStaticOrDirect
+  /// CHECK:         InvokeStaticOrDirect
+  //
+  /// CHECK-NOT:     InvokeStaticOrDirect
+
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:false
+  /// CHECK-NOT:     InstanceFieldSet predicated:false
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldGet
+  //
+  /// CHECK-NOT:     InstanceFieldGet
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  //
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static int $noinline$testPartialEscape2(TestClass obj, boolean escape) {
+    TestClass i = new SubTestClass();
+    if ($noinline$getBoolean(escape)) {
+      i.next = obj;
+      $noinline$Escape(i);
+    } else {
+      i.next = obj;
+    }
+    $noinline$clobberObservables();
+    // Predicated-get
+    TestClass res = i.next;
+    // Predicated-set
+    i.next = null;
+    return res.i;
+  }
+
+  /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static float $noinline$testPartialEscape3_float(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.floatField -= 1f;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.floatField *= 10;
+    // Predicated get
+    return tc.floatField;
+  }
+
+  /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static double $noinline$testPartialEscape3_double(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.doubleField -= 1d;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.doubleField *= 10;
+    // Predicated get
+    return tc.doubleField;
+  }
+
+  /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static short $noinline$testPartialEscape3_short(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.shortField -= 1;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.shortField *= 10;
+    // Predicated get
+    return tc.shortField;
+  }
+
+  /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static byte $noinline$testPartialEscape3_byte(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.byteField -= 1;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.byteField *= 10;
+    // Predicated get
+    return tc.byteField;
+  }
+
+  /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static int $noinline$testPartialEscape3_int(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.intField -= 1;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.intField *= 10;
+    // Predicated get
+    return tc.intField;
+  }
+
+  /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (before)
+  /// CHECK-NOT:     Phi
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  //
+  /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+  /// CHECK:         Phi
+  /// CHECK:         Phi
+  /// CHECK-NOT:     Phi
+  //
+  /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+  /// CHECK:         InstanceFieldSet predicated:true
+  /// CHECK-NOT:     InstanceFieldSet predicated:true
+  //
+  /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+  /// CHECK:         PredicatedInstanceFieldGet
+  /// CHECK-NOT:     PredicatedInstanceFieldGet
+  private static long $noinline$testPartialEscape3_long(boolean escape) {
+    TestClass4 tc = new TestClass4();
+    if ($noinline$getBoolean(escape)) {
+      $noinline$Escape4(tc);
+    } else {
+      tc.longField -= 1;
+    }
+    // Partial escape
+    $noinline$clobberObservables();
+    // Predicated set
+    tc.longField *= 10;
+    // Predicated get
+    return tc.longField;
+  }
 
   private static void $noinline$clobberObservables() {}
 
@@ -4196,5 +4463,19 @@
     assertLongEquals(testOverlapLoop(50), 7778742049l);
     assertIntEquals($noinline$testPartialEscape1(new TestClass(), true), 1);
     assertIntEquals($noinline$testPartialEscape1(new TestClass(), false), 0);
+    assertIntEquals($noinline$testPartialEscape2(new TestClass(), true), 1);
+    assertIntEquals($noinline$testPartialEscape2(new TestClass(), false), 0);
+    assertDoubleEquals($noinline$testPartialEscape3_double(true), -20d);
+    assertDoubleEquals($noinline$testPartialEscape3_double(false), -40d);
+    assertFloatEquals($noinline$testPartialEscape3_float(true), -20f);
+    assertFloatEquals($noinline$testPartialEscape3_float(false), -40f);
+    assertIntEquals($noinline$testPartialEscape3_int(true), -20);
+    assertIntEquals($noinline$testPartialEscape3_int(false), -40);
+    assertIntEquals($noinline$testPartialEscape3_byte(true), -20);
+    assertIntEquals($noinline$testPartialEscape3_byte(false), -40);
+    assertIntEquals($noinline$testPartialEscape3_short(true), -20);
+    assertIntEquals($noinline$testPartialEscape3_short(false), -40);
+    assertLongEquals($noinline$testPartialEscape3_long(true), -20);
+    assertLongEquals($noinline$testPartialEscape3_long(false), -40);
   }
 }