xref: /aosp_15_r20/art/test/530-checker-loops2/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 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 //
18*795d594fSAndroid Build Coastguard Worker // Test on loop optimizations, in particular around less common induction.
19*795d594fSAndroid Build Coastguard Worker //
20*795d594fSAndroid Build Coastguard Worker public class Main {
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker   static int sResult;
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker   //
25*795d594fSAndroid Build Coastguard Worker   // Various sequence variables used in bound checks.
26*795d594fSAndroid Build Coastguard Worker   //
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.bubble(int[]) BCE (before)
29*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
30*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
31*795d594fSAndroid Build Coastguard Worker   //
32*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.bubble(int[]) BCE (after)
33*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
34*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
bubble(int[] a)35*795d594fSAndroid Build Coastguard Worker   private static void bubble(int[] a) {
36*795d594fSAndroid Build Coastguard Worker     for (int i = a.length; --i >= 0;) {
37*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < i; j++) {
38*795d594fSAndroid Build Coastguard Worker         if (a[j] > a[j+1]) {
39*795d594fSAndroid Build Coastguard Worker           int tmp = a[j];
40*795d594fSAndroid Build Coastguard Worker           a[j]  = a[j+1];
41*795d594fSAndroid Build Coastguard Worker           a[j+1] = tmp;
42*795d594fSAndroid Build Coastguard Worker         }
43*795d594fSAndroid Build Coastguard Worker       }
44*795d594fSAndroid Build Coastguard Worker     }
45*795d594fSAndroid Build Coastguard Worker   }
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
48*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
49*795d594fSAndroid Build Coastguard Worker   //
50*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
51*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
52*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
periodicIdiom(int tc)53*795d594fSAndroid Build Coastguard Worker   private static int periodicIdiom(int tc) {
54*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 3 };
55*795d594fSAndroid Build Coastguard Worker     // Loop with periodic sequence (0, 1).
56*795d594fSAndroid Build Coastguard Worker     int k = 0;
57*795d594fSAndroid Build Coastguard Worker     int result = 0;
58*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < tc; i++) {
59*795d594fSAndroid Build Coastguard Worker       result += x[k];
60*795d594fSAndroid Build Coastguard Worker       k = 1 - k;
61*795d594fSAndroid Build Coastguard Worker     }
62*795d594fSAndroid Build Coastguard Worker     return result;
63*795d594fSAndroid Build Coastguard Worker   }
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
66*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
67*795d594fSAndroid Build Coastguard Worker   //
68*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
69*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
70*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
periodicSequence2(int tc)71*795d594fSAndroid Build Coastguard Worker   private static int periodicSequence2(int tc) {
72*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 3 };
73*795d594fSAndroid Build Coastguard Worker     // Loop with periodic sequence (0, 1).
74*795d594fSAndroid Build Coastguard Worker     int k = 0;
75*795d594fSAndroid Build Coastguard Worker     int l = 1;
76*795d594fSAndroid Build Coastguard Worker     int result = 0;
77*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < tc; i++) {
78*795d594fSAndroid Build Coastguard Worker       result += x[k];
79*795d594fSAndroid Build Coastguard Worker       int t = l;
80*795d594fSAndroid Build Coastguard Worker       l = k;
81*795d594fSAndroid Build Coastguard Worker       k = t;
82*795d594fSAndroid Build Coastguard Worker     }
83*795d594fSAndroid Build Coastguard Worker     return result;
84*795d594fSAndroid Build Coastguard Worker   }
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
88*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
89*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
90*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
91*795d594fSAndroid Build Coastguard Worker   //
92*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
93*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
94*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
periodicSequence4(int tc)95*795d594fSAndroid Build Coastguard Worker   private static int periodicSequence4(int tc) {
96*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 3, 5, 7 };
97*795d594fSAndroid Build Coastguard Worker     // Loop with periodic sequence (0, 1, 2, 3).
98*795d594fSAndroid Build Coastguard Worker     int k = 0;
99*795d594fSAndroid Build Coastguard Worker     int l = 1;
100*795d594fSAndroid Build Coastguard Worker     int m = 2;
101*795d594fSAndroid Build Coastguard Worker     int n = 3;
102*795d594fSAndroid Build Coastguard Worker     int result = 0;
103*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < tc; i++) {
104*795d594fSAndroid Build Coastguard Worker       result += x[k] + x[l] + x[m] + x[n];  // all used at once
105*795d594fSAndroid Build Coastguard Worker       int t = n;
106*795d594fSAndroid Build Coastguard Worker       n = k;
107*795d594fSAndroid Build Coastguard Worker       k = l;
108*795d594fSAndroid Build Coastguard Worker       l = m;
109*795d594fSAndroid Build Coastguard Worker       m = t;
110*795d594fSAndroid Build Coastguard Worker     }
111*795d594fSAndroid Build Coastguard Worker     return result;
112*795d594fSAndroid Build Coastguard Worker   }
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicXorSequence(int) BCE (before)
115*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
116*795d594fSAndroid Build Coastguard Worker   //
117*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicXorSequence(int) BCE (after)
118*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
119*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
periodicXorSequence(int tc)120*795d594fSAndroid Build Coastguard Worker   private static int periodicXorSequence(int tc) {
121*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 3 };
122*795d594fSAndroid Build Coastguard Worker     // Loop with periodic sequence (0, 1).
123*795d594fSAndroid Build Coastguard Worker     int k = 0;
124*795d594fSAndroid Build Coastguard Worker     int result = 0;
125*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < tc; i++) {
126*795d594fSAndroid Build Coastguard Worker       result += x[k];
127*795d594fSAndroid Build Coastguard Worker       k ^= 1;
128*795d594fSAndroid Build Coastguard Worker     }
129*795d594fSAndroid Build Coastguard Worker     return result;
130*795d594fSAndroid Build Coastguard Worker   }
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp1() BCE (before)
133*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
134*795d594fSAndroid Build Coastguard Worker   //
135*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp1() BCE (after)
136*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
137*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightUp1()138*795d594fSAndroid Build Coastguard Worker   private static int justRightUp1() {
139*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
140*795d594fSAndroid Build Coastguard Worker     int result = 0;
141*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
142*795d594fSAndroid Build Coastguard Worker       result += x[k++];
143*795d594fSAndroid Build Coastguard Worker     }
144*795d594fSAndroid Build Coastguard Worker     return result;
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp2() BCE (before)
148*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
149*795d594fSAndroid Build Coastguard Worker   //
150*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp2() BCE (after)
151*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
152*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightUp2()153*795d594fSAndroid Build Coastguard Worker   private static int justRightUp2() {
154*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
155*795d594fSAndroid Build Coastguard Worker     int result = 0;
156*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
157*795d594fSAndroid Build Coastguard Worker       result += x[i - Integer.MAX_VALUE + 10];
158*795d594fSAndroid Build Coastguard Worker     }
159*795d594fSAndroid Build Coastguard Worker     return result;
160*795d594fSAndroid Build Coastguard Worker   }
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp3() BCE (before)
163*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
164*795d594fSAndroid Build Coastguard Worker   //
165*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightUp3() BCE (after)
166*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
167*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightUp3()168*795d594fSAndroid Build Coastguard Worker   private static int justRightUp3() {
169*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
170*795d594fSAndroid Build Coastguard Worker     int result = 0;
171*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
172*795d594fSAndroid Build Coastguard Worker       result += x[k++];
173*795d594fSAndroid Build Coastguard Worker     }
174*795d594fSAndroid Build Coastguard Worker     return result;
175*795d594fSAndroid Build Coastguard Worker   }
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBUp() BCE (before)
178*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
179*795d594fSAndroid Build Coastguard Worker   //
180*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBUp() BCE (after)
181*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
182*795d594fSAndroid Build Coastguard Worker   //
183*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBUp() BCE (after)
184*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justOOBUp()185*795d594fSAndroid Build Coastguard Worker   private static int justOOBUp() {
186*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
187*795d594fSAndroid Build Coastguard Worker     int result = 0;
188*795d594fSAndroid Build Coastguard Worker     // Infinite loop!
189*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
190*795d594fSAndroid Build Coastguard Worker       result += x[k++];
191*795d594fSAndroid Build Coastguard Worker     }
192*795d594fSAndroid Build Coastguard Worker     return result;
193*795d594fSAndroid Build Coastguard Worker   }
194*795d594fSAndroid Build Coastguard Worker 
195*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown1() BCE (before)
196*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
197*795d594fSAndroid Build Coastguard Worker   //
198*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown1() BCE (after)
199*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightDown1()201*795d594fSAndroid Build Coastguard Worker   private static int justRightDown1() {
202*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
203*795d594fSAndroid Build Coastguard Worker     int result = 0;
204*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
205*795d594fSAndroid Build Coastguard Worker       result += x[k++];
206*795d594fSAndroid Build Coastguard Worker     }
207*795d594fSAndroid Build Coastguard Worker     return result;
208*795d594fSAndroid Build Coastguard Worker   }
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown2() BCE (before)
211*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
212*795d594fSAndroid Build Coastguard Worker   //
213*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown2() BCE (after)
214*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
215*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightDown2()216*795d594fSAndroid Build Coastguard Worker   private static int justRightDown2() {
217*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
218*795d594fSAndroid Build Coastguard Worker     int result = 0;
219*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
220*795d594fSAndroid Build Coastguard Worker       result += x[Integer.MAX_VALUE + i];
221*795d594fSAndroid Build Coastguard Worker     }
222*795d594fSAndroid Build Coastguard Worker     return result;
223*795d594fSAndroid Build Coastguard Worker   }
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown3() BCE (before)
226*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
227*795d594fSAndroid Build Coastguard Worker   //
228*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justRightDown3() BCE (after)
229*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
230*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightDown3()231*795d594fSAndroid Build Coastguard Worker   private static int justRightDown3() {
232*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
233*795d594fSAndroid Build Coastguard Worker     int result = 0;
234*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
235*795d594fSAndroid Build Coastguard Worker       result += x[k++];
236*795d594fSAndroid Build Coastguard Worker     }
237*795d594fSAndroid Build Coastguard Worker     return result;
238*795d594fSAndroid Build Coastguard Worker   }
239*795d594fSAndroid Build Coastguard Worker 
240*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBDown() BCE (before)
241*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
242*795d594fSAndroid Build Coastguard Worker   //
243*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBDown() BCE (after)
244*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
245*795d594fSAndroid Build Coastguard Worker   //
246*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.justOOBDown() BCE (after)
247*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justOOBDown()248*795d594fSAndroid Build Coastguard Worker   private static int justOOBDown() {
249*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
250*795d594fSAndroid Build Coastguard Worker     int result = 0;
251*795d594fSAndroid Build Coastguard Worker     // Infinite loop!
252*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
253*795d594fSAndroid Build Coastguard Worker       result += x[k++];
254*795d594fSAndroid Build Coastguard Worker     }
255*795d594fSAndroid Build Coastguard Worker     return result;
256*795d594fSAndroid Build Coastguard Worker   }
257*795d594fSAndroid Build Coastguard Worker 
258*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.lowerOOB(int[]) BCE (before)
259*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
260*795d594fSAndroid Build Coastguard Worker   //
261*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
262*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
263*795d594fSAndroid Build Coastguard Worker   //
264*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
265*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
lowerOOB(int[] x)266*795d594fSAndroid Build Coastguard Worker   private static void lowerOOB(int[] x) {
267*795d594fSAndroid Build Coastguard Worker     // OOB!
268*795d594fSAndroid Build Coastguard Worker     for (int i = -1; i < x.length; i++) {
269*795d594fSAndroid Build Coastguard Worker       sResult += x[i];
270*795d594fSAndroid Build Coastguard Worker     }
271*795d594fSAndroid Build Coastguard Worker   }
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.upperOOB(int[]) BCE (before)
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
275*795d594fSAndroid Build Coastguard Worker   //
276*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
277*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
278*795d594fSAndroid Build Coastguard Worker   //
279*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
280*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
upperOOB(int[] x)281*795d594fSAndroid Build Coastguard Worker   private static void upperOOB(int[] x) {
282*795d594fSAndroid Build Coastguard Worker     // OOB!
283*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i <= x.length; i++) {
284*795d594fSAndroid Build Coastguard Worker       sResult += x[i];
285*795d594fSAndroid Build Coastguard Worker     }
286*795d594fSAndroid Build Coastguard Worker   }
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileUpOOB() BCE (before)
289*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
290*795d594fSAndroid Build Coastguard Worker   //
291*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
292*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
293*795d594fSAndroid Build Coastguard Worker   //
294*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
doWhileUpOOB()296*795d594fSAndroid Build Coastguard Worker   private static void doWhileUpOOB() {
297*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
298*795d594fSAndroid Build Coastguard Worker     int i = 0;
299*795d594fSAndroid Build Coastguard Worker     // OOB!
300*795d594fSAndroid Build Coastguard Worker     do {
301*795d594fSAndroid Build Coastguard Worker       sResult += x[i++];
302*795d594fSAndroid Build Coastguard Worker     } while (i <= x.length);
303*795d594fSAndroid Build Coastguard Worker   }
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileDownOOB() BCE (before)
306*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
307*795d594fSAndroid Build Coastguard Worker   //
308*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
309*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
310*795d594fSAndroid Build Coastguard Worker   //
311*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
312*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
doWhileDownOOB()313*795d594fSAndroid Build Coastguard Worker   private static void doWhileDownOOB() {
314*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
315*795d594fSAndroid Build Coastguard Worker     int i = x.length - 1;
316*795d594fSAndroid Build Coastguard Worker     // OOB!
317*795d594fSAndroid Build Coastguard Worker     do {
318*795d594fSAndroid Build Coastguard Worker       sResult += x[i--];
319*795d594fSAndroid Build Coastguard Worker     } while (-1 <= i);
320*795d594fSAndroid Build Coastguard Worker   }
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justRightTriangular1() BCE (before)
323*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
324*795d594fSAndroid Build Coastguard Worker   //
325*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justRightTriangular1() BCE (after)
326*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
327*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightTriangular1()328*795d594fSAndroid Build Coastguard Worker   private static void justRightTriangular1() {
329*795d594fSAndroid Build Coastguard Worker     int[] a = { 1 } ;
330*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 5; i <= Integer.MIN_VALUE + 10; i++) {
331*795d594fSAndroid Build Coastguard Worker       for (int j = Integer.MIN_VALUE + 4; j < i - 5; j++) {
332*795d594fSAndroid Build Coastguard Worker         sResult += a[j - (Integer.MIN_VALUE + 4)];
333*795d594fSAndroid Build Coastguard Worker       }
334*795d594fSAndroid Build Coastguard Worker     }
335*795d594fSAndroid Build Coastguard Worker   }
336*795d594fSAndroid Build Coastguard Worker 
337*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justRightTriangular2() BCE (before)
338*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
339*795d594fSAndroid Build Coastguard Worker   //
340*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justRightTriangular2() BCE (after)
341*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
342*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
justRightTriangular2()343*795d594fSAndroid Build Coastguard Worker   private static void justRightTriangular2() {
344*795d594fSAndroid Build Coastguard Worker     int[] a = { 1 } ;
345*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 5; i <= 10; i++) {
346*795d594fSAndroid Build Coastguard Worker       for (int j = 4; j < i - 5; j++) {
347*795d594fSAndroid Build Coastguard Worker         sResult += a[j - 4];
348*795d594fSAndroid Build Coastguard Worker       }
349*795d594fSAndroid Build Coastguard Worker     }
350*795d594fSAndroid Build Coastguard Worker   }
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justOOBTriangular() BCE (before)
353*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
354*795d594fSAndroid Build Coastguard Worker   //
355*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justOOBTriangular() BCE (after)
356*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize
357*795d594fSAndroid Build Coastguard Worker   //
358*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.justOOBTriangular() BCE (after)
359*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
justOOBTriangular()360*795d594fSAndroid Build Coastguard Worker   private static void justOOBTriangular() {
361*795d594fSAndroid Build Coastguard Worker     int[] a = { 1 } ;
362*795d594fSAndroid Build Coastguard Worker     for (int i = Integer.MIN_VALUE + 4; i <= 10; i++) {
363*795d594fSAndroid Build Coastguard Worker       for (int j = 4; j < i - 5; j++) {
364*795d594fSAndroid Build Coastguard Worker         sResult += a[j - 4];
365*795d594fSAndroid Build Coastguard Worker       }
366*795d594fSAndroid Build Coastguard Worker     }
367*795d594fSAndroid Build Coastguard Worker   }
368*795d594fSAndroid Build Coastguard Worker 
369*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB1(int) BCE (before)
370*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
371*795d594fSAndroid Build Coastguard Worker   //
372*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB1(int) BCE (after)
373*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize
374*795d594fSAndroid Build Coastguard Worker   //
375*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB1(int) BCE (after)
376*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
hiddenOOB1(int lo)377*795d594fSAndroid Build Coastguard Worker   private static void hiddenOOB1(int lo) {
378*795d594fSAndroid Build Coastguard Worker     int[] a = { 1 } ;
379*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i <= 10; i++) {
380*795d594fSAndroid Build Coastguard Worker       // Dangerous loop where careless static range analysis would yield strict upper bound
381*795d594fSAndroid Build Coastguard Worker       // on index j of 5. When, for instance, lo and thus i = -2147483648, the upper bound
382*795d594fSAndroid Build Coastguard Worker       // becomes really positive due to arithmetic wrap-around, causing OOB.
383*795d594fSAndroid Build Coastguard Worker       for (int j = 4; j < i - 5; j++) {
384*795d594fSAndroid Build Coastguard Worker         sResult += a[j - 4];
385*795d594fSAndroid Build Coastguard Worker       }
386*795d594fSAndroid Build Coastguard Worker     }
387*795d594fSAndroid Build Coastguard Worker   }
388*795d594fSAndroid Build Coastguard Worker 
389*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB2(int) BCE (before)
390*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
391*795d594fSAndroid Build Coastguard Worker   //
392*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB2(int) BCE (after)
393*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize
394*795d594fSAndroid Build Coastguard Worker   //
395*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB2(int) BCE (after)
396*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
hiddenOOB2(int hi)397*795d594fSAndroid Build Coastguard Worker   private static void hiddenOOB2(int hi) {
398*795d594fSAndroid Build Coastguard Worker     int[] a = { 1 } ;
399*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < hi; i++) {
400*795d594fSAndroid Build Coastguard Worker       // Dangerous loop where careless static range analysis would yield strict lower bound
401*795d594fSAndroid Build Coastguard Worker       // on index j of 5. When, for instance, hi and thus i = 2147483647, the upper bound
402*795d594fSAndroid Build Coastguard Worker       // becomes really negative due to arithmetic wrap-around, causing OOB.
403*795d594fSAndroid Build Coastguard Worker       for (int j = 6; j > i + 5; j--) {
404*795d594fSAndroid Build Coastguard Worker         sResult += a[j - 6];
405*795d594fSAndroid Build Coastguard Worker       }
406*795d594fSAndroid Build Coastguard Worker     }
407*795d594fSAndroid Build Coastguard Worker   }
408*795d594fSAndroid Build Coastguard Worker 
409*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB3(int) BCE (before)
410*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
411*795d594fSAndroid Build Coastguard Worker   //
412*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB3(int) BCE (after)
413*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize
414*795d594fSAndroid Build Coastguard Worker   //
415*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenOOB3(int) BCE (after)
416*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
hiddenOOB3(int hi)417*795d594fSAndroid Build Coastguard Worker   private static void hiddenOOB3(int hi) {
418*795d594fSAndroid Build Coastguard Worker     int[] a = { 11 } ;
419*795d594fSAndroid Build Coastguard Worker     for (int i = -1; i <= hi; i++) {
420*795d594fSAndroid Build Coastguard Worker       // Dangerous loop where careless static range analysis would yield strict lower bound
421*795d594fSAndroid Build Coastguard Worker       // on index j of 0. For large i, the initial value of j becomes really negative due
422*795d594fSAndroid Build Coastguard Worker       // to arithmetic wrap-around, causing OOB.
423*795d594fSAndroid Build Coastguard Worker       for (int j = i + 1; j < 1; j++) {
424*795d594fSAndroid Build Coastguard Worker         sResult += a[j];
425*795d594fSAndroid Build Coastguard Worker       }
426*795d594fSAndroid Build Coastguard Worker     }
427*795d594fSAndroid Build Coastguard Worker   }
428*795d594fSAndroid Build Coastguard Worker 
429*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (before)
430*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
431*795d594fSAndroid Build Coastguard Worker   //
432*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (after)
433*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
434*795d594fSAndroid Build Coastguard Worker   //
435*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenInfiniteOOB() BCE (after)
436*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
hiddenInfiniteOOB()437*795d594fSAndroid Build Coastguard Worker   private static void hiddenInfiniteOOB() {
438*795d594fSAndroid Build Coastguard Worker     int[] a = { 11 } ;
439*795d594fSAndroid Build Coastguard Worker     for (int i = -1; i <= 0; i++) {
440*795d594fSAndroid Build Coastguard Worker       // Dangerous loop where careless static range analysis would yield a safe upper bound
441*795d594fSAndroid Build Coastguard Worker       // of -3. In reality, due to arithmetic wrap-around (when i = -1, j <= 2147483647;
442*795d594fSAndroid Build Coastguard Worker       // whereas when i = 0, j <= -3), this is an infinite loop that goes OOB.
443*795d594fSAndroid Build Coastguard Worker       for (int j = -3; j <= 2147483646 * i - 3; j++) {
444*795d594fSAndroid Build Coastguard Worker         sResult += a[j + 3];
445*795d594fSAndroid Build Coastguard Worker       }
446*795d594fSAndroid Build Coastguard Worker     }
447*795d594fSAndroid Build Coastguard Worker   }
448*795d594fSAndroid Build Coastguard Worker 
449*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenFiniteOOB() BCE (before)
450*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
451*795d594fSAndroid Build Coastguard Worker   //
452*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenFiniteOOB() BCE (after)
453*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize
454*795d594fSAndroid Build Coastguard Worker   //
455*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.hiddenFiniteOOB() BCE (after)
456*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
hiddenFiniteOOB()457*795d594fSAndroid Build Coastguard Worker   private static void hiddenFiniteOOB() {
458*795d594fSAndroid Build Coastguard Worker     int[] a = { 111 } ;
459*795d594fSAndroid Build Coastguard Worker     for (int i = -1; i <= 0; i++) {
460*795d594fSAndroid Build Coastguard Worker       // Dangerous loop similar as above where the loop is now finite, but the
461*795d594fSAndroid Build Coastguard Worker       // loop still goes out of bounds for i = -1 due to the large upper bound.
462*795d594fSAndroid Build Coastguard Worker       for (int j = -4; j < 2147483646 * i - 3; j++) {
463*795d594fSAndroid Build Coastguard Worker         sResult += a[j + 4];
464*795d594fSAndroid Build Coastguard Worker       }
465*795d594fSAndroid Build Coastguard Worker     }
466*795d594fSAndroid Build Coastguard Worker   }
467*795d594fSAndroid Build Coastguard Worker 
468*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inductionOOB(int[]) BCE (before)
469*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
470*795d594fSAndroid Build Coastguard Worker   //
471*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inductionOOB(int[]) BCE (after)
472*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
473*795d594fSAndroid Build Coastguard Worker   //
474*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.inductionOOB(int[]) BCE (after)
475*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
inductionOOB(int[] a)476*795d594fSAndroid Build Coastguard Worker   private static void inductionOOB(int[] a) {
477*795d594fSAndroid Build Coastguard Worker     // Careless range analysis would remove the bounds check.
478*795d594fSAndroid Build Coastguard Worker     // However, the narrower induction b wraps around arithmetically
479*795d594fSAndroid Build Coastguard Worker     // before it reaches the end of arrays longer than 127.
480*795d594fSAndroid Build Coastguard Worker     byte b = 0;
481*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
482*795d594fSAndroid Build Coastguard Worker       a[b++] = i;
483*795d594fSAndroid Build Coastguard Worker     }
484*795d594fSAndroid Build Coastguard Worker   }
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.controlOOB(int[]) BCE (before)
487*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
488*795d594fSAndroid Build Coastguard Worker   //
489*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.controlOOB(int[]) BCE (after)
490*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
491*795d594fSAndroid Build Coastguard Worker   //
492*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.controlOOB(int[]) BCE (after)
493*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
controlOOB(int[] a)494*795d594fSAndroid Build Coastguard Worker   private static void controlOOB(int[] a) {
495*795d594fSAndroid Build Coastguard Worker     // As above, but now the loop control also wraps around.
496*795d594fSAndroid Build Coastguard Worker     for (byte i = 0; i < a.length; i++) {
497*795d594fSAndroid Build Coastguard Worker       a[i] = -i;
498*795d594fSAndroid Build Coastguard Worker     }
499*795d594fSAndroid Build Coastguard Worker   }
500*795d594fSAndroid Build Coastguard Worker 
501*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.conversionOOB(int[]) BCE (before)
502*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
503*795d594fSAndroid Build Coastguard Worker   //
504*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.conversionOOB(int[]) BCE (after)
505*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
506*795d594fSAndroid Build Coastguard Worker   //
507*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.conversionOOB(int[]) BCE (after)
508*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
conversionOOB(int[] a)509*795d594fSAndroid Build Coastguard Worker   private static void conversionOOB(int[] a) {
510*795d594fSAndroid Build Coastguard Worker     // As above, but with wrap around caused by an explicit conversion.
511*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; ) {
512*795d594fSAndroid Build Coastguard Worker       a[i] = i;
513*795d594fSAndroid Build Coastguard Worker       i = (byte) (i + 1);
514*795d594fSAndroid Build Coastguard Worker     }
515*795d594fSAndroid Build Coastguard Worker   }
516*795d594fSAndroid Build Coastguard Worker 
517*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.doNotHoist(int[]) BCE (before)
518*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
519*795d594fSAndroid Build Coastguard Worker   //
520*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.doNotHoist(int[]) BCE (after)
521*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
doNotHoist(int[] a)522*795d594fSAndroid Build Coastguard Worker   public static int doNotHoist(int[] a) {
523*795d594fSAndroid Build Coastguard Worker      int n = a.length;
524*795d594fSAndroid Build Coastguard Worker      int x = 0;
525*795d594fSAndroid Build Coastguard Worker      // BCE applies, but hoisting would crash the loop.
526*795d594fSAndroid Build Coastguard Worker      for (int i = -10000; i < 10000; i++) {
527*795d594fSAndroid Build Coastguard Worker        for (int j = 0; j <= 1; j++) {
528*795d594fSAndroid Build Coastguard Worker          if (0 <= i && i < n)
529*795d594fSAndroid Build Coastguard Worker            x += a[i];
530*795d594fSAndroid Build Coastguard Worker        }
531*795d594fSAndroid Build Coastguard Worker     }
532*795d594fSAndroid Build Coastguard Worker     return x;
533*795d594fSAndroid Build Coastguard Worker   }
534*795d594fSAndroid Build Coastguard Worker 
535*795d594fSAndroid Build Coastguard Worker 
536*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.add() BCE (before)
537*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
538*795d594fSAndroid Build Coastguard Worker   //
539*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.add() BCE (after)
540*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
541*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
add()542*795d594fSAndroid Build Coastguard Worker   private static int[] add() {
543*795d594fSAndroid Build Coastguard Worker     int[] a = new int[10];
544*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i <= 3; i++) {
545*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j <= 6; j++) {
546*795d594fSAndroid Build Coastguard Worker         a[i + j] += 1;
547*795d594fSAndroid Build Coastguard Worker       }
548*795d594fSAndroid Build Coastguard Worker     }
549*795d594fSAndroid Build Coastguard Worker     return a;
550*795d594fSAndroid Build Coastguard Worker   }
551*795d594fSAndroid Build Coastguard Worker 
552*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.multiply1() BCE (before)
553*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
554*795d594fSAndroid Build Coastguard Worker   //
555*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.multiply1() BCE (after)
556*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
557*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
multiply1()558*795d594fSAndroid Build Coastguard Worker   private static int[] multiply1() {
559*795d594fSAndroid Build Coastguard Worker     int[] a = new int[10];
560*795d594fSAndroid Build Coastguard Worker     try {
561*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i <= 3; i++) {
562*795d594fSAndroid Build Coastguard Worker         for (int j = 0; j <= 3; j++) {
563*795d594fSAndroid Build Coastguard Worker           // Range [0,9]: safe.
564*795d594fSAndroid Build Coastguard Worker           a[i * j] += 1;
565*795d594fSAndroid Build Coastguard Worker         }
566*795d594fSAndroid Build Coastguard Worker       }
567*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
568*795d594fSAndroid Build Coastguard Worker       a[0] += 1000;
569*795d594fSAndroid Build Coastguard Worker     }
570*795d594fSAndroid Build Coastguard Worker     return a;
571*795d594fSAndroid Build Coastguard Worker   }
572*795d594fSAndroid Build Coastguard Worker 
573*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.multiply2() BCE (before)
574*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
575*795d594fSAndroid Build Coastguard Worker   //
576*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.multiply2() BCE (after)
577*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
578*795d594fSAndroid Build Coastguard Worker   //
579*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.multiply2() BCE (after)
580*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
multiply2()581*795d594fSAndroid Build Coastguard Worker   static int[] multiply2() {
582*795d594fSAndroid Build Coastguard Worker     int[] a = new int[10];
583*795d594fSAndroid Build Coastguard Worker     try {
584*795d594fSAndroid Build Coastguard Worker       for (int i = -3; i <= 3; i++) {
585*795d594fSAndroid Build Coastguard Worker         for (int j = -3; j <= 3; j++) {
586*795d594fSAndroid Build Coastguard Worker           // Range [-9,9]: unsafe.
587*795d594fSAndroid Build Coastguard Worker           a[i * j] += 1;
588*795d594fSAndroid Build Coastguard Worker         }
589*795d594fSAndroid Build Coastguard Worker       }
590*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
591*795d594fSAndroid Build Coastguard Worker       a[0] += 1000;
592*795d594fSAndroid Build Coastguard Worker     }
593*795d594fSAndroid Build Coastguard Worker     return a;
594*795d594fSAndroid Build Coastguard Worker   }
595*795d594fSAndroid Build Coastguard Worker 
596*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (before)
597*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
598*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
599*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
600*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
601*795d594fSAndroid Build Coastguard Worker   //
602*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
603*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:{{B\d+}}
604*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
605*795d594fSAndroid Build Coastguard Worker   //
606*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
607*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
608*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
609*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
linearDynamicBCE1(int[] x, int lo, int hi)610*795d594fSAndroid Build Coastguard Worker   private static int linearDynamicBCE1(int[] x, int lo, int hi) {
611*795d594fSAndroid Build Coastguard Worker     int result = 0;
612*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i < hi; i++) {
613*795d594fSAndroid Build Coastguard Worker       sResult += x[i];
614*795d594fSAndroid Build Coastguard Worker     }
615*795d594fSAndroid Build Coastguard Worker     return result;
616*795d594fSAndroid Build Coastguard Worker   }
617*795d594fSAndroid Build Coastguard Worker 
618*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (before)
619*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
620*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
621*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
622*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
623*795d594fSAndroid Build Coastguard Worker   //
624*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
625*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:{{B\d+}}
626*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
627*795d594fSAndroid Build Coastguard Worker   //
628*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
629*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
630*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
631*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
linearDynamicBCE2(int[] x, int lo, int hi, int offset)632*795d594fSAndroid Build Coastguard Worker   private static int linearDynamicBCE2(int[] x, int lo, int hi, int offset) {
633*795d594fSAndroid Build Coastguard Worker     int result = 0;
634*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i < hi; i++) {
635*795d594fSAndroid Build Coastguard Worker       sResult += x[offset + i];
636*795d594fSAndroid Build Coastguard Worker     }
637*795d594fSAndroid Build Coastguard Worker     return result;
638*795d594fSAndroid Build Coastguard Worker   }
639*795d594fSAndroid Build Coastguard Worker 
640*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (before)
641*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
642*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
643*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
644*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
645*795d594fSAndroid Build Coastguard Worker   //
646*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
647*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:{{B\d+}}
648*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
649*795d594fSAndroid Build Coastguard Worker   //
650*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
651*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
652*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
653*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
wrapAroundDynamicBCE(int[] x)654*795d594fSAndroid Build Coastguard Worker   private static int wrapAroundDynamicBCE(int[] x) {
655*795d594fSAndroid Build Coastguard Worker     int w = 9;
656*795d594fSAndroid Build Coastguard Worker     int result = 0;
657*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++) {
658*795d594fSAndroid Build Coastguard Worker       result += x[w];
659*795d594fSAndroid Build Coastguard Worker       w = i;
660*795d594fSAndroid Build Coastguard Worker     }
661*795d594fSAndroid Build Coastguard Worker     return result;
662*795d594fSAndroid Build Coastguard Worker   }
663*795d594fSAndroid Build Coastguard Worker 
664*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (before)
665*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
666*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
667*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
668*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
669*795d594fSAndroid Build Coastguard Worker   //
670*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
671*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:{{B\d+}}
672*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
673*795d594fSAndroid Build Coastguard Worker   //
674*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
675*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
676*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
677*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
periodicDynamicBCE(int[] x)678*795d594fSAndroid Build Coastguard Worker   private static int periodicDynamicBCE(int[] x) {
679*795d594fSAndroid Build Coastguard Worker     int k = 0;
680*795d594fSAndroid Build Coastguard Worker     int result = 0;
681*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++) {
682*795d594fSAndroid Build Coastguard Worker       result += x[k];
683*795d594fSAndroid Build Coastguard Worker       k = 1 - k;
684*795d594fSAndroid Build Coastguard Worker     }
685*795d594fSAndroid Build Coastguard Worker     return result;
686*795d594fSAndroid Build Coastguard Worker   }
687*795d594fSAndroid Build Coastguard Worker 
688*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
689*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
690*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
691*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
692*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
693*795d594fSAndroid Build Coastguard Worker   //
694*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
695*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:{{B\d+}}
696*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
697*795d594fSAndroid Build Coastguard Worker   //
698*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
699*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
700*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
701*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi)702*795d594fSAndroid Build Coastguard Worker   static int dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
703*795d594fSAndroid Build Coastguard Worker     // This loop could be infinite for hi = max int. Since i is also used
704*795d594fSAndroid Build Coastguard Worker     // as subscript, however, dynamic bce can proceed.
705*795d594fSAndroid Build Coastguard Worker     int result = 0;
706*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i <= hi; i++) {
707*795d594fSAndroid Build Coastguard Worker       result += x[i];
708*795d594fSAndroid Build Coastguard Worker     }
709*795d594fSAndroid Build Coastguard Worker     return result;
710*795d594fSAndroid Build Coastguard Worker   }
711*795d594fSAndroid Build Coastguard Worker 
712*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
713*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
714*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
715*795d594fSAndroid Build Coastguard Worker   //
716*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
717*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
718*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
719*795d594fSAndroid Build Coastguard Worker   //
720*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
721*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi)722*795d594fSAndroid Build Coastguard Worker   static int noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
723*795d594fSAndroid Build Coastguard Worker     // As above, but now the index is not used as subscript,
724*795d594fSAndroid Build Coastguard Worker     // and dynamic bce is not applied.
725*795d594fSAndroid Build Coastguard Worker     int result = 0;
726*795d594fSAndroid Build Coastguard Worker     for (int k = 0, i = lo; i <= hi; i++) {
727*795d594fSAndroid Build Coastguard Worker       result += x[k++];
728*795d594fSAndroid Build Coastguard Worker     }
729*795d594fSAndroid Build Coastguard Worker     return result;
730*795d594fSAndroid Build Coastguard Worker   }
731*795d594fSAndroid Build Coastguard Worker 
732*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (before)
733*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
734*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
735*795d594fSAndroid Build Coastguard Worker   //
736*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
737*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
738*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
739*795d594fSAndroid Build Coastguard Worker   //
740*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
741*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi)742*795d594fSAndroid Build Coastguard Worker   static int noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi) {
743*795d594fSAndroid Build Coastguard Worker     int result = 0;
744*795d594fSAndroid Build Coastguard Worker     // Mix of int and long induction.
745*795d594fSAndroid Build Coastguard Worker     int k = 0;
746*795d594fSAndroid Build Coastguard Worker     for (long i = lo; i < hi; i++) {
747*795d594fSAndroid Build Coastguard Worker       result += x[k++];
748*795d594fSAndroid Build Coastguard Worker     }
749*795d594fSAndroid Build Coastguard Worker     return result;
750*795d594fSAndroid Build Coastguard Worker   }
751*795d594fSAndroid Build Coastguard Worker 
752*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (before)
753*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<InnerLoop:B\d+>>
754*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<InnerLoop>>
755*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: If          loop:<<InnerLoop>>
756*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: If          loop:<<OuterLoop:B\d+>>
757*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
758*795d594fSAndroid Build Coastguard Worker   //
759*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after)
760*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet   loop:<<InnerLoop:B\d+>>
761*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>>
762*795d594fSAndroid Build Coastguard Worker   /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
763*795d594fSAndroid Build Coastguard Worker   //
764*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after)
765*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
766*795d594fSAndroid Build Coastguard Worker   //
767*795d594fSAndroid Build Coastguard Worker   //  No additional top tests were introduced.
768*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEConstantRange(int[]) BCE (after)
769*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: If
770*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: If
771*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: If
dynamicBCEConstantRange(int[] x)772*795d594fSAndroid Build Coastguard Worker   static int dynamicBCEConstantRange(int[] x) {
773*795d594fSAndroid Build Coastguard Worker     int result = 0;
774*795d594fSAndroid Build Coastguard Worker     for (int i = 2; i <= 6; i++) {
775*795d594fSAndroid Build Coastguard Worker       // Range analysis sees that innermost loop is finite and always taken.
776*795d594fSAndroid Build Coastguard Worker       for (int j = i - 2; j <= i + 2; j++) {
777*795d594fSAndroid Build Coastguard Worker         result += x[j];
778*795d594fSAndroid Build Coastguard Worker       }
779*795d594fSAndroid Build Coastguard Worker     }
780*795d594fSAndroid Build Coastguard Worker     return result;
781*795d594fSAndroid Build Coastguard Worker   }
782*795d594fSAndroid Build Coastguard Worker 
783*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (before)
784*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop:B\d+>>
785*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
786*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
787*795d594fSAndroid Build Coastguard Worker   //
788*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
789*795d594fSAndroid Build Coastguard Worker   //  Order matters:
790*795d594fSAndroid Build Coastguard Worker   /// CHECK:              Deoptimize loop:<<Loop:B\d+>>
791*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:          Goto       loop:<<Loop>>
792*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet   loop:<<Loop>>
793*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet   loop:<<Loop>>
794*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: {{l\d+}} ArrayGet   loop:<<Loop>>
795*795d594fSAndroid Build Coastguard Worker   /// CHECK:              Goto       loop:<<Loop>>
796*795d594fSAndroid Build Coastguard Worker   //
797*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
798*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize loop:none
dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi)799*795d594fSAndroid Build Coastguard Worker   static int dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi) {
800*795d594fSAndroid Build Coastguard Worker     // Deliberately test array length on a before the loop so that only bounds checks
801*795d594fSAndroid Build Coastguard Worker     // on constant subscripts remain, making them a viable candidate for hoisting.
802*795d594fSAndroid Build Coastguard Worker     if (a.length == 0) {
803*795d594fSAndroid Build Coastguard Worker       return -1;
804*795d594fSAndroid Build Coastguard Worker     }
805*795d594fSAndroid Build Coastguard Worker     // Loop that allows BCE on x[i].
806*795d594fSAndroid Build Coastguard Worker     int result = 0;
807*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i < hi; i++) {
808*795d594fSAndroid Build Coastguard Worker       result += x[i];
809*795d594fSAndroid Build Coastguard Worker       if ((i % 10) != 0) {
810*795d594fSAndroid Build Coastguard Worker         // None of the subscripts inside a conditional are removed by dynamic bce,
811*795d594fSAndroid Build Coastguard Worker         // making them a candidate for deoptimization based on constant indices.
812*795d594fSAndroid Build Coastguard Worker         // Compiler should ensure the array loads are not subsequently hoisted
813*795d594fSAndroid Build Coastguard Worker         // "above" the deoptimization "barrier" on the bounds.
814*795d594fSAndroid Build Coastguard Worker         a[1][i] = 1;
815*795d594fSAndroid Build Coastguard Worker         a[2][i] = 2;
816*795d594fSAndroid Build Coastguard Worker         a[99][i] = 3;
817*795d594fSAndroid Build Coastguard Worker       }
818*795d594fSAndroid Build Coastguard Worker     }
819*795d594fSAndroid Build Coastguard Worker     return result;
820*795d594fSAndroid Build Coastguard Worker   }
821*795d594fSAndroid Build Coastguard Worker 
822*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (before)
823*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
824*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
825*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
826*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
827*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
828*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
829*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
830*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
831*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
832*795d594fSAndroid Build Coastguard Worker   //  For brevity, just test occurrence of at least one of each in the loop:
833*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
834*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
835*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
836*795d594fSAndroid Build Coastguard Worker   //
837*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
838*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
839*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayGet    loop:<<Loop>>
840*795d594fSAndroid Build Coastguard Worker   //
841*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
842*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: NullCheck   loop:{{B\d+}}
843*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
844*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
845*795d594fSAndroid Build Coastguard Worker   //
846*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
847*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
dynamicBCEAndConstantIndicesAllPrimTypes(int[] q, boolean[] r, byte[] s, char[] t, short[] u, int[] v, long[] w, float[] x, double[] y, int lo, int hi)848*795d594fSAndroid Build Coastguard Worker   static int dynamicBCEAndConstantIndicesAllPrimTypes(int[] q,
849*795d594fSAndroid Build Coastguard Worker                                                       boolean[] r,
850*795d594fSAndroid Build Coastguard Worker                                                       byte[] s,
851*795d594fSAndroid Build Coastguard Worker                                                       char[] t,
852*795d594fSAndroid Build Coastguard Worker                                                       short[] u,
853*795d594fSAndroid Build Coastguard Worker                                                       int[] v,
854*795d594fSAndroid Build Coastguard Worker                                                       long[] w,
855*795d594fSAndroid Build Coastguard Worker                                                       float[] x,
856*795d594fSAndroid Build Coastguard Worker                                                       double[] y, int lo, int hi) {
857*795d594fSAndroid Build Coastguard Worker     int result = 0;
858*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i < hi; i++) {
859*795d594fSAndroid Build Coastguard Worker       // All constant index array references can be hoisted out of the loop during BCE on q[i].
860*795d594fSAndroid Build Coastguard Worker       result += q[i] + (r[0] ? 1 : 0) + (int) s[0] + (int) t[0] + (int) u[0] + (int) v[0] +
861*795d594fSAndroid Build Coastguard Worker                                         (int) w[0] + (int) x[0] + (int) y[0];
862*795d594fSAndroid Build Coastguard Worker     }
863*795d594fSAndroid Build Coastguard Worker     return result;
864*795d594fSAndroid Build Coastguard Worker   }
865*795d594fSAndroid Build Coastguard Worker 
866*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (before)
867*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
868*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
869*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
870*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
871*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop>>
872*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: NullCheck   loop:<<Loop>>
873*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayLength loop:<<Loop>>
874*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
875*795d594fSAndroid Build Coastguard Worker   //
876*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after)
877*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: ArrayGet    loop:<<Loop:B\d+>>
878*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: Deoptimize  loop:none
879*795d594fSAndroid Build Coastguard Worker   //
880*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after)
881*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: ArrayLength loop:{{B\d+}}
882*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
dynamicBCEAndConstantIndexRefType(int[] q, Integer[] z, int lo, int hi)883*795d594fSAndroid Build Coastguard Worker   static int dynamicBCEAndConstantIndexRefType(int[] q, Integer[] z, int lo, int hi) {
884*795d594fSAndroid Build Coastguard Worker     int result = 0;
885*795d594fSAndroid Build Coastguard Worker     for (int i = lo; i < hi; i++) {
886*795d594fSAndroid Build Coastguard Worker       // Similar to above, but now implicit call to intValue() may prevent hoisting
887*795d594fSAndroid Build Coastguard Worker       // z[0] itself during BCE on q[i]. Therefore, we just check BCE on q[i].
888*795d594fSAndroid Build Coastguard Worker       result += q[i] + z[0];
889*795d594fSAndroid Build Coastguard Worker     }
890*795d594fSAndroid Build Coastguard Worker     return result;
891*795d594fSAndroid Build Coastguard Worker   }
892*795d594fSAndroid Build Coastguard Worker 
893*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.shortIndex(int[]) BCE (before)
894*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>>
895*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
896*795d594fSAndroid Build Coastguard Worker   //
897*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.shortIndex(int[]) BCE (after)
898*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>>
899*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck loop:<<Loop>>
900*795d594fSAndroid Build Coastguard Worker   //
901*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.shortIndex(int[]) BCE (after)
902*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
shortIndex(int[] a)903*795d594fSAndroid Build Coastguard Worker   static int shortIndex(int[] a) {
904*795d594fSAndroid Build Coastguard Worker     int r = 0;
905*795d594fSAndroid Build Coastguard Worker     // Make sure short/int conversions compiles well (b/32193474).
906*795d594fSAndroid Build Coastguard Worker     for (short i = 1; i < 10; i++) {
907*795d594fSAndroid Build Coastguard Worker       int ki = i - 1;
908*795d594fSAndroid Build Coastguard Worker       r += a[ki] + a[i];
909*795d594fSAndroid Build Coastguard Worker     }
910*795d594fSAndroid Build Coastguard Worker     return r;
911*795d594fSAndroid Build Coastguard Worker   }
912*795d594fSAndroid Build Coastguard Worker 
913*795d594fSAndroid Build Coastguard Worker   //
914*795d594fSAndroid Build Coastguard Worker   // Verifier.
915*795d594fSAndroid Build Coastguard Worker   //
916*795d594fSAndroid Build Coastguard Worker 
main(String[] args)917*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
918*795d594fSAndroid Build Coastguard Worker     // Set to run expensive tests for correctness too.
919*795d594fSAndroid Build Coastguard Worker     boolean HEAVY = false;
920*795d594fSAndroid Build Coastguard Worker 
921*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
922*795d594fSAndroid Build Coastguard Worker 
923*795d594fSAndroid Build Coastguard Worker     int[] a200 = new int[200];
924*795d594fSAndroid Build Coastguard Worker 
925*795d594fSAndroid Build Coastguard Worker     // Sorting.
926*795d594fSAndroid Build Coastguard Worker     int[] sort = { 5, 4, 1, 9, 10, 2, 7, 6, 3, 8 };
927*795d594fSAndroid Build Coastguard Worker     bubble(sort);
928*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++) {
929*795d594fSAndroid Build Coastguard Worker       expectEquals(sort[i], x[i]);
930*795d594fSAndroid Build Coastguard Worker     }
931*795d594fSAndroid Build Coastguard Worker 
932*795d594fSAndroid Build Coastguard Worker     // Periodic adds (1, 3), one at the time.
933*795d594fSAndroid Build Coastguard Worker     expectEquals(0, periodicIdiom(-1));
934*795d594fSAndroid Build Coastguard Worker     for (int tc = 0; tc < 32; tc++) {
935*795d594fSAndroid Build Coastguard Worker       int expected = (tc >> 1) << 2;
936*795d594fSAndroid Build Coastguard Worker       if ((tc & 1) != 0) {
937*795d594fSAndroid Build Coastguard Worker         expected += 1;
938*795d594fSAndroid Build Coastguard Worker       }
939*795d594fSAndroid Build Coastguard Worker       expectEquals(expected, periodicIdiom(tc));
940*795d594fSAndroid Build Coastguard Worker     }
941*795d594fSAndroid Build Coastguard Worker 
942*795d594fSAndroid Build Coastguard Worker     // Periodic adds (1, 3), one at the time.
943*795d594fSAndroid Build Coastguard Worker     expectEquals(0, periodicSequence2(-1));
944*795d594fSAndroid Build Coastguard Worker     for (int tc = 0; tc < 32; tc++) {
945*795d594fSAndroid Build Coastguard Worker       int expected = (tc >> 1) << 2;
946*795d594fSAndroid Build Coastguard Worker       if ((tc & 1) != 0) {
947*795d594fSAndroid Build Coastguard Worker         expected += 1;
948*795d594fSAndroid Build Coastguard Worker       }
949*795d594fSAndroid Build Coastguard Worker       expectEquals(expected, periodicSequence2(tc));
950*795d594fSAndroid Build Coastguard Worker     }
951*795d594fSAndroid Build Coastguard Worker 
952*795d594fSAndroid Build Coastguard Worker     // Periodic adds (1, 3, 5, 7), all at once.
953*795d594fSAndroid Build Coastguard Worker     expectEquals(0, periodicSequence4(-1));
954*795d594fSAndroid Build Coastguard Worker     for (int tc = 0; tc < 32; tc++) {
955*795d594fSAndroid Build Coastguard Worker       expectEquals(tc * 16, periodicSequence4(tc));
956*795d594fSAndroid Build Coastguard Worker     }
957*795d594fSAndroid Build Coastguard Worker 
958*795d594fSAndroid Build Coastguard Worker     // Periodic adds (1, 3), one at the time.
959*795d594fSAndroid Build Coastguard Worker     expectEquals(0, periodicXorSequence(-1));
960*795d594fSAndroid Build Coastguard Worker     for (int tc = 0; tc < 32; tc++) {
961*795d594fSAndroid Build Coastguard Worker       int expected = (tc >> 1) << 2;
962*795d594fSAndroid Build Coastguard Worker       if ((tc & 1) != 0) {
963*795d594fSAndroid Build Coastguard Worker         expected += 1;
964*795d594fSAndroid Build Coastguard Worker       }
965*795d594fSAndroid Build Coastguard Worker       expectEquals(expected, periodicXorSequence(tc));
966*795d594fSAndroid Build Coastguard Worker     }
967*795d594fSAndroid Build Coastguard Worker 
968*795d594fSAndroid Build Coastguard Worker     // Large bounds.
969*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightUp1());
970*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightUp2());
971*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightUp3());
972*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightDown1());
973*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightDown2());
974*795d594fSAndroid Build Coastguard Worker     expectEquals(55, justRightDown3());
975*795d594fSAndroid Build Coastguard Worker 
976*795d594fSAndroid Build Coastguard Worker     // Large bounds OOB.
977*795d594fSAndroid Build Coastguard Worker     sResult = 0;
978*795d594fSAndroid Build Coastguard Worker     try {
979*795d594fSAndroid Build Coastguard Worker       justOOBUp();
980*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
981*795d594fSAndroid Build Coastguard Worker       sResult = 1;
982*795d594fSAndroid Build Coastguard Worker     }
983*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
984*795d594fSAndroid Build Coastguard Worker     sResult = 0;
985*795d594fSAndroid Build Coastguard Worker     try {
986*795d594fSAndroid Build Coastguard Worker       justOOBDown();
987*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
988*795d594fSAndroid Build Coastguard Worker       sResult = 1;
989*795d594fSAndroid Build Coastguard Worker     }
990*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
991*795d594fSAndroid Build Coastguard Worker 
992*795d594fSAndroid Build Coastguard Worker     // Lower bound goes OOB.
993*795d594fSAndroid Build Coastguard Worker     sResult = 0;
994*795d594fSAndroid Build Coastguard Worker     try {
995*795d594fSAndroid Build Coastguard Worker       lowerOOB(x);
996*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
997*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
998*795d594fSAndroid Build Coastguard Worker     }
999*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1000*795d594fSAndroid Build Coastguard Worker 
1001*795d594fSAndroid Build Coastguard Worker     // Upper bound goes OOB.
1002*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1003*795d594fSAndroid Build Coastguard Worker     try {
1004*795d594fSAndroid Build Coastguard Worker       upperOOB(x);
1005*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1006*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1007*795d594fSAndroid Build Coastguard Worker     }
1008*795d594fSAndroid Build Coastguard Worker     expectEquals(1055, sResult);
1009*795d594fSAndroid Build Coastguard Worker 
1010*795d594fSAndroid Build Coastguard Worker     // Do while up goes OOB.
1011*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1012*795d594fSAndroid Build Coastguard Worker     try {
1013*795d594fSAndroid Build Coastguard Worker       doWhileUpOOB();
1014*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1015*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1016*795d594fSAndroid Build Coastguard Worker     }
1017*795d594fSAndroid Build Coastguard Worker     expectEquals(1055, sResult);
1018*795d594fSAndroid Build Coastguard Worker 
1019*795d594fSAndroid Build Coastguard Worker     // Do while down goes OOB.
1020*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1021*795d594fSAndroid Build Coastguard Worker     try {
1022*795d594fSAndroid Build Coastguard Worker       doWhileDownOOB();
1023*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1024*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1025*795d594fSAndroid Build Coastguard Worker     }
1026*795d594fSAndroid Build Coastguard Worker     expectEquals(1055, sResult);
1027*795d594fSAndroid Build Coastguard Worker 
1028*795d594fSAndroid Build Coastguard Worker     // Triangular.
1029*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1030*795d594fSAndroid Build Coastguard Worker     justRightTriangular1();
1031*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
1032*795d594fSAndroid Build Coastguard Worker     if (HEAVY) {
1033*795d594fSAndroid Build Coastguard Worker       sResult = 0;
1034*795d594fSAndroid Build Coastguard Worker       justRightTriangular2();
1035*795d594fSAndroid Build Coastguard Worker       expectEquals(1, sResult);
1036*795d594fSAndroid Build Coastguard Worker     }
1037*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1038*795d594fSAndroid Build Coastguard Worker     try {
1039*795d594fSAndroid Build Coastguard Worker       justOOBTriangular();
1040*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1041*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1042*795d594fSAndroid Build Coastguard Worker     }
1043*795d594fSAndroid Build Coastguard Worker     expectEquals(1001, sResult);
1044*795d594fSAndroid Build Coastguard Worker 
1045*795d594fSAndroid Build Coastguard Worker     // Hidden OOB.
1046*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1047*795d594fSAndroid Build Coastguard Worker     try {
1048*795d594fSAndroid Build Coastguard Worker       hiddenOOB1(10);  // no OOB
1049*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1050*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1051*795d594fSAndroid Build Coastguard Worker     }
1052*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
1053*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1054*795d594fSAndroid Build Coastguard Worker     try {
1055*795d594fSAndroid Build Coastguard Worker       hiddenOOB1(-2147483648);  // OOB
1056*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1057*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1058*795d594fSAndroid Build Coastguard Worker     }
1059*795d594fSAndroid Build Coastguard Worker     expectEquals(1001, sResult);
1060*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1061*795d594fSAndroid Build Coastguard Worker     try {
1062*795d594fSAndroid Build Coastguard Worker       hiddenOOB2(1);  // no OOB
1063*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1064*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1065*795d594fSAndroid Build Coastguard Worker     }
1066*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
1067*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1068*795d594fSAndroid Build Coastguard Worker     try {
1069*795d594fSAndroid Build Coastguard Worker       hiddenOOB3(-1);  // no OOB
1070*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1071*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1072*795d594fSAndroid Build Coastguard Worker     }
1073*795d594fSAndroid Build Coastguard Worker     expectEquals(11, sResult);
1074*795d594fSAndroid Build Coastguard Worker 
1075*795d594fSAndroid Build Coastguard Worker     // Expensive hidden OOB test.
1076*795d594fSAndroid Build Coastguard Worker     if (HEAVY) {
1077*795d594fSAndroid Build Coastguard Worker       sResult = 0;
1078*795d594fSAndroid Build Coastguard Worker       try {
1079*795d594fSAndroid Build Coastguard Worker         hiddenOOB2(2147483647);  // OOB
1080*795d594fSAndroid Build Coastguard Worker       } catch (ArrayIndexOutOfBoundsException e) {
1081*795d594fSAndroid Build Coastguard Worker         sResult += 1000;
1082*795d594fSAndroid Build Coastguard Worker       }
1083*795d594fSAndroid Build Coastguard Worker       expectEquals(1002, sResult);
1084*795d594fSAndroid Build Coastguard Worker       sResult = 0;
1085*795d594fSAndroid Build Coastguard Worker       try {
1086*795d594fSAndroid Build Coastguard Worker         hiddenOOB3(2147483647);  // OOB
1087*795d594fSAndroid Build Coastguard Worker       } catch (ArrayIndexOutOfBoundsException e) {
1088*795d594fSAndroid Build Coastguard Worker         sResult += 1000;
1089*795d594fSAndroid Build Coastguard Worker       }
1090*795d594fSAndroid Build Coastguard Worker       expectEquals(1011, sResult);
1091*795d594fSAndroid Build Coastguard Worker     }
1092*795d594fSAndroid Build Coastguard Worker 
1093*795d594fSAndroid Build Coastguard Worker     // More hidden OOB.
1094*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1095*795d594fSAndroid Build Coastguard Worker     try {
1096*795d594fSAndroid Build Coastguard Worker       hiddenInfiniteOOB();
1097*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1098*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1099*795d594fSAndroid Build Coastguard Worker     }
1100*795d594fSAndroid Build Coastguard Worker     expectEquals(1011, sResult);
1101*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1102*795d594fSAndroid Build Coastguard Worker     try {
1103*795d594fSAndroid Build Coastguard Worker       hiddenFiniteOOB();
1104*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1105*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1106*795d594fSAndroid Build Coastguard Worker     }
1107*795d594fSAndroid Build Coastguard Worker     expectEquals(1111, sResult);
1108*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1109*795d594fSAndroid Build Coastguard Worker     try {
1110*795d594fSAndroid Build Coastguard Worker       inductionOOB(a200);
1111*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1112*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1113*795d594fSAndroid Build Coastguard Worker     }
1114*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1115*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 200; i++) {
1116*795d594fSAndroid Build Coastguard Worker       expectEquals(i < 128 ? i : 0, a200[i]);
1117*795d594fSAndroid Build Coastguard Worker     }
1118*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1119*795d594fSAndroid Build Coastguard Worker     try {
1120*795d594fSAndroid Build Coastguard Worker       controlOOB(a200);
1121*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1122*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1123*795d594fSAndroid Build Coastguard Worker     }
1124*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1125*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 200; i++) {
1126*795d594fSAndroid Build Coastguard Worker       expectEquals(i < 128 ? -i : 0, a200[i]);
1127*795d594fSAndroid Build Coastguard Worker     }
1128*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1129*795d594fSAndroid Build Coastguard Worker     try {
1130*795d594fSAndroid Build Coastguard Worker       conversionOOB(a200);
1131*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1132*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1133*795d594fSAndroid Build Coastguard Worker     }
1134*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1135*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 200; i++) {
1136*795d594fSAndroid Build Coastguard Worker       expectEquals(i < 128 ? i : 0, a200[i]);
1137*795d594fSAndroid Build Coastguard Worker     }
1138*795d594fSAndroid Build Coastguard Worker 
1139*795d594fSAndroid Build Coastguard Worker     // No hoisting after BCE.
1140*795d594fSAndroid Build Coastguard Worker     expectEquals(110, doNotHoist(x));
1141*795d594fSAndroid Build Coastguard Worker 
1142*795d594fSAndroid Build Coastguard Worker     // Addition.
1143*795d594fSAndroid Build Coastguard Worker     {
1144*795d594fSAndroid Build Coastguard Worker       int[] e1 ={ 1, 2, 3, 4, 4, 4, 4, 3, 2, 1 };
1145*795d594fSAndroid Build Coastguard Worker       int[] a1 = add();
1146*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 10; i++) {
1147*795d594fSAndroid Build Coastguard Worker         expectEquals(a1[i], e1[i]);
1148*795d594fSAndroid Build Coastguard Worker       }
1149*795d594fSAndroid Build Coastguard Worker     }
1150*795d594fSAndroid Build Coastguard Worker 
1151*795d594fSAndroid Build Coastguard Worker     // Multiplication.
1152*795d594fSAndroid Build Coastguard Worker     {
1153*795d594fSAndroid Build Coastguard Worker       int[] e1 = { 7, 1, 2, 2, 1, 0, 2, 0, 0, 1 };
1154*795d594fSAndroid Build Coastguard Worker       int[] a1 = multiply1();
1155*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 10; i++) {
1156*795d594fSAndroid Build Coastguard Worker         expectEquals(a1[i], e1[i]);
1157*795d594fSAndroid Build Coastguard Worker       }
1158*795d594fSAndroid Build Coastguard Worker       int[] e2 = { 1001, 0, 0, 1, 0, 0, 1, 0, 0, 1 };
1159*795d594fSAndroid Build Coastguard Worker       int[] a2 = multiply2();
1160*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 10; i++) {
1161*795d594fSAndroid Build Coastguard Worker         expectEquals(a2[i], e2[i]);
1162*795d594fSAndroid Build Coastguard Worker       }
1163*795d594fSAndroid Build Coastguard Worker     }
1164*795d594fSAndroid Build Coastguard Worker 
1165*795d594fSAndroid Build Coastguard Worker     // Dynamic BCE.
1166*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1167*795d594fSAndroid Build Coastguard Worker     try {
1168*795d594fSAndroid Build Coastguard Worker       linearDynamicBCE1(x, -1, x.length);
1169*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1170*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1171*795d594fSAndroid Build Coastguard Worker     }
1172*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1173*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1174*795d594fSAndroid Build Coastguard Worker     linearDynamicBCE1(x, 0, x.length);
1175*795d594fSAndroid Build Coastguard Worker     expectEquals(55, sResult);
1176*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1177*795d594fSAndroid Build Coastguard Worker     try {
1178*795d594fSAndroid Build Coastguard Worker       linearDynamicBCE1(x, 0, x.length + 1);
1179*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1180*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1181*795d594fSAndroid Build Coastguard Worker     }
1182*795d594fSAndroid Build Coastguard Worker     expectEquals(1055, sResult);
1183*795d594fSAndroid Build Coastguard Worker 
1184*795d594fSAndroid Build Coastguard Worker     // Dynamic BCE with offset.
1185*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1186*795d594fSAndroid Build Coastguard Worker     try {
1187*795d594fSAndroid Build Coastguard Worker       linearDynamicBCE2(x, 0, x.length, -1);
1188*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1189*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1190*795d594fSAndroid Build Coastguard Worker     }
1191*795d594fSAndroid Build Coastguard Worker     expectEquals(1000, sResult);
1192*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1193*795d594fSAndroid Build Coastguard Worker     linearDynamicBCE2(x, 0, x.length, 0);
1194*795d594fSAndroid Build Coastguard Worker     expectEquals(55, sResult);
1195*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1196*795d594fSAndroid Build Coastguard Worker     try {
1197*795d594fSAndroid Build Coastguard Worker       linearDynamicBCE2(x, 0, x.length, 1);
1198*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1199*795d594fSAndroid Build Coastguard Worker       sResult += 1000;
1200*795d594fSAndroid Build Coastguard Worker     }
1201*795d594fSAndroid Build Coastguard Worker     expectEquals(1054, sResult);
1202*795d594fSAndroid Build Coastguard Worker 
1203*795d594fSAndroid Build Coastguard Worker     // Dynamic BCE candidates.
1204*795d594fSAndroid Build Coastguard Worker     expectEquals(55, wrapAroundDynamicBCE(x));
1205*795d594fSAndroid Build Coastguard Worker     expectEquals(15, periodicDynamicBCE(x));
1206*795d594fSAndroid Build Coastguard Worker     expectEquals(55, dynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1207*795d594fSAndroid Build Coastguard Worker     expectEquals(55, noDynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1208*795d594fSAndroid Build Coastguard Worker     expectEquals(55, noDynamicBCEMixedInductionTypes(x, 0, 10));
1209*795d594fSAndroid Build Coastguard Worker     expectEquals(125, dynamicBCEConstantRange(x));
1210*795d594fSAndroid Build Coastguard Worker 
1211*795d594fSAndroid Build Coastguard Worker     // Dynamic BCE combined with constant indices.
1212*795d594fSAndroid Build Coastguard Worker     int[][] a;
1213*795d594fSAndroid Build Coastguard Worker     a = new int[0][0];
1214*795d594fSAndroid Build Coastguard Worker     expectEquals(-1, dynamicBCEAndConstantIndices(x, a, 0, 10));
1215*795d594fSAndroid Build Coastguard Worker     a = new int[100][10];
1216*795d594fSAndroid Build Coastguard Worker     expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1217*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 10; i++) {
1218*795d594fSAndroid Build Coastguard Worker       expectEquals((i % 10) != 0 ? 1 : 0, a[1][i]);
1219*795d594fSAndroid Build Coastguard Worker       expectEquals((i % 10) != 0 ? 2 : 0, a[2][i]);
1220*795d594fSAndroid Build Coastguard Worker       expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]);
1221*795d594fSAndroid Build Coastguard Worker     }
1222*795d594fSAndroid Build Coastguard Worker     a = new int[3][10];
1223*795d594fSAndroid Build Coastguard Worker     sResult = 0;
1224*795d594fSAndroid Build Coastguard Worker     try {
1225*795d594fSAndroid Build Coastguard Worker       expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1226*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
1227*795d594fSAndroid Build Coastguard Worker       sResult = 1;
1228*795d594fSAndroid Build Coastguard Worker     }
1229*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
1230*795d594fSAndroid Build Coastguard Worker     expectEquals(a[1][1], 1);
1231*795d594fSAndroid Build Coastguard Worker     expectEquals(a[2][1], 2);
1232*795d594fSAndroid Build Coastguard Worker 
1233*795d594fSAndroid Build Coastguard Worker     // Dynamic BCE combined with constant indices of all types.
1234*795d594fSAndroid Build Coastguard Worker     boolean[] x1 = { true };
1235*795d594fSAndroid Build Coastguard Worker     byte[] x2 = { 2 };
1236*795d594fSAndroid Build Coastguard Worker     char[] x3 = { 3 };
1237*795d594fSAndroid Build Coastguard Worker     short[] x4 = { 4 };
1238*795d594fSAndroid Build Coastguard Worker     int[] x5 = { 5 };
1239*795d594fSAndroid Build Coastguard Worker     long[] x6 = { 6 };
1240*795d594fSAndroid Build Coastguard Worker     float[] x7 = { 7 };
1241*795d594fSAndroid Build Coastguard Worker     double[] x8 = { 8 };
1242*795d594fSAndroid Build Coastguard Worker     expectEquals(415,
1243*795d594fSAndroid Build Coastguard Worker         dynamicBCEAndConstantIndicesAllPrimTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, 0, 10));
1244*795d594fSAndroid Build Coastguard Worker     Integer[] x9 = { 9 };
1245*795d594fSAndroid Build Coastguard Worker     expectEquals(145, dynamicBCEAndConstantIndexRefType(x, x9, 0, 10));
1246*795d594fSAndroid Build Coastguard Worker 
1247*795d594fSAndroid Build Coastguard Worker     expectEquals(99, shortIndex(x));
1248*795d594fSAndroid Build Coastguard Worker 
1249*795d594fSAndroid Build Coastguard Worker     System.out.println("passed");
1250*795d594fSAndroid Build Coastguard Worker   }
1251*795d594fSAndroid Build Coastguard Worker 
1252*795d594fSAndroid Build Coastguard Worker   private static void expectEquals(int expected, int result) {
1253*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
1254*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
1255*795d594fSAndroid Build Coastguard Worker     }
1256*795d594fSAndroid Build Coastguard Worker   }
1257*795d594fSAndroid Build Coastguard Worker }
1258