Temporarily disable partial LSE.

Due to a bug in it. Add a regression test.

Bug: 197818595
Test: 828-partial-lse
Change-Id: I65da4f7ef09cd2a1f6c4b21799ecd7a42c1adac2
diff --git a/compiler/optimizing/load_store_elimination.h b/compiler/optimizing/load_store_elimination.h
index e73ef5e..6ad2eb2 100644
--- a/compiler/optimizing/load_store_elimination.h
+++ b/compiler/optimizing/load_store_elimination.h
@@ -27,7 +27,7 @@
  public:
   // Whether or not we should attempt partial Load-store-elimination which
   // requires additional blocks and predicated instructions.
-  static constexpr bool kEnablePartialLSE = true;
+  static constexpr bool kEnablePartialLSE = false;
 
   // Controls whether to enable VLOG(compiler) logs explaining the transforms taking place.
   static constexpr bool kVerboseLoggingMode = false;
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index 35f1dc2..a707a8a 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -3964,249 +3964,6 @@
     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() {}
 
   static void assertLongEquals(long result, long expected) {
@@ -4613,19 +4370,5 @@
     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);
   }
 }
diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java
index 28fa57c..91c3ec4 100644
--- a/test/639-checker-code-sinking/src/Main.java
+++ b/test/639-checker-code-sinking/src/Main.java
@@ -110,8 +110,6 @@
   /// CHECK: <<Int42:i\d+>>       IntConstant 42
   /// CHECK:                      begin_block
   /// CHECK: <<LoadClass:l\d+>>   LoadClass class_name:Main
-  /// CHECK:                      If
-  /// CHECK:                      begin_block
   /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>]
   /// CHECK:                      InstanceFieldSet [<<NewInstance>>,<<Int42>>]
   /// CHECK:                      Throw
@@ -121,14 +119,14 @@
   /// CHECK-NOT:                  NewInstance
   /// CHECK:                      If
   /// CHECK:                      begin_block
+  /// CHECK: <<Error:l\d+>>       LoadClass class_name:java.lang.Error
+  /// CHECK-NOT:                  begin_block
   /// CHECK: <<LoadClass:l\d+>>   LoadClass class_name:Main
   /// CHECK-NOT:                  begin_block
   /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>]
   /// CHECK-NOT:                  begin_block
   /// CHECK:                      InstanceFieldSet [<<NewInstance>>,<<Int42>>]
   /// CHECK-NOT:                  begin_block
-  /// CHECK: <<Error:l\d+>>       LoadClass class_name:java.lang.Error
-  /// CHECK-NOT:                  begin_block
   /// CHECK: <<Throw:l\d+>>       NewInstance [<<Error>>]
   /// CHECK-NOT:                  begin_block
   /// CHECK:                      Throw [<<Throw>>]
@@ -325,12 +323,7 @@
   /// CHECK: <<Int42:i\d+>>       IntConstant 42
   /// CHECK: <<Int43:i\d+>>       IntConstant 43
   /// CHECK: <<LoadClass:l\d+>>   LoadClass class_name:Main
-  /// CHECK:                      If
-  /// CHECK:                      begin_block
-  // Moved to throw block by partial-LSE and DCE.
   /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>]
-  // These were moved by partial LSE and order of sets is not observable and are
-  // in an arbitrary order.
   /// CHECK-DAG:                  InstanceFieldSet [<<NewInstance>>,<<Int42>>]
   /// CHECK-DAG:                  InstanceFieldSet [<<NewInstance>>,<<Int43>>]
   /// CHECK:                      Throw
@@ -342,14 +335,14 @@
   /// CHECK-NOT:                  NewInstance
   /// CHECK:                      If
   /// CHECK:                      begin_block
+  /// CHECK: <<Error:l\d+>>       LoadClass class_name:java.lang.Error
+  /// CHECK-NOT:                  begin_block
   /// CHECK: <<LoadClass:l\d+>>   LoadClass class_name:Main
   /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>]
   /// CHECK-NOT:                  begin_block
   /// CHECK-DAG:                  InstanceFieldSet [<<NewInstance>>,<<Int42>>]
   /// CHECK-DAG:                  InstanceFieldSet [<<NewInstance>>,<<Int43>>]
   /// CHECK-NOT:                  begin_block
-  /// CHECK: <<Error:l\d+>>       LoadClass class_name:java.lang.Error
-  /// CHECK-NOT:                  begin_block
   /// CHECK:                      NewInstance [<<Error>>]
   /// CHECK:                      Throw
   /// CHECK-NOT:                  InstanceFieldSet
diff --git a/test/828-partial-lse/expected-stderr.txt b/test/828-partial-lse/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/828-partial-lse/expected-stderr.txt
diff --git a/test/828-partial-lse/expected-stdout.txt b/test/828-partial-lse/expected-stdout.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/828-partial-lse/expected-stdout.txt
diff --git a/test/828-partial-lse/info.txt b/test/828-partial-lse/info.txt
new file mode 100644
index 0000000..8d28cbd
--- /dev/null
+++ b/test/828-partial-lse/info.txt
@@ -0,0 +1,2 @@
+Regression test for the partial LSE pass, see
+https://issuetracker.google.com/197818595.
diff --git a/test/828-partial-lse/src/Main.java b/test/828-partial-lse/src/Main.java
new file mode 100644
index 0000000..2dde0ef
--- /dev/null
+++ b/test/828-partial-lse/src/Main.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class Main {
+
+  public static void $noinline$testMain(Main m) {
+    expectEquals(0, m.myField);
+  }
+
+  public static void main(String[] args) {
+    $noinline$doTest(true);
+    $noinline$doTest(false);
+  }
+
+  public static void $noinline$doTest(boolean testValue) {
+    Main m = new Main();
+    // LSE will find that this store can be removed, as both branches override the value with a new
+    // one.
+    m.myField = 42;
+    if (testValue) {
+      // LSE will remove this store as well, as it's the value after the store of 42 is removed.
+      m.myField = 0;
+      // This makes sure `m` gets materialized. At this point, the bug is that the partial LSE
+      // optimization thinks the value incoming this block for `m.myField` is 42, however that
+      // store, as well as the store to 0, have been removed.
+      $noinline$testMain(m);
+    } else {
+      m.myField = 3;
+      expectEquals(3, m.myField);
+    }
+  }
+
+  public static void expectEquals(int expected, int actual) {
+    if (expected != actual) {
+      throw new Error("Expected " + expected + ", got " + actual);
+    }
+  }
+
+  int myField = 0;
+}