Partial LSE: handle all kinds of infinite loops.

A subgraph could also have an infinite loop.

Test: 826-inifinite-loop
Bug: 196246395
Merged-In: Ifd1e1ae0f42dfe2cc156386fc166101c20748fc9
(cherry picked from commit 96dadefd24331f6808cb287048269ba772423c33)
Change-Id: I410ec26aefbc42629ba7dbe5a19a87399cefe396
diff --git a/compiler/optimizing/execution_subgraph.cc b/compiler/optimizing/execution_subgraph.cc
index 6d10566..66fdfcd 100644
--- a/compiler/optimizing/execution_subgraph.cc
+++ b/compiler/optimizing/execution_subgraph.cc
@@ -86,12 +86,6 @@
     ScopedArenaVector<std::bitset<kMaxFilterableSuccessors>> results(
         graph_->GetBlocks().size(), temporaries.Adapter(kArenaAllocLSA));
     unreachable_blocks_.ClearAllBits();
-    // TODO We should support infinite loops as well.
-    if (UNLIKELY(graph_->GetExitBlock() == nullptr)) {
-      // Infinite loop
-      valid_ = false;
-      return;
-    }
     // Fills up the 'results' map with what we need to add to update
     // allowed_successors in order to prune sink nodes.
     bool start_reaches_end = false;
@@ -170,8 +164,11 @@
             << "current path size: " << current_path.size()
             << " cur_block id: " << cur_block->GetBlockId() << " entry id "
             << graph_->GetEntryBlock()->GetBlockId();
-        DCHECK(!visiting.IsBitSet(id))
-            << "Somehow ended up in a loop! This should have been caught before now! " << id;
+        if (visiting.IsBitSet(id)) {
+          // TODO We should support infinite loops as well.
+          start_reaches_end = false;
+          break;
+        }
         std::bitset<kMaxFilterableSuccessors>& result = results[id];
         if (cur_block == graph_->GetExitBlock()) {
           start_reaches_end = true;
diff --git a/test/826-infinite-loop/expected-stderr.txt b/test/826-infinite-loop/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/826-infinite-loop/expected-stderr.txt
diff --git a/test/826-infinite-loop/expected-stdout.txt b/test/826-infinite-loop/expected-stdout.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/826-infinite-loop/expected-stdout.txt
diff --git a/test/826-infinite-loop/info.txt b/test/826-infinite-loop/info.txt
new file mode 100644
index 0000000..13a89d8
--- /dev/null
+++ b/test/826-infinite-loop/info.txt
@@ -0,0 +1,2 @@
+Regression test for partial escape elimination, which used to crash when
+visiting an infinite loop.
diff --git a/test/826-infinite-loop/src/Main.java b/test/826-infinite-loop/src/Main.java
new file mode 100644
index 0000000..85bcb28
--- /dev/null
+++ b/test/826-infinite-loop/src/Main.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+final class Main {
+  public static void main(String[] args) {
+    Object o = new Object();
+    if (args.length == 0) {
+      while (true) {
+        System.out.println(new Object());
+      }
+    }
+  }
+}