Home | History | Annotate | Download | only in smali
      1 # Copyright (C) 2015 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 .class public LBuilder;
     16 
     17 .super Ljava/lang/Object;
     18 
     19 # Basic test case with two try blocks and three catch handlers, one of which
     20 # is shared by the two tries.
     21 
     22 ## CHECK-START: int Builder.testMultipleTryCatch(int, int, int) builder (after)
     23 
     24 ## CHECK:      name             "B0"
     25 ## CHECK:      successors       "<<BEnterTry1:B\d+>>"
     26 ## CHECK-DAG:  <<Minus1:i\d+>>  IntConstant -1
     27 ## CHECK-DAG:  <<Minus2:i\d+>>  IntConstant -2
     28 ## CHECK-DAG:  <<Minus3:i\d+>>  IntConstant -3
     29 
     30 ## CHECK:  name             "<<BTry1:B\d+>>"
     31 ## CHECK:  predecessors     "<<BEnterTry1>>"
     32 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
     33 ## CHECK:  DivZeroCheck
     34 
     35 ## CHECK:  name             "<<BAdd:B\d+>>"
     36 ## CHECK:  predecessors     "<<BExitTry1>>"
     37 ## CHECK:  successors       "<<BEnterTry2:B\d+>>"
     38 ## CHECK:  Add
     39 
     40 ## CHECK:  name             "<<BTry2:B\d+>>"
     41 ## CHECK:  predecessors     "<<BEnterTry2>>"
     42 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
     43 ## CHECK:  DivZeroCheck
     44 ## CHECK:  <<Div:i\d+>> Div
     45 
     46 ## CHECK:  name             "<<BAfterTry2:B\d+>>"
     47 ## CHECK:  predecessors     "<<BExitTry2>>"
     48 ## CHECK:  successors       "<<BReturn:B\d+>>"
     49 ## CHECK:  Goto
     50 
     51 ## CHECK:  name             "<<BReturn>>"
     52 ## CHECK:  predecessors     "<<BAfterTry2>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>" "<<BCatch3:B\d+>>"
     53 ## CHECK:  Phi [<<Div>>,<<Minus1>>,<<Minus2>>,<<Minus3>>]
     54 ## CHECK:  Return
     55 
     56 ## CHECK:  name             "<<BCatch1>>"
     57 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BExitTry1>>"
     58 ## CHECK:  successors       "<<BReturn>>"
     59 ## CHECK:  flags            "catch_block"
     60 ## CHECK:  Goto
     61 
     62 ## CHECK:  name             "<<BCatch2>>"
     63 ## CHECK:  predecessors     "<<BEnterTry2>>" "<<BExitTry2>>"
     64 ## CHECK:  successors       "<<BReturn>>"
     65 ## CHECK:  flags            "catch_block"
     66 ## CHECK:  Goto
     67 
     68 ## CHECK:  name             "<<BCatch3>>"
     69 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
     70 ## CHECK:  successors       "<<BReturn>>"
     71 ## CHECK:  flags            "catch_block"
     72 ## CHECK:  Goto
     73 
     74 ## CHECK:  name             "<<BEnterTry1>>"
     75 ## CHECK:  predecessors     "B0"
     76 ## CHECK:  successors       "<<BTry1>>"
     77 ## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch3>>"
     78 ## CHECK:  TryBoundary      kind:entry
     79 
     80 ## CHECK:  name             "<<BEnterTry2>>"
     81 ## CHECK:  predecessors     "<<BAdd>>"
     82 ## CHECK:  successors       "<<BTry2>>"
     83 ## CHECK:  xhandlers        "<<BCatch2>>" "<<BCatch3>>"
     84 ## CHECK:  TryBoundary      kind:entry
     85 
     86 ## CHECK:  name             "<<BExitTry1>>"
     87 ## CHECK:  predecessors     "<<BTry1>>"
     88 ## CHECK:  successors       "<<BAdd>>"
     89 ## CHECK:  xhandlers        "<<BCatch1>>" "<<BCatch3>>"
     90 ## CHECK:  TryBoundary      kind:exit
     91 
     92 ## CHECK:  name             "<<BExitTry2>>"
     93 ## CHECK:  predecessors     "<<BTry2>>"
     94 ## CHECK:  successors       "<<BAfterTry2>>"
     95 ## CHECK:  xhandlers        "<<BCatch2>>" "<<BCatch3>>"
     96 ## CHECK:  TryBoundary      kind:exit
     97 
     98 .method public static testMultipleTryCatch(III)I
     99     .registers 3
    100 
    101     :try_start_1
    102     div-int/2addr p0, p1
    103     :try_end_1
    104     .catch Ljava/lang/ArithmeticException; {:try_start_1 .. :try_end_1} :catch_arith
    105     .catchall {:try_start_1 .. :try_end_1} :catch_other
    106 
    107     add-int/2addr p0, p0
    108 
    109     :try_start_2
    110     div-int/2addr p0, p2
    111     :try_end_2
    112     .catch Ljava/lang/OutOfMemoryError; {:try_start_2 .. :try_end_2} :catch_mem
    113     .catchall {:try_start_2 .. :try_end_2} :catch_other
    114 
    115     nop
    116 
    117     :return
    118     return p0
    119 
    120     :catch_arith
    121     const/4 p0, -0x1
    122     goto :return
    123 
    124     :catch_mem
    125     const/4 p0, -0x2
    126     goto :return
    127 
    128     :catch_other
    129     const/4 p0, -0x3
    130     goto :return
    131 .end method
    132 
    133 # Tests try-entry block when there are multiple entry points into the try block.
    134 
    135 ## CHECK-START: int Builder.testMultipleEntries(int, int, int, int) builder (after)
    136 
    137 ## CHECK:  name             "B0"
    138 ## CHECK:  successors       "<<BIf:B\d+>>"
    139 ## CHECK:  <<Minus1:i\d+>>  IntConstant -1
    140 
    141 ## CHECK:  name             "<<BIf>>"
    142 ## CHECK:  predecessors     "B0"
    143 ## CHECK:  successors       "<<BSplit1:B\d+>>" "<<BThen:B\d+>>"
    144 ## CHECK:  If
    145 
    146 ## CHECK:  name             "<<BThen>>"
    147 ## CHECK:  predecessors     "<<BIf>>"
    148 ## CHECK:  successors       "<<BEnterTry1:B\d+>>"
    149 ## CHECK:  Div
    150 
    151 ## CHECK:  name             "<<BTry1:B\d+>>"
    152 ## CHECK:  predecessors     "<<BEnterTry1>>"
    153 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
    154 ## CHECK:  Div
    155 
    156 ## CHECK:  name             "<<BTry2:B\d+>>"
    157 ## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
    158 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
    159 ## CHECK:  Div
    160 
    161 ## CHECK:  name             "<<BReturn:B\d+>>"
    162 ## CHECK:  predecessors     "<<BSplit3:B\d+>>" "<<BCatch:B\d+>>"
    163 ## CHECK:  Return
    164 
    165 ## CHECK:  name             "<<BCatch>>"
    166 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
    167 ## CHECK:  successors       "<<BReturn>>"
    168 ## CHECK:  flags            "catch_block"
    169 ## CHECK:  Goto
    170 
    171 ## CHECK:  name             "<<BEnterTry1>>"
    172 ## CHECK:  predecessors     "<<BThen>>"
    173 ## CHECK:  successors       "<<BTry1>>"
    174 ## CHECK:  xhandlers        "<<BCatch>>"
    175 ## CHECK:  TryBoundary      kind:entry
    176 
    177 ## CHECK:  name             "<<BEnterTry2>>"
    178 ## CHECK:  predecessors     "<<BSplit1>>" "<<BSplit2:B\d+>>"
    179 ## CHECK:  successors       "<<BTry2>>"
    180 ## CHECK:  xhandlers        "<<BCatch>>"
    181 ## CHECK:  TryBoundary      kind:entry
    182 
    183 ## CHECK:  name             "<<BExitTry1>>"
    184 ## CHECK:  predecessors     "<<BTry1>>"
    185 ## CHECK:  successors       "<<BSplit2>>"
    186 ## CHECK:  xhandlers        "<<BCatch>>"
    187 ## CHECK:  TryBoundary      kind:exit
    188 
    189 ## CHECK:  name             "<<BExitTry2>>"
    190 ## CHECK:  predecessors     "<<BTry2>>"
    191 ## CHECK:  successors       "<<BSplit3>>"
    192 ## CHECK:  xhandlers        "<<BCatch>>"
    193 ## CHECK:  TryBoundary      kind:exit
    194 
    195 ## CHECK:  name             "<<BSplit1>>"
    196 ## CHECK:  predecessors     "<<BIf>>"
    197 ## CHECK:  successors       "<<BEnterTry2>>"
    198 ## CHECK:  Goto
    199 
    200 ## CHECK:  name             "<<BSplit2>>"
    201 ## CHECK:  predecessors     "<<BExitTry1>>"
    202 ## CHECK:  successors       "<<BEnterTry2>>"
    203 ## CHECK:  Goto
    204 
    205 ## CHECK:  name             "<<BSplit3>>"
    206 ## CHECK:  predecessors     "<<BExitTry2>>"
    207 ## CHECK:  successors       "<<BReturn>>"
    208 ## CHECK:  Goto
    209 
    210 .method public static testMultipleEntries(IIII)I
    211     .registers 4
    212 
    213     if-eqz p2, :else
    214 
    215     div-int/2addr p0, p1
    216 
    217     :try_start
    218     div-int/2addr p0, p2
    219 
    220     :else
    221     div-int/2addr p0, p3
    222     :try_end
    223     .catchall {:try_start .. :try_end} :catch_all
    224 
    225     :return
    226     return p0
    227 
    228     :catch_all
    229     const/4 p0, -0x1
    230     goto :return
    231 
    232 .end method
    233 
    234 # Test that multiple try-exit blocks are generated if (normal) control flow can
    235 # jump out of the try block at multiple points.
    236 
    237 ## CHECK-START: int Builder.testMultipleExits(int, int) builder (after)
    238 
    239 ## CHECK:      name             "B0"
    240 ## CHECK:      successors       "<<BEnterTry:B\d+>>"
    241 ## CHECK-DAG:  <<Minus1:i\d+>>  IntConstant -1
    242 ## CHECK-DAG:  <<Minus2:i\d+>>  IntConstant -2
    243 
    244 ## CHECK:  name             "<<BTry:B\d+>>"
    245 ## CHECK:  predecessors     "<<BEnterTry>>"
    246 ## CHECK:  successors       "<<BExitTry1:B\d+>>" "<<BExitTry2:B\d+>>"
    247 ## CHECK:  <<Div:i\d+>> Div
    248 ## CHECK:  If
    249 
    250 ## CHECK:  name             "<<BReturn:B\d+>>"
    251 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BThen:B\d+>>" "<<BCatch:B\d+>>"
    252 ## CHECK:  Phi [<<Div>>,<<Minus1>>,<<Minus2>>]
    253 ## CHECK:  Return
    254 
    255 ## CHECK:  name             "<<BThen>>"
    256 ## CHECK:  predecessors     "<<BExitTry1>>"
    257 ## CHECK:  successors       "<<BReturn>>"
    258 ## CHECK:  Goto
    259 
    260 ## CHECK:  name             "<<BCatch>>"
    261 ## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry1>>" "<<BExitTry2>>"
    262 ## CHECK:  successors       "<<BReturn>>"
    263 ## CHECK:  flags            "catch_block"
    264 ## CHECK:  Goto
    265 
    266 ## CHECK:  name             "<<BEnterTry>>"
    267 ## CHECK:  predecessors     "B0"
    268 ## CHECK:  successors       "<<BTry>>"
    269 ## CHECK:  xhandlers        "<<BCatch>>"
    270 ## CHECK:  TryBoundary      kind:entry
    271 
    272 ## CHECK:  name             "<<BExitTry1>>"
    273 ## CHECK:  predecessors     "<<BTry>>"
    274 ## CHECK:  successors       "<<BThen>>"
    275 ## CHECK:  xhandlers        "<<BCatch>>"
    276 ## CHECK:  TryBoundary      kind:exit
    277 
    278 ## CHECK:  name             "<<BExitTry2>>"
    279 ## CHECK:  predecessors     "<<BTry>>"
    280 ## CHECK:  successors       "<<BSplit>>"
    281 ## CHECK:  xhandlers        "<<BCatch>>"
    282 ## CHECK:  TryBoundary      kind:exit
    283 
    284 ## CHECK:  name             "<<BSplit>>"
    285 ## CHECK:  predecessors     "<<BExitTry2>>"
    286 ## CHECK:  successors       "<<BReturn>>"
    287 ## CHECK:  Goto
    288 
    289 .method public static testMultipleExits(II)I
    290     .registers 2
    291 
    292     :try_start
    293     div-int/2addr p0, p1
    294     if-eqz p0, :then
    295     :try_end
    296     .catchall {:try_start .. :try_end} :catch_all
    297 
    298     :return
    299     return p0
    300 
    301     :then
    302     const/4 p0, -0x1
    303     goto :return
    304 
    305     :catch_all
    306     const/4 p0, -0x2
    307     goto :return
    308 .end method
    309 
    310 # Test that only one TryBoundary is inserted when an edge connects two different
    311 # try ranges.
    312 
    313 ## CHECK-START: int Builder.testSharedBoundary(int, int, int) builder (after)
    314 
    315 ## CHECK:      name             "B0"
    316 ## CHECK:      successors       "<<BEnter1:B\d+>>"
    317 ## CHECK-DAG:  <<Minus1:i\d+>>  IntConstant -1
    318 ## CHECK-DAG:  <<Minus2:i\d+>>  IntConstant -2
    319 
    320 ## CHECK:  name             "<<BTry1:B\d+>>"
    321 ## CHECK:  predecessors     "<<BEnter1>>"
    322 ## CHECK:  successors       "<<BExit1:B\d+>>"
    323 ## CHECK:  Div
    324 
    325 ## CHECK:  name             "<<BTry2:B\d+>>"
    326 ## CHECK:  predecessors     "<<BEnter2:B\d+>>"
    327 ## CHECK:  successors       "<<BExit2:B\d+>>"
    328 ## CHECK:  <<Div:i\d+>> Div
    329 ## CHECK:  Goto
    330 
    331 ## CHECK:  name             "<<BReturn:B\d+>>"
    332 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>"
    333 ## CHECK:  Phi [<<Div>>,<<Minus1>>,<<Minus2>>]
    334 ## CHECK:  Return
    335 
    336 ## CHECK:  name             "<<BCatch1>>"
    337 ## CHECK:  predecessors     "<<BEnter1>>" "<<BExit1>>"
    338 ## CHECK:  successors       "<<BReturn>>"
    339 ## CHECK:  flags            "catch_block"
    340 ## CHECK:  Goto
    341 
    342 ## CHECK:  name             "<<BCatch2>>"
    343 ## CHECK:  predecessors     "<<BEnter2>>" "<<BExit2>>"
    344 ## CHECK:  successors       "<<BReturn>>"
    345 ## CHECK:  flags            "catch_block"
    346 ## CHECK:  Goto
    347 
    348 ## CHECK:  name             "<<BEnter1>>"
    349 ## CHECK:  predecessors     "B0"
    350 ## CHECK:  successors       "<<BTry1>>"
    351 ## CHECK:  xhandlers        "<<BCatch1>>"
    352 ## CHECK:  TryBoundary      kind:entry
    353 
    354 ## CHECK:  name             "<<BEnter2>>"
    355 ## CHECK:  predecessors     "<<BExit1>>"
    356 ## CHECK:  successors       "<<BTry2>>"
    357 ## CHECK:  xhandlers        "<<BCatch2>>"
    358 ## CHECK:  TryBoundary      kind:entry
    359 
    360 ## CHECK:  name             "<<BExit1>>"
    361 ## CHECK:  predecessors     "<<BTry1>>"
    362 ## CHECK:  successors       "<<BEnter2>>"
    363 ## CHECK:  xhandlers        "<<BCatch1>>"
    364 ## CHECK:  TryBoundary      kind:exit
    365 
    366 ## CHECK:  name             "<<BExit2>>"
    367 ## CHECK:  predecessors     "<<BTry2>>"
    368 ## CHECK:  successors       "<<BSplit>>"
    369 ## CHECK:  xhandlers        "<<BCatch2>>"
    370 ## CHECK:  TryBoundary      kind:exit
    371 
    372 ## CHECK:  name             "<<BSplit>>"
    373 ## CHECK:  predecessors     "<<BExit2>>"
    374 ## CHECK:  successors       "<<BReturn>>"
    375 ## CHECK:  Goto
    376 
    377 .method public static testSharedBoundary(III)I
    378     .registers 3
    379 
    380     :try_start_1
    381     div-int/2addr p0, p1
    382     :try_end_1
    383     .catchall {:try_start_1 .. :try_end_1} :catch_all_1
    384 
    385     :try_start_2
    386     div-int/2addr p0, p2
    387     :try_end_2
    388     .catchall {:try_start_2 .. :try_end_2} :catch_all_2
    389 
    390     :return
    391     return p0
    392 
    393     :catch_all_1
    394     const/4 p0, -0x1
    395     goto :return
    396 
    397     :catch_all_2
    398     const/4 p0, -0x2
    399     goto :return
    400 .end method
    401 
    402 # Same as previous test, only the blocks are processed in the opposite order.
    403 
    404 ## CHECK-START: int Builder.testSharedBoundary_Reverse(int, int, int) builder (after)
    405 
    406 ## CHECK:      name             "B0"
    407 ## CHECK:      successors       "<<BGoto:B\d+>>"
    408 ## CHECK-DAG:  <<Minus1:i\d+>>  IntConstant -1
    409 ## CHECK-DAG:  <<Minus2:i\d+>>  IntConstant -2
    410 
    411 ## CHECK:  name             "<<BGoto>>"
    412 ## CHECK:  successors       "<<BEnter2:B\d+>>"
    413 ## CHECK:  Goto
    414 
    415 ## CHECK:  name             "<<BTry1:B\d+>>"
    416 ## CHECK:  predecessors     "<<BEnter1:B\d+>>"
    417 ## CHECK:  successors       "<<BExit1:B\d+>>"
    418 ## CHECK:  <<Div:i\d+>> Div
    419 ## CHECK:  Goto
    420 
    421 ## CHECK:  name             "<<BTry2:B\d+>>"
    422 ## CHECK:  predecessors     "<<BEnter2>>"
    423 ## CHECK:  successors       "<<BExit2:B\d+>>"
    424 ## CHECK:  Div
    425 ## CHECK:  Goto
    426 
    427 ## CHECK:  name             "<<BReturn:B\d+>>"
    428 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>"
    429 ## CHECK:  Phi [<<Div>>,<<Minus1>>,<<Minus2>>]
    430 ## CHECK:  Return
    431 
    432 ## CHECK:  name             "<<BCatch1>>"
    433 ## CHECK:  predecessors     "<<BEnter1>>" "<<BExit1>>"
    434 ## CHECK:  successors       "<<BReturn>>"
    435 ## CHECK:  flags            "catch_block"
    436 ## CHECK:  Goto
    437 
    438 ## CHECK:  name             "<<BCatch2>>"
    439 ## CHECK:  predecessors     "<<BEnter2>>" "<<BExit2>>"
    440 ## CHECK:  successors       "<<BReturn>>"
    441 ## CHECK:  flags            "catch_block"
    442 ## CHECK:  Goto
    443 
    444 ## CHECK:  name             "<<BEnter1>>"
    445 ## CHECK:  predecessors     "<<BExit2>>"
    446 ## CHECK:  successors       "<<BTry1>>"
    447 ## CHECK:  xhandlers        "<<BCatch1>>"
    448 ## CHECK:  TryBoundary      kind:entry
    449 
    450 ## CHECK:  name             "<<BEnter2>>"
    451 ## CHECK:  predecessors     "<<BGoto>>"
    452 ## CHECK:  successors       "<<BTry2>>"
    453 ## CHECK:  xhandlers        "<<BCatch2>>"
    454 ## CHECK:  TryBoundary      kind:entry
    455 
    456 ## CHECK:  name             "<<BExit1>>"
    457 ## CHECK:  predecessors     "<<BTry1>>"
    458 ## CHECK:  successors       "<<BSplit>>"
    459 ## CHECK:  xhandlers        "<<BCatch1>>"
    460 ## CHECK:  TryBoundary      kind:exit
    461 
    462 ## CHECK:  name             "<<BExit2>>"
    463 ## CHECK:  predecessors     "<<BTry2>>"
    464 ## CHECK:  successors       "<<BEnter1>>"
    465 ## CHECK:  xhandlers        "<<BCatch2>>"
    466 ## CHECK:  TryBoundary      kind:exit
    467 
    468 ## CHECK:  name             "<<BSplit>>"
    469 ## CHECK:  predecessors     "<<BExit1>>"
    470 ## CHECK:  successors       "<<BReturn>>"
    471 ## CHECK:  Goto
    472 
    473 .method public static testSharedBoundary_Reverse(III)I
    474     .registers 3
    475 
    476     goto :try_start_2
    477 
    478     :try_start_1
    479     div-int/2addr p0, p1
    480     goto :return
    481     :try_end_1
    482     .catchall {:try_start_1 .. :try_end_1} :catch_all_1
    483 
    484     :try_start_2
    485     div-int/2addr p0, p2
    486     goto :try_start_1
    487     :try_end_2
    488     .catchall {:try_start_2 .. :try_end_2} :catch_all_2
    489 
    490     :return
    491     return p0
    492 
    493     :catch_all_1
    494     const/4 p0, -0x1
    495     goto :return
    496 
    497     :catch_all_2
    498     const/4 p0, -0x2
    499     goto :return
    500 .end method
    501 
    502 # Test that nested tries are split into non-overlapping blocks and TryBoundary
    503 # blocks are correctly created between them.
    504 
    505 ## CHECK-START: int Builder.testNestedTry(int, int, int, int) builder (after)
    506 
    507 ## CHECK:      name             "B0"
    508 ## CHECK-DAG:  <<Minus1:i\d+>>  IntConstant -1
    509 ## CHECK-DAG:  <<Minus2:i\d+>>  IntConstant -2
    510 
    511 ## CHECK:  name             "<<BTry1:B\d+>>"
    512 ## CHECK:  predecessors     "<<BEnter1:B\d+>>"
    513 ## CHECK:  successors       "<<BExit1:B\d+>>"
    514 ## CHECK:  Div
    515 
    516 ## CHECK:  name             "<<BTry2:B\d+>>"
    517 ## CHECK:  predecessors     "<<BEnter2:B\d+>>"
    518 ## CHECK:  successors       "<<BExit2:B\d+>>"
    519 ## CHECK:  Div
    520 ## CHECK:  Goto
    521 
    522 ## CHECK:  name             "<<BTry3:B\d+>>"
    523 ## CHECK:  predecessors     "<<BEnter3:B\d+>>"
    524 ## CHECK:  successors       "<<BExit3:B\d+>>"
    525 ## CHECK:  <<Div:i\d+>> Div
    526 ## CHECK:  Goto
    527 
    528 ## CHECK:  name             "<<BReturn:B\d+>>"
    529 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BCatchArith:B\d+>>" "<<BCatchAll:B\d+>>"
    530 ## CHECK:  Phi [<<Div>>,<<Minus1>>,<<Minus2>>]
    531 ## CHECK:  Return
    532 
    533 ## CHECK:  name             "<<BCatchArith>>"
    534 ## CHECK:  predecessors     "<<BEnter2>>" "<<BExit2>>"
    535 ## CHECK:  successors       "<<BReturn>>"
    536 ## CHECK:  flags            "catch_block"
    537 ## CHECK:  Goto
    538 
    539 ## CHECK:  name             "<<BCatchAll>>"
    540 ## CHECK:  predecessors     "<<BEnter1>>" "<<BEnter2>>" "<<BEnter3>>" "<<BExit1>>" "<<BExit2>>" "<<BExit3>>"
    541 ## CHECK:  successors       "<<BReturn>>"
    542 ## CHECK:  flags            "catch_block"
    543 ## CHECK:  Goto
    544 
    545 ## CHECK:  name             "<<BEnter1>>"
    546 ## CHECK:  predecessors     "B0"
    547 ## CHECK:  successors       "<<BTry1>>"
    548 ## CHECK:  xhandlers        "<<BCatchAll>>"
    549 ## CHECK:  TryBoundary      kind:entry
    550 
    551 ## CHECK:  name             "<<BEnter2>>"
    552 ## CHECK:  predecessors     "<<BExit1>>"
    553 ## CHECK:  successors       "<<BTry2>>"
    554 ## CHECK:  xhandlers        "<<BCatchArith>>" "<<BCatchAll>>"
    555 ## CHECK:  TryBoundary      kind:entry
    556 
    557 ## CHECK:  name             "<<BEnter3>>"
    558 ## CHECK:  predecessors     "<<BExit2>>"
    559 ## CHECK:  successors       "<<BTry3>>"
    560 ## CHECK:  xhandlers        "<<BCatchAll>>"
    561 ## CHECK:  TryBoundary      kind:entry
    562 
    563 ## CHECK:  name             "<<BExit1>>"
    564 ## CHECK:  predecessors     "<<BTry1>>"
    565 ## CHECK:  successors       "<<BEnter2>>"
    566 ## CHECK:  xhandlers        "<<BCatchAll>>"
    567 ## CHECK:  TryBoundary      kind:exit
    568 
    569 ## CHECK:  name             "<<BExit2>>"
    570 ## CHECK:  predecessors     "<<BTry2>>"
    571 ## CHECK:  successors       "<<BEnter3>>"
    572 ## CHECK:  xhandlers        "<<BCatchArith>>" "<<BCatchAll>>"
    573 ## CHECK:  TryBoundary      kind:exit
    574 
    575 ## CHECK:  name             "<<BExit3>>"
    576 ## CHECK:  predecessors     "<<BTry3>>"
    577 ## CHECK:  successors       "<<BSplit>>"
    578 ## CHECK:  xhandlers        "<<BCatchAll>>"
    579 ## CHECK:  TryBoundary      kind:exit
    580 
    581 ## CHECK:  name             "<<BSplit>>"
    582 ## CHECK:  predecessors     "<<BExit3>>"
    583 ## CHECK:  successors       "<<BReturn>>"
    584 ## CHECK:  Goto
    585 
    586 .method public static testNestedTry(IIII)I
    587     .registers 4
    588 
    589     :try_start_1
    590     div-int/2addr p0, p1
    591 
    592     :try_start_2
    593     div-int/2addr p0, p2
    594     :try_end_2
    595     .catch Ljava/lang/ArithmeticException; {:try_start_2 .. :try_end_2} :catch_arith
    596 
    597     div-int/2addr p0, p3
    598     :try_end_1
    599     .catchall {:try_start_1 .. :try_end_1} :catch_all
    600 
    601     :return
    602     return p0
    603 
    604     :catch_arith
    605     const/4 p0, -0x1
    606     goto :return
    607 
    608     :catch_all
    609     const/4 p0, -0x2
    610     goto :return
    611 .end method
    612 
    613 # Test control flow that enters a try block, leaves it and returns again.
    614 
    615 ## CHECK-START: int Builder.testIncontinuousTry(int, int, int, int) builder (after)
    616 
    617 ## CHECK:  name             "B0"
    618 ## CHECK:  <<Minus1:i\d+>>  IntConstant -1
    619 
    620 ## CHECK:  name             "<<BTry1:B\d+>>"
    621 ## CHECK:  predecessors     "<<BEnterTry1:B\d+>>"
    622 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
    623 ## CHECK:  Div
    624 ## CHECK:  Goto
    625 
    626 ## CHECK:  name             "<<BTry2:B\d+>>"
    627 ## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
    628 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
    629 ## CHECK:  <<Div:i\d+>> Div
    630 ## CHECK:  Goto
    631 
    632 ## CHECK:  name             "<<BReturn:B\d+>>"
    633 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BCatch:B\d+>>"
    634 ## CHECK:  Phi [<<Div>>,<<Minus1>>]
    635 ## CHECK:  Return
    636 
    637 ## CHECK:  name             "<<BOutside:B\d+>>"
    638 ## CHECK:  predecessors     "<<BExitTry1>>"
    639 ## CHECK:  successors       "<<BEnterTry2>>"
    640 ## CHECK:  Div
    641 
    642 ## CHECK:  name             "<<BCatch>>"
    643 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
    644 ## CHECK:  successors       "<<BReturn>>"
    645 ## CHECK:  flags            "catch_block"
    646 ## CHECK:  Goto
    647 
    648 ## CHECK:  name             "<<BEnterTry1>>"
    649 ## CHECK:  predecessors     "B0"
    650 ## CHECK:  successors       "<<BTry1>>"
    651 ## CHECK:  xhandlers        "<<BCatch>>"
    652 ## CHECK:  TryBoundary      kind:entry
    653 
    654 ## CHECK:  name             "<<BEnterTry2>>"
    655 ## CHECK:  predecessors     "<<BOutside>>"
    656 ## CHECK:  successors       "<<BTry2>>"
    657 ## CHECK:  xhandlers        "<<BCatch>>"
    658 ## CHECK:  TryBoundary      kind:entry
    659 
    660 ## CHECK:  name             "<<BExitTry1>>"
    661 ## CHECK:  predecessors     "<<BTry1>>"
    662 ## CHECK:  successors       "<<BOutside>>"
    663 ## CHECK:  xhandlers        "<<BCatch>>"
    664 ## CHECK:  TryBoundary      kind:exit
    665 
    666 ## CHECK:  name             "<<BExitTry2>>"
    667 ## CHECK:  predecessors     "<<BTry2>>"
    668 ## CHECK:  successors       "<<BSplit>>"
    669 ## CHECK:  xhandlers        "<<BCatch>>"
    670 ## CHECK:  TryBoundary      kind:exit
    671 
    672 ## CHECK:  name             "<<BSplit>>"
    673 ## CHECK:  predecessors     "<<BExitTry2>>"
    674 ## CHECK:  successors       "<<BReturn>>"
    675 ## CHECK:  Goto
    676 
    677 .method public static testIncontinuousTry(IIII)I
    678     .registers 4
    679 
    680     :try_start
    681     div-int/2addr p0, p1
    682     goto :outside
    683 
    684     :inside
    685     div-int/2addr p0, p3
    686     :try_end
    687     .catchall {:try_start .. :try_end} :catch_all
    688 
    689     :return
    690     return p0
    691 
    692     :outside
    693     div-int/2addr p0, p2
    694     goto :inside
    695 
    696     :catch_all
    697     const/4 p0, -0x1
    698     goto :return
    699 .end method
    700 
    701 ## CHECK-START: int Builder.testSwitchTryEnter(int, int, int, int) builder (after)
    702 
    703 ## CHECK:  name             "B0"
    704 ## CHECK:  successors       "<<BPSwitch0:B\d+>>"
    705 
    706 ## CHECK:  name             "<<BPSwitch0>>"
    707 ## CHECK:  predecessors     "B0"
    708 ## CHECK:  successors       "<<BSplit1:B\d+>>" "<<BPSwitch1:B\d+>>"
    709 ## CHECK:  If
    710 
    711 ## CHECK:  name             "<<BPSwitch1>>"
    712 ## CHECK:  predecessors     "<<BPSwitch0>>"
    713 ## CHECK:  successors       "<<BSplit2:B\d+>>" "<<BEnterTry1:B\d+>>"
    714 ## CHECK:  If
    715 
    716 ## CHECK:  name             "<<BTry1:B\d+>>"
    717 ## CHECK:  predecessors     "<<BEnterTry1>>"
    718 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
    719 ## CHECK:  Div
    720 
    721 ## CHECK:  name             "<<BTry2:B\d+>>"
    722 ## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
    723 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
    724 ## CHECK:  Div
    725 
    726 ## CHECK:  name             "<<BOutside:B\d+>>"
    727 ## CHECK:  predecessors     "<<BSplit2>>" "<<BSplit4:B\d+>>"
    728 ## CHECK:  successors       "<<BReturn:B\d+>>"
    729 ## CHECK:  Div
    730 
    731 ## CHECK:  name             "<<BReturn>>"
    732 ## CHECK:  predecessors     "<<BOutside>>" "<<BCatch:B\d+>>"
    733 ## CHECK:  successors       "<<BExit:B\d+>>"
    734 ## CHECK:  Return
    735 
    736 ## CHECK:  name             "<<BExit>>"
    737 ## CHECK:  Exit
    738 
    739 ## CHECK:  name             "<<BCatch>>"
    740 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
    741 ## CHECK:  successors       "<<BReturn>>"
    742 ## CHECK:  flags            "catch_block"
    743 ## CHECK:  Goto
    744 
    745 ## CHECK:  name             "<<BEnterTry1>>"
    746 ## CHECK:  predecessors     "<<BPSwitch1>>"
    747 ## CHECK:  successors       "<<BTry1>>"
    748 ## CHECK:  xhandlers        "<<BCatch>>"
    749 ## CHECK:  TryBoundary      kind:entry
    750 
    751 ## CHECK:  name             "<<BEnterTry2>>"
    752 ## CHECK:  predecessors     "<<BSplit1>>" "<<BSplit3:B\d+>>"
    753 ## CHECK:  successors       "<<BTry2>>"
    754 ## CHECK:  xhandlers        "<<BCatch>>"
    755 ## CHECK:  TryBoundary      kind:entry
    756 
    757 ## CHECK:  name             "<<BExitTry1>>"
    758 ## CHECK:  predecessors     "<<BTry1>>"
    759 ## CHECK:  successors       "<<BSplit3>>"
    760 ## CHECK:  xhandlers        "<<BCatch>>"
    761 ## CHECK:  TryBoundary      kind:exit
    762 
    763 ## CHECK:  name             "<<BExitTry2>>"
    764 ## CHECK:  predecessors     "<<BTry2>>"
    765 ## CHECK:  successors       "<<BSplit4>>"
    766 ## CHECK:  xhandlers        "<<BCatch>>"
    767 ## CHECK:  TryBoundary      kind:exit
    768 
    769 ## CHECK:  name             "<<BSplit1>>"
    770 ## CHECK:  predecessors     "<<BPSwitch0>>"
    771 ## CHECK:  successors       "<<BEnterTry2>>"
    772 ## CHECK:  Goto
    773 
    774 ## CHECK:  name             "<<BSplit2>>"
    775 ## CHECK:  predecessors     "<<BPSwitch1>>"
    776 ## CHECK:  successors       "<<BOutside>>"
    777 ## CHECK:  Goto
    778 
    779 ## CHECK:  name             "<<BSplit3>>"
    780 ## CHECK:  predecessors     "<<BExitTry1>>"
    781 ## CHECK:  successors       "<<BEnterTry2>>"
    782 ## CHECK:  Goto
    783 
    784 ## CHECK:  name             "<<BSplit4>>"
    785 ## CHECK:  predecessors     "<<BExitTry2>>"
    786 ## CHECK:  successors       "<<BOutside>>"
    787 ## CHECK:  Goto
    788 
    789 .method public static testSwitchTryEnter(IIII)I
    790     .registers 4
    791 
    792     packed-switch p0, :pswitch_data
    793 
    794     :try_start
    795     div-int/2addr p0, p1
    796 
    797     :pswitch1
    798     div-int/2addr p0, p2
    799     goto :pswitch2
    800 
    801     :pswitch_data
    802     .packed-switch 0x0
    803         :pswitch1
    804         :pswitch2
    805     .end packed-switch
    806     :try_end
    807     .catchall {:try_start .. :try_end} :catch_all
    808 
    809     :pswitch2
    810     div-int/2addr p0, p3
    811 
    812     :catch_all
    813     return p0
    814 .end method
    815 
    816 ## CHECK-START: int Builder.testSwitchTryExit(int, int, int, int) builder (after)
    817 
    818 ## CHECK:  name             "B0"
    819 ## CHECK:  successors       "<<BEnterTry1:B\d+>>"
    820 
    821 ## CHECK:  name             "<<BPSwitch0:B\d+>>"
    822 ## CHECK:  predecessors     "<<BEnterTry1>>"
    823 ## CHECK:  successors       "<<BSplit1:B\d+>>" "<<BExitTry1:B\d+>>"
    824 ## CHECK:  If
    825 
    826 ## CHECK:  name             "<<BPSwitch1:B\d+>>"
    827 ## CHECK:  predecessors     "<<BExitTry1>>"
    828 ## CHECK:  successors       "<<BSplit2:B\d+>>" "<<BEnterTry2:B\d+>>"
    829 ## CHECK:  If
    830 
    831 ## CHECK:  name             "<<BTry1:B\d+>>"
    832 ## CHECK:  predecessors     "<<BEnterTry2>>"
    833 ## CHECK:  successors       "<<BTry2:B\d+>>"
    834 ## CHECK:  Div
    835 
    836 ## CHECK:  name             "<<BTry2>>"
    837 ## CHECK:  predecessors     "<<BSplit1>>" "<<BTry1>>"
    838 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
    839 ## CHECK:  Div
    840 
    841 ## CHECK:  name             "<<BOutside:B\d+>>"
    842 ## CHECK:  predecessors     "<<BSplit2>>" "<<BSplit3:B\d+>>"
    843 ## CHECK:  successors       "<<BReturn:B\d+>>"
    844 ## CHECK:  Div
    845 
    846 ## CHECK:  name             "<<BReturn>>"
    847 ## CHECK:  predecessors     "<<BOutside>>" "<<BCatch:B\d+>>"
    848 ## CHECK:  successors       "<<BExit:B\d+>>"
    849 ## CHECK:  Return
    850 
    851 ## CHECK:  name             "<<BExit>>"
    852 ## CHECK:  Exit
    853 
    854 ## CHECK:  name             "<<BCatch>>"
    855 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
    856 ## CHECK:  successors       "<<BReturn>>"
    857 ## CHECK:  flags            "catch_block"
    858 ## CHECK:  Goto
    859 
    860 ## CHECK:  name             "<<BEnterTry1>>"
    861 ## CHECK:  predecessors     "B0"
    862 ## CHECK:  successors       "<<BPSwitch0>>"
    863 ## CHECK:  xhandlers        "<<BCatch>>"
    864 ## CHECK:  TryBoundary      kind:entry
    865 
    866 ## CHECK:  name             "<<BEnterTry2>>"
    867 ## CHECK:  predecessors     "<<BPSwitch1>>"
    868 ## CHECK:  successors       "<<BTry1>>"
    869 ## CHECK:  xhandlers        "<<BCatch>>"
    870 ## CHECK:  TryBoundary      kind:entry
    871 
    872 ## CHECK:  name             "<<BExitTry1>>"
    873 ## CHECK:  predecessors     "<<BPSwitch0>>"
    874 ## CHECK:  successors       "<<BPSwitch1>>"
    875 ## CHECK:  xhandlers        "<<BCatch>>"
    876 ## CHECK:  TryBoundary      kind:exit
    877 
    878 ## CHECK:  name             "<<BExitTry2>>"
    879 ## CHECK:  predecessors     "<<BTry2>>"
    880 ## CHECK:  successors       "<<BSplit3>>"
    881 ## CHECK:  xhandlers        "<<BCatch>>"
    882 ## CHECK:  TryBoundary      kind:exit
    883 
    884 ## CHECK:  name             "<<BSplit1>>"
    885 ## CHECK:  predecessors     "<<BPSwitch0>>"
    886 ## CHECK:  successors       "<<BTry2>>"
    887 ## CHECK:  Goto
    888 
    889 ## CHECK:  name             "<<BSplit2>>"
    890 ## CHECK:  predecessors     "<<BPSwitch1>>"
    891 ## CHECK:  successors       "<<BOutside>>"
    892 ## CHECK:  Goto
    893 
    894 ## CHECK:  name             "<<BSplit3>>"
    895 ## CHECK:  predecessors     "<<BExitTry2>>"
    896 ## CHECK:  successors       "<<BOutside>>"
    897 ## CHECK:  Goto
    898 
    899 .method public static testSwitchTryExit(IIII)I
    900     .registers 4
    901 
    902     :try_start
    903     div-int/2addr p0, p1
    904     packed-switch p0, :pswitch_data
    905 
    906     div-int/2addr p0, p1
    907 
    908     :pswitch1
    909     div-int/2addr p0, p2
    910     :try_end
    911     .catchall {:try_start .. :try_end} :catch_all
    912 
    913     :pswitch2
    914     div-int/2addr p0, p3
    915 
    916     :catch_all
    917     return p0
    918 
    919     :pswitch_data
    920     .packed-switch 0x0
    921         :pswitch1
    922         :pswitch2
    923     .end packed-switch
    924 .end method
    925 
    926 # Test that a TryBoundary is inserted between a Throw instruction and the exit
    927 # block when covered by a try range.
    928 
    929 ## CHECK-START: int Builder.testThrow(java.lang.Exception) builder (after)
    930 
    931 ## CHECK:  name             "B0"
    932 ## CHECK:  successors       "<<BEnterTry:B\d+>>"
    933 ## CHECK:  <<Minus1:i\d+>>  IntConstant -1
    934 
    935 ## CHECK:  name             "<<BTry:B\d+>>"
    936 ## CHECK:  predecessors     "<<BEnterTry>>"
    937 ## CHECK:  successors       "<<BExitTry:B\d+>>"
    938 ## CHECK:  Throw
    939 
    940 ## CHECK:  name             "<<BCatch:B\d+>>"
    941 ## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry>>"
    942 ## CHECK:  successors       "<<BExit:B\d+>>"
    943 ## CHECK:  flags            "catch_block"
    944 ## CHECK:  Return [<<Minus1>>]
    945 
    946 ## CHECK:  name             "<<BExit>>"
    947 ## CHECK:  predecessors     "<<BExitTry>>" "<<BCatch>>"
    948 ## CHECK:  Exit
    949 
    950 ## CHECK:  name             "<<BEnterTry>>"
    951 ## CHECK:  predecessors     "B0"
    952 ## CHECK:  successors       "<<BTry>>"
    953 ## CHECK:  xhandlers        "<<BCatch>>"
    954 ## CHECK:  TryBoundary      kind:entry
    955 
    956 ## CHECK:  name             "<<BExitTry>>"
    957 ## CHECK:  predecessors     "<<BTry>>"
    958 ## CHECK:  successors       "<<BExit>>"
    959 ## CHECK:  xhandlers        "<<BCatch>>"
    960 ## CHECK:  TryBoundary      kind:exit
    961 
    962 .method public static testThrow(Ljava/lang/Exception;)I
    963     .registers 2
    964 
    965     :try_start
    966     throw p0
    967     :try_end
    968     .catchall {:try_start .. :try_end} :catch_all
    969 
    970     :catch_all
    971     const/4 v0, -0x1
    972     return v0
    973 .end method
    974 
    975 # Test graph with a throw/catch loop.
    976 
    977 ## CHECK-START: int Builder.testCatchLoop(int, int, int) builder (after)
    978 
    979 ## CHECK:  name             "B0"
    980 ## CHECK:  successors       "<<BSplit:B\d+>>"
    981 
    982 ## CHECK:  name             "<<BTry:B\d+>>"
    983 ## CHECK:  predecessors     "<<BEnterTry:B\d+>>"
    984 ## CHECK:  successors       "<<BExitTry:B\d+>>"
    985 ## CHECK:  Div
    986 
    987 ## CHECK:  name             "<<BReturn:B\d+>>"
    988 ## CHECK:  predecessors     "<<BExitTry>>"
    989 ## CHECK:  successors       "<<BExit:B\d+>>"
    990 ## CHECK:  Return
    991 
    992 ## CHECK:  name             "<<BExit>>"
    993 ## CHECK:  predecessors     "<<BReturn>>"
    994 ## CHECK:  Exit
    995 
    996 ## CHECK:  name             "<<BCatch:B\d+>>"
    997 ## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry>>"
    998 ## CHECK:  successors       "<<BEnterTry>>"
    999 ## CHECK:  flags            "catch_block"
   1000 ## CHECK:  Goto
   1001 
   1002 ## CHECK:  name             "<<BEnterTry>>"
   1003 ## CHECK:  predecessors     "<<BSplit>>" "<<BCatch>>"
   1004 ## CHECK:  successors       "<<BTry>>"
   1005 ## CHECK:  xhandlers        "<<BCatch>>"
   1006 ## CHECK:  TryBoundary      kind:entry
   1007 
   1008 ## CHECK:  name             "<<BExitTry>>"
   1009 ## CHECK:  predecessors     "<<BTry>>"
   1010 ## CHECK:  successors       "<<BReturn>>"
   1011 ## CHECK:  xhandlers        "<<BCatch>>"
   1012 ## CHECK:  TryBoundary      kind:exit
   1013 
   1014 ## CHECK:  name             "<<BSplit>>"
   1015 ## CHECK:  predecessors     "B0"
   1016 ## CHECK:  successors       "<<BEnterTry>>"
   1017 ## CHECK:  Goto
   1018 
   1019 .method public static testCatchLoop(III)I
   1020     .registers 4
   1021 
   1022     :try_start
   1023     :catch_all
   1024     div-int/2addr p0, p2
   1025     :try_end
   1026     .catchall {:try_start .. :try_end} :catch_all
   1027 
   1028     :return
   1029     return p0
   1030 .end method
   1031 
   1032 # Test that handler edges are not split. In this scenario, the catch block is
   1033 # only the handler of the try block.
   1034 
   1035 ## CHECK-START: int Builder.testHandlerEdge1(int, int, int) builder (after)
   1036 
   1037 ## CHECK:  name             "B0"
   1038 ## CHECK:  successors       "<<BEnterTry1:B\d+>>"
   1039 
   1040 ## CHECK:  name             "<<BTry1:B\d+>>"
   1041 ## CHECK:  predecessors     "<<BEnterTry1>>"
   1042 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
   1043 ## CHECK:  Div
   1044 
   1045 ## CHECK:  name             "<<BTry2:B\d+>>"
   1046 ## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
   1047 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
   1048 ## CHECK:  Div
   1049 
   1050 ## CHECK:  name             "<<BReturn:B\d+>>"
   1051 ## CHECK:  predecessors     "<<BExitTry2>>"
   1052 ## CHECK:  successors       "<<BExit:B\d+>>"
   1053 ## CHECK:  Return
   1054 
   1055 ## CHECK:  name             "<<BExit>>"
   1056 ## CHECK:  predecessors     "<<BReturn>>"
   1057 ## CHECK:  Exit
   1058 
   1059 ## CHECK:  name             "<<BCatch:B\d+>>"
   1060 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>"
   1061 ## CHECK:  successors       "<<BEnterTry2>>"
   1062 ## CHECK:  flags            "catch_block"
   1063 ## CHECK:  Goto
   1064 
   1065 ## CHECK:  name             "<<BEnterTry1>>"
   1066 ## CHECK:  predecessors     "B0"
   1067 ## CHECK:  successors       "<<BTry1>>"
   1068 ## CHECK:  xhandlers        "<<BCatch>>"
   1069 ## CHECK:  TryBoundary      kind:entry
   1070 
   1071 ## CHECK:  name             "<<BEnterTry2>>"
   1072 ## CHECK:  predecessors     "<<BSplit:B\d+>>" "<<BCatch>>"
   1073 ## CHECK:  successors       "<<BTry2>>"
   1074 ## CHECK:  xhandlers        "<<BCatch>>"
   1075 ## CHECK:  TryBoundary      kind:entry
   1076 
   1077 ## CHECK:  name             "<<BExitTry1>>"
   1078 ## CHECK:  predecessors     "<<BTry1>>"
   1079 ## CHECK:  successors       "<<BSplit>>"
   1080 ## CHECK:  xhandlers        "<<BCatch>>"
   1081 ## CHECK:  TryBoundary      kind:exit
   1082 
   1083 ## CHECK:  name             "<<BExitTry2>>"
   1084 ## CHECK:  predecessors     "<<BTry2>>"
   1085 ## CHECK:  successors       "<<BReturn>>"
   1086 ## CHECK:  xhandlers        "<<BCatch>>"
   1087 ## CHECK:  TryBoundary      kind:exit
   1088 
   1089 ## CHECK:  name             "<<BSplit>>"
   1090 ## CHECK:  predecessors     "<<BExitTry1>>"
   1091 ## CHECK:  successors       "<<BEnterTry2>>"
   1092 ## CHECK:  Goto
   1093 
   1094 .method public static testHandlerEdge1(III)I
   1095     .registers 4
   1096 
   1097     :try_start
   1098     div-int/2addr p0, p1
   1099 
   1100     :catch_all
   1101     div-int/2addr p0, p2
   1102     :try_end
   1103     .catchall {:try_start .. :try_end} :catch_all
   1104 
   1105     return p0
   1106 .end method
   1107 
   1108 # Test that handler edges are not split. In this scenario, the catch block is
   1109 # the handler and also the successor of the try block.
   1110 
   1111 ## CHECK-START: int Builder.testHandlerEdge2(int, int, int) builder (after)
   1112 
   1113 ## CHECK:  name             "B0"
   1114 ## CHECK:  successors       "<<BSplit1:B\d+>>"
   1115 
   1116 ## CHECK:  name             "<<BTry1:B\d+>>"
   1117 ## CHECK:  predecessors     "<<BEnterTry1:B\d+>>"
   1118 ## CHECK:  successors       "<<BExitTry1:B\d+>>"
   1119 ## CHECK:  Div
   1120 
   1121 ## CHECK:  name             "<<BTry2:B\d+>>"
   1122 ## CHECK:  predecessors     "<<BEnterTry2:B\d+>>"
   1123 ## CHECK:  successors       "<<BExitTry2:B\d+>>"
   1124 ## CHECK:  Div
   1125 
   1126 ## CHECK:  name             "<<BReturn:B\d+>>"
   1127 ## CHECK:  predecessors     "<<BExitTry2>>"
   1128 ## CHECK:  successors       "<<BExit:B\d+>>"
   1129 ## CHECK:  Return
   1130 
   1131 ## CHECK:  name             "<<BExit>>"
   1132 ## CHECK:  Exit
   1133 
   1134 ## CHECK:  name             "<<BCatch2:B\d+>>"
   1135 ## CHECK:  predecessors     "<<BEnterTry1>>" "<<BExitTry1>>"
   1136 ## CHECK:  successors       "<<BEnterTry2>>"
   1137 ## CHECK:  flags            "catch_block"
   1138 
   1139 ## CHECK:  name             "<<BCatch1:B\d+>>"
   1140 ## CHECK:  predecessors     "<<BEnterTry2>>" "<<BExitTry2>>"
   1141 ## CHECK:  successors       "<<BEnterTry1>>"
   1142 ## CHECK:  flags            "catch_block"
   1143 
   1144 ## CHECK:  name             "<<BEnterTry1>>"
   1145 ## CHECK:  predecessors     "<<BSplit1>>" "<<BCatch1>>"
   1146 ## CHECK:  successors       "<<BTry1>>"
   1147 ## CHECK:  xhandlers        "<<BCatch2>>"
   1148 ## CHECK:  TryBoundary      kind:entry
   1149 
   1150 ## CHECK:  name             "<<BEnterTry2>>"
   1151 ## CHECK:  predecessors     "<<BSplit2:B\d+>>" "<<BCatch2>>"
   1152 ## CHECK:  successors       "<<BTry2>>"
   1153 ## CHECK:  xhandlers        "<<BCatch1>>"
   1154 ## CHECK:  TryBoundary      kind:entry
   1155 
   1156 ## CHECK:  name             "<<BExitTry1>>"
   1157 ## CHECK:  predecessors     "<<BTry1>>"
   1158 ## CHECK:  successors       "<<BSplit2>>"
   1159 ## CHECK:  xhandlers        "<<BCatch2>>"
   1160 ## CHECK:  TryBoundary      kind:exit
   1161 
   1162 ## CHECK:  name             "<<BExitTry2>>"
   1163 ## CHECK:  predecessors     "<<BTry2>>"
   1164 ## CHECK:  successors       "<<BReturn>>"
   1165 ## CHECK:  xhandlers        "<<BCatch1>>"
   1166 ## CHECK:  TryBoundary      kind:exit
   1167 
   1168 ## CHECK:  name             "<<BSplit1>>"
   1169 ## CHECK:  predecessors     "B0"
   1170 ## CHECK:  successors       "<<BEnterTry1>>"
   1171 ## CHECK:  Goto
   1172 
   1173 ## CHECK:  name             "<<BSplit2>>"
   1174 ## CHECK:  predecessors     "<<BExitTry1>>"
   1175 ## CHECK:  successors       "<<BEnterTry2>>"
   1176 ## CHECK:  Goto
   1177 
   1178 .method public static testHandlerEdge2(III)I
   1179     .registers 4
   1180 
   1181     :try_start_1
   1182     :catch_all_1
   1183     div-int/2addr p0, p1
   1184     :try_end_1
   1185     .catchall {:try_start_1 .. :try_end_1} :catch_all_2
   1186 
   1187     :try_start_2
   1188     :catch_all_2
   1189     div-int/2addr p0, p2
   1190     :try_end_2
   1191     .catchall {:try_start_2 .. :try_end_2} :catch_all_1
   1192 
   1193     return p0
   1194 .end method
   1195 
   1196 # Test graph with try/catch inside a loop.
   1197 
   1198 ## CHECK-START: int Builder.testTryInLoop(int, int) builder (after)
   1199 
   1200 ## CHECK:  name             "B0"
   1201 ## CHECK:  successors       "<<BSplit1:B\d+>>"
   1202 
   1203 ## CHECK:  name             "<<BTry:B\d+>>"
   1204 ## CHECK:  predecessors     "<<BEnterTry:B\d+>>"
   1205 ## CHECK:  successors       "<<BExitTry:B\d+>>"
   1206 ## CHECK:  Div
   1207 
   1208 ## CHECK:  name             "<<BCatch:B\d+>>"
   1209 ## CHECK:  predecessors     "<<BEnterTry>>" "<<BExitTry>>"
   1210 ## CHECK:  successors       "<<BEnterTry>>"
   1211 ## CHECK:  flags            "catch_block"
   1212 
   1213 ## CHECK:  name             "<<BEnterTry>>"
   1214 ## CHECK:  predecessors     "<<BSplit1>>"
   1215 ## CHECK:  successors       "<<BTry>>"
   1216 ## CHECK:  xhandlers        "<<BCatch>>"
   1217 ## CHECK:  TryBoundary      kind:entry
   1218 
   1219 ## CHECK:  name             "<<BExitTry>>"
   1220 ## CHECK:  predecessors     "<<BTry>>"
   1221 ## CHECK:  successors       "<<BSplit2:B\d+>>"
   1222 ## CHECK:  xhandlers        "<<BCatch>>"
   1223 ## CHECK:  TryBoundary      kind:exit
   1224 
   1225 ## CHECK:  name             "<<BSplit1>>"
   1226 ## CHECK:  predecessors     "B0"
   1227 ## CHECK:  successors       "<<BEnterTry>>"
   1228 ## CHECK:  Goto
   1229 
   1230 ## CHECK:  name             "<<BSplit2>>"
   1231 ## CHECK:  predecessors     "<<BExitTry>>"
   1232 ## CHECK:  successors       "<<BEnterTry>>"
   1233 ## CHECK:  Goto
   1234 
   1235 .method public static testTryInLoop(II)I
   1236     .registers 3
   1237 
   1238     :try_start
   1239     div-int/2addr p0, p1
   1240     goto :try_start
   1241     :try_end
   1242     .catchall {:try_start .. :try_end} :catch_all
   1243 
   1244     :catch_all
   1245     goto :try_start
   1246 .end method
   1247 
   1248 # Test that a MOVE_RESULT instruction is placed into the same block as the
   1249 # INVOKE it follows, even if there is a try boundary between them.
   1250 
   1251 ## CHECK-START: int Builder.testMoveResult_Invoke(int, int, int) builder (after)
   1252 ## CHECK-DAG:     <<M1:i\d+>>  IntConstant -1
   1253 ## CHECK-DAG:     <<Res:i\d+>> InvokeStaticOrDirect
   1254 ## CHECK-DAG:     <<Phi:i\d+>> Phi [<<Res>>,<<M1>>]
   1255 ## CHECK-DAG:                  Return [<<Phi>>]
   1256 
   1257 .method public static testMoveResult_Invoke(III)I
   1258     .registers 3
   1259 
   1260     :try_start
   1261     invoke-static {p0, p1, p2}, LBuilder;->testCatchLoop(III)I
   1262     :try_end
   1263     .catchall {:try_start .. :try_end} :catch_all
   1264 
   1265     move-result p0
   1266 
   1267     :return
   1268     return p0
   1269 
   1270     :catch_all
   1271     const/4 p0, -0x1
   1272     goto :return
   1273 .end method
   1274 
   1275 # Test that a MOVE_RESULT instruction is placed into the same block as the
   1276 # FILLED_NEW_ARRAY it follows, even if there is a try boundary between them.
   1277 
   1278 ## CHECK-START: int[] Builder.testMoveResult_FilledNewArray(int, int, int) builder (after)
   1279 ## CHECK-DAG:     <<Arg1:i\d+>> ParameterValue
   1280 ## CHECK-DAG:     <<Arg2:i\d+>> ParameterValue
   1281 ## CHECK-DAG:     <<Arg3:i\d+>> ParameterValue
   1282 ## CHECK-DAG:     <<Null:l\d+>> NullConstant
   1283 ## CHECK-DAG:     <<Res:l\d+>>  NewArray
   1284 ## CHECK-DAG:                   ArraySet   [<<Res>>,{{i\d+}},<<Arg1>>]
   1285 ## CHECK-DAG:                   ArraySet   [<<Res>>,{{i\d+}},<<Arg2>>]
   1286 ## CHECK-DAG:                   ArraySet   [<<Res>>,{{i\d+}},<<Arg3>>]
   1287 ## CHECK-DAG:     <<Phi:l\d+>>  Phi [<<Res>>,<<Null>>]
   1288 ## CHECK-DAG:                   Return [<<Phi>>]
   1289 
   1290 .method public static testMoveResult_FilledNewArray(III)[I
   1291     .registers 3
   1292 
   1293     :try_start
   1294     filled-new-array {p0, p1, p2}, [I
   1295     :try_end
   1296     .catchall {:try_start .. :try_end} :catch_all
   1297 
   1298     move-result-object p0
   1299 
   1300     :return
   1301     return-object p0
   1302 
   1303     :catch_all
   1304     const/4 p0, 0x0
   1305     goto :return
   1306 .end method
   1307 
   1308 # Test case for ReturnVoid inside a try block. Builder needs to move it outside
   1309 # the try block so as to not split the ReturnVoid-Exit edge.
   1310 # This invariant is enforced by GraphChecker.
   1311 
   1312 .method public static testReturnVoidInTry(II)V
   1313     .registers 2
   1314 
   1315     :catch_all
   1316     :try_start
   1317     return-void
   1318     :try_end
   1319     .catchall {:try_start .. :try_end} :catch_all
   1320 .end method
   1321 
   1322 # Test case for Return inside a try block. Builder needs to move it outside the
   1323 # try block so as to not split the Return-Exit edge.
   1324 # This invariant is enforced by GraphChecker.
   1325 
   1326 .method public static testReturnInTry(II)I
   1327     .registers 2
   1328 
   1329     :try_start
   1330     div-int/2addr p0, p1
   1331     return p0
   1332     :try_end
   1333     .catchall {:try_start .. :try_end} :catch_all
   1334 
   1335     :catch_all
   1336     const/4 v0, 0x0
   1337     return v0
   1338 .end method
   1339 
   1340 # Test a (dead) try block which flows out of the method. The block will be
   1341 # removed by DCE but needs to pass post-builder GraphChecker.
   1342 
   1343 ## CHECK-START: int Builder.testDeadEndTry(int) builder (after)
   1344 ## CHECK-NOT:     TryBoundary is_exit:true
   1345 
   1346 .method public static testDeadEndTry(I)I
   1347     .registers 1
   1348 
   1349     return p0
   1350 
   1351     :catch_all
   1352     nop
   1353 
   1354     :try_start
   1355     nop
   1356     :try_end
   1357     .catchall {:try_start .. :try_end} :catch_all
   1358 .end method
   1359 
   1360 # Test that a throw-catch loop on monitor-exit is eliminated.
   1361 # Note that we do not test this until after DCE which merges trivially split blocks.
   1362 
   1363 ## CHECK-START: int Builder.testSynchronized(java.lang.Object) dead_code_elimination (after)
   1364 ## CHECK:      flags "catch_block"
   1365 ## CHECK-NOT:  end_block
   1366 ## CHECK:      MonitorOperation kind:exit
   1367 
   1368 .method public static testSynchronized(Ljava/lang/Object;)I
   1369   .registers 2
   1370 
   1371   monitor-enter p0
   1372 
   1373   :try_start_9
   1374   invoke-virtual {p0}, Ljava/lang/Object;->hashCode()I
   1375   move-result v0
   1376 
   1377   monitor-exit p0
   1378   return v0
   1379 
   1380   :catchall_11
   1381   move-exception v0
   1382   monitor-exit p0
   1383   :try_end_15
   1384   .catchall {:try_start_9 .. :try_end_15} :catchall_11
   1385 
   1386   throw v0
   1387 .end method
   1388