xref: /aosp_15_r20/art/test/530-checker-lse-try-catch/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 class Point {
18*795d594fSAndroid Build Coastguard Worker   int x;
19*795d594fSAndroid Build Coastguard Worker   int y;
20*795d594fSAndroid Build Coastguard Worker }
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker public class Main {
main(String[] args)23*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
24*795d594fSAndroid Build Coastguard Worker     final boolean boolean_throw = false;
25*795d594fSAndroid Build Coastguard Worker     final boolean boolean_other_throw = false;
26*795d594fSAndroid Build Coastguard Worker     assertEquals(3,
27*795d594fSAndroid Build Coastguard Worker         $noinline$testDifferentFields(
28*795d594fSAndroid Build Coastguard Worker             new Point(), new Point(), boolean_throw, boolean_other_throw));
29*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testRedundantStore(new Point(), boolean_throw, boolean_other_throw));
30*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testTryCatchBlocking(new Point(), boolean_throw));
31*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testTryCatchPhi(new Point(), boolean_throw));
32*795d594fSAndroid Build Coastguard Worker     assertEquals(2, $noinline$testTryCatchPhiWithTwoCatches(new Point(), new int[0]));
33*795d594fSAndroid Build Coastguard Worker     assertEquals(1, $noinline$testKeepStoreInsideTry());
34*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testDontKeepStoreInsideCatch(new int[]{10}));
35*795d594fSAndroid Build Coastguard Worker     assertEquals(30, $noinline$testDontKeepStoreInsideCatch(new int[]{}));
36*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testKeepStoreInsideCatchWithOuterTry(new int[]{10}));
37*795d594fSAndroid Build Coastguard Worker     assertEquals(30, $noinline$testKeepStoreInsideCatchWithOuterTry(new int[]{}));
38*795d594fSAndroid Build Coastguard Worker     assertEquals(40, $noinline$testDontKeepStoreInsideFinally(new int[]{10}));
39*795d594fSAndroid Build Coastguard Worker     try {
40*795d594fSAndroid Build Coastguard Worker       assertEquals(30, $noinline$testDontKeepStoreInsideFinally(new int[]{}));
41*795d594fSAndroid Build Coastguard Worker       throw new Error("Unreachable");
42*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException expected) {
43*795d594fSAndroid Build Coastguard Worker     }
44*795d594fSAndroid Build Coastguard Worker     assertEquals(10, $noinline$testDontKeepStoreInsideOuterCatch(new int[]{10}));
45*795d594fSAndroid Build Coastguard Worker     assertEquals(100030, $noinline$testDontKeepStoreInsideOuterCatch(new int[]{}));
46*795d594fSAndroid Build Coastguard Worker     assertEquals(150, $noinline$test40());
47*795d594fSAndroid Build Coastguard Worker   }
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDifferentFields(Point, Point, boolean, boolean) load_store_elimination (before)
50*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.x
51*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
52*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldGet field_name:Point.x
53*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldGet field_name:Point.y
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDifferentFields(Point, Point, boolean, boolean) load_store_elimination (after)
56*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.x
57*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDifferentFields(Point, Point, boolean, boolean) load_store_elimination (after)
60*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     InstanceFieldGet field_name:Point.x
61*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     InstanceFieldGet field_name:Point.y
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catches weren't removed by an earlier pass.
64*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDifferentFields(Point, Point, boolean, boolean) load_store_elimination (after)
65*795d594fSAndroid Build Coastguard Worker   /// CHECK:         TryBoundary kind:entry
66*795d594fSAndroid Build Coastguard Worker   /// CHECK:         TryBoundary kind:entry
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   // Different fields shouldn't alias.
$noinline$testDifferentFields( Point obj1, Point obj2, boolean boolean_throw, boolean boolean_other_throw)69*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDifferentFields(
70*795d594fSAndroid Build Coastguard Worker       Point obj1, Point obj2, boolean boolean_throw, boolean boolean_other_throw) {
71*795d594fSAndroid Build Coastguard Worker     try {
72*795d594fSAndroid Build Coastguard Worker       if (boolean_throw) {
73*795d594fSAndroid Build Coastguard Worker         throw new Error();
74*795d594fSAndroid Build Coastguard Worker       }
75*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
76*795d594fSAndroid Build Coastguard Worker       return 0;
77*795d594fSAndroid Build Coastguard Worker     }
78*795d594fSAndroid Build Coastguard Worker     obj1.x = 1;
79*795d594fSAndroid Build Coastguard Worker     obj2.y = 2;
80*795d594fSAndroid Build Coastguard Worker     int result = obj1.x + obj2.y;
81*795d594fSAndroid Build Coastguard Worker     try {
82*795d594fSAndroid Build Coastguard Worker       if (boolean_other_throw) {
83*795d594fSAndroid Build Coastguard Worker         throw new Error();
84*795d594fSAndroid Build Coastguard Worker       }
85*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
86*795d594fSAndroid Build Coastguard Worker       return 0;
87*795d594fSAndroid Build Coastguard Worker     }
88*795d594fSAndroid Build Coastguard Worker     return result;
89*795d594fSAndroid Build Coastguard Worker   }
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRedundantStore(Point, boolean, boolean) load_store_elimination (before)
92*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
93*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
94*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldGet field_name:Point.y
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRedundantStore(Point, boolean, boolean) load_store_elimination (after)
97*795d594fSAndroid Build Coastguard Worker   /// CHECK:         InstanceFieldSet field_name:Point.y
98*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     InstanceFieldSet field_name:Point.y
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRedundantStore(Point, boolean, boolean) load_store_elimination (after)
101*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     InstanceFieldGet field_name:Point.y
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catches weren't removed by an earlier pass.
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testRedundantStore(Point, boolean, boolean) load_store_elimination (after)
105*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     TryBoundary kind:entry
106*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     TryBoundary kind:entry
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker   // Redundant store of the same value.
$noinline$testRedundantStore( Point obj, boolean boolean_throw, boolean boolean_other_throw)109*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testRedundantStore(
110*795d594fSAndroid Build Coastguard Worker       Point obj, boolean boolean_throw, boolean boolean_other_throw) {
111*795d594fSAndroid Build Coastguard Worker     try {
112*795d594fSAndroid Build Coastguard Worker       if (boolean_throw) {
113*795d594fSAndroid Build Coastguard Worker         throw new Error();
114*795d594fSAndroid Build Coastguard Worker       }
115*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
116*795d594fSAndroid Build Coastguard Worker       return 0;
117*795d594fSAndroid Build Coastguard Worker     }
118*795d594fSAndroid Build Coastguard Worker     obj.y = 1;
119*795d594fSAndroid Build Coastguard Worker     obj.y = 1;
120*795d594fSAndroid Build Coastguard Worker     try {
121*795d594fSAndroid Build Coastguard Worker       if (boolean_other_throw) {
122*795d594fSAndroid Build Coastguard Worker         throw new Error();
123*795d594fSAndroid Build Coastguard Worker       }
124*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
125*795d594fSAndroid Build Coastguard Worker       return 0;
126*795d594fSAndroid Build Coastguard Worker     }
127*795d594fSAndroid Build Coastguard Worker     return obj.y;
128*795d594fSAndroid Build Coastguard Worker   }
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchBlocking(Point, boolean) load_store_elimination (before)
131*795d594fSAndroid Build Coastguard Worker   /// CHECK: InstanceFieldSet field_name:Point.y
132*795d594fSAndroid Build Coastguard Worker   /// CHECK: InstanceFieldGet field_name:Point.y
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchBlocking(Point, boolean) load_store_elimination (after)
135*795d594fSAndroid Build Coastguard Worker   /// CHECK: InstanceFieldSet field_name:Point.y
136*795d594fSAndroid Build Coastguard Worker   /// CHECK: InstanceFieldGet field_name:Point.y
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catch wasn't removed by an earlier pass.
139*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchBlocking(Point, boolean) load_store_elimination (after)
140*795d594fSAndroid Build Coastguard Worker   /// CHECK: TryBoundary kind:entry
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   // We cannot remove the Get since we might have thrown.
$noinline$testTryCatchBlocking(Point obj, boolean boolean_throw)143*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testTryCatchBlocking(Point obj, boolean boolean_throw) {
144*795d594fSAndroid Build Coastguard Worker     obj.y = 1;
145*795d594fSAndroid Build Coastguard Worker     try {
146*795d594fSAndroid Build Coastguard Worker       if (boolean_throw) {
147*795d594fSAndroid Build Coastguard Worker         throw new Error();
148*795d594fSAndroid Build Coastguard Worker       }
149*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
150*795d594fSAndroid Build Coastguard Worker     }
151*795d594fSAndroid Build Coastguard Worker     return obj.y;
152*795d594fSAndroid Build Coastguard Worker   }
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhi(Point, boolean) load_store_elimination (before)
155*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
156*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
157*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldGet field_name:Point.y
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhi(Point, boolean) load_store_elimination (after)
160*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
161*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhi(Point, boolean) load_store_elimination (after)
164*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     InstanceFieldGet field_name:Point.y
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catch wasn't removed by an earlier pass.
167*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhi(Point, boolean) load_store_elimination (after)
168*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     TryBoundary kind:entry
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker   // We either threw and we set the value in the catch, or we didn't throw and we set the value
171*795d594fSAndroid Build Coastguard Worker   // before the catch. We can solve that with a Phi and skip the get.
$noinline$testTryCatchPhi(Point obj, boolean boolean_throw)172*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testTryCatchPhi(Point obj, boolean boolean_throw) {
173*795d594fSAndroid Build Coastguard Worker     obj.y = 1;
174*795d594fSAndroid Build Coastguard Worker     try {
175*795d594fSAndroid Build Coastguard Worker       if (boolean_throw) {
176*795d594fSAndroid Build Coastguard Worker         throw new Error();
177*795d594fSAndroid Build Coastguard Worker       }
178*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
179*795d594fSAndroid Build Coastguard Worker       obj.y = 2;
180*795d594fSAndroid Build Coastguard Worker     }
181*795d594fSAndroid Build Coastguard Worker     return obj.y;
182*795d594fSAndroid Build Coastguard Worker   }
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhiWithTwoCatches(Point, int[]) load_store_elimination (before)
186*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
187*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
188*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
189*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldGet field_name:Point.y
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhiWithTwoCatches(Point, int[]) load_store_elimination (after)
192*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
193*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
194*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     InstanceFieldSet field_name:Point.y
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhiWithTwoCatches(Point, int[]) load_store_elimination (after)
197*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldGet field_name:Point.y
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catch wasn't removed by an earlier pass.
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testTryCatchPhiWithTwoCatches(Point, int[]) load_store_elimination (after)
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: TryBoundary kind:entry
$noinline$testTryCatchPhiWithTwoCatches(Point obj, int[] numbers)202*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testTryCatchPhiWithTwoCatches(Point obj, int[] numbers) {
203*795d594fSAndroid Build Coastguard Worker     obj.y = 1;
204*795d594fSAndroid Build Coastguard Worker     try {
205*795d594fSAndroid Build Coastguard Worker       if (numbers[0] == 1) {
206*795d594fSAndroid Build Coastguard Worker         throw new Error();
207*795d594fSAndroid Build Coastguard Worker       }
208*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
209*795d594fSAndroid Build Coastguard Worker       obj.y = 2;
210*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
211*795d594fSAndroid Build Coastguard Worker       obj.y = 3;
212*795d594fSAndroid Build Coastguard Worker     }
213*795d594fSAndroid Build Coastguard Worker     return obj.y;
214*795d594fSAndroid Build Coastguard Worker   }
215*795d594fSAndroid Build Coastguard Worker 
216*795d594fSAndroid Build Coastguard Worker   // Check that we don't eliminate the first store to `main.sumForKeepStoreInsideTryCatch` since it
217*795d594fSAndroid Build Coastguard Worker   // is observable.
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   // Consistency check to make sure the try/catch wasn't removed by an earlier pass.
220*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testKeepStoreInsideTry() load_store_elimination (after)
221*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: TryBoundary kind:entry
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testKeepStoreInsideTry() load_store_elimination (before)
224*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
225*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testKeepStoreInsideTry() load_store_elimination (after)
228*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
229*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
$noinline$testKeepStoreInsideTry()230*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testKeepStoreInsideTry() {
231*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
232*795d594fSAndroid Build Coastguard Worker     main.sumForKeepStoreInsideTryCatch = 0;
233*795d594fSAndroid Build Coastguard Worker     try {
234*795d594fSAndroid Build Coastguard Worker       int[] array = {1};
235*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += array[0];
236*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += array[1];
237*795d594fSAndroid Build Coastguard Worker       throw new RuntimeException("Unreachable");
238*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
239*795d594fSAndroid Build Coastguard Worker       return main.sumForKeepStoreInsideTryCatch;
240*795d594fSAndroid Build Coastguard Worker     }
241*795d594fSAndroid Build Coastguard Worker   }
242*795d594fSAndroid Build Coastguard Worker 
$noinline$returnValue(int value)243*795d594fSAndroid Build Coastguard Worker   private static int $noinline$returnValue(int value) {
244*795d594fSAndroid Build Coastguard Worker     return value;
245*795d594fSAndroid Build Coastguard Worker   }
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideCatch(int[]) load_store_elimination (before)
248*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
249*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
250*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideCatch(int[]) load_store_elimination (after)
253*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
$noinline$testDontKeepStoreInsideCatch(int[] array)254*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDontKeepStoreInsideCatch(int[] array) {
255*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
256*795d594fSAndroid Build Coastguard Worker     int value = 0;
257*795d594fSAndroid Build Coastguard Worker     try {
258*795d594fSAndroid Build Coastguard Worker       value = array[0];
259*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
260*795d594fSAndroid Build Coastguard Worker       // These sets can be eliminated even though we have invokes since this catch is not part of an
261*795d594fSAndroid Build Coastguard Worker       // outer try.
262*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(10);
263*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(20);
264*795d594fSAndroid Build Coastguard Worker     }
265*795d594fSAndroid Build Coastguard Worker     return main.sumForKeepStoreInsideTryCatch + value;
266*795d594fSAndroid Build Coastguard Worker   }
267*795d594fSAndroid Build Coastguard Worker 
268*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testKeepStoreInsideCatchWithOuterTry(int[]) load_store_elimination (before)
269*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
270*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
271*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testKeepStoreInsideCatchWithOuterTry(int[]) load_store_elimination (after)
274*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
275*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
276*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
$noinline$testKeepStoreInsideCatchWithOuterTry(int[] array)277*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testKeepStoreInsideCatchWithOuterTry(int[] array) {
278*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
279*795d594fSAndroid Build Coastguard Worker     int value = 0;
280*795d594fSAndroid Build Coastguard Worker     try {
281*795d594fSAndroid Build Coastguard Worker       try {
282*795d594fSAndroid Build Coastguard Worker         value = array[0];
283*795d594fSAndroid Build Coastguard Worker       } catch (Exception e) {
284*795d594fSAndroid Build Coastguard Worker         // These sets can't be eliminated since this catch is part of a outer try.
285*795d594fSAndroid Build Coastguard Worker         main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(10);
286*795d594fSAndroid Build Coastguard Worker         main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(20);
287*795d594fSAndroid Build Coastguard Worker       }
288*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
289*795d594fSAndroid Build Coastguard Worker       value = 100000;
290*795d594fSAndroid Build Coastguard Worker     }
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker     return main.sumForKeepStoreInsideTryCatch + value;
293*795d594fSAndroid Build Coastguard Worker   }
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker   // Note that there are four `InstanceFieldSet` instead of two since we split the `finally` block
296*795d594fSAndroid Build Coastguard Worker   // into the normal path, and the exceptional path.
297*795d594fSAndroid Build Coastguard Worker 
298*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideFinally(int[]) load_store_elimination (before)
299*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
300*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
301*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
302*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
303*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideFinally(int[]) load_store_elimination (after)
306*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
$noinline$testDontKeepStoreInsideFinally(int[] array)307*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDontKeepStoreInsideFinally(int[] array) {
308*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
309*795d594fSAndroid Build Coastguard Worker     int value = 0;
310*795d594fSAndroid Build Coastguard Worker     try {
311*795d594fSAndroid Build Coastguard Worker       value = array[0];
312*795d594fSAndroid Build Coastguard Worker     } finally {
313*795d594fSAndroid Build Coastguard Worker       // These sets can be eliminated even though we have invokes since this catch is not part of an
314*795d594fSAndroid Build Coastguard Worker       // outer try.
315*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(10);
316*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(20);
317*795d594fSAndroid Build Coastguard Worker     }
318*795d594fSAndroid Build Coastguard Worker     return main.sumForKeepStoreInsideTryCatch + value;
319*795d594fSAndroid Build Coastguard Worker   }
320*795d594fSAndroid Build Coastguard Worker 
321*795d594fSAndroid Build Coastguard Worker   // Checks that we are able to do LSE inside of catches which are outside of try blocks.
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideOuterCatch(int[]) load_store_elimination (before)
324*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
325*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
326*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker   // This store potentially can be eliminated too, but our phi creation logic doesn't realize it can
329*795d594fSAndroid Build Coastguard Worker   // create a Phi for `main.sumForKeepStoreInsideTryCatch` and skip a store+load.
330*795d594fSAndroid Build Coastguard Worker 
331*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$testDontKeepStoreInsideOuterCatch(int[]) load_store_elimination (after)
332*795d594fSAndroid Build Coastguard Worker   /// CHECK:     InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
333*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: InstanceFieldSet field_name:Main.sumForKeepStoreInsideTryCatch
334*795d594fSAndroid Build Coastguard Worker 
$noinline$testDontKeepStoreInsideOuterCatch(int[] array)335*795d594fSAndroid Build Coastguard Worker   private static int $noinline$testDontKeepStoreInsideOuterCatch(int[] array) {
336*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
337*795d594fSAndroid Build Coastguard Worker     int value = 0;
338*795d594fSAndroid Build Coastguard Worker     try {
339*795d594fSAndroid Build Coastguard Worker       value = array[0];
340*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException expected) {
341*795d594fSAndroid Build Coastguard Worker       // These sets and gets are not considered to be part of a try so they are free to be
342*795d594fSAndroid Build Coastguard Worker       // eliminated.
343*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(10);
344*795d594fSAndroid Build Coastguard Worker       main.sumForKeepStoreInsideTryCatch += $noinline$returnValue(20);
345*795d594fSAndroid Build Coastguard Worker       try {
346*795d594fSAndroid Build Coastguard Worker         value = array[0];
347*795d594fSAndroid Build Coastguard Worker       } catch (ArrayIndexOutOfBoundsException expectedToo) {
348*795d594fSAndroid Build Coastguard Worker         value = 100000;
349*795d594fSAndroid Build Coastguard Worker       }
350*795d594fSAndroid Build Coastguard Worker     }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker     return main.sumForKeepStoreInsideTryCatch + value;
353*795d594fSAndroid Build Coastguard Worker   }
354*795d594fSAndroid Build Coastguard Worker 
355*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$test40() load_store_elimination (before)
356*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
357*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
358*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
359*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
360*795d594fSAndroid Build Coastguard Worker   //
361*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
362*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
363*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
364*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
365*795d594fSAndroid Build Coastguard Worker   //
366*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
367*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
368*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
369*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                 ArraySet
370*795d594fSAndroid Build Coastguard Worker 
371*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.$noinline$test40() load_store_elimination (after)
372*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
373*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
374*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
375*795d594fSAndroid Build Coastguard Worker   //
376*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
377*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
378*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
379*795d594fSAndroid Build Coastguard Worker   //
380*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                 ArraySet
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker   // Like `test40` from 530-checker-lse but with $inline$ for the inner method so we check that we
383*795d594fSAndroid Build Coastguard Worker   // have the array set inside try catches too.
384*795d594fSAndroid Build Coastguard Worker   // Since we are inlining, we know the parameters and are able to elimnate (some) of the
385*795d594fSAndroid Build Coastguard Worker   // `ArraySet`s.
$noinline$test40()386*795d594fSAndroid Build Coastguard Worker   private static int $noinline$test40() {
387*795d594fSAndroid Build Coastguard Worker     int[] array = new int[1];
388*795d594fSAndroid Build Coastguard Worker     try {
389*795d594fSAndroid Build Coastguard Worker       $inline$fillArrayTest40(array, 100, 0);
390*795d594fSAndroid Build Coastguard Worker       System.out.println("UNREACHABLE");
391*795d594fSAndroid Build Coastguard Worker     } catch (Throwable expected) {
392*795d594fSAndroid Build Coastguard Worker     }
393*795d594fSAndroid Build Coastguard Worker     assertEquals(1, array[0]);
394*795d594fSAndroid Build Coastguard Worker     try {
395*795d594fSAndroid Build Coastguard Worker       $inline$fillArrayTest40(array, 100, 1);
396*795d594fSAndroid Build Coastguard Worker       System.out.println("UNREACHABLE");
397*795d594fSAndroid Build Coastguard Worker     } catch (Throwable expected) {
398*795d594fSAndroid Build Coastguard Worker     }
399*795d594fSAndroid Build Coastguard Worker     assertEquals(2, array[0]);
400*795d594fSAndroid Build Coastguard Worker     $inline$fillArrayTest40(array, 100, 2);
401*795d594fSAndroid Build Coastguard Worker     assertEquals(150, array[0]);
402*795d594fSAndroid Build Coastguard Worker     return array[0];
403*795d594fSAndroid Build Coastguard Worker   }
404*795d594fSAndroid Build Coastguard Worker 
405*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.$inline$fillArrayTest40(int[], int, int) load_store_elimination (before)
406*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
407*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
408*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
409*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
410*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
411*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                 ArraySet
412*795d594fSAndroid Build Coastguard Worker 
413*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.$inline$fillArrayTest40(int[], int, int) load_store_elimination (after)
414*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
415*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
416*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
417*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     DivZeroCheck
418*795d594fSAndroid Build Coastguard Worker   /// CHECK:                     ArraySet
419*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                 ArraySet
420*795d594fSAndroid Build Coastguard Worker 
421*795d594fSAndroid Build Coastguard Worker   // Check that the stores to array[0] are not eliminated since we can throw in between the stores.
$inline$fillArrayTest40(int[] array, int a, int b)422*795d594fSAndroid Build Coastguard Worker   private static void $inline$fillArrayTest40(int[] array, int a, int b) {
423*795d594fSAndroid Build Coastguard Worker     array[0] = 1;
424*795d594fSAndroid Build Coastguard Worker     int x = a / b;
425*795d594fSAndroid Build Coastguard Worker     array[0] = 2;
426*795d594fSAndroid Build Coastguard Worker     int y = a / (b - 1);
427*795d594fSAndroid Build Coastguard Worker     array[0] = x + y;
428*795d594fSAndroid Build Coastguard Worker   }
429*795d594fSAndroid Build Coastguard Worker 
assertEquals(int expected, int actual)430*795d594fSAndroid Build Coastguard Worker   private static void assertEquals(int expected, int actual) {
431*795d594fSAndroid Build Coastguard Worker     if (expected != actual) {
432*795d594fSAndroid Build Coastguard Worker       throw new AssertionError("Expected: " + expected + ", Actual: " + actual);
433*795d594fSAndroid Build Coastguard Worker     }
434*795d594fSAndroid Build Coastguard Worker   }
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker   int sumForKeepStoreInsideTryCatch;
437*795d594fSAndroid Build Coastguard Worker }
438