Enable LoopOptimization for graphs with try catch blocks

We can enable the optimization when the graph has try catch blocks,
but we do not perform the optimizations if the loops themselves
have try catch blocks.

Bug: 227283906
Change-Id: I8889d2ed7a5a260d5c2dcbbc5184cb7eaf3a8f9f
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 77dfe68..2d7c208 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -491,9 +491,9 @@
 }
 
 bool HLoopOptimization::Run() {
-  // Skip if there is no loop or the graph has try-catch/irreducible loops.
+  // Skip if there is no loop or the graph has irreducible loops.
   // TODO: make this less of a sledgehammer.
-  if (!graph_->HasLoops() || graph_->HasTryCatch() || graph_->HasIrreducibleLoops()) {
+  if (!graph_->HasLoops() || graph_->HasIrreducibleLoops()) {
     return false;
   }
 
@@ -502,7 +502,7 @@
   loop_allocator_ = &allocator;
 
   // Perform loop optimizations.
-  bool didLoopOpt = LocalRun();
+  const bool did_loop_opt = LocalRun();
   if (top_loop_ == nullptr) {
     graph_->SetHasLoops(false);  // no more loops
   }
@@ -511,7 +511,7 @@
   loop_allocator_ = nullptr;
   last_loop_ = top_loop_ = nullptr;
 
-  return didLoopOpt;
+  return did_loop_opt;
 }
 
 //
@@ -519,7 +519,6 @@
 //
 
 bool HLoopOptimization::LocalRun() {
-  bool didLoopOpt = false;
   // Build the linear order using the phase-local allocator. This step enables building
   // a loop hierarchy that properly reflects the outer-inner and previous-next relation.
   ScopedArenaVector<HBasicBlock*> linear_order(loop_allocator_->Adapter(kArenaAllocLinearOrder));
@@ -532,34 +531,37 @@
     }
   }
 
+  // TODO(solanes): How can `top_loop_` be null if `graph_->HasLoops()` is true?
+  if (top_loop_ == nullptr) {
+    return false;
+  }
+
   // Traverse the loop hierarchy inner-to-outer and optimize. Traversal can use
   // temporary data structures using the phase-local allocator. All new HIR
   // should use the global allocator.
-  if (top_loop_ != nullptr) {
-    ScopedArenaSet<HInstruction*> iset(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
-    ScopedArenaSafeMap<HInstruction*, HInstruction*> reds(
-        std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
-    ScopedArenaSet<ArrayReference> refs(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
-    ScopedArenaSafeMap<HInstruction*, HInstruction*> map(
-        std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
-    ScopedArenaSafeMap<HInstruction*, HInstruction*> perm(
-        std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
-    // Attach.
-    iset_ = &iset;
-    reductions_ = &reds;
-    vector_refs_ = &refs;
-    vector_map_ = &map;
-    vector_permanent_map_ = &perm;
-    // Traverse.
-    didLoopOpt = TraverseLoopsInnerToOuter(top_loop_);
-    // Detach.
-    iset_ = nullptr;
-    reductions_ = nullptr;
-    vector_refs_ = nullptr;
-    vector_map_ = nullptr;
-    vector_permanent_map_ = nullptr;
-  }
-  return didLoopOpt;
+  ScopedArenaSet<HInstruction*> iset(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+  ScopedArenaSafeMap<HInstruction*, HInstruction*> reds(
+      std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+  ScopedArenaSet<ArrayReference> refs(loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+  ScopedArenaSafeMap<HInstruction*, HInstruction*> map(
+      std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+  ScopedArenaSafeMap<HInstruction*, HInstruction*> perm(
+      std::less<HInstruction*>(), loop_allocator_->Adapter(kArenaAllocLoopOptimization));
+  // Attach.
+  iset_ = &iset;
+  reductions_ = &reds;
+  vector_refs_ = &refs;
+  vector_map_ = &map;
+  vector_permanent_map_ = &perm;
+  // Traverse.
+  const bool did_loop_opt = TraverseLoopsInnerToOuter(top_loop_);
+  // Detach.
+  iset_ = nullptr;
+  reductions_ = nullptr;
+  vector_refs_ = nullptr;
+  vector_map_ = nullptr;
+  vector_permanent_map_ = nullptr;
+  return did_loop_opt;
 }
 
 void HLoopOptimization::AddLoop(HLoopInformation* loop_info) {
@@ -618,6 +620,18 @@
       induction_range_.ReVisit(node->loop_info);
       changed = true;
     }
+
+    CalculateAndSetTryCatchKind(node);
+    if (node->try_catch_kind == LoopNode::TryCatchKind::kHasTryCatch) {
+      // The current optimizations assume that the loops do not contain try/catches.
+      // TODO(solanes, 227283906): Assess if we can modify them to work with try/catches.
+      continue;
+    }
+
+    DCHECK(node->try_catch_kind == LoopNode::TryCatchKind::kNoTryCatch)
+        << "kind: " << static_cast<int>(node->try_catch_kind)
+        << ". LoopOptimization requires the loops to not have try catches.";
+
     // Repeat simplifications in the loop-body until no more changes occur.
     // Note that since each simplification consists of eliminating code (without
     // introducing new code), this process is always finite.
@@ -635,6 +649,37 @@
   return changed;
 }
 
+void HLoopOptimization::CalculateAndSetTryCatchKind(LoopNode* node) {
+  DCHECK(node != nullptr);
+  DCHECK(node->try_catch_kind == LoopNode::TryCatchKind::kUnknown)
+      << "kind: " << static_cast<int>(node->try_catch_kind)
+      << ". SetTryCatchKind should be called only once per LoopNode.";
+
+  // If a inner loop has a try catch, then the outer loop has one too (as it contains `inner`).
+  // Knowing this, we could skip iterating through all of the outer loop's parents with a simple
+  // check.
+  for (LoopNode* inner = node->inner; inner != nullptr; inner = inner->next) {
+    DCHECK(inner->try_catch_kind != LoopNode::TryCatchKind::kUnknown)
+        << "kind: " << static_cast<int>(inner->try_catch_kind)
+        << ". Should have updated the inner loop before the outer loop.";
+
+    if (inner->try_catch_kind == LoopNode::TryCatchKind::kHasTryCatch) {
+      node->try_catch_kind = LoopNode::TryCatchKind::kHasTryCatch;
+      return;
+    }
+  }
+
+  for (HBlocksInLoopIterator it_loop(*node->loop_info); !it_loop.Done(); it_loop.Advance()) {
+    HBasicBlock* block = it_loop.Current();
+    if (block->GetTryCatchInformation() != nullptr) {
+      node->try_catch_kind = LoopNode::TryCatchKind::kHasTryCatch;
+      return;
+    }
+  }
+
+  node->try_catch_kind = LoopNode::TryCatchKind::kNoTryCatch;
+}
+
 //
 // Optimization.
 //
@@ -782,8 +827,6 @@
   return TryOptimizeInnerLoopFinite(node) || TryPeelingAndUnrolling(node);
 }
 
-
-
 //
 // Scalar loop peeling and unrolling: generic part methods.
 //
diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h
index 3acd5b1..b178616 100644
--- a/compiler/optimizing/loop_optimization.h
+++ b/compiler/optimizing/loop_optimization.h
@@ -57,12 +57,23 @@
           outer(nullptr),
           inner(nullptr),
           previous(nullptr),
-          next(nullptr) {}
+          next(nullptr),
+          try_catch_kind(TryCatchKind::kUnknown) {}
+
+    enum class TryCatchKind {
+      kUnknown,
+      // Either if we have a try catch in the loop, or if the loop is inside of an outer try catch,
+      // we set `kHasTryCatch`.
+      kHasTryCatch,
+      kNoTryCatch
+    };
+
     HLoopInformation* loop_info;
     LoopNode* outer;
     LoopNode* inner;
     LoopNode* previous;
     LoopNode* next;
+    TryCatchKind try_catch_kind;
   };
 
   /*
@@ -131,6 +142,11 @@
   // Returns true if loops nested inside current loop (node) have changed.
   bool TraverseLoopsInnerToOuter(LoopNode* node);
 
+  // Calculates `node`'s `try_catch_kind` and sets it to:
+  // 1) kHasTryCatch if it has try catches (or if it's inside of an outer try catch)
+  // 2) kNoTryCatch otherwise.
+  void CalculateAndSetTryCatchKind(LoopNode* node);
+
   //
   // Optimization.
   //
diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc
index b46d193..a5f919c 100644
--- a/compiler/optimizing/superblock_cloner.cc
+++ b/compiler/optimizing/superblock_cloner.cc
@@ -855,11 +855,20 @@
 }
 
 bool SuperblockCloner::IsSubgraphClonable() const {
-  // TODO: Support irreducible graphs and graphs with try-catch.
-  if (graph_->HasIrreducibleLoops() || graph_->HasTryCatch()) {
+  // TODO: Support irreducible graphs and subgraphs with try-catch.
+  if (graph_->HasIrreducibleLoops()) {
     return false;
   }
 
+  for (HBasicBlock* block : graph_->GetReversePostOrder()) {
+    if (!IsInOrigBBSet(block)) {
+      continue;
+    }
+    if (block->GetTryCatchInformation() != nullptr) {
+      return false;
+    }
+  }
+
   HInstructionMap live_outs(
       std::less<HInstruction*>(), graph_->GetAllocator()->Adapter(kArenaAllocSuperblockCloner));
 
diff --git a/test/530-checker-loops-try-catch/expected-stderr.txt b/test/530-checker-loops-try-catch/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/530-checker-loops-try-catch/expected-stderr.txt
diff --git a/test/530-checker-loops-try-catch/expected-stdout.txt b/test/530-checker-loops-try-catch/expected-stdout.txt
new file mode 100644
index 0000000..b0aad4d
--- /dev/null
+++ b/test/530-checker-loops-try-catch/expected-stdout.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/530-checker-loops-try-catch/info.txt b/test/530-checker-loops-try-catch/info.txt
new file mode 100644
index 0000000..5ff3c22
--- /dev/null
+++ b/test/530-checker-loops-try-catch/info.txt
@@ -0,0 +1 @@
+Test on loop optimizations, in particular with try catches.
diff --git a/test/530-checker-loops-try-catch/src/Main.java b/test/530-checker-loops-try-catch/src/Main.java
new file mode 100644
index 0000000..8d44b65
--- /dev/null
+++ b/test/530-checker-loops-try-catch/src/Main.java
@@ -0,0 +1,1558 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+//
+// Test on loop optimizations, in particular with try catches.
+//
+public class Main {
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Mul loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
+  /// CHECK-DAG: <<Par:i\d+>> ParameterValue         loop:none
+  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0          loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none
+  /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>]  loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>]  loop:none
+  /// CHECK-DAG:              Return [<<Add>>]       loop:none
+
+  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$geo1(int a) {
+    for (int i = 0; i < 10; i++) {
+      a *= 10;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Mul loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Mul loop:<<Loop>>
+  private static int $noinline$geo1_Blocking(int a) {
+    for (int i = 0; i < 10; i++) {
+      a *= 10;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
+  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
+  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024      loop:none
+  /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
+  /// CHECK-DAG:              Return [<<Add>>]      loop:none
+
+  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$geo2(int a) {
+    for (int i = 0; i < 10; i++) {
+      a <<= 1;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+  private static int $noinline$geo2_Blocking(int a) {
+    for (int i = 0; i < 10; i++) {
+      a <<= 1;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Div loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
+  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
+  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049     loop:none
+  /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none
+  /// CHECK-DAG:              Return [<<Add>>]      loop:none
+
+  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$geo3(int a) {
+    for (int i = 0; i < 10; i++) {
+      a /= 3;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Div loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Div loop:<<Loop>>
+  private static int $noinline$geo3_Blocking(int a) {
+    for (int i = 0; i < 10; i++) {
+      a /= 3;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Rem loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
+  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 7         loop:none
+  /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none
+  /// CHECK-DAG:              Return [<<Rem>>]      loop:none
+
+  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$geo4(int a) {
+    for (int i = 0; i < 10; i++) {
+      a %= 7; // a wrap-around induction
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Rem loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Rem loop:<<Loop>>
+  private static int $noinline$geo4_Blocking(int a) {
+    for (int i = 0; i < 10; i++) {
+      a %= 7; // a wrap-around induction
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shr loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
+  /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0          loop:none
+  /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
+  /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024       loop:none
+  /// CHECK-DAG: <<Div:i\d+>>  Div [<<Int1>>,<<Int2>>] loop:none
+  /// CHECK-DAG: <<Add:i\d+>>  Add [<<Div>>,<<Zero>>]  loop:none
+  /// CHECK-DAG:               Return [<<Add>>]        loop:none
+
+  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$geo5() {
+    int a = 0x7fffffff;
+    for (int i = 0; i < 10; i++) {
+      a >>= 1;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shr loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shr loop:<<Loop>>
+  private static int $noinline$geo5_Blocking() {
+    int a = 0x7fffffff;
+    for (int i = 0; i < 10; i++) {
+      a >>= 1;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+  // Tests taken from 530-checker-loops4
+  private static void $noinline$loops4Tests() {
+    int m = 1410065408;
+    for (int i = -100; i <= 100; i++) {
+      expectEquals(m * i, $noinline$geo1(i));
+      expectEquals(m * i, $noinline$geo1_Blocking(i));
+    }
+    for (int i = 1; i <= 1000000000; i *= 10) {
+      expectEquals(m * i, $noinline$geo1(i));
+      expectEquals(m * i, $noinline$geo1_Blocking(i));
+      expectEquals(-m * i, $noinline$geo1(-i));
+      expectEquals(-m * i, $noinline$geo1_Blocking(-i));
+    }
+
+    for (int i = -100; i <= 100; i++) {
+      expectEquals(i << 10, $noinline$geo2(i));
+      expectEquals(i << 10, $noinline$geo2_Blocking(i));
+    }
+    for (int i = 0; i < 22; i++) {
+      expectEquals(1 << (i + 10), $noinline$geo2(1 << i));
+      expectEquals(1 << (i + 10), $noinline$geo2_Blocking(1 << i));
+    }
+    expectEquals(0x80000400, $noinline$geo2(0x00200001));
+    expectEquals(0x80000400, $noinline$geo2_Blocking(0x00200001));
+    expectEquals(0x00000000, $noinline$geo2(0x00400000));
+    expectEquals(0x00000000, $noinline$geo2_Blocking(0x00400000));
+    expectEquals(0x00000400, $noinline$geo2(0x00400001));
+    expectEquals(0x00000400, $noinline$geo2_Blocking(0x00400001));
+
+    int d = 59049;
+    for (int i = -100; i <= 100; i++) {
+      expectEquals(0, $noinline$geo3(i));
+      expectEquals(0, $noinline$geo3_Blocking(i));
+    }
+    for (int i = 1; i <= 100; i++) {
+      expectEquals(i, $noinline$geo3(i * d));
+      expectEquals(i, $noinline$geo3_Blocking(i * d));
+      expectEquals(i, $noinline$geo3(i * d + 1));
+      expectEquals(i, $noinline$geo3_Blocking(i * d + 1));
+      expectEquals(-i, $noinline$geo3(-i * d));
+      expectEquals(-i, $noinline$geo3_Blocking(-i * d));
+      expectEquals(-i, $noinline$geo3(-i * d - 1));
+      expectEquals(-i, $noinline$geo3_Blocking(-i * d - 1));
+    }
+
+    for (int i = -100; i <= 100; i++) {
+      expectEquals(i % 7, $noinline$geo4(i));
+      expectEquals(i % 7, $noinline$geo4_Blocking(i));
+    }
+
+    expectEquals(0x1fffff, $noinline$geo5());
+    expectEquals(0x1fffff, $noinline$geo5_Blocking());
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
+  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 55        loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none
+  /// CHECK-DAG:              Return [<<Add>>]      loop:none
+
+  /// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$after_bce (after)
+  /// CHECK-DAG: <<Int:i\d+>>  IntConstant 55 loop:none
+  /// CHECK-DAG:               Return [<<Int>>]  loop:none
+
+  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$poly1() {
+    int a = 0;
+    for (int i = 0; i <= 10; i++) {
+      a += i;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  private static int $noinline$poly1_Blocking() {
+    int a = 0;
+    for (int i = 0; i <= 10; i++) {
+      a += i;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+
+    return a;
+  }
+
+  // Multiplication in linear induction has been optimized earlier,
+  // but that does not stop the induction variable recognition
+  // and loop optimizer.
+  //
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
+  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant 185       loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
+  /// CHECK-DAG:              Return [<<Add>>]      loop:none
+
+  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$poly2(int a) {
+    for (int i = 0; i < 10; i++) {
+      int k = 3 * i + 5;
+      a += k;
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Shl loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  private static int $noinline$poly2_Blocking(int a) {
+    for (int i = 0; i < 10; i++) {
+      int k = 3 * i + 5;
+      a += k;
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
+  /// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345       loop:none
+  /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none
+  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>]   loop:none
+  /// CHECK-DAG:              Return [<<Add>>]        loop:none
+
+  /// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$after_bce (after)
+  /// CHECK-DAG: <<Int:i\d+>>  IntConstant -2146724623 loop:none
+  /// CHECK-DAG:               Return [<<Int>>]        loop:none
+
+  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
+  /// CHECK-NOT: Phi
+  private static int $noinline$poly3() {
+    int a = 12345;
+    for (int i = 0; i <= 10; i++) {
+      a += (2147483646 * i + 67890);
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+    return a;
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+
+  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after)
+  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  /// CHECK-DAG: Add loop:<<Loop>>
+  private static int $noinline$poly3_Blocking() {
+    int a = 12345;
+    for (int i = 0; i <= 10; i++) {
+      a += (2147483646 * i + 67890);
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+    return a;
+  }
+
+  // Tests taken from 530-checker-loops5
+  private static void $noinline$loops5Tests() {
+    expectEquals(55, $noinline$poly1());
+    expectEquals(55, $noinline$poly1_Blocking());
+    expectEquals(185, $noinline$poly2(0));
+    expectEquals(185, $noinline$poly2_Blocking(0));
+    expectEquals(192, $noinline$poly2(7));
+    expectEquals(192, $noinline$poly2_Blocking(7));
+    expectEquals(-2146724623, $noinline$poly3());
+    expectEquals(-2146724623, $noinline$poly3_Blocking());
+  }
+
+  // Constants used for peel unroll tests.
+  private static final int LENGTH = 4 * 1024;
+  private static final int RESULT_POS = 4;
+
+  private static final void initIntArray(int[] a) {
+    for (int i = 0; i < a.length; i++) {
+      a[i] = i % 4;
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
+  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
+  /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
+  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
+  //
+  /// CHECK-DAG: <<CheckA:z\d+>>  GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IfA:v\d+>>     If [<<Const0>>]                           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get0A:i\d+>>   ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>]               loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get1A:i\d+>>   ArrayGet [<<Array>>,<<IndAddA>>]          loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<AddA:i\d+>>    Add [<<Get0A>>,<<Get1A>>]                 loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG:                  ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>]  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingLoadStoreElimination(int[] a) {
+    for (int i = 0; i < LENGTH - 2; i++) {
+      a[i] += a[i + 1];
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
+  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
+  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
+  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingLoadStoreElimination_Blocking(int[] a) {
+    for (int i = 0; i < LENGTH - 2; i++) {
+      a[i] += a[i + 1];
+
+      // Try catch blocks optimizations.
+      try {
+        if (doThrow) {
+          $noinline$unreachable();
+        }
+      } catch (Error e) {
+        System.out.println("Not expected");
+      }
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<AddI:i\d+>>     Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+  //
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingInTheNest(int[] a, int[] b, int x) {
+    for (int k = 0; k < 16; k++) {
+      for (int j = 0; j < 16; j++) {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+          a[i] = a[i] + 1;
+        }
+      }
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  //
+  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  //
+  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x) {
+    for (int k = 0; k < 16; k++) {
+      for (int j = 0; j < 16; j++) {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+          a[i] = a[i] + 1;
+
+          // Try catch blocks optimizations.
+          try {
+            if (doThrow) {
+              $noinline$unreachable();
+            }
+          } catch (Error e) {
+            System.out.println("Not expected");
+          }
+        }
+      }
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  //
+  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG: <<AddI:i\d+>>     Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
+  //
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
+
+  // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x) {
+    for (int k = 0; k < 16; k++) {
+      for (int j = 0; j < 16; j++) {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+          a[i] = a[i] + 1;
+        }
+        // Try catch does not block the optimization in the innermost loop.
+        try {
+          if (doThrow) {
+            $noinline$unreachable();
+          }
+        } catch (Error e) {
+          System.out.println("Not expected");
+        }
+      }
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   Add [<<AddI2>>,<<Const1>>]                loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   Add [<<AddI3>>,<<Const1>>]                loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // LoopOptimization adds two `if`s. One for each loop unrolling.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
+    for (int k = 0; k < 128; k++) {
+      if (x > 100) {
+        for (int j = 0; j < 128; j++) {
+          a[x]++;
+        }
+      } else {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+        }
+      }
+    }
+
+    // Outer try catch does not block loop optimizations.
+    try {
+      if (doThrow) {
+        $noinline$unreachable();
+      }
+    } catch (Error e) {
+      System.out.println("Not expected");
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  // Unrelated to the optimization itself, the try catch has an if.
+  /// CHECK-DAG: <<Get:z\d+>>      StaticFieldGet field_name:Main.doThrow
+  /// CHECK-DAG:                   If [<<Get>>]
+  //
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   Add [<<AddI3>>,<<Const1>>]                loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // LoopOptimization adds two `if`s. One for each loop unrolling.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x) {
+    for (int k = 0; k < 128; k++) {
+      if (x > 100) {
+        for (int j = 0; j < 128; j++) {
+          a[x]++;
+          // Try catch blocks optimizations.
+          try {
+            if (doThrow) {
+              $noinline$unreachable();
+            }
+          } catch (Error e) {
+            System.out.println("Not expected");
+          }
+        }
+      } else {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+        }
+      }
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   Add [<<AddI2>>,<<Const1>>]                loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // LoopOptimization adds two `if`s. One for each loop unrolling.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x) {
+    for (int k = 0; k < 128; k++) {
+      if (x > 100) {
+        for (int j = 0; j < 128; j++) {
+          a[x]++;
+        }
+      } else {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+          // Try catch blocks optimizations.
+          try {
+            if (doThrow) {
+              $noinline$unreachable();
+            }
+          } catch (Error e) {
+            System.out.println("Not expected");
+          }
+        }
+      }
+    }
+  }
+
+  // Consistency check to see we haven't eliminated the try/catch.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:     TryBoundary
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catchs have the 5th and 6th `if`.
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
+  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
+  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
+  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
+  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
+  //
+  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  // Unrelated to the optimization itself, the try catch has an if.
+  /// CHECK-DAG: <<Get1:z\d+>>     StaticFieldGet field_name:Main.doThrow
+  /// CHECK-DAG:                   If [<<Get1>>]
+  //
+  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
+  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
+  //
+  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+  private static final void $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x) {
+    for (int k = 0; k < 128; k++) {
+      if (x > 100) {
+        for (int j = 0; j < 128; j++) {
+          a[x]++;
+          // Try catch blocks optimizations.
+          try {
+            if (doThrow) {
+              $noinline$unreachable();
+            }
+          } catch (Error e) {
+            System.out.println("Not expected");
+          }
+        }
+      } else {
+        for (int i = 0; i < 128; i++) {
+          b[x]++;
+          // Try catch blocks optimizations.
+          try {
+            if (doThrow) {
+              $noinline$unreachable();
+            }
+          } catch (Error e) {
+            System.out.println("Not expected");
+          }
+        }
+      }
+    }
+  }
+
+  // Tests taken from 530-checker-peel-unroll
+  private static void $noinline$peelUnrollTests() {
+    int[] a = new int[LENGTH];
+    int[] b = new int[LENGTH];
+    initIntArray(a);
+    initIntArray(b);
+
+    $noinline$unrollingLoadStoreElimination(a);
+    $noinline$unrollingLoadStoreElimination_Blocking(a);
+    $noinline$unrollingInTheNest(a, b, RESULT_POS);
+    $noinline$unrollingInTheNest_Blocking(a, b, RESULT_POS);
+    $noinline$unrollingInTheNest_TryCatchNotBlocking(a, b, RESULT_POS);
+    $noinline$unrollingTwoLoopsInTheNest(a, b, RESULT_POS);
+    $noinline$unrollingTwoLoopsInTheNest_OneBlocking(a, b, RESULT_POS);
+    $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(a, b, RESULT_POS);
+    $noinline$unrollingTwoLoopsInTheNest_BothBlocking(a, b, RESULT_POS);
+  }
+
+  public static void main(String[] args) {
+    // Use existing tests to show that the difference between having a try catch inside or outside
+    // the loop.
+    $noinline$loops4Tests();
+    $noinline$loops5Tests();
+    $noinline$peelUnrollTests();
+
+    System.out.println("passed");
+  }
+
+  private static void expectEquals(int expected, int result) {
+    if (expected != result) {
+      throw new Error("Expected: " + expected + ", found: " + result);
+    }
+  }
+
+  private static void $noinline$unreachable() {
+    throw new Error("Unreachable");
+  }
+
+  private static boolean doThrow = false;
+}
diff --git a/test/530-checker-peel-unroll/src/Main.java b/test/530-checker-peel-unroll/src/Main.java
index aee32b7..f909af3 100644
--- a/test/530-checker-peel-unroll/src/Main.java
+++ b/test/530-checker-peel-unroll/src/Main.java
@@ -78,9 +78,15 @@
   /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                  ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
   /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
@@ -103,9 +109,18 @@
   /// CHECK-DAG: <<Get1A:i\d+>>   ArrayGet [<<Array>>,<<IndAddA>>]          loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<AddA:i\d+>>    Add [<<Get0A>>,<<Get1A>>]                 loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>]  loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                  ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingLoadStoreElimination(int[] a) {
     for (int i = 0; i < LENGTH - 2; i++) {
       a[i] += a[i + 1];
@@ -124,9 +139,14 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
@@ -144,9 +164,16 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<AddI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingSwitch(int[] a) {
     for (int i = 0; i < LENGTH; i++) {
       switch (i % 3) {
@@ -173,9 +200,16 @@
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
@@ -197,9 +231,20 @@
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<AddI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingSwapElements(int[] array) {
     for (int i = 0; i < LENGTH - 2; i++) {
       if (array[i] > array[i + 1]) {
@@ -225,9 +270,21 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<PhiI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  // We have two other `ArrayGet` before the `If` that appears in the CHECK-DAG above.
+  /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
@@ -251,9 +308,25 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   Add [<<AddI>>,<<Const1>>]                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   ArrayGet                                  loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:                   ArraySet                                  loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingRInnerproduct(double[][] result,
                                                    double[][] a,
                                                    double[][] b,
@@ -284,11 +357,24 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
   /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
-  //
-  /// CHECK-NOT:                   ArrayGet
-  /// CHECK-NOT:                   ArraySet
+
+  // Each one of the three `for` loops has an `if`.
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
   /// CHECK-NOT:                   If
 
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
   /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
@@ -309,10 +395,28 @@
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
-  //
-  /// CHECK-NOT:                   ArrayGet
-  /// CHECK-NOT:                   ArraySet
+
+  // Loop unrolling adds a 4th `if`. It is the one with `Const0` above.
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
   /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingInTheNest(int[] a, int[] b, int x) {
     for (int k = 0; k < 16; k++) {
       for (int j = 0; j < 16; j++) {
@@ -349,11 +453,25 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
   /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
-  //
-  /// CHECK-NOT:                   ArrayGet
-  /// CHECK-NOT:                   ArraySet
+
+  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`.
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
   /// CHECK-NOT:                   If
 
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
+
   /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
@@ -382,10 +500,30 @@
   /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
   /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
   /// CHECK-DAG:                   Add [<<AddI3>>,<<Const1>>]                loop:<<Loop3>>      outer_loop:<<Loop1>>
-  //
-  /// CHECK-NOT:                   ArrayGet
-  /// CHECK-NOT:                   ArraySet
+
+  // LoopOptimization adds two `if`s. One for each loop unrolling.
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
+  /// CHECK:                       If
   /// CHECK-NOT:                   If
+
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
     for (int k = 0; k < 128; k++) {
       if (x > 100) {
@@ -423,7 +561,14 @@
   /// CHECK-DAG: <<ZCheck:i\d+>>  DivZeroCheck [<<STAdd>>] env:[[<<PhiS>>,<<PhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none
   /// CHECK-DAG: <<Div:i\d+>>     Div [<<Const1>>,<<ZCheck>>]               loop:none
   /// CHECK-DAG:                  Return [<<Div>>]                          loop:none
+
+  /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
@@ -461,8 +606,17 @@
   /// CHECK-DAG: <<ZCheck:i\d+>>  DivZeroCheck [<<STAdd>>] env:[[<<RetPhiS>>,<<RetPhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none
   /// CHECK-DAG: <<Div:i\d+>>     Div [<<Const1>>,<<ZCheck>>]               loop:none
   /// CHECK-DAG:                  Return [<<Div>>]                          loop:none
-  //
+
+  /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
   private static final int unrollingSimpleLiveOuts(int[] a) {
     int s = 1;
@@ -502,8 +656,14 @@
   /// CHECK-DAG:                  ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>]  loop:<<Loop1>>      outer_loop:<<Loop0>>
   //
   /// CHECK-DAG:                  Add [<<OutPhiJ>>,<<Const1>>]              loop:<<Loop0>>      outer_loop:none
-  //
+
+  /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
@@ -545,8 +705,17 @@
   //
   /// CHECK-DAG: <<RetAdd:i\d+>>  Add [<<OutPhiS>>,<<OutPhiT>>]             loop:none
   /// CHECK-DAG:                  Return [<<RetAdd>>]                       loop:none
-  //
+
+  /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
   private static final int unrollingLiveOutsNested(int[] a) {
     int s = 1;
@@ -566,16 +735,21 @@
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   InstanceOf                                loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   InstanceOf
+
+  /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (before)
+  /// CHECK:                      InstanceOf
+  /// CHECK-NOT:                  InstanceOf
 
   /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   InstanceOf                                loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   InstanceOf                                loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   InstanceOf
+
+  /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after)
+  /// CHECK:                      InstanceOf
+  /// CHECK:                      InstanceOf
+  /// CHECK-NOT:                  InstanceOf
   public void unrollingInstanceOf(int[] a, Object[] obj_array) {
     for (int i = 0; i < LENGTH_B; i++) {
       if (obj_array[i] instanceof Integer) {
@@ -588,16 +762,21 @@
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   DivZeroCheck                              loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   DivZeroCheck
+
+  /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (before)
+  /// CHECK:                      DivZeroCheck
+  /// CHECK-NOT:                  DivZeroCheck
 
   /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   DivZeroCheck                              loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   DivZeroCheck                              loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   DivZeroCheck
+
+  /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after)
+  /// CHECK:                      DivZeroCheck
+  /// CHECK:                      DivZeroCheck
+  /// CHECK-NOT:                  DivZeroCheck
   public void unrollingDivZeroCheck(int[] a, int r) {
     for (int i = 0; i < LENGTH_B; i++) {
       a[i] += a[i] / r;
@@ -608,16 +787,21 @@
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   TypeConversion                            loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   TypeConversion
+
+  /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (before)
+  /// CHECK:                      TypeConversion
+  /// CHECK-NOT:                  TypeConversion
 
   /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   TypeConversion                            loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   TypeConversion                            loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   TypeConversion
+
+  /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after)
+  /// CHECK:                      TypeConversion
+  /// CHECK:                      TypeConversion
+  /// CHECK-NOT:                  TypeConversion
   public void unrollingTypeConversion(int[] a, double[] b) {
     for (int i = 0; i < LENGTH_B; i++) {
       a[i] = (int) b[i];
@@ -634,16 +818,21 @@
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   CheckCast                                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   CheckCast
+
+  /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (before)
+  /// CHECK:                      CheckCast
+  /// CHECK-NOT:                  CheckCast
 
   /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after)
   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
   /// CHECK-DAG:                   Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                   CheckCast                                 loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                   CheckCast                                 loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                   CheckCast
+
+  /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after)
+  /// CHECK:                      CheckCast
+  /// CHECK:                      CheckCast
+  /// CHECK-NOT:                  CheckCast
   public void unrollingCheckCast(int[] a, Object o) {
     for (int i = 0; i < LENGTH_B; i++) {
       if (((SubMain)o) == o) {
@@ -664,10 +853,22 @@
   /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+  /// CHECK:                      Phi
   /// CHECK-NOT:                  Phi
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+  /// CHECK:                      If
   /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
@@ -676,10 +877,22 @@
   /// CHECK-DAG:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet                                  loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+  /// CHECK:                      Phi
   /// CHECK-NOT:                  Phi
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+  /// CHECK:                      If
   /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
   private static final void noUnrollingOddTripCount(int[] a) {
     for (int i = 0; i < LENGTH - 1; i++) {
@@ -699,9 +912,24 @@
   /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+  /// CHECK:                      Phi
   /// CHECK-NOT:                  Phi
+
+  // One `if` for the `for` loop, and another one for a deoptimize.
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
@@ -710,9 +938,23 @@
   /// CHECK-DAG:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                  ArraySet                                  loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+  /// CHECK:                      Phi
   /// CHECK-NOT:                  Phi
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
   /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after)
+  /// CHECK:                      ArraySet
   /// CHECK-NOT:                  ArraySet
   private static final void noUnrollingNotKnownTripCount(int[] a, int n) {
     for (int i = 0; i < n; i++) {
@@ -732,9 +974,15 @@
   /// CHECK-DAG:                    ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<IndAdd:i\d+>>    Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                    If
-  /// CHECK-NOT:                    ArraySet
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (before)
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (before)
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
   /// CHECK-DAG: <<Param:z\d+>>     ParameterValue                            loop:none
@@ -754,9 +1002,18 @@
   /// CHECK-DAG:                    ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<IndAdd:i\d+>>    Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                    If
-  /// CHECK-NOT:                    ArraySet
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
 
   /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
   /// CHECK-DAG: <<Param:z\d+>>     ParameterValue                            loop:none
@@ -772,11 +1029,25 @@
   /// CHECK-DAG:                    ArrayGet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                                  loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<IndAdd:i\d+>>    Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                    GreaterThanOrEqual
-  /// CHECK-NOT:                    If
-  /// CHECK-NOT:                    ArrayGet
-  /// CHECK-NOT:                    ArraySet
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                      GreaterThanOrEqual
+  /// CHECK-NOT:                  GreaterThanOrEqual
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                      If
+  /// CHECK:                      If
+  /// CHECK-NOT:                  If
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                      ArrayGet
+  /// CHECK:                      ArrayGet
+  /// CHECK-NOT:                  ArrayGet
+
+  /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                      ArraySet
+  /// CHECK:                      ArraySet
+  /// CHECK-NOT:                  ArraySet
   private static final void peelingSimple(int[] a, boolean f) {
     for (int i = 0; i < LENGTH; i++) {
       if (f) {
@@ -808,8 +1079,13 @@
   /// CHECK-DAG: <<Check:z\d+>>     GreaterThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    If [<<Check>>]                        loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                              loop:<<Loop>>      outer_loop:none
-  //
-  /// CHECK-NOT:                    If [<<Eq>>]                           loop:<<Loop>>      outer_loop:none
+
+  // There's a 3rd `if` due to bounds checks.
+  /// CHECK-START: void Main.peelingAddInts(int[]) dead_code_elimination$final (after)
+  /// CHECK:                        If
+  /// CHECK:                        If
+  /// CHECK:                        If
+  /// CHECK-NOT:                    If
   private static final void peelingAddInts(int[] a) {
     for (int i = 0; a != null && i < a.length; i++) {
       a[i] += 1;
@@ -830,8 +1106,16 @@
   /// CHECK-DAG:                    ArraySet                                loop:<<Loop1>>      outer_loop:<<Loop0>>
   /// CHECK-DAG: <<IndAdd1:i\d+>>   Add [<<Phi1>>,<<Const1>>]               loop:<<Loop1>>      outer_loop:<<Loop0>>
   /// CHECK-DAG: <<IndAdd0:i\d+>>   Add [<<Phi0>>,<<Const1>>]               loop:<<Loop0>>      outer_loop:none
-  //
+
+  // The two loops have an `if`. The 3rd `if` is the explicit one in the innermost loop.
+  /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) loop_optimization (before)
+  /// CHECK:                        If
+  /// CHECK:                        If
+  /// CHECK:                        If
   /// CHECK-NOT:                    If
+
+  /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) loop_optimization (before)
+  /// CHECK:                        ArraySet
   /// CHECK-NOT:                    ArraySet
 
   /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
@@ -850,8 +1134,16 @@
   /// CHECK-DAG:                    ArraySet                                loop:<<Loop1>>      outer_loop:<<Loop0>>
   /// CHECK-DAG: <<IndAdd1:i\d+>>   Add [<<Phi1>>,<<Const1>>]               loop:<<Loop1>>      outer_loop:<<Loop0>>
   /// CHECK-DAG: <<IndAdd0:i\d+>>   Add [<<Phi0>>,<<Const1>>]               loop:<<Loop0>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                        If
+  /// CHECK:                        If
+  /// CHECK:                        If
   /// CHECK-NOT:                    If
+
+  /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after)
+  /// CHECK:                        ArraySet
+  /// CHECK:                        ArraySet
   /// CHECK-NOT:                    ArraySet
   private static final void peelingBreakFromNest(int[] a, boolean f) {
     outer:
@@ -873,7 +1165,9 @@
   /// CHECK-DAG: <<Phi:i\d+>>       Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:                    If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG: <<IndAdd:i\d+>>    Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: int Main.peelingHoistOneControl(int) loop_optimization (before)
+  /// CHECK:                        If
   /// CHECK-NOT:                    If
 
   /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
@@ -886,8 +1180,15 @@
   //
   //  Check that the loop has no instruction except SuspendCheck and Goto (indefinite loop).
   /// CHECK-NOT:                                                              loop:<<Loop>>      outer_loop:none
+
+  /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
+  /// CHECK:                        If
   /// CHECK-NOT:                    If
+
+  /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
   /// CHECK-NOT:                    Phi
+
+  /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after)
   /// CHECK-NOT:                    Add
   private static final int peelingHoistOneControl(int x) {
     int i = 0;
@@ -902,11 +1203,17 @@
   /// CHECK-DAG: <<Phi:i\d+>> Phi  loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
-  //
+
   /// CHECK-START: int Main.peelingHoistOneControl(int, int) dead_code_elimination$final (after)
   /// CHECK-DAG: <<Phi:i\d+>> Phi  loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:              If   loop:<<Loop>>      outer_loop:none
+
+  // One `if` inside the loop (the one no longer invariant), two outside of it.
+  /// CHECK-START: int Main.peelingHoistOneControl(int, int) dead_code_elimination$final (after)
+  /// CHECK:                  If
+  /// CHECK:                  If
+  /// CHECK:                  If
+  /// CHECK-NOT:              If
   private static final int peelingHoistOneControl(int x, int y) {
     while (true) {
       if (x == 0)
@@ -922,11 +1229,18 @@
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
-  //
+
   /// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) dead_code_elimination$final (after)
   /// CHECK-DAG: <<Phi:i\d+>> Phi  loop:<<Loop:B\d+>> outer_loop:none
   /// CHECK-DAG:              If   loop:<<Loop>>      outer_loop:none
-  /// CHECK-NOT:              If   loop:<<Loop>>      outer_loop:none
+
+  // One `if` inside the loop (the one no longer invariant), three outside of it.
+  /// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) dead_code_elimination$final (after)
+  /// CHECK:                  If
+  /// CHECK:                  If
+  /// CHECK:                  If
+  /// CHECK:                  If
+  /// CHECK-NOT:              If
   private static final int peelingHoistTwoControl(int x, int y, int z) {
     while (true) {
       if (x == 0)
@@ -948,8 +1262,14 @@
   /// CHECK-DAG:                    ArrayGet                                loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArrayGet                                loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                                loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (before)
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
   /// CHECK-NOT:                    ArrayGet
+
+  /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (before)
+  /// CHECK:                        ArraySet
   /// CHECK-NOT:                    ArraySet
 
   /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
@@ -970,8 +1290,20 @@
   /// CHECK-DAG:                    ArrayGet                                loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    ArraySet                                loop:<<Loop>>      outer_loop:none
   /// CHECK-DAG:                    If [<<Const1>>]                         loop:<<Loop>>      outer_loop:none
-  //
+
+  /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
+  /// CHECK:                        ArrayGet
   /// CHECK-NOT:                    ArrayGet
+
+  /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after)
+  /// CHECK:                        ArraySet
+  /// CHECK:                        ArraySet
+  /// CHECK:                        ArraySet
   /// CHECK-NOT:                    ArraySet
   private static final void unrollingFull(int[] a) {
     for (int i = 0; i < 2; i++) {