xref: /aosp_15_r20/art/test/2042-checker-dce-always-throw/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     // Basic test
20*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimplifyThrow(1));
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker     // Basic test for non-trivial blocks (i.e. not just an invoke and a Goto)
23*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimplifyThrowAndPrint(1));
24*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimplifyTwoThrows(1));
25*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimplifyWithArgument(1));
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker     // Try catch tests
28*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testDoNotSimplifyInTry(1));
29*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testSimplifyInCatch(1));
30*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1, 1));
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker     // Test that we update the phis correctly after simplifying an always throwing method, and
33*795d594fSAndroid Build Coastguard Worker     // recomputing dominance.
34*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testUpdatePhisCorrectly(1));
35*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testDeleteAllUsesBeforeDeletingInstruction(1));
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker     // SimplifyAlwaysThrows for blocks without a goto at the end
38*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testEndsWithIf(1, 1));
39*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testEndsWithReturn(1));
40*795d594fSAndroid Build Coastguard Worker     // Since we cannot use `assertEquals`, not throwing would be the success.
41*795d594fSAndroid Build Coastguard Worker     $noinline$testEndsWithReturnVoid(1);
42*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testEndsWithSwitch(1, 1));
43*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testEndsWithThrow(1));
44*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testEndsWithTryBoundary(1));
45*795d594fSAndroid Build Coastguard Worker 
46*795d594fSAndroid Build Coastguard Worker     // SimplifyAlwaysThrows for invokes in catch blocks
47*795d594fSAndroid Build Coastguard Worker     assertEquals(0, $noinline$testInsideCatch(1));
48*795d594fSAndroid Build Coastguard Worker   }
49*795d594fSAndroid Build Coastguard Worker 
alwaysThrows()50*795d594fSAndroid Build Coastguard Worker   private static void alwaysThrows() throws Error {
51*795d594fSAndroid Build Coastguard Worker     throw new Error("");
52*795d594fSAndroid Build Coastguard Worker   }
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrow(int) dead_code_elimination$after_inlining (before)
55*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
56*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
57*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
58*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrow(int) dead_code_elimination$after_inlining (after)
61*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
62*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
63*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   // Tests that we simplify the always throwing branch directly to the exit.
$noinline$testSimplifyThrow(int num)66*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyThrow(int num) {
67*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
68*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
69*795d594fSAndroid Build Coastguard Worker     }
70*795d594fSAndroid Build Coastguard Worker     return 0;
71*795d594fSAndroid Build Coastguard Worker   }
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (before)
74*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
75*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
76*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
77*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
78*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
79*795d594fSAndroid Build Coastguard Worker 
80*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (after)
81*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
82*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
83*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowAndPrint(int) dead_code_elimination$after_inlining (after)
86*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testSimplifyThrowAndPrint(int num)87*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyThrowAndPrint(int num) {
88*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
89*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
90*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
91*795d594fSAndroid Build Coastguard Worker     }
92*795d594fSAndroid Build Coastguard Worker     return 0;
93*795d594fSAndroid Build Coastguard Worker   }
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (before)
96*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
97*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock>> method_name:Main.alwaysThrows always_throws:true
98*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
99*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
100*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (after)
103*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
105*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   // Check that the second `alwaysThrows` gets removed.
108*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyTwoThrows(int) dead_code_elimination$after_inlining (after)
109*795d594fSAndroid Build Coastguard Worker   /// CHECK:       InvokeStaticOrDirect method_name:Main.alwaysThrows always_throws:true
110*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeStaticOrDirect method_name:Main.alwaysThrows always_throws:true
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker   // Tests that we simplify the always throwing branch directly to the exit, even with blocks that
113*795d594fSAndroid Build Coastguard Worker   // are not just the throwing instruction and a Goto.
$noinline$testSimplifyTwoThrows(int num)114*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyTwoThrows(int num) {
115*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
116*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
117*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
118*795d594fSAndroid Build Coastguard Worker     }
119*795d594fSAndroid Build Coastguard Worker     return 0;
120*795d594fSAndroid Build Coastguard Worker   }
121*795d594fSAndroid Build Coastguard Worker 
throwIfZero(int num)122*795d594fSAndroid Build Coastguard Worker   private static int throwIfZero(int num) {
123*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
124*795d594fSAndroid Build Coastguard Worker       throw new Error("num is 0!");
125*795d594fSAndroid Build Coastguard Worker     }
126*795d594fSAndroid Build Coastguard Worker     return num / num;
127*795d594fSAndroid Build Coastguard Worker   }
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (before)
130*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.throwIfZero always_throws:true
131*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
132*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
133*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
134*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
135*795d594fSAndroid Build Coastguard Worker 
136*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (after)
137*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.throwIfZero always_throws:true
138*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
139*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyWithArgument(int) dead_code_elimination$after_inlining (after)
142*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testSimplifyWithArgument(int num)143*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyWithArgument(int num) {
144*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
145*795d594fSAndroid Build Coastguard Worker       throwIfZero(0);
146*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
147*795d594fSAndroid Build Coastguard Worker     }
148*795d594fSAndroid Build Coastguard Worker     return 0;
149*795d594fSAndroid Build Coastguard Worker   }
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (before)
152*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
153*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
154*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
155*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (after)
158*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
159*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
160*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure we have the try catches in the graph at this stage.
163*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyThrowWithTryCatch(int) dead_code_elimination$after_inlining (before)
164*795d594fSAndroid Build Coastguard Worker   /// CHECK:       TryBoundary kind:entry
165*795d594fSAndroid Build Coastguard Worker   /// CHECK:       TryBoundary kind:entry
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   // Tests that we simplify the always throwing branch directly to the exit, with non-blocking try
168*795d594fSAndroid Build Coastguard Worker   // catches in the graph.
$noinline$testSimplifyThrowWithTryCatch(int num)169*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyThrowWithTryCatch(int num) {
170*795d594fSAndroid Build Coastguard Worker     try {
171*795d594fSAndroid Build Coastguard Worker       if (num == 123) {
172*795d594fSAndroid Build Coastguard Worker         throw new Error();
173*795d594fSAndroid Build Coastguard Worker       }
174*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
175*795d594fSAndroid Build Coastguard Worker       return 123;
176*795d594fSAndroid Build Coastguard Worker     }
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
179*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
180*795d594fSAndroid Build Coastguard Worker     }
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker     try {
183*795d594fSAndroid Build Coastguard Worker       if (num == 456) {
184*795d594fSAndroid Build Coastguard Worker         throw new Error();
185*795d594fSAndroid Build Coastguard Worker       }
186*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
187*795d594fSAndroid Build Coastguard Worker       return 456;
188*795d594fSAndroid Build Coastguard Worker     }
189*795d594fSAndroid Build Coastguard Worker     return 0;
190*795d594fSAndroid Build Coastguard Worker   }
191*795d594fSAndroid Build Coastguard Worker 
$inline$testDoNotSimplifyInner(int num)192*795d594fSAndroid Build Coastguard Worker   private static void $inline$testDoNotSimplifyInner(int num) {
193*795d594fSAndroid Build Coastguard Worker     alwaysThrows();
194*795d594fSAndroid Build Coastguard Worker     while (num == 0) {
195*795d594fSAndroid Build Coastguard Worker       // We should never hit this since we are always throwing.
196*795d594fSAndroid Build Coastguard Worker       System.out.println(num);
197*795d594fSAndroid Build Coastguard Worker     }
198*795d594fSAndroid Build Coastguard Worker   }
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (before)
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
202*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
203*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
204*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
205*795d594fSAndroid Build Coastguard Worker 
206*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (after)
207*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
208*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
209*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
210*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
211*795d594fSAndroid Build Coastguard Worker 
212*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure we have the try catch in the graph at this stage.
213*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$after_inlining (before)
214*795d594fSAndroid Build Coastguard Worker   /// CHECK:       TryBoundary kind:entry
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker   // Consistency check to that we do not simplify it by the last DCE pass either
217*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInTry(int) dead_code_elimination$before_codegen (after)
218*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
219*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
221*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker   // Tests that we have the necessary conditions for us to simplify the always throwing instruction
224*795d594fSAndroid Build Coastguard Worker   // (e.g. InvokeStaticOrDirect followed by a Goto) but we are blocking this due to being in a try.
225*795d594fSAndroid Build Coastguard Worker   // Changing the Goto here for the exit would be wrong since we want to flow to the catch rather
226*795d594fSAndroid Build Coastguard Worker   // than the Exit. The preconditions are tricky to do with just one function (since we will have an
227*795d594fSAndroid Build Coastguard Worker   // invoke followed by a TryBoundary rather than a Goto) but we can do so with the help of the
228*795d594fSAndroid Build Coastguard Worker   // inliner.
$noinline$testDoNotSimplifyInTry(int num)229*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDoNotSimplifyInTry(int num) {
230*795d594fSAndroid Build Coastguard Worker     try {
231*795d594fSAndroid Build Coastguard Worker       $inline$testDoNotSimplifyInner(num);
232*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
233*795d594fSAndroid Build Coastguard Worker       return 0;
234*795d594fSAndroid Build Coastguard Worker     }
235*795d594fSAndroid Build Coastguard Worker     return 123;
236*795d594fSAndroid Build Coastguard Worker   }
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (before)
239*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
240*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
241*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
242*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
243*795d594fSAndroid Build Coastguard Worker 
244*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (after)
245*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
246*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
247*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure we have the try catch in the graph at this stage.
250*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testSimplifyInCatch(int) dead_code_elimination$after_inlining (before)
251*795d594fSAndroid Build Coastguard Worker   /// CHECK:       TryBoundary kind:entry
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   // We are able to simplify the `alwaysThrows` even though we are inside of the catch { ... } since
254*795d594fSAndroid Build Coastguard Worker   // the if makes it so that we are not the first block of the catch and therefore not in the
255*795d594fSAndroid Build Coastguard Worker   // "catch_block".
$noinline$testSimplifyInCatch(int num)256*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testSimplifyInCatch(int num) {
257*795d594fSAndroid Build Coastguard Worker     try {
258*795d594fSAndroid Build Coastguard Worker       throw new Error();
259*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
260*795d594fSAndroid Build Coastguard Worker       if (num == 0) {
261*795d594fSAndroid Build Coastguard Worker         alwaysThrows();
262*795d594fSAndroid Build Coastguard Worker       }
263*795d594fSAndroid Build Coastguard Worker       return 0;
264*795d594fSAndroid Build Coastguard Worker     }
265*795d594fSAndroid Build Coastguard Worker   }
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
268*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
269*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
270*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
271*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (after)
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
275*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
276*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
277*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure we have the try catches in the graph at this stage.
280*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
281*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   TryBoundary kind:entry
282*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   TryBoundary kind:entry
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   // Consistency check to that we do not simplify it by the last DCE pass either
285*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$before_codegen (after)
286*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
287*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
288*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
289*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker   // Similar to testSimplifyInCatch, but now the throw is in an outer try and we shouldn't simplify
292*795d594fSAndroid Build Coastguard Worker   // it. Like in testDoNotSimplifyInTry, we need the help of the inliner to have an invoke followed
293*795d594fSAndroid Build Coastguard Worker   // by a Goto.
$noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num)294*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num) {
295*795d594fSAndroid Build Coastguard Worker     try {
296*795d594fSAndroid Build Coastguard Worker       try {
297*795d594fSAndroid Build Coastguard Worker         throw new Error();
298*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
299*795d594fSAndroid Build Coastguard Worker         if (num == 0) {
300*795d594fSAndroid Build Coastguard Worker           // We use `other_num` here because otherwise we propagate the knowledge that `num` equals
301*795d594fSAndroid Build Coastguard Worker           // zero.
302*795d594fSAndroid Build Coastguard Worker           $inline$testDoNotSimplifyInner(other_num);
303*795d594fSAndroid Build Coastguard Worker         }
304*795d594fSAndroid Build Coastguard Worker         return 0;
305*795d594fSAndroid Build Coastguard Worker       }
306*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
307*795d594fSAndroid Build Coastguard Worker       return 123;
308*795d594fSAndroid Build Coastguard Worker     }
309*795d594fSAndroid Build Coastguard Worker   }
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker   // Check that when we perform SimplifyAlwaysThrows, that the phi for `phi_value` exists, and that
312*795d594fSAndroid Build Coastguard Worker   // we correctly update it after running DCE.
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (before)
315*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
316*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Const5:i\d+>> IntConstant 5
317*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Const5>>]
318*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return [<<ReturnValue>>]
319*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
320*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
321*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
322*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
325*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
326*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return [<<Const0>>]
327*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
328*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
329*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
330*795d594fSAndroid Build Coastguard Worker 
331*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testUpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
332*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   Phi
$noinline$testUpdatePhisCorrectly(int num)333*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testUpdatePhisCorrectly(int num) {
334*795d594fSAndroid Build Coastguard Worker     int phi_value = 0;
335*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
336*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
337*795d594fSAndroid Build Coastguard Worker       phi_value = 5;
338*795d594fSAndroid Build Coastguard Worker     }
339*795d594fSAndroid Build Coastguard Worker     return phi_value;
340*795d594fSAndroid Build Coastguard Worker   }
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker   // Test to check that we delete all uses before the instruction.
$noinline$foo(int num)343*795d594fSAndroid Build Coastguard Worker   private static int $noinline$foo(int num) {
344*795d594fSAndroid Build Coastguard Worker     return num;
345*795d594fSAndroid Build Coastguard Worker   }
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (before)
348*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
349*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Invoke:i\d+>> InvokeStaticOrDirect method_name:Main.$noinline$foo
350*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Invoke>>]
351*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return [<<ReturnValue>>]
352*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
353*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   TryBoundary block:<<InvokeBlock>>
354*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (after)
357*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
358*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return [<<Const0>>]
359*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
360*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
361*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
362*795d594fSAndroid Build Coastguard Worker 
363*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDeleteAllUsesBeforeDeletingInstruction(int) dead_code_elimination$after_inlining (after)
364*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   Phi
$noinline$testDeleteAllUsesBeforeDeletingInstruction(int num)365*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDeleteAllUsesBeforeDeletingInstruction(int num) {
366*795d594fSAndroid Build Coastguard Worker     int phi_value = 0;
367*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
368*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
369*795d594fSAndroid Build Coastguard Worker       try {
370*795d594fSAndroid Build Coastguard Worker         phi_value = $noinline$foo(2);
371*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
372*795d594fSAndroid Build Coastguard Worker         throw new Error("We shouldn't hit this");
373*795d594fSAndroid Build Coastguard Worker       }
374*795d594fSAndroid Build Coastguard Worker     }
375*795d594fSAndroid Build Coastguard Worker     return phi_value;
376*795d594fSAndroid Build Coastguard Worker   }
377*795d594fSAndroid Build Coastguard Worker 
378*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (before)
379*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
380*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   If block:<<InvokeBlock>>
381*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
382*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (after)
385*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
386*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
387*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
388*795d594fSAndroid Build Coastguard Worker 
389*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithIf(int, int) dead_code_elimination$after_inlining (after)
390*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithIf(int num, int other_num)391*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testEndsWithIf(int num, int other_num) {
392*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
393*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
394*795d594fSAndroid Build Coastguard Worker       if (other_num == 0) {
395*795d594fSAndroid Build Coastguard Worker         System.out.println("I am unrechable!");
396*795d594fSAndroid Build Coastguard Worker       }
397*795d594fSAndroid Build Coastguard Worker     }
398*795d594fSAndroid Build Coastguard Worker     return 0;
399*795d594fSAndroid Build Coastguard Worker   }
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (before)
402*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
403*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return block:<<InvokeBlock>>
404*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
405*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
406*795d594fSAndroid Build Coastguard Worker 
407*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (after)
408*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
409*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
410*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithReturn(int) dead_code_elimination$after_inlining (after)
413*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithReturn(int num)414*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testEndsWithReturn(int num) {
415*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
416*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
417*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
418*795d594fSAndroid Build Coastguard Worker       return 1;
419*795d594fSAndroid Build Coastguard Worker     }
420*795d594fSAndroid Build Coastguard Worker     return 0;
421*795d594fSAndroid Build Coastguard Worker   }
422*795d594fSAndroid Build Coastguard Worker 
423*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (before)
424*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
425*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   ReturnVoid block:<<InvokeBlock>>
426*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
427*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
428*795d594fSAndroid Build Coastguard Worker 
429*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (after)
430*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
431*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
432*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
433*795d594fSAndroid Build Coastguard Worker 
434*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.$noinline$testEndsWithReturnVoid(int) dead_code_elimination$after_inlining (after)
435*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithReturnVoid(int num)436*795d594fSAndroid Build Coastguard Worker   private static void $noinline$testEndsWithReturnVoid(int num) {
437*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
438*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
439*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
440*795d594fSAndroid Build Coastguard Worker       return;
441*795d594fSAndroid Build Coastguard Worker     }
442*795d594fSAndroid Build Coastguard Worker     return;
443*795d594fSAndroid Build Coastguard Worker   }
444*795d594fSAndroid Build Coastguard Worker 
445*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (before)
446*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
447*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   PackedSwitch block:<<InvokeBlock>>
448*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
449*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
450*795d594fSAndroid Build Coastguard Worker 
451*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (after)
452*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
453*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
454*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
455*795d594fSAndroid Build Coastguard Worker 
456*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithSwitch(int, int) dead_code_elimination$after_inlining (after)
457*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithSwitch(int num, int other_num)458*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testEndsWithSwitch(int num, int other_num) {
459*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
460*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
461*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
462*795d594fSAndroid Build Coastguard Worker       int result = 10;
463*795d594fSAndroid Build Coastguard Worker       switch (other_num) {
464*795d594fSAndroid Build Coastguard Worker         case 1:
465*795d594fSAndroid Build Coastguard Worker           result = 100;
466*795d594fSAndroid Build Coastguard Worker           break;
467*795d594fSAndroid Build Coastguard Worker         case 2:
468*795d594fSAndroid Build Coastguard Worker           result = 300;
469*795d594fSAndroid Build Coastguard Worker           break;
470*795d594fSAndroid Build Coastguard Worker         case 3:
471*795d594fSAndroid Build Coastguard Worker           result = 500;
472*795d594fSAndroid Build Coastguard Worker           break;
473*795d594fSAndroid Build Coastguard Worker         case 4:
474*795d594fSAndroid Build Coastguard Worker           result = 700;
475*795d594fSAndroid Build Coastguard Worker           break;
476*795d594fSAndroid Build Coastguard Worker       }
477*795d594fSAndroid Build Coastguard Worker       return result;
478*795d594fSAndroid Build Coastguard Worker     }
479*795d594fSAndroid Build Coastguard Worker     return 0;
480*795d594fSAndroid Build Coastguard Worker   }
481*795d594fSAndroid Build Coastguard Worker 
482*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (before)
483*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
484*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Throw block:<<InvokeBlock>>
485*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
486*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
487*795d594fSAndroid Build Coastguard Worker 
488*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (after)
489*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
490*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
491*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
492*795d594fSAndroid Build Coastguard Worker 
493*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithThrow(int) dead_code_elimination$after_inlining (after)
494*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithThrow(int num)495*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testEndsWithThrow(int num) {
496*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
497*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
498*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
499*795d594fSAndroid Build Coastguard Worker       throw new Error("Other error");
500*795d594fSAndroid Build Coastguard Worker     }
501*795d594fSAndroid Build Coastguard Worker     return 0;
502*795d594fSAndroid Build Coastguard Worker   }
503*795d594fSAndroid Build Coastguard Worker 
504*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (before)
505*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
506*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   TryBoundary block:<<InvokeBlock>>
507*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
508*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
509*795d594fSAndroid Build Coastguard Worker 
510*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (after)
511*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
512*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
513*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
514*795d594fSAndroid Build Coastguard Worker 
515*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testEndsWithTryBoundary(int) dead_code_elimination$after_inlining (after)
516*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testEndsWithTryBoundary(int num)517*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testEndsWithTryBoundary(int num) {
518*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
519*795d594fSAndroid Build Coastguard Worker       alwaysThrows();
520*795d594fSAndroid Build Coastguard Worker       System.out.println("I am unrechable!");
521*795d594fSAndroid Build Coastguard Worker       try {
522*795d594fSAndroid Build Coastguard Worker         alwaysThrows();
523*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
524*795d594fSAndroid Build Coastguard Worker         return 1;
525*795d594fSAndroid Build Coastguard Worker       }
526*795d594fSAndroid Build Coastguard Worker     }
527*795d594fSAndroid Build Coastguard Worker     return 0;
528*795d594fSAndroid Build Coastguard Worker   }
529*795d594fSAndroid Build Coastguard Worker 
530*795d594fSAndroid Build Coastguard Worker   // Empty method to forbid the try from disappearing
$noinline$emptyMethod()531*795d594fSAndroid Build Coastguard Worker   private static void $noinline$emptyMethod() {}
532*795d594fSAndroid Build Coastguard Worker 
533*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (before)
534*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
535*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Return block:<<InvokeBlock>>
536*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeVirtual method_name:java.io.PrintStream.println
537*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
538*795d594fSAndroid Build Coastguard Worker 
539*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (after)
540*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
541*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
542*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
543*795d594fSAndroid Build Coastguard Worker 
544*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testInsideCatch(int) dead_code_elimination$after_inlining (after)
545*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:   InvokeVirtual method_name:java.io.PrintStream.println
$noinline$testInsideCatch(int num)546*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testInsideCatch(int num) {
547*795d594fSAndroid Build Coastguard Worker     if (num == 0) {
548*795d594fSAndroid Build Coastguard Worker       try {
549*795d594fSAndroid Build Coastguard Worker         $noinline$emptyMethod();
550*795d594fSAndroid Build Coastguard Worker       } catch (Error e) {
551*795d594fSAndroid Build Coastguard Worker         alwaysThrows();
552*795d594fSAndroid Build Coastguard Worker         System.out.println("I am unrechable!");
553*795d594fSAndroid Build Coastguard Worker         return 1;
554*795d594fSAndroid Build Coastguard Worker       }
555*795d594fSAndroid Build Coastguard Worker     }
556*795d594fSAndroid Build Coastguard Worker     return 0;
557*795d594fSAndroid Build Coastguard Worker   }
558*795d594fSAndroid Build Coastguard Worker 
assertEquals(int expected, int actual)559*795d594fSAndroid Build Coastguard Worker   static void assertEquals(int expected, int actual) {
560*795d594fSAndroid Build Coastguard Worker     if (expected != actual) {
561*795d594fSAndroid Build Coastguard Worker       throw new AssertionError("Expected " + expected + " got " + actual);
562*795d594fSAndroid Build Coastguard Worker     }
563*795d594fSAndroid Build Coastguard Worker   }
564*795d594fSAndroid Build Coastguard Worker }
565