Allow to sink code within its try block

Bug: 226143661
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: Ie1edc849d8b6db670987cca2206299ab5a4e9d01
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc
index 0f336a2..c14ad9c 100644
--- a/compiler/optimizing/code_sinking.cc
+++ b/compiler/optimizing/code_sinking.cc
@@ -222,10 +222,14 @@
     // TODO(solanes): Here we could do something similar to the loop above and move to the first
     // dominator, which is not a try block, instead of just returning nullptr. If we do so, we have
     // to also make sure we are not in a loop.
-    // TODO(solanes): Alternatively, we could split the try block at the try boundary having two
-    // blocks: A and B. Block B would have the try boundary (and xhandler) and therefore block A
-    // would be the target block available to move the instruction.
-    return nullptr;
+
+    if (instruction->GetBlock()->IsTryBlock() &&
+        instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry().GetId() ==
+            target_block->GetTryCatchInformation()->GetTryEntry().GetId()) {
+      // Sink within the same try block is allowed.
+    } else {
+      return nullptr;
+    }
   }
 
   // Find insertion position. No need to filter anymore, as we have found a
diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java
index 361806a..bd50fa6 100644
--- a/test/639-checker-code-sinking/src/Main.java
+++ b/test/639-checker-code-sinking/src/Main.java
@@ -395,6 +395,7 @@
     assertEquals(456, testSinkToCatchBlock());
     assertEquals(456, testDoNotSinkToTry());
     assertEquals(456, testDoNotSinkToCatchInsideTry());
+    assertEquals(456, testSinkWithinTryBlock());
   }
 
   /// CHECK-START: int Main.testSinkToCatchBlock() code_sinking (before)
@@ -488,6 +489,27 @@
     return 456;
   }
 
+  /// CHECK-START: int Main.testSinkWithinTryBlock() code_sinking (before)
+  /// CHECK: <<ObjLoadClass:l\d+>>   LoadClass class_name:java.lang.Object
+  /// CHECK:                         NewInstance [<<ObjLoadClass>>]
+  /// CHECK:                         If
+
+  /// CHECK-START: int Main.testSinkWithinTryBlock() code_sinking (after)
+  /// CHECK:                         If
+  /// CHECK: <<ObjLoadClass:l\d+>>   LoadClass class_name:java.lang.Object
+  /// CHECK:                         NewInstance [<<ObjLoadClass>>]
+  private static int testSinkWithinTryBlock() {
+    try {
+      Object o = new Object();
+      if (doEarlyReturn) {
+        throw new Error(o.toString());
+      }
+    } catch (Error e) {
+      return 123;
+    }
+    return 456;
+  }
+
   private static void assertEquals(int expected, int actual) {
     if (expected != actual) {
       throw new AssertionError("Expected: " + expected + ", Actual: " + actual);