xref: /aosp_15_r20/art/test/530-checker-loops1/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 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: int Main.linear(int[]) BCE (before)
29*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
30*795d594fSAndroid Build Coastguard Worker   //
31*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linear(int[]) BCE (after)
32*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
33*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linear(int[] x)34*795d594fSAndroid Build Coastguard Worker   private static int linear(int[] x) {
35*795d594fSAndroid Build Coastguard Worker     int result = 0;
36*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; i++) {
37*795d594fSAndroid Build Coastguard Worker       result += x[i];
38*795d594fSAndroid Build Coastguard Worker     }
39*795d594fSAndroid Build Coastguard Worker     return result;
40*795d594fSAndroid Build Coastguard Worker   }
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDown(int[]) BCE (before)
43*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
44*795d594fSAndroid Build Coastguard Worker   //
45*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDown(int[]) BCE (after)
46*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
47*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearDown(int[] x)48*795d594fSAndroid Build Coastguard Worker   private static int linearDown(int[] x) {
49*795d594fSAndroid Build Coastguard Worker     int result = 0;
50*795d594fSAndroid Build Coastguard Worker     for (int i = x.length - 1; i >= 0; i--) {
51*795d594fSAndroid Build Coastguard Worker       result += x[i];
52*795d594fSAndroid Build Coastguard Worker     }
53*795d594fSAndroid Build Coastguard Worker     return result;
54*795d594fSAndroid Build Coastguard Worker   }
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
57*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
58*795d594fSAndroid Build Coastguard Worker   //
59*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
60*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
61*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearObscure(int[] x)62*795d594fSAndroid Build Coastguard Worker   private static int linearObscure(int[] x) {
63*795d594fSAndroid Build Coastguard Worker     int result = 0;
64*795d594fSAndroid Build Coastguard Worker     for (int i = x.length - 1; i >= 0; i--) {
65*795d594fSAndroid Build Coastguard Worker       int k = i + 5;
66*795d594fSAndroid Build Coastguard Worker       result += x[k - 5];
67*795d594fSAndroid Build Coastguard Worker     }
68*795d594fSAndroid Build Coastguard Worker     return result;
69*795d594fSAndroid Build Coastguard Worker   }
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
72*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
73*795d594fSAndroid Build Coastguard Worker   //
74*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
75*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
76*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearVeryObscure(int[] x)77*795d594fSAndroid Build Coastguard Worker   private static int linearVeryObscure(int[] x) {
78*795d594fSAndroid Build Coastguard Worker     int result = 0;
79*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; i++) {
80*795d594fSAndroid Build Coastguard Worker       int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
81*795d594fSAndroid Build Coastguard Worker       result += x[k - 5];
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.hiddenStride(int[]) BCE (before)
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
88*795d594fSAndroid Build Coastguard Worker   //
89*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.hiddenStride(int[]) BCE (after)
90*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
91*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
hiddenStride(int[] a)92*795d594fSAndroid Build Coastguard Worker   static int hiddenStride(int[] a) {
93*795d594fSAndroid Build Coastguard Worker     int result = 0;
94*795d594fSAndroid Build Coastguard Worker     for (int i = 1; i <= 1; i++) {
95*795d594fSAndroid Build Coastguard Worker       // Obscured unit stride.
96*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < a.length; j += i) {
97*795d594fSAndroid Build Coastguard Worker         result += a[j];
98*795d594fSAndroid Build Coastguard Worker       }
99*795d594fSAndroid Build Coastguard Worker     }
100*795d594fSAndroid Build Coastguard Worker     return result;
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
105*795d594fSAndroid Build Coastguard Worker   //
106*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
107*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
108*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWhile(int[] x)109*795d594fSAndroid Build Coastguard Worker   private static int linearWhile(int[] x) {
110*795d594fSAndroid Build Coastguard Worker     int i = 0;
111*795d594fSAndroid Build Coastguard Worker     int result = 0;
112*795d594fSAndroid Build Coastguard Worker     while (i < x.length) {
113*795d594fSAndroid Build Coastguard Worker       result += x[i++];
114*795d594fSAndroid Build Coastguard Worker     }
115*795d594fSAndroid Build Coastguard Worker     return result;
116*795d594fSAndroid Build Coastguard Worker   }
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
119*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
120*795d594fSAndroid Build Coastguard Worker   //
121*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
122*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
123*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearThreeWayPhi(int[] x)124*795d594fSAndroid Build Coastguard Worker   private static int linearThreeWayPhi(int[] x) {
125*795d594fSAndroid Build Coastguard Worker     int result = 0;
126*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; ) {
127*795d594fSAndroid Build Coastguard Worker       if (x[i] == 5) {
128*795d594fSAndroid Build Coastguard Worker         i++;
129*795d594fSAndroid Build Coastguard Worker         continue;
130*795d594fSAndroid Build Coastguard Worker       }
131*795d594fSAndroid Build Coastguard Worker       result += x[i++];
132*795d594fSAndroid Build Coastguard Worker     }
133*795d594fSAndroid Build Coastguard Worker     return result;
134*795d594fSAndroid Build Coastguard Worker   }
135*795d594fSAndroid Build Coastguard Worker 
136*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
137*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
138*795d594fSAndroid Build Coastguard Worker   //
139*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
140*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
141*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearFourWayPhi(int[] x)142*795d594fSAndroid Build Coastguard Worker   private static int linearFourWayPhi(int[] x) {
143*795d594fSAndroid Build Coastguard Worker     int result = 0;
144*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; ) {
145*795d594fSAndroid Build Coastguard Worker       if (x[i] == 5) {
146*795d594fSAndroid Build Coastguard Worker         i++;
147*795d594fSAndroid Build Coastguard Worker         continue;
148*795d594fSAndroid Build Coastguard Worker       } else if (x[i] == 6) {
149*795d594fSAndroid Build Coastguard Worker         i++;
150*795d594fSAndroid Build Coastguard Worker         result += 7;
151*795d594fSAndroid Build Coastguard Worker         continue;
152*795d594fSAndroid Build Coastguard Worker       }
153*795d594fSAndroid Build Coastguard Worker       result += x[i++];
154*795d594fSAndroid Build Coastguard Worker     }
155*795d594fSAndroid Build Coastguard Worker     return result;
156*795d594fSAndroid Build Coastguard Worker   }
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
159*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
160*795d594fSAndroid Build Coastguard Worker   //
161*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
162*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
163*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
wrapAroundThenLinear(int[] x)164*795d594fSAndroid Build Coastguard Worker   private static int wrapAroundThenLinear(int[] x) {
165*795d594fSAndroid Build Coastguard Worker     // Loop with wrap around (length - 1, 0, 1, 2, ..).
166*795d594fSAndroid Build Coastguard Worker     int w = x.length - 1;
167*795d594fSAndroid Build Coastguard Worker     int result = 0;
168*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; i++) {
169*795d594fSAndroid Build Coastguard Worker       result += x[w];
170*795d594fSAndroid Build Coastguard Worker       w = i;
171*795d594fSAndroid Build Coastguard Worker     }
172*795d594fSAndroid Build Coastguard Worker     return result;
173*795d594fSAndroid Build Coastguard Worker   }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
176*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
177*795d594fSAndroid Build Coastguard Worker   //
178*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
179*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
180*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
wrapAroundThenLinearThreeWayPhi(int[] x)181*795d594fSAndroid Build Coastguard Worker   private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
182*795d594fSAndroid Build Coastguard Worker     // Loop with wrap around (length - 1, 0, 1, 2, ..).
183*795d594fSAndroid Build Coastguard Worker     int w = x.length - 1;
184*795d594fSAndroid Build Coastguard Worker     int result = 0;
185*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; ) {
186*795d594fSAndroid Build Coastguard Worker        if (x[w] == 1) {
187*795d594fSAndroid Build Coastguard Worker          w = i++;
188*795d594fSAndroid Build Coastguard Worker          continue;
189*795d594fSAndroid Build Coastguard Worker        }
190*795d594fSAndroid Build Coastguard Worker        result += x[w];
191*795d594fSAndroid Build Coastguard Worker        w = i++;
192*795d594fSAndroid Build Coastguard Worker     }
193*795d594fSAndroid Build Coastguard Worker     return result;
194*795d594fSAndroid Build Coastguard Worker   }
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
197*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
198*795d594fSAndroid Build Coastguard Worker   //
199*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
200*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithParameter(int n)202*795d594fSAndroid Build Coastguard Worker   private static int[] linearWithParameter(int n) {
203*795d594fSAndroid Build Coastguard Worker     int[] x = new int[n];
204*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
205*795d594fSAndroid Build Coastguard Worker       x[i] = i;
206*795d594fSAndroid Build Coastguard Worker     }
207*795d594fSAndroid Build Coastguard Worker     return x;
208*795d594fSAndroid Build Coastguard Worker   }
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
211*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
212*795d594fSAndroid Build Coastguard Worker   //
213*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
214*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
215*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearCopy(int x[])216*795d594fSAndroid Build Coastguard Worker   private static int[] linearCopy(int x[]) {
217*795d594fSAndroid Build Coastguard Worker     int n = x.length;
218*795d594fSAndroid Build Coastguard Worker     int y[] = new int[n];
219*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
220*795d594fSAndroid Build Coastguard Worker       y[i] = x[i];
221*795d594fSAndroid Build Coastguard Worker     }
222*795d594fSAndroid Build Coastguard Worker     return y;
223*795d594fSAndroid Build Coastguard Worker   }
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwo(int[]) BCE (before)
226*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
227*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
228*795d594fSAndroid Build Coastguard Worker   //
229*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwo(int[]) BCE (after)
230*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
231*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearByTwo(int x[])232*795d594fSAndroid Build Coastguard Worker   private static int linearByTwo(int x[]) {
233*795d594fSAndroid Build Coastguard Worker     int n = x.length / 2;
234*795d594fSAndroid Build Coastguard Worker     int result = 0;
235*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
236*795d594fSAndroid Build Coastguard Worker       int ii = i << 1;
237*795d594fSAndroid Build Coastguard Worker       result += x[ii];
238*795d594fSAndroid Build Coastguard Worker       result += x[ii + 1];
239*795d594fSAndroid Build Coastguard Worker     }
240*795d594fSAndroid Build Coastguard Worker     return result;
241*795d594fSAndroid Build Coastguard Worker   }
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (before)
244*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
245*795d594fSAndroid Build Coastguard Worker   //
246*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (after)
247*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
248*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearByTwoSkip1(int x[])249*795d594fSAndroid Build Coastguard Worker   private static int linearByTwoSkip1(int x[]) {
250*795d594fSAndroid Build Coastguard Worker     int result = 0;
251*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length / 2; i++) {
252*795d594fSAndroid Build Coastguard Worker       result += x[2 * i];
253*795d594fSAndroid Build Coastguard Worker     }
254*795d594fSAndroid Build Coastguard Worker     return result;
255*795d594fSAndroid Build Coastguard Worker   }
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (before)
258*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
259*795d594fSAndroid Build Coastguard Worker   //
260*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
261*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
262*795d594fSAndroid Build Coastguard Worker   //
263*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
264*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearByTwoSkip2(int x[])265*795d594fSAndroid Build Coastguard Worker   private static int linearByTwoSkip2(int x[]) {
266*795d594fSAndroid Build Coastguard Worker     int result = 0;
267*795d594fSAndroid Build Coastguard Worker     // This case is not optimized.
268*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < x.length; i+=2) {
269*795d594fSAndroid Build Coastguard Worker       result += x[i];
270*795d594fSAndroid Build Coastguard Worker     }
271*795d594fSAndroid Build Coastguard Worker     return result;
272*795d594fSAndroid Build Coastguard Worker   }
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
275*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
276*795d594fSAndroid Build Coastguard Worker   //
277*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
278*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
279*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithCompoundStride()280*795d594fSAndroid Build Coastguard Worker   private static int linearWithCompoundStride() {
281*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
282*795d594fSAndroid Build Coastguard Worker     int result = 0;
283*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i <= 12; ) {
284*795d594fSAndroid Build Coastguard Worker       i++;
285*795d594fSAndroid Build Coastguard Worker       result += x[i];
286*795d594fSAndroid Build Coastguard Worker       i++;
287*795d594fSAndroid Build Coastguard Worker     }
288*795d594fSAndroid Build Coastguard Worker     return result;
289*795d594fSAndroid Build Coastguard Worker   }
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
292*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
293*795d594fSAndroid Build Coastguard Worker   //
294*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
295*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
296*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithLargePositiveStride()297*795d594fSAndroid Build Coastguard Worker   private static int linearWithLargePositiveStride() {
298*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
299*795d594fSAndroid Build Coastguard Worker     int result = 0;
300*795d594fSAndroid Build Coastguard Worker     int k = 0;
301*795d594fSAndroid Build Coastguard Worker     // Range analysis has no problem with a trip-count defined by a
302*795d594fSAndroid Build Coastguard Worker     // reasonably large positive stride far away from upper bound.
303*795d594fSAndroid Build Coastguard Worker     for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
304*795d594fSAndroid Build Coastguard Worker       result += x[k++];
305*795d594fSAndroid Build Coastguard Worker     }
306*795d594fSAndroid Build Coastguard Worker     return result;
307*795d594fSAndroid Build Coastguard Worker   }
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
310*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
311*795d594fSAndroid Build Coastguard Worker   //
312*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
313*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
314*795d594fSAndroid Build Coastguard Worker   //
315*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
316*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithVeryLargePositiveStride()317*795d594fSAndroid Build Coastguard Worker   private static int linearWithVeryLargePositiveStride() {
318*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
319*795d594fSAndroid Build Coastguard Worker     int result = 0;
320*795d594fSAndroid Build Coastguard Worker     int k = 0;
321*795d594fSAndroid Build Coastguard Worker     // Range analysis conservatively bails due to potential of wrap-around
322*795d594fSAndroid Build Coastguard Worker     // arithmetic while computing the trip-count for this very large stride.
323*795d594fSAndroid Build Coastguard Worker     for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
324*795d594fSAndroid Build Coastguard Worker       result += x[k++];
325*795d594fSAndroid Build Coastguard Worker     }
326*795d594fSAndroid Build Coastguard Worker     return result;
327*795d594fSAndroid Build Coastguard Worker   }
328*795d594fSAndroid Build Coastguard Worker 
329*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
330*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
331*795d594fSAndroid Build Coastguard Worker   //
332*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
333*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
334*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithLargeNegativeStride()335*795d594fSAndroid Build Coastguard Worker   private static int linearWithLargeNegativeStride() {
336*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
337*795d594fSAndroid Build Coastguard Worker     int result = 0;
338*795d594fSAndroid Build Coastguard Worker     int k = 0;
339*795d594fSAndroid Build Coastguard Worker     // Range analysis has no problem with a trip-count defined by a
340*795d594fSAndroid Build Coastguard Worker     // reasonably large negative stride far away from lower bound.
341*795d594fSAndroid Build Coastguard Worker     for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
342*795d594fSAndroid Build Coastguard Worker       result += x[k++];
343*795d594fSAndroid Build Coastguard Worker     }
344*795d594fSAndroid Build Coastguard Worker     return result;
345*795d594fSAndroid Build Coastguard Worker   }
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
348*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
349*795d594fSAndroid Build Coastguard Worker   //
350*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
351*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
352*795d594fSAndroid Build Coastguard Worker   //
353*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
354*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearWithVeryLargeNegativeStride()355*795d594fSAndroid Build Coastguard Worker   private static int linearWithVeryLargeNegativeStride() {
356*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
357*795d594fSAndroid Build Coastguard Worker     int result = 0;
358*795d594fSAndroid Build Coastguard Worker     int k = 0;
359*795d594fSAndroid Build Coastguard Worker     // Range analysis conservatively bails due to potential of wrap-around
360*795d594fSAndroid Build Coastguard Worker     // arithmetic while computing the trip-count for this very large stride.
361*795d594fSAndroid Build Coastguard Worker     for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
362*795d594fSAndroid Build Coastguard Worker       result += x[k++];
363*795d594fSAndroid Build Coastguard Worker     }
364*795d594fSAndroid Build Coastguard Worker     return result;
365*795d594fSAndroid Build Coastguard Worker   }
366*795d594fSAndroid Build Coastguard Worker 
367*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEUp() BCE (before)
368*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
369*795d594fSAndroid Build Coastguard Worker   //
370*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEUp() BCE (after)
371*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
372*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearForNEUp()373*795d594fSAndroid Build Coastguard Worker   private static int linearForNEUp() {
374*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
375*795d594fSAndroid Build Coastguard Worker     int result = 0;
376*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i != 10; i++) {
377*795d594fSAndroid Build Coastguard Worker       result += x[i];
378*795d594fSAndroid Build Coastguard Worker     }
379*795d594fSAndroid Build Coastguard Worker     return result;
380*795d594fSAndroid Build Coastguard Worker   }
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEDown() BCE (before)
383*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
384*795d594fSAndroid Build Coastguard Worker   //
385*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEDown() BCE (after)
386*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
387*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearForNEDown()388*795d594fSAndroid Build Coastguard Worker   private static int linearForNEDown() {
389*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
390*795d594fSAndroid Build Coastguard Worker     int result = 0;
391*795d594fSAndroid Build Coastguard Worker     for (int i = 9; i != -1; i--) {
392*795d594fSAndroid Build Coastguard Worker       result += x[i];
393*795d594fSAndroid Build Coastguard Worker     }
394*795d594fSAndroid Build Coastguard Worker     return result;
395*795d594fSAndroid Build Coastguard Worker   }
396*795d594fSAndroid Build Coastguard Worker 
397*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (before)
398*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
399*795d594fSAndroid Build Coastguard Worker   //
400*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEArrayLengthUp(int[]) BCE (after)
401*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
402*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearForNEArrayLengthUp(int[] x)403*795d594fSAndroid Build Coastguard Worker   private static int linearForNEArrayLengthUp(int[] x) {
404*795d594fSAndroid Build Coastguard Worker     int result = 0;
405*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i != x.length; i++) {
406*795d594fSAndroid Build Coastguard Worker       result += x[i];
407*795d594fSAndroid Build Coastguard Worker     }
408*795d594fSAndroid Build Coastguard Worker     return result;
409*795d594fSAndroid Build Coastguard Worker   }
410*795d594fSAndroid Build Coastguard Worker 
411*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (before)
412*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
413*795d594fSAndroid Build Coastguard Worker   //
414*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearForNEArrayLengthDown(int[]) BCE (after)
415*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
416*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearForNEArrayLengthDown(int[] x)417*795d594fSAndroid Build Coastguard Worker   private static int linearForNEArrayLengthDown(int[] x) {
418*795d594fSAndroid Build Coastguard Worker     int result = 0;
419*795d594fSAndroid Build Coastguard Worker     for (int i = x.length - 1; i != -1; i--) {
420*795d594fSAndroid Build Coastguard Worker       result += x[i];
421*795d594fSAndroid Build Coastguard Worker     }
422*795d594fSAndroid Build Coastguard Worker     return result;
423*795d594fSAndroid Build Coastguard Worker   }
424*795d594fSAndroid Build Coastguard Worker 
425*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
426*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
427*795d594fSAndroid Build Coastguard Worker   //
428*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
429*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
430*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearDoWhileUp()431*795d594fSAndroid Build Coastguard Worker   private static int linearDoWhileUp() {
432*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
433*795d594fSAndroid Build Coastguard Worker     int result = 0;
434*795d594fSAndroid Build Coastguard Worker     int i = 0;
435*795d594fSAndroid Build Coastguard Worker     do {
436*795d594fSAndroid Build Coastguard Worker       result += x[i++];
437*795d594fSAndroid Build Coastguard Worker     } while (i < 10);
438*795d594fSAndroid Build Coastguard Worker     return result;
439*795d594fSAndroid Build Coastguard Worker   }
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
442*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
443*795d594fSAndroid Build Coastguard Worker   //
444*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
445*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
446*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearDoWhileDown()447*795d594fSAndroid Build Coastguard Worker   private static int linearDoWhileDown() {
448*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
449*795d594fSAndroid Build Coastguard Worker     int result = 0;
450*795d594fSAndroid Build Coastguard Worker     int i = 9;
451*795d594fSAndroid Build Coastguard Worker     do {
452*795d594fSAndroid Build Coastguard Worker       result += x[i--];
453*795d594fSAndroid Build Coastguard Worker     } while (0 <= i);
454*795d594fSAndroid Build Coastguard Worker     return result;
455*795d594fSAndroid Build Coastguard Worker   }
456*795d594fSAndroid Build Coastguard Worker 
457*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearLong() BCE (before)
458*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
459*795d594fSAndroid Build Coastguard Worker   //
460*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearLong() BCE (after)
461*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
462*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearLong()463*795d594fSAndroid Build Coastguard Worker   private static int linearLong() {
464*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
465*795d594fSAndroid Build Coastguard Worker     int result = 0;
466*795d594fSAndroid Build Coastguard Worker     // Induction on constant interval is done in higher precision than necessary,
467*795d594fSAndroid Build Coastguard Worker     // but truncated at the use as subscript.
468*795d594fSAndroid Build Coastguard Worker     for (long i = 0; i < 10; i++) {
469*795d594fSAndroid Build Coastguard Worker       result += x[(int)i];
470*795d594fSAndroid Build Coastguard Worker     }
471*795d594fSAndroid Build Coastguard Worker     return result;
472*795d594fSAndroid Build Coastguard Worker   }
473*795d594fSAndroid Build Coastguard Worker 
474*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearLongAlt(int[]) BCE (before)
475*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
476*795d594fSAndroid Build Coastguard Worker   //
477*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearLongAlt(int[]) BCE (after)
478*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
479*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearLongAlt(int[] x)480*795d594fSAndroid Build Coastguard Worker   private static int linearLongAlt(int[] x) {
481*795d594fSAndroid Build Coastguard Worker     int result = 0;
482*795d594fSAndroid Build Coastguard Worker     // Induction on array length is done in higher precision than necessary,
483*795d594fSAndroid Build Coastguard Worker     // but truncated at the use as subscript.
484*795d594fSAndroid Build Coastguard Worker     for (long i = 0; i < x.length; i++) {
485*795d594fSAndroid Build Coastguard Worker       result += x[(int)i];
486*795d594fSAndroid Build Coastguard Worker     }
487*795d594fSAndroid Build Coastguard Worker     return result;
488*795d594fSAndroid Build Coastguard Worker   }
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearShort() BCE (before)
491*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
492*795d594fSAndroid Build Coastguard Worker   //
493*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearShort() BCE (after)
494*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
495*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearShort()496*795d594fSAndroid Build Coastguard Worker   private static int linearShort() {
497*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
498*795d594fSAndroid Build Coastguard Worker     int result = 0;
499*795d594fSAndroid Build Coastguard Worker     // Induction is done in short precision, but fits.
500*795d594fSAndroid Build Coastguard Worker     for (short i = 0; i < 10; i++) {
501*795d594fSAndroid Build Coastguard Worker       result += x[i];
502*795d594fSAndroid Build Coastguard Worker     }
503*795d594fSAndroid Build Coastguard Worker     return result;
504*795d594fSAndroid Build Coastguard Worker   }
505*795d594fSAndroid Build Coastguard Worker 
506*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearChar() BCE (before)
507*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
508*795d594fSAndroid Build Coastguard Worker   //
509*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearChar() BCE (after)
510*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
511*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearChar()512*795d594fSAndroid Build Coastguard Worker   private static int linearChar() {
513*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
514*795d594fSAndroid Build Coastguard Worker     int result = 0;
515*795d594fSAndroid Build Coastguard Worker     // Induction is done in char precision, but fits.
516*795d594fSAndroid Build Coastguard Worker     for (char i = 0; i < 10; i++) {
517*795d594fSAndroid Build Coastguard Worker       result += x[i];
518*795d594fSAndroid Build Coastguard Worker     }
519*795d594fSAndroid Build Coastguard Worker     return result;
520*795d594fSAndroid Build Coastguard Worker   }
521*795d594fSAndroid Build Coastguard Worker 
522*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByte() BCE (before)
523*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
524*795d594fSAndroid Build Coastguard Worker   //
525*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.linearByte() BCE (after)
526*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
527*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearByte()528*795d594fSAndroid Build Coastguard Worker   private static int linearByte() {
529*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
530*795d594fSAndroid Build Coastguard Worker     int result = 0;
531*795d594fSAndroid Build Coastguard Worker     // Induction is done in byte precision, but fits.
532*795d594fSAndroid Build Coastguard Worker     for (byte i = 0; i < 10; i++) {
533*795d594fSAndroid Build Coastguard Worker       result += x[i];
534*795d594fSAndroid Build Coastguard Worker     }
535*795d594fSAndroid Build Coastguard Worker     return result;
536*795d594fSAndroid Build Coastguard Worker   }
537*795d594fSAndroid Build Coastguard Worker 
538*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before)
539*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
540*795d594fSAndroid Build Coastguard Worker   //
541*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after)
542*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
543*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
invariantFromPreLoop(int[] x, int y)544*795d594fSAndroid Build Coastguard Worker   private static int invariantFromPreLoop(int[] x, int y) {
545*795d594fSAndroid Build Coastguard Worker     int result = 0;
546*795d594fSAndroid Build Coastguard Worker     // Strange pre-loop that sets upper bound.
547*795d594fSAndroid Build Coastguard Worker     int hi;
548*795d594fSAndroid Build Coastguard Worker     while (true) {
549*795d594fSAndroid Build Coastguard Worker       y = y % 3;
550*795d594fSAndroid Build Coastguard Worker       hi = x.length;
551*795d594fSAndroid Build Coastguard Worker       if (y != 123) break;
552*795d594fSAndroid Build Coastguard Worker     }
553*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < hi; i++) {
554*795d594fSAndroid Build Coastguard Worker        result += x[i];
555*795d594fSAndroid Build Coastguard Worker     }
556*795d594fSAndroid Build Coastguard Worker     return result;
557*795d594fSAndroid Build Coastguard Worker   }
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (before)
560*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
561*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
562*795d594fSAndroid Build Coastguard Worker   //
563*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after)
564*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
565*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularOnTwoArrayLengths(int n)566*795d594fSAndroid Build Coastguard Worker   private static void linearTriangularOnTwoArrayLengths(int n) {
567*795d594fSAndroid Build Coastguard Worker     int[] a = new int[n];
568*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
569*795d594fSAndroid Build Coastguard Worker       int[] b = new int[i];
570*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < b.length; j++) {
571*795d594fSAndroid Build Coastguard Worker         // Need to know j < b.length < a.length for static bce.
572*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
573*795d594fSAndroid Build Coastguard Worker         // Need to know just j < b.length for static bce.
574*795d594fSAndroid Build Coastguard Worker         b[j] += 1;
575*795d594fSAndroid Build Coastguard Worker       }
576*795d594fSAndroid Build Coastguard Worker       verifyTriangular(a, b, i, n);
577*795d594fSAndroid Build Coastguard Worker     }
578*795d594fSAndroid Build Coastguard Worker   }
579*795d594fSAndroid Build Coastguard Worker 
580*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (before)
581*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
582*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
583*795d594fSAndroid Build Coastguard Worker   //
584*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (after)
585*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
586*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularOnOneArrayLength(int n)587*795d594fSAndroid Build Coastguard Worker   private static void linearTriangularOnOneArrayLength(int n) {
588*795d594fSAndroid Build Coastguard Worker     int[] a = new int[n];
589*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
590*795d594fSAndroid Build Coastguard Worker       int[] b = new int[i];
591*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < i; j++) {
592*795d594fSAndroid Build Coastguard Worker         // Need to know j < i < a.length for static bce.
593*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
594*795d594fSAndroid Build Coastguard Worker         // Need to know just j < i for static bce.
595*795d594fSAndroid Build Coastguard Worker         b[j] += 1;
596*795d594fSAndroid Build Coastguard Worker       }
597*795d594fSAndroid Build Coastguard Worker       verifyTriangular(a, b, i, n);
598*795d594fSAndroid Build Coastguard Worker     }
599*795d594fSAndroid Build Coastguard Worker   }
600*795d594fSAndroid Build Coastguard Worker 
601*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (before)
602*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
603*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
604*795d594fSAndroid Build Coastguard Worker   //
605*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after)
606*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
607*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularOnParameter(int n)608*795d594fSAndroid Build Coastguard Worker   private static void linearTriangularOnParameter(int n) {
609*795d594fSAndroid Build Coastguard Worker     int[] a = new int[n];
610*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
611*795d594fSAndroid Build Coastguard Worker       int[] b = new int[i];
612*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < i; j++) {
613*795d594fSAndroid Build Coastguard Worker         // Need to know j < i < n for static bce.
614*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
615*795d594fSAndroid Build Coastguard Worker         // Need to know just j < i for static bce.
616*795d594fSAndroid Build Coastguard Worker         b[j] += 1;
617*795d594fSAndroid Build Coastguard Worker       }
618*795d594fSAndroid Build Coastguard Worker       verifyTriangular(a, b, i, n);
619*795d594fSAndroid Build Coastguard Worker     }
620*795d594fSAndroid Build Coastguard Worker   }
621*795d594fSAndroid Build Coastguard Worker 
622*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (before)
623*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
624*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
625*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
626*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
627*795d594fSAndroid Build Coastguard Worker   //
628*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularStrictLower(int) BCE (after)
629*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
630*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularStrictLower(int n)631*795d594fSAndroid Build Coastguard Worker   private static void linearTriangularStrictLower(int n) {
632*795d594fSAndroid Build Coastguard Worker     int[] a = new int[n];
633*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
634*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j < i; j++) {
635*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
636*795d594fSAndroid Build Coastguard Worker       }
637*795d594fSAndroid Build Coastguard Worker       for (int j = i - 1; j >= 0; j--) {
638*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
639*795d594fSAndroid Build Coastguard Worker       }
640*795d594fSAndroid Build Coastguard Worker       for (int j = i; j < n; j++) {
641*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
642*795d594fSAndroid Build Coastguard Worker       }
643*795d594fSAndroid Build Coastguard Worker       for (int j = n - 1; j >= i; j--) {
644*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
645*795d594fSAndroid Build Coastguard Worker       }
646*795d594fSAndroid Build Coastguard Worker     }
647*795d594fSAndroid Build Coastguard Worker     verifyTriangular(a);
648*795d594fSAndroid Build Coastguard Worker   }
649*795d594fSAndroid Build Coastguard Worker 
650*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (before)
651*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
652*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
653*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
654*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
655*795d594fSAndroid Build Coastguard Worker   //
656*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.linearTriangularStrictUpper(int) BCE (after)
657*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: BoundsCheck
658*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularStrictUpper(int n)659*795d594fSAndroid Build Coastguard Worker   private static void linearTriangularStrictUpper(int n) {
660*795d594fSAndroid Build Coastguard Worker     int[] a = new int[n];
661*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
662*795d594fSAndroid Build Coastguard Worker       for (int j = 0; j <= i; j++) {
663*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
664*795d594fSAndroid Build Coastguard Worker       }
665*795d594fSAndroid Build Coastguard Worker       for (int j = i; j >= 0; j--) {
666*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
667*795d594fSAndroid Build Coastguard Worker       }
668*795d594fSAndroid Build Coastguard Worker       for (int j = i + 1; j < n; j++) {
669*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
670*795d594fSAndroid Build Coastguard Worker       }
671*795d594fSAndroid Build Coastguard Worker       for (int j = n - 1; j >= i + 1; j--) {
672*795d594fSAndroid Build Coastguard Worker         a[j] += 1;
673*795d594fSAndroid Build Coastguard Worker       }
674*795d594fSAndroid Build Coastguard Worker     }
675*795d594fSAndroid Build Coastguard Worker     verifyTriangular(a);
676*795d594fSAndroid Build Coastguard Worker   }
677*795d594fSAndroid Build Coastguard Worker 
678*795d594fSAndroid Build Coastguard Worker   // Verifier for triangular loops.
verifyTriangular(int[] a, int[] b, int m, int n)679*795d594fSAndroid Build Coastguard Worker   private static void verifyTriangular(int[] a, int[] b, int m, int n) {
680*795d594fSAndroid Build Coastguard Worker     expectEquals(n, a.length);
681*795d594fSAndroid Build Coastguard Worker     for (int i = 0, k = m; i < n; i++) {
682*795d594fSAndroid Build Coastguard Worker       expectEquals(a[i], k);
683*795d594fSAndroid Build Coastguard Worker       if (k > 0) k--;
684*795d594fSAndroid Build Coastguard Worker     }
685*795d594fSAndroid Build Coastguard Worker     expectEquals(m, b.length);
686*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < m; i++) {
687*795d594fSAndroid Build Coastguard Worker       expectEquals(b[i], 1);
688*795d594fSAndroid Build Coastguard Worker     }
689*795d594fSAndroid Build Coastguard Worker   }
690*795d594fSAndroid Build Coastguard Worker 
691*795d594fSAndroid Build Coastguard Worker   // Verifier for triangular loops.
verifyTriangular(int[] a)692*795d594fSAndroid Build Coastguard Worker   private static void verifyTriangular(int[] a) {
693*795d594fSAndroid Build Coastguard Worker     int n = a.length;
694*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < n; i++) {
695*795d594fSAndroid Build Coastguard Worker       expectEquals(a[i], n + n);
696*795d594fSAndroid Build Coastguard Worker     }
697*795d594fSAndroid Build Coastguard Worker   }
698*795d594fSAndroid Build Coastguard Worker 
699*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearTriangularOOB() BCE (before)
700*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
701*795d594fSAndroid Build Coastguard Worker   //
702*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after)
703*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: BoundsCheck
704*795d594fSAndroid Build Coastguard Worker   //
705*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: int[] Main.linearTriangularOOB() BCE (after)
706*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: Deoptimize
linearTriangularOOB()707*795d594fSAndroid Build Coastguard Worker   private static int[] linearTriangularOOB() {
708*795d594fSAndroid Build Coastguard Worker     int[] a = new int[200];
709*795d594fSAndroid Build Coastguard Worker     try {
710*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 200; i++) {
711*795d594fSAndroid Build Coastguard Worker         // Lower bound must be recognized as lower precision induction with arithmetic
712*795d594fSAndroid Build Coastguard Worker         // wrap-around to -128 when i exceeds 127.
713*795d594fSAndroid Build Coastguard Worker         for (int j = (byte) i; j < 200; j++) {
714*795d594fSAndroid Build Coastguard Worker           a[j] += 1;
715*795d594fSAndroid Build Coastguard Worker         }
716*795d594fSAndroid Build Coastguard Worker       }
717*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException e) {
718*795d594fSAndroid Build Coastguard Worker       return a;
719*795d594fSAndroid Build Coastguard Worker     }
720*795d594fSAndroid Build Coastguard Worker     return null;  // failure if this is reached
721*795d594fSAndroid Build Coastguard Worker   }
722*795d594fSAndroid Build Coastguard Worker 
723*795d594fSAndroid Build Coastguard Worker   //
724*795d594fSAndroid Build Coastguard Worker   // Verifier.
725*795d594fSAndroid Build Coastguard Worker   //
726*795d594fSAndroid Build Coastguard Worker 
main(String[] args)727*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
728*795d594fSAndroid Build Coastguard Worker     int[] empty = { };
729*795d594fSAndroid Build Coastguard Worker     int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
730*795d594fSAndroid Build Coastguard Worker 
731*795d594fSAndroid Build Coastguard Worker     // Linear and wrap-around.
732*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linear(empty));
733*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linear(x));
734*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearDown(empty));
735*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearDown(x));
736*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearObscure(empty));
737*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearObscure(x));
738*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearVeryObscure(empty));
739*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearVeryObscure(x));
740*795d594fSAndroid Build Coastguard Worker     expectEquals(0, hiddenStride(empty));
741*795d594fSAndroid Build Coastguard Worker     expectEquals(55, hiddenStride(x));
742*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearWhile(empty));
743*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearWhile(x));
744*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearThreeWayPhi(empty));
745*795d594fSAndroid Build Coastguard Worker     expectEquals(50, linearThreeWayPhi(x));
746*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearFourWayPhi(empty));
747*795d594fSAndroid Build Coastguard Worker     expectEquals(51, linearFourWayPhi(x));
748*795d594fSAndroid Build Coastguard Worker     expectEquals(0, wrapAroundThenLinear(empty));
749*795d594fSAndroid Build Coastguard Worker     expectEquals(55, wrapAroundThenLinear(x));
750*795d594fSAndroid Build Coastguard Worker     expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
751*795d594fSAndroid Build Coastguard Worker     expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
752*795d594fSAndroid Build Coastguard Worker 
753*795d594fSAndroid Build Coastguard Worker     // Linear with parameter.
754*795d594fSAndroid Build Coastguard Worker     sResult = 0;
755*795d594fSAndroid Build Coastguard Worker     try {
756*795d594fSAndroid Build Coastguard Worker       linearWithParameter(-1);
757*795d594fSAndroid Build Coastguard Worker     } catch (NegativeArraySizeException e) {
758*795d594fSAndroid Build Coastguard Worker       sResult = 1;
759*795d594fSAndroid Build Coastguard Worker     }
760*795d594fSAndroid Build Coastguard Worker     expectEquals(1, sResult);
761*795d594fSAndroid Build Coastguard Worker     for (int n = 0; n < 32; n++) {
762*795d594fSAndroid Build Coastguard Worker       int[] r = linearWithParameter(n);
763*795d594fSAndroid Build Coastguard Worker       expectEquals(n, r.length);
764*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < n; i++) {
765*795d594fSAndroid Build Coastguard Worker         expectEquals(i, r[i]);
766*795d594fSAndroid Build Coastguard Worker       }
767*795d594fSAndroid Build Coastguard Worker     }
768*795d594fSAndroid Build Coastguard Worker 
769*795d594fSAndroid Build Coastguard Worker     // Linear copy.
770*795d594fSAndroid Build Coastguard Worker     expectEquals(0, linearCopy(empty).length);
771*795d594fSAndroid Build Coastguard Worker     {
772*795d594fSAndroid Build Coastguard Worker       int[] r = linearCopy(x);
773*795d594fSAndroid Build Coastguard Worker       expectEquals(x.length, r.length);
774*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < x.length; i++) {
775*795d594fSAndroid Build Coastguard Worker         expectEquals(x[i], r[i]);
776*795d594fSAndroid Build Coastguard Worker       }
777*795d594fSAndroid Build Coastguard Worker     }
778*795d594fSAndroid Build Coastguard Worker 
779*795d594fSAndroid Build Coastguard Worker     // Linear with non-unit strides.
780*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearByTwo(x));
781*795d594fSAndroid Build Coastguard Worker     expectEquals(25, linearByTwoSkip1(x));
782*795d594fSAndroid Build Coastguard Worker     expectEquals(25, linearByTwoSkip2(x));
783*795d594fSAndroid Build Coastguard Worker     expectEquals(56, linearWithCompoundStride());
784*795d594fSAndroid Build Coastguard Worker     expectEquals(66, linearWithLargePositiveStride());
785*795d594fSAndroid Build Coastguard Worker     expectEquals(66, linearWithVeryLargePositiveStride());
786*795d594fSAndroid Build Coastguard Worker     expectEquals(66, linearWithLargeNegativeStride());
787*795d594fSAndroid Build Coastguard Worker     expectEquals(66, linearWithVeryLargeNegativeStride());
788*795d594fSAndroid Build Coastguard Worker 
789*795d594fSAndroid Build Coastguard Worker     // Special forms.
790*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearForNEUp());
791*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearForNEDown());
792*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearForNEArrayLengthUp(x));
793*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearForNEArrayLengthDown(x));
794*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearDoWhileUp());
795*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearDoWhileDown());
796*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearLong());
797*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearLongAlt(x));
798*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearShort());
799*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearChar());
800*795d594fSAndroid Build Coastguard Worker     expectEquals(55, linearByte());
801*795d594fSAndroid Build Coastguard Worker     expectEquals(55, invariantFromPreLoop(x, 1));
802*795d594fSAndroid Build Coastguard Worker     linearTriangularOnTwoArrayLengths(10);
803*795d594fSAndroid Build Coastguard Worker     linearTriangularOnOneArrayLength(10);
804*795d594fSAndroid Build Coastguard Worker     linearTriangularOnParameter(10);
805*795d594fSAndroid Build Coastguard Worker     linearTriangularStrictLower(10);
806*795d594fSAndroid Build Coastguard Worker     linearTriangularStrictUpper(10);
807*795d594fSAndroid Build Coastguard Worker     {
808*795d594fSAndroid Build Coastguard Worker       int[] t = linearTriangularOOB();
809*795d594fSAndroid Build Coastguard Worker       for (int i = 0; i < 200; i++) {
810*795d594fSAndroid Build Coastguard Worker         expectEquals(i <= 127 ? i + 1 : 128, t[i]);
811*795d594fSAndroid Build Coastguard Worker       }
812*795d594fSAndroid Build Coastguard Worker     }
813*795d594fSAndroid Build Coastguard Worker 
814*795d594fSAndroid Build Coastguard Worker     System.out.println("passed");
815*795d594fSAndroid Build Coastguard Worker   }
816*795d594fSAndroid Build Coastguard Worker 
expectEquals(int expected, int result)817*795d594fSAndroid Build Coastguard Worker   private static void expectEquals(int expected, int result) {
818*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
819*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
820*795d594fSAndroid Build Coastguard Worker     }
821*795d594fSAndroid Build Coastguard Worker   }
822*795d594fSAndroid Build Coastguard Worker }
823