xref: /aosp_15_r20/art/test/2244-checker-remove-try-boundary/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
main(String[] args)18*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Exception {
19*795d594fSAndroid Build Coastguard Worker     assertEquals(2, $noinline$testDivideOverTen(20));
20*795d594fSAndroid Build Coastguard Worker     assertEquals(-2, $noinline$testDivideOverTen(-20));
21*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimpleDivisionInLoop(0));
22*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testSimpleDivisionInLoop(81));
23*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testOptimizeSeparateBranches(60, true));
24*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testOptimizeSeparateBranches(80, false));
25*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testDoNotOptimizeOneBranchThrows(81, false));
26*795d594fSAndroid Build Coastguard Worker     assertEquals(-1000, $noinline$testDoNotOptimizeOneBranchThrows(81, true));
27*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testOptimizeAfterOneBranchDisappears(81, false));
28*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testRemoveTryBoundaryNested(60));
29*795d594fSAndroid Build Coastguard Worker     assertEquals(-2000, $noinline$testRemoveTryBoundaryNestedButNotCatch(60, true));
30*795d594fSAndroid Build Coastguard Worker     assertEquals(30, $noinline$testRemoveTryBoundaryNestedButNotCatch(60, false));
31*795d594fSAndroid Build Coastguard Worker     assertEquals(30, $noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(60, false));
32*795d594fSAndroid Build Coastguard Worker   }
33*795d594fSAndroid Build Coastguard Worker 
assertEquals(int expected, int result)34*795d594fSAndroid Build Coastguard Worker   public static void assertEquals(int expected, int result) {
35*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
36*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
37*795d594fSAndroid Build Coastguard Worker     }
38*795d594fSAndroid Build Coastguard Worker   }
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker   // Check that this version cannot remove the TryBoundary instructions since we may throw.
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$inline$division(int, int) register (after)
43*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
44*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
45*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$inline$division(int, int) register (after)
48*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
$inline$division(int a, int b)49*795d594fSAndroid Build Coastguard Worker   private static int $inline$division(int a, int b) {
50*795d594fSAndroid Build Coastguard Worker     try {
51*795d594fSAndroid Build Coastguard Worker       return a / b;
52*795d594fSAndroid Build Coastguard Worker     } catch (Error unexpected) {
53*795d594fSAndroid Build Coastguard Worker       return -1000;
54*795d594fSAndroid Build Coastguard Worker     }
55*795d594fSAndroid Build Coastguard Worker   }
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker   // Check that we can remove the TryBoundary afer inlining since we know we can't throw.
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDivideOverTen(int) inliner (after)
60*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDivideOverTen(int) inliner (after)
63*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testDivideOverTen(int a)64*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDivideOverTen(int a) {
65*795d594fSAndroid Build Coastguard Worker     return $inline$division(a, 10);
66*795d594fSAndroid Build Coastguard Worker   }
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimpleDivisionInLoop(int) dead_code_elimination$initial (before)
69*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
70*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
71*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimpleDivisionInLoop(int) dead_code_elimination$initial (before)
74*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimpleDivisionInLoop(int) dead_code_elimination$initial (after)
77*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimpleDivisionInLoop(int) dead_code_elimination$initial (after)
80*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testSimpleDivisionInLoop(int a)81*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimpleDivisionInLoop(int a) {
82*795d594fSAndroid Build Coastguard Worker     try {
83*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 4; i++) {
84*795d594fSAndroid Build Coastguard Worker         a /= 3;
85*795d594fSAndroid Build Coastguard Worker       }
86*795d594fSAndroid Build Coastguard Worker     } catch (Error unexpected) {
87*795d594fSAndroid Build Coastguard Worker       return -1000;
88*795d594fSAndroid Build Coastguard Worker     }
89*795d594fSAndroid Build Coastguard Worker     return a;
90*795d594fSAndroid Build Coastguard Worker   }
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker   // Even though the `TryBoundary`s are split, we can remove them as nothing in the try can throw.
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeSeparateBranches(int, boolean) dead_code_elimination$initial (before)
95*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
96*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
97*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
98*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeSeparateBranches(int, boolean) dead_code_elimination$initial (before)
101*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
102*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeSeparateBranches(int, boolean) dead_code_elimination$initial (after)
105*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeSeparateBranches(int, boolean) dead_code_elimination$initial (after)
108*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testOptimizeSeparateBranches(int a, boolean val)109*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testOptimizeSeparateBranches(int a, boolean val) {
110*795d594fSAndroid Build Coastguard Worker     try {
111*795d594fSAndroid Build Coastguard Worker       if (val) {
112*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
113*795d594fSAndroid Build Coastguard Worker         a /= 3;
114*795d594fSAndroid Build Coastguard Worker       } else {
115*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
116*795d594fSAndroid Build Coastguard Worker         a /= 4;
117*795d594fSAndroid Build Coastguard Worker       }
118*795d594fSAndroid Build Coastguard Worker       a /= 2;
119*795d594fSAndroid Build Coastguard Worker       // TryBoundary kind:exit
120*795d594fSAndroid Build Coastguard Worker     } catch (Error unexpected) {
121*795d594fSAndroid Build Coastguard Worker       return -1000;
122*795d594fSAndroid Build Coastguard Worker     }
123*795d594fSAndroid Build Coastguard Worker     return a;
124*795d594fSAndroid Build Coastguard Worker   }
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker   // Even though the `a /= 3;` can't throw, we don't eliminate any `TryBoundary` instructions. This
127*795d594fSAndroid Build Coastguard Worker   // is because we have the `throw new Error();` in the try as well. We could potentially support
128*795d594fSAndroid Build Coastguard Worker   // removing some `TryBoundary` instructions and not all in the try, but this would complicate the
129*795d594fSAndroid Build Coastguard Worker   // code and wouldn't bring code size reductions since we would be unable to remove the catch
130*795d594fSAndroid Build Coastguard Worker   // block.
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotOptimizeOneBranchThrows(int, boolean) register (after)
133*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
134*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
135*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
136*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
137*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotOptimizeOneBranchThrows(int, boolean) register (after)
140*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
$noinline$testDoNotOptimizeOneBranchThrows(int a, boolean val)141*795d594fSAndroid Build Coastguard Worker   public static int $noinline$testDoNotOptimizeOneBranchThrows(int a, boolean val) {
142*795d594fSAndroid Build Coastguard Worker     try {
143*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 4; i++) {
144*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
145*795d594fSAndroid Build Coastguard Worker         a /= 3;
146*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
147*795d594fSAndroid Build Coastguard Worker       }
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker       if (val) {
150*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
151*795d594fSAndroid Build Coastguard Worker         throw new Error();
152*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
153*795d594fSAndroid Build Coastguard Worker       }
154*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
155*795d594fSAndroid Build Coastguard Worker       return -1000;
156*795d594fSAndroid Build Coastguard Worker     }
157*795d594fSAndroid Build Coastguard Worker     return a;
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker   // The throw gets eliminated by `SimplifyIfs` in DCE, so we can detect that nothing can throw in
161*795d594fSAndroid Build Coastguard Worker   // the graph and eliminate the `TryBoundary` instructions.
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (before)
164*795d594fSAndroid Build Coastguard Worker   /// CHECK:     Throw
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (before)
167*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
168*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
169*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
170*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
171*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (before)
174*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
175*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (after)
178*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Throw
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (after)
181*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testOptimizeAfterOneBranchDisappears(int, boolean) dead_code_elimination$initial (after)
184*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testOptimizeAfterOneBranchDisappears(int a, boolean val)185*795d594fSAndroid Build Coastguard Worker   public static int $noinline$testOptimizeAfterOneBranchDisappears(int a, boolean val) {
186*795d594fSAndroid Build Coastguard Worker     try {
187*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 4; i++) {
188*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
189*795d594fSAndroid Build Coastguard Worker         a /= 3;
190*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
191*795d594fSAndroid Build Coastguard Worker       }
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker       if (val && !val) {
194*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
195*795d594fSAndroid Build Coastguard Worker         throw new Error();
196*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
197*795d594fSAndroid Build Coastguard Worker       }
198*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
199*795d594fSAndroid Build Coastguard Worker       return -1000;
200*795d594fSAndroid Build Coastguard Worker     }
201*795d594fSAndroid Build Coastguard Worker     return a;
202*795d594fSAndroid Build Coastguard Worker   }
203*795d594fSAndroid Build Coastguard Worker 
204*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNested(int) dead_code_elimination$initial (before)
205*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
206*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
207*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
208*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
209*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNested(int) dead_code_elimination$initial (before)
212*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
213*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
214*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNested(int) dead_code_elimination$initial (after)
217*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNested(int) dead_code_elimination$initial (after)
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testRemoveTryBoundaryNested(int a)221*795d594fSAndroid Build Coastguard Worker   public static int $noinline$testRemoveTryBoundaryNested(int a) {
222*795d594fSAndroid Build Coastguard Worker     try {
223*795d594fSAndroid Build Coastguard Worker       // TryBoundary kind:entry
224*795d594fSAndroid Build Coastguard Worker       a /= 2;
225*795d594fSAndroid Build Coastguard Worker       // TryBoundary kind:exit
226*795d594fSAndroid Build Coastguard Worker       try {
227*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:entry
228*795d594fSAndroid Build Coastguard Worker         a /= 3;
229*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
230*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
231*795d594fSAndroid Build Coastguard Worker         return -2000;
232*795d594fSAndroid Build Coastguard Worker       }
233*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
234*795d594fSAndroid Build Coastguard Worker       return -1000;
235*795d594fSAndroid Build Coastguard Worker     }
236*795d594fSAndroid Build Coastguard Worker     return a;
237*795d594fSAndroid Build Coastguard Worker   }
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker   // We can remove the `TryBoundary` instructions surrounding `a /= 2;` but since the inner try can
240*795d594fSAndroid Build Coastguard Worker   // throw, we must keep both the inner and outer catches as they are catch handlers of the inner
241*795d594fSAndroid Build Coastguard Worker   // try.
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNestedButNotCatch(int, boolean) dead_code_elimination$initial (before)
244*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
245*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
246*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
247*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
248*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNestedButNotCatch(int, boolean) dead_code_elimination$initial (before)
251*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
252*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
253*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
254*795d594fSAndroid Build Coastguard Worker 
255*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNestedButNotCatch(int, boolean) dead_code_elimination$initial (after)
256*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
257*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
258*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRemoveTryBoundaryNestedButNotCatch(int, boolean) dead_code_elimination$initial (after)
261*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
262*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
263*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
$noinline$testRemoveTryBoundaryNestedButNotCatch(int a, boolean val)264*795d594fSAndroid Build Coastguard Worker   public static int $noinline$testRemoveTryBoundaryNestedButNotCatch(int a, boolean val) {
265*795d594fSAndroid Build Coastguard Worker     try {
266*795d594fSAndroid Build Coastguard Worker       // TryBoundary kind:entry
267*795d594fSAndroid Build Coastguard Worker       a /= 2;
268*795d594fSAndroid Build Coastguard Worker       // TryBoundary kind:exit
269*795d594fSAndroid Build Coastguard Worker       try {
270*795d594fSAndroid Build Coastguard Worker         if (val) {
271*795d594fSAndroid Build Coastguard Worker           // TryBoundary kind:entry
272*795d594fSAndroid Build Coastguard Worker           throw new Error();
273*795d594fSAndroid Build Coastguard Worker           // TryBoundary kind:exit
274*795d594fSAndroid Build Coastguard Worker         }
275*795d594fSAndroid Build Coastguard Worker         // TryBoundary kind:exit
276*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
277*795d594fSAndroid Build Coastguard Worker         return -2000;
278*795d594fSAndroid Build Coastguard Worker       }
279*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
280*795d594fSAndroid Build Coastguard Worker       return -1000;
281*795d594fSAndroid Build Coastguard Worker     }
282*795d594fSAndroid Build Coastguard Worker     return a;
283*795d594fSAndroid Build Coastguard Worker   }
284*795d594fSAndroid Build Coastguard Worker 
285*795d594fSAndroid Build Coastguard Worker   // We eliminate the return -1000 catch block which is outside of the loop in
286*795d594fSAndroid Build Coastguard Worker   // dead_code_elimination$initial. We can do so since we eliminated the TryBoundary of `a /= 2;`.
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (before)
289*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
290*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
291*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
292*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
293*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (before)
296*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
297*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
298*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
299*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (before)
302*795d594fSAndroid Build Coastguard Worker   /// CHECK:     IntConstant -1000
303*795d594fSAndroid Build Coastguard Worker 
304*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (after)
305*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
306*795d594fSAndroid Build Coastguard Worker   /// CHECK:     TryBoundary
307*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: TryBoundary
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (after)
310*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
311*795d594fSAndroid Build Coastguard Worker   /// CHECK:     flags "catch_block"
312*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: flags "catch_block"
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (after)
315*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: IntConstant -1000
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker   // When removing that block, we are removing a block outside of a loop but we still need to update
318*795d594fSAndroid Build Coastguard Worker   // the loop information in the graph since we removed TryBoundary instructions inside of a loop
319*795d594fSAndroid Build Coastguard Worker   // and now `a /= 2;` is not considered part of a loop (Cannot throw so it will not `continue` and
320*795d594fSAndroid Build Coastguard Worker   // will always return).
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (before)
323*795d594fSAndroid Build Coastguard Worker   /// CHECK:     Div loop:B2
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (after)
326*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:  Div loop:B2
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(int, boolean) dead_code_elimination$initial (after)
329*795d594fSAndroid Build Coastguard Worker   /// CHECK:      Div
330*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:  Div
$noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop( int a, boolean val)331*795d594fSAndroid Build Coastguard Worker   public static int $noinline$testNestedTryBoundariesWithLoopAndCatchOutsideOfLoop(
332*795d594fSAndroid Build Coastguard Worker           int a, boolean val) {
333*795d594fSAndroid Build Coastguard Worker     try {
334*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 4; ++i) {
335*795d594fSAndroid Build Coastguard Worker         try {
336*795d594fSAndroid Build Coastguard Worker           try {
337*795d594fSAndroid Build Coastguard Worker             if (val) {
338*795d594fSAndroid Build Coastguard Worker               // TryBoundary kind:entry
339*795d594fSAndroid Build Coastguard Worker               throw new Error();
340*795d594fSAndroid Build Coastguard Worker               // TryBoundary kind:exit
341*795d594fSAndroid Build Coastguard Worker             }
342*795d594fSAndroid Build Coastguard Worker             // TryBoundary kind:exit
343*795d594fSAndroid Build Coastguard Worker           } catch (Exception e) {
344*795d594fSAndroid Build Coastguard Worker               continue;
345*795d594fSAndroid Build Coastguard Worker           }
346*795d594fSAndroid Build Coastguard Worker           // TryBoundary kind:entry
347*795d594fSAndroid Build Coastguard Worker           a /= 2;
348*795d594fSAndroid Build Coastguard Worker           // TryBoundary kind:exit
349*795d594fSAndroid Build Coastguard Worker           return a;
350*795d594fSAndroid Build Coastguard Worker         } catch (Error e) {
351*795d594fSAndroid Build Coastguard Worker           continue;
352*795d594fSAndroid Build Coastguard Worker         }
353*795d594fSAndroid Build Coastguard Worker       }
354*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
355*795d594fSAndroid Build Coastguard Worker       return -1000;
356*795d594fSAndroid Build Coastguard Worker     }
357*795d594fSAndroid Build Coastguard Worker     return a;
358*795d594fSAndroid Build Coastguard Worker   }
359*795d594fSAndroid Build Coastguard Worker }
360