blob: 34d2f64bf4047ffcd312f4bc169fc6abba7bd289 [file] [log] [blame]
Aart Bik22af3be2015-09-10 12:50:58 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Test on loop optimizations.
19//
20public class Main {
21
22 static int sResult;
23
24 //
Aart Bik9401f532015-09-28 16:25:56 -070025 // Various sequence variables used in bound checks.
Aart Bik22af3be2015-09-10 12:50:58 -070026 //
27
28 /// CHECK-START: int Main.linear(int[]) BCE (before)
29 /// CHECK-DAG: BoundsCheck
30 /// CHECK-START: int Main.linear(int[]) BCE (after)
31 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080032 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070033 private static int linear(int[] x) {
34 int result = 0;
35 for (int i = 0; i < x.length; i++) {
36 result += x[i];
37 }
38 return result;
39 }
40
41 /// CHECK-START: int Main.linearDown(int[]) BCE (before)
42 /// CHECK-DAG: BoundsCheck
43 /// CHECK-START: int Main.linearDown(int[]) BCE (after)
44 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080045 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070046 private static int linearDown(int[] x) {
47 int result = 0;
48 for (int i = x.length - 1; i >= 0; i--) {
49 result += x[i];
50 }
51 return result;
52 }
53
54 /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
55 /// CHECK-DAG: BoundsCheck
56 /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
57 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080058 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070059 private static int linearObscure(int[] x) {
60 int result = 0;
61 for (int i = x.length - 1; i >= 0; i--) {
62 int k = i + 5;
63 result += x[k - 5];
64 }
65 return result;
66 }
67
Aart Bikf475bee2015-09-16 12:50:25 -070068 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
69 /// CHECK-DAG: BoundsCheck
70 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
71 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080072 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -070073 private static int linearVeryObscure(int[] x) {
74 int result = 0;
75 for (int i = 0; i < x.length; i++) {
76 int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
77 result += x[k - 5];
78 }
79 return result;
80 }
81
Aart Bik22af3be2015-09-10 12:50:58 -070082 /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
83 /// CHECK-DAG: BoundsCheck
84 /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
85 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080086 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070087 private static int linearWhile(int[] x) {
88 int i = 0;
89 int result = 0;
90 while (i < x.length) {
91 result += x[i++];
92 }
93 return result;
94 }
95
Aart Bikf475bee2015-09-16 12:50:25 -070096 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
97 /// CHECK-DAG: BoundsCheck
98 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
99 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800100 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700101 private static int linearThreeWayPhi(int[] x) {
102 int result = 0;
103 for (int i = 0; i < x.length; ) {
104 if (x[i] == 5) {
105 i++;
106 continue;
107 }
108 result += x[i++];
109 }
110 return result;
111 }
112
113 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
114 /// CHECK-DAG: BoundsCheck
115 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
116 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800117 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700118 private static int linearFourWayPhi(int[] x) {
119 int result = 0;
120 for (int i = 0; i < x.length; ) {
121 if (x[i] == 5) {
122 i++;
123 continue;
124 } else if (x[i] == 6) {
125 i++;
126 result += 7;
127 continue;
128 }
129 result += x[i++];
130 }
131 return result;
132 }
133
Aart Bik22af3be2015-09-10 12:50:58 -0700134 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
135 /// CHECK-DAG: BoundsCheck
136 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
137 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800138 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700139 private static int wrapAroundThenLinear(int[] x) {
140 // Loop with wrap around (length - 1, 0, 1, 2, ..).
141 int w = x.length - 1;
142 int result = 0;
143 for (int i = 0; i < x.length; i++) {
144 result += x[w];
145 w = i;
146 }
147 return result;
148 }
149
Aart Bikf475bee2015-09-16 12:50:25 -0700150 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
151 /// CHECK-DAG: BoundsCheck
152 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
153 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800154 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700155 private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
156 // Loop with wrap around (length - 1, 0, 1, 2, ..).
157 int w = x.length - 1;
158 int result = 0;
159 for (int i = 0; i < x.length; ) {
160 if (x[w] == 1) {
161 w = i++;
162 continue;
163 }
164 result += x[w];
165 w = i++;
166 }
167 return result;
168 }
169
Aart Bik22af3be2015-09-10 12:50:58 -0700170 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
171 /// CHECK-DAG: BoundsCheck
172 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
173 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800174 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700175 private static int[] linearWithParameter(int n) {
176 int[] x = new int[n];
177 for (int i = 0; i < n; i++) {
178 x[i] = i;
179 }
180 return x;
181 }
182
Aart Bikf475bee2015-09-16 12:50:25 -0700183 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
184 /// CHECK-DAG: BoundsCheck
185 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
186 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800187 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700188 private static int[] linearCopy(int x[]) {
189 int n = x.length;
190 int y[] = new int[n];
191 for (int i = 0; i < n; i++) {
192 y[i] = x[i];
193 }
194 return y;
195 }
196
Aart Bik4a342772015-11-30 10:17:46 -0800197 /// CHECK-START: int Main.linearByTwo(int[]) BCE (before)
198 /// CHECK-DAG: BoundsCheck
199 /// CHECK-DAG: BoundsCheck
200 /// CHECK-START: int Main.linearByTwo(int[]) BCE (after)
201 /// CHECK-NOT: BoundsCheck
202 /// CHECK-NOT: Deoptimize
203 private static int linearByTwo(int x[]) {
204 int n = x.length / 2;
205 int result = 0;
206 for (int i = 0; i < n; i++) {
207 int ii = i << 1;
208 result += x[ii];
209 result += x[ii + 1];
210 }
211 return result;
212 }
213
214 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (before)
215 /// CHECK-DAG: BoundsCheck
216 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (after)
217 /// CHECK-NOT: BoundsCheck
218 /// CHECK-NOT: Deoptimize
219 private static int linearByTwoSkip1(int x[]) {
220 int result = 0;
221 for (int i = 0; i < x.length / 2; i++) {
222 result += x[2 * i];
223 }
224 return result;
225 }
226
227 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (before)
228 /// CHECK-DAG: BoundsCheck
229 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
230 /// CHECK-DAG: BoundsCheck
231 /// CHECK-NOT: Deoptimize
232 private static int linearByTwoSkip2(int x[]) {
233 int result = 0;
234 // This case is not optimized.
235 for (int i = 0; i < x.length; i+=2) {
236 result += x[i];
237 }
238 return result;
239 }
240
Aart Bik22af3be2015-09-10 12:50:58 -0700241 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
242 /// CHECK-DAG: BoundsCheck
243 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
244 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800245 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700246 private static int linearWithCompoundStride() {
247 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
248 int result = 0;
249 for (int i = 0; i <= 12; ) {
250 i++;
251 result += x[i];
252 i++;
253 }
254 return result;
255 }
256
257 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
258 /// CHECK-DAG: BoundsCheck
259 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
260 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800261 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700262 private static int linearWithLargePositiveStride() {
263 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
264 int result = 0;
265 int k = 0;
266 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700267 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700268 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
269 result += x[k++];
270 }
271 return result;
272 }
273
274 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
275 /// CHECK-DAG: BoundsCheck
276 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
277 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800278 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700279 private static int linearWithVeryLargePositiveStride() {
280 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
281 int result = 0;
282 int k = 0;
283 // Range analysis conservatively bails due to potential of wrap-around
284 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700285 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700286 result += x[k++];
287 }
288 return result;
289 }
290
291 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
292 /// CHECK-DAG: BoundsCheck
293 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
294 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800295 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700296 private static int linearWithLargeNegativeStride() {
297 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
298 int result = 0;
299 int k = 0;
300 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700301 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700302 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
303 result += x[k++];
304 }
305 return result;
306 }
307
308 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
309 /// CHECK-DAG: BoundsCheck
310 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
311 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800312 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700313 private static int linearWithVeryLargeNegativeStride() {
314 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
315 int result = 0;
316 int k = 0;
317 // Range analysis conservatively bails due to potential of wrap-around
318 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700319 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700320 result += x[k++];
321 }
322 return result;
323 }
324
Aart Bik9401f532015-09-28 16:25:56 -0700325 /// CHECK-START: int Main.linearForNEUp() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700326 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700327 /// CHECK-START: int Main.linearForNEUp() BCE (after)
Aart Bikf475bee2015-09-16 12:50:25 -0700328 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800329 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700330 private static int linearForNEUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700331 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
332 int result = 0;
333 for (int i = 0; i != 10; i++) {
334 result += x[i];
335 }
336 return result;
337 }
338
Aart Bik9401f532015-09-28 16:25:56 -0700339 /// CHECK-START: int Main.linearForNEDown() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700340 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700341 /// CHECK-START: int Main.linearForNEDown() BCE (after)
342 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800343 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700344 private static int linearForNEDown() {
345 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
346 int result = 0;
347 for (int i = 9; i != -1; i--) {
348 result += x[i];
349 }
350 return result;
351 }
352
353 /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700354 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700355 /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
356 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800357 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700358 private static int linearDoWhileUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700359 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
360 int result = 0;
361 int i = 0;
Aart Bikf475bee2015-09-16 12:50:25 -0700362 do {
363 result += x[i++];
364 } while (i < 10);
365 return result;
366 }
367
Aart Bik9401f532015-09-28 16:25:56 -0700368 /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
369 /// CHECK-DAG: BoundsCheck
370 /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
371 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800372 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700373 private static int linearDoWhileDown() {
374 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
375 int result = 0;
376 int i = 9;
377 do {
378 result += x[i--];
379 } while (0 <= i);
380 return result;
381 }
382
Aart Bikf475bee2015-09-16 12:50:25 -0700383 /// CHECK-START: int Main.linearShort() BCE (before)
384 /// CHECK-DAG: BoundsCheck
385 /// CHECK-START: int Main.linearShort() BCE (after)
386 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800387 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700388 private static int linearShort() {
389 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
390 int result = 0;
391 // TODO: make this work
392 for (short i = 0; i < 10; i++) {
393 result += x[i];
394 }
395 return result;
396 }
397
Aart Bik4a342772015-11-30 10:17:46 -0800398 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before)
399 /// CHECK-DAG: BoundsCheck
400 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after)
401 /// CHECK-NOT: BoundsCheck
402 /// CHECK-NOT: Deoptimize
403 private static int invariantFromPreLoop(int[] x, int y) {
404 int result = 0;
405 // Strange pre-loop that sets upper bound.
406 int hi;
407 while (true) {
408 y = y % 3;
409 hi = x.length;
410 if (y != 123) break;
411 }
412 for (int i = 0; i < hi; i++) {
413 result += x[i];
414 }
415 return result;
416 }
417
Aart Bik22af3be2015-09-10 12:50:58 -0700418 /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
419 /// CHECK-DAG: BoundsCheck
420 /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
421 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800422 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700423 private static int periodicIdiom(int tc) {
424 int[] x = { 1, 3 };
425 // Loop with periodic sequence (0, 1).
426 int k = 0;
427 int result = 0;
428 for (int i = 0; i < tc; i++) {
429 result += x[k];
430 k = 1 - k;
431 }
432 return result;
433 }
434
435 /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
436 /// CHECK-DAG: BoundsCheck
437 /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
438 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800439 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700440 private static int periodicSequence2(int tc) {
441 int[] x = { 1, 3 };
442 // Loop with periodic sequence (0, 1).
443 int k = 0;
444 int l = 1;
445 int result = 0;
446 for (int i = 0; i < tc; i++) {
447 result += x[k];
448 int t = l;
449 l = k;
450 k = t;
451 }
452 return result;
453 }
454
455 /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
456 /// CHECK-DAG: BoundsCheck
457 /// CHECK-DAG: BoundsCheck
458 /// CHECK-DAG: BoundsCheck
459 /// CHECK-DAG: BoundsCheck
460 /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
461 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800462 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700463 private static int periodicSequence4(int tc) {
464 int[] x = { 1, 3, 5, 7 };
465 // Loop with periodic sequence (0, 1, 2, 3).
466 int k = 0;
467 int l = 1;
468 int m = 2;
469 int n = 3;
470 int result = 0;
471 for (int i = 0; i < tc; i++) {
472 result += x[k] + x[l] + x[m] + x[n]; // all used at once
473 int t = n;
474 n = k;
475 k = l;
476 l = m;
477 m = t;
478 }
479 return result;
480 }
481
Aart Bikf475bee2015-09-16 12:50:25 -0700482 /// CHECK-START: int Main.justRightUp1() BCE (before)
483 /// CHECK-DAG: BoundsCheck
484 /// CHECK-START: int Main.justRightUp1() BCE (after)
485 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800486 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700487 private static int justRightUp1() {
488 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
489 int result = 0;
490 for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
491 result += x[k++];
492 }
493 return result;
494 }
495
496 /// CHECK-START: int Main.justRightUp2() BCE (before)
497 /// CHECK-DAG: BoundsCheck
498 /// CHECK-START: int Main.justRightUp2() BCE (after)
499 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800500 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700501 private static int justRightUp2() {
502 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
503 int result = 0;
504 for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
505 result += x[i - Integer.MAX_VALUE + 10];
506 }
507 return result;
508 }
509
510 /// CHECK-START: int Main.justRightUp3() BCE (before)
511 /// CHECK-DAG: BoundsCheck
512 /// CHECK-START: int Main.justRightUp3() BCE (after)
513 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800514 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700515 private static int justRightUp3() {
516 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
517 int result = 0;
518 for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
519 result += x[k++];
520 }
521 return result;
522 }
523
524 /// CHECK-START: int Main.justOOBUp() BCE (before)
525 /// CHECK-DAG: BoundsCheck
526 /// CHECK-START: int Main.justOOBUp() BCE (after)
527 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800528 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700529 private static int justOOBUp() {
530 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
531 int result = 0;
532 // Infinite loop!
533 for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
534 result += x[k++];
535 }
536 return result;
537 }
538
539 /// CHECK-START: int Main.justRightDown1() BCE (before)
540 /// CHECK-DAG: BoundsCheck
541 /// CHECK-START: int Main.justRightDown1() BCE (after)
542 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800543 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700544 private static int justRightDown1() {
545 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
546 int result = 0;
547 for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
548 result += x[k++];
549 }
550 return result;
551 }
552
553 /// CHECK-START: int Main.justRightDown2() BCE (before)
554 /// CHECK-DAG: BoundsCheck
555 /// CHECK-START: int Main.justRightDown2() BCE (after)
556 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800557 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700558 private static int justRightDown2() {
559 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
560 int result = 0;
561 for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
562 result += x[Integer.MAX_VALUE + i];
563 }
564 return result;
565 }
566
567 /// CHECK-START: int Main.justRightDown3() BCE (before)
568 /// CHECK-DAG: BoundsCheck
569 /// CHECK-START: int Main.justRightDown3() BCE (after)
570 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800571 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700572 private static int justRightDown3() {
573 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
574 int result = 0;
575 for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
576 result += x[k++];
577 }
578 return result;
579 }
580
581 /// CHECK-START: int Main.justOOBDown() BCE (before)
582 /// CHECK-DAG: BoundsCheck
583 /// CHECK-START: int Main.justOOBDown() BCE (after)
584 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800585 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700586 private static int justOOBDown() {
587 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
588 int result = 0;
589 // Infinite loop!
590 for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
591 result += x[k++];
592 }
593 return result;
594 }
595
Aart Bik9401f532015-09-28 16:25:56 -0700596 /// CHECK-START: void Main.lowerOOB(int[]) BCE (before)
597 /// CHECK-DAG: BoundsCheck
598 /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
599 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800600 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700601 private static void lowerOOB(int[] x) {
602 for (int i = -1; i < x.length; i++) {
603 sResult += x[i];
604 }
605 }
606
Aart Bik9401f532015-09-28 16:25:56 -0700607 /// CHECK-START: void Main.upperOOB(int[]) BCE (before)
608 /// CHECK-DAG: BoundsCheck
609 /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
610 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800611 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700612 private static void upperOOB(int[] x) {
613 for (int i = 0; i <= x.length; i++) {
614 sResult += x[i];
615 }
616 }
617
Aart Bik9401f532015-09-28 16:25:56 -0700618 /// CHECK-START: void Main.doWhileUpOOB() BCE (before)
619 /// CHECK-DAG: BoundsCheck
620 /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
621 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800622 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700623 private static void doWhileUpOOB() {
624 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
625 int i = 0;
626 do {
627 sResult += x[i++];
628 } while (i <= x.length);
629 }
630
631 /// CHECK-START: void Main.doWhileDownOOB() BCE (before)
632 /// CHECK-DAG: BoundsCheck
633 /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
634 /// CHECK-DAG: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800635 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700636 private static void doWhileDownOOB() {
637 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
638 int i = x.length - 1;
639 do {
640 sResult += x[i--];
641 } while (-1 <= i);
642 }
643
Aart Bik4a342772015-11-30 10:17:46 -0800644 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (before)
645 /// CHECK-DAG: StaticFieldGet
646 /// CHECK-DAG: NullCheck
647 /// CHECK-DAG: ArrayLength
648 /// CHECK-DAG: BoundsCheck
649 /// CHECK-DAG: ArrayGet
650 /// CHECK-DAG: StaticFieldSet
651 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
652 /// CHECK-DAG: StaticFieldGet
653 /// CHECK-NOT: NullCheck
654 /// CHECK-NOT: ArrayLength
655 /// CHECK-NOT: BoundsCheck
656 /// CHECK-DAG: ArrayGet
657 /// CHECK-DAG: StaticFieldSet
658 /// CHECK-DAG: Exit
659 /// CHECK-DAG: Deoptimize
660 /// CHECK-DAG: Deoptimize
661 /// CHECK-DAG: Deoptimize
662 private static int linearDynamicBCE1(int[] x, int lo, int hi) {
663 int result = 0;
664 for (int i = lo; i < hi; i++) {
665 sResult += x[i];
666 }
667 return result;
668 }
669
670 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (before)
671 /// CHECK-DAG: StaticFieldGet
672 /// CHECK-DAG: NullCheck
673 /// CHECK-DAG: ArrayLength
674 /// CHECK-DAG: BoundsCheck
675 /// CHECK-DAG: ArrayGet
676 /// CHECK-DAG: StaticFieldSet
677 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
678 /// CHECK-DAG: StaticFieldGet
679 /// CHECK-NOT: NullCheck
680 /// CHECK-NOT: ArrayLength
681 /// CHECK-NOT: BoundsCheck
682 /// CHECK-DAG: ArrayGet
683 /// CHECK-DAG: StaticFieldSet
684 /// CHECK-DAG: Exit
685 /// CHECK-DAG: Deoptimize
686 /// CHECK-DAG: Deoptimize
687 /// CHECK-DAG: Deoptimize
688 private static int linearDynamicBCE2(int[] x, int lo, int hi, int offset) {
689 int result = 0;
690 for (int i = lo; i < hi; i++) {
691 sResult += x[offset + i];
692 }
693 return result;
694 }
695
696 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (before)
697 /// CHECK-DAG: NullCheck
698 /// CHECK-DAG: ArrayLength
699 /// CHECK-DAG: BoundsCheck
700 /// CHECK-DAG: ArrayGet
701 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
702 /// CHECK-DAG: Deoptimize
703 /// CHECK-DAG: Deoptimize
704 /// CHECK-DAG: Deoptimize
705 /// CHECK-NOT: NullCheck
706 /// CHECK-NOT: ArrayLength
707 /// CHECK-NOT: BoundsCheck
708 /// CHECK-DAG: ArrayGet
709 private static int wrapAroundDynamicBCE(int[] x) {
710 int w = 9;
711 int result = 0;
712 for (int i = 0; i < 10; i++) {
713 result += x[w];
714 w = i;
715 }
716 return result;
717 }
718
719 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (before)
720 /// CHECK-DAG: NullCheck
721 /// CHECK-DAG: ArrayLength
722 /// CHECK-DAG: BoundsCheck
723 /// CHECK-DAG: ArrayGet
724 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
725 /// CHECK-DAG: Deoptimize
726 /// CHECK-DAG: Deoptimize
727 /// CHECK-DAG: Deoptimize
728 /// CHECK-NOT: NullCheck
729 /// CHECK-NOT: ArrayLength
730 /// CHECK-NOT: BoundsCheck
731 /// CHECK-DAG: ArrayGet
732 private static int periodicDynamicBCE(int[] x) {
733 int k = 0;
734 int result = 0;
735 for (int i = 0; i < 10; i++) {
736 result += x[k];
737 k = 1 - k;
738 }
739 return result;
740 }
741
742 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
743 /// CHECK-DAG: NullCheck
744 /// CHECK-DAG: ArrayLength
745 /// CHECK-DAG: BoundsCheck
746 /// CHECK-DAG: ArrayGet
747 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
748 /// CHECK-NOT: NullCheck
749 /// CHECK-NOT: ArrayLength
750 /// CHECK-NOT: BoundsCheck
751 /// CHECK-DAG: ArrayGet
752 /// CHECK-DAG: Exit
753 /// CHECK-DAG: Deoptimize
754 /// CHECK-DAG: Deoptimize
755 /// CHECK-DAG: Deoptimize
756 static int dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
757 // This loop could be infinite for hi = max int. Since i is also used
758 // as subscript, however, dynamic bce can proceed.
759 int result = 0;
760 for (int i = lo; i <= hi; i++) {
761 result += x[i];
762 }
763 return result;
764 }
765
766 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
767 /// CHECK-DAG: NullCheck
768 /// CHECK-DAG: ArrayLength
769 /// CHECK-DAG: BoundsCheck
770 /// CHECK-DAG: ArrayGet
771 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
772 /// CHECK-DAG: NullCheck
773 /// CHECK-DAG: ArrayLength
774 /// CHECK-DAG: BoundsCheck
775 /// CHECK-DAG: ArrayGet
776 /// CHECK-NOT: Deoptimize
777 static int noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
778 // As above, but now the index is not used as subscript,
779 // and dynamic bce is not applied.
780 int result = 0;
781 for (int k = 0, i = lo; i <= hi; i++) {
782 result += x[k++];
783 }
784 return result;
785 }
786
787 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (before)
788 /// CHECK-DAG: NullCheck
789 /// CHECK-DAG: ArrayLength
790 /// CHECK-DAG: BoundsCheck
791 /// CHECK-DAG: ArrayGet
792 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
793 /// CHECK-DAG: NullCheck
794 /// CHECK-DAG: ArrayLength
795 /// CHECK-DAG: BoundsCheck
796 /// CHECK-DAG: ArrayGet
797 /// CHECK-NOT: Deoptimize
798 static int noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi) {
799 int result = 0;
800 // Mix of int and long induction.
801 int k = 0;
802 for (long i = lo; i < hi; i++) {
803 result += x[k++];
804 }
805 return result;
806 }
807
808 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (before)
809 /// CHECK-DAG: NullCheck
810 /// CHECK-DAG: ArrayLength
811 /// CHECK-DAG: NotEqual
812 /// CHECK-DAG: If
813 /// CHECK-DAG: If
814 /// CHECK-DAG: NullCheck
815 /// CHECK-DAG: ArrayLength
816 /// CHECK-DAG: BoundsCheck
817 /// CHECK-DAG: ArrayGet
818 /// CHECK-DAG: If
819 /// CHECK-DAG: BoundsCheck
820 /// CHECK-DAG: BoundsCheck
821 /// CHECK-DAG: BoundsCheck
822 /// CHECK-DAG: BoundsCheck
823 /// CHECK-DAG: BoundsCheck
824 /// CHECK-DAG: BoundsCheck
825 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
826 /// CHECK-DAG: NullCheck
827 /// CHECK-DAG: ArrayLength
828 /// CHECK-DAG: NotEqual
829 /// CHECK-DAG: If
830 /// CHECK-DAG: If
831 /// CHECK-NOT: BoundsCheck
832 /// CHECK-DAG: ArrayGet
833 /// CHECK-DAG: If
834 /// CHECK-DAG: Deoptimize
835 /// CHECK-DAG: BoundsCheck
836 /// CHECK-DAG: BoundsCheck
837 /// CHECK-DAG: BoundsCheck
838 /// CHECK-NOT: BoundsCheck
839 /// CHECK-DAG: Exit
840 /// CHECK-DAG: Deoptimize
841 /// CHECK-DAG: Deoptimize
842 /// CHECK-DAG: Deoptimize
843 /// CHECK-NOT: ArrayGet
844 static int dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi) {
845 // Deliberately test array length on a before the loop so that only bounds checks
846 // on constant subscripts remain, making them a viable candidate for hoisting.
847 if (a.length == 0) {
848 return -1;
849 }
850 // Loop that allows BCE on x[i].
851 int result = 0;
852 for (int i = lo; i < hi; i++) {
853 result += x[i];
854 if ((i % 10) != 0) {
855 // None of the subscripts inside a conditional are removed by dynamic bce,
856 // making them a candidate for deoptimization based on constant indices.
857 // Compiler should ensure the array loads are not subsequently hoisted
858 // "above" the deoptimization "barrier" on the bounds.
859 a[0][i] = 1;
860 a[1][i] = 2;
861 a[99][i] = 3;
862 }
863 }
864 return result;
865 }
866
867 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], java.lang.Integer[], int, int) BCE (before)
868 /// CHECK-DAG: If
869 /// CHECK-DAG: BoundsCheck
870 /// CHECK-DAG: ArrayGet
871 /// CHECK-DAG: BoundsCheck
872 /// CHECK-DAG: ArrayGet
873 /// CHECK-DAG: BoundsCheck
874 /// CHECK-DAG: ArrayGet
875 /// CHECK-DAG: BoundsCheck
876 /// CHECK-DAG: ArrayGet
877 /// CHECK-DAG: BoundsCheck
878 /// CHECK-DAG: ArrayGet
879 /// CHECK-DAG: BoundsCheck
880 /// CHECK-DAG: ArrayGet
881 /// CHECK-DAG: BoundsCheck
882 /// CHECK-DAG: ArrayGet
883 /// CHECK-DAG: BoundsCheck
884 /// CHECK-DAG: ArrayGet
885 /// CHECK-DAG: BoundsCheck
886 /// CHECK-DAG: ArrayGet
887 /// CHECK-DAG: BoundsCheck
888 /// CHECK-DAG: ArrayGet
889 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], java.lang.Integer[], int, int) BCE (after)
890 /// CHECK-DAG: If
891 /// CHECK-NOT: BoundsCheck
892 /// CHECK-DAG: ArrayGet
893 /// CHECK-NOT: BoundsCheck
894 /// CHECK-NOT: ArrayGet
895 /// CHECK-DAG: Exit
896 /// CHECK-DAG: Deoptimize
897 /// CHECK-DAG: Deoptimize
898 /// CHECK-DAG: Deoptimize
899 /// CHECK-DAG: Deoptimize
900 /// CHECK-DAG: Deoptimize
901 /// CHECK-DAG: ArrayGet
902 /// CHECK-DAG: Deoptimize
903 /// CHECK-DAG: Deoptimize
904 /// CHECK-DAG: ArrayGet
905 /// CHECK-DAG: Deoptimize
906 /// CHECK-DAG: Deoptimize
907 /// CHECK-DAG: ArrayGet
908 /// CHECK-DAG: Deoptimize
909 /// CHECK-DAG: Deoptimize
910 /// CHECK-DAG: ArrayGet
911 /// CHECK-DAG: Deoptimize
912 /// CHECK-DAG: Deoptimize
913 /// CHECK-DAG: ArrayGet
914 /// CHECK-DAG: Deoptimize
915 /// CHECK-DAG: Deoptimize
916 /// CHECK-DAG: ArrayGet
917 /// CHECK-DAG: Deoptimize
918 /// CHECK-DAG: Deoptimize
919 /// CHECK-DAG: ArrayGet
920 /// CHECK-DAG: Deoptimize
921 /// CHECK-DAG: Deoptimize
922 /// CHECK-DAG: ArrayGet
923 /// CHECK-DAG: Deoptimize
924 /// CHECK-DAG: Deoptimize
925 /// CHECK-DAG: ArrayGet
926 static int dynamicBCEAndConstantIndicesAllTypes(int[] q,
927 boolean[] r,
928 byte[] s,
929 char[] t,
930 short[] u,
931 int[] v,
932 long[] w,
933 float[] x,
934 double[] y,
935 Integer[] z, int lo, int hi) {
936 int result = 0;
937 for (int i = lo; i < hi; i++) {
938 result += q[i] + (r[0] ? 1 : 0) + (int) s[0] + (int) t[0] + (int) u[0] + (int) v[0] +
939 (int) w[0] + (int) x[0] + (int) y[0] + (int) z[0];
940 }
941 return result;
942 }
943
Aart Bik22af3be2015-09-10 12:50:58 -0700944 //
945 // Verifier.
946 //
947
948 public static void main(String[] args) {
949 int[] empty = { };
950 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
951
952 // Linear and wrap-around.
953 expectEquals(0, linear(empty));
954 expectEquals(55, linear(x));
955 expectEquals(0, linearDown(empty));
956 expectEquals(55, linearDown(x));
957 expectEquals(0, linearObscure(empty));
958 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700959 expectEquals(0, linearVeryObscure(empty));
960 expectEquals(55, linearVeryObscure(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700961 expectEquals(0, linearWhile(empty));
962 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700963 expectEquals(0, linearThreeWayPhi(empty));
964 expectEquals(50, linearThreeWayPhi(x));
965 expectEquals(0, linearFourWayPhi(empty));
966 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700967 expectEquals(0, wrapAroundThenLinear(empty));
968 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700969 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
970 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700971
972 // Linear with parameter.
973 sResult = 0;
974 try {
975 linearWithParameter(-1);
976 } catch (NegativeArraySizeException e) {
977 sResult = 1;
978 }
979 expectEquals(1, sResult);
980 for (int n = 0; n < 32; n++) {
981 int[] r = linearWithParameter(n);
982 expectEquals(n, r.length);
983 for (int i = 0; i < n; i++) {
984 expectEquals(i, r[i]);
985 }
986 }
987
Aart Bikf475bee2015-09-16 12:50:25 -0700988 // Linear copy.
989 expectEquals(0, linearCopy(empty).length);
990 {
991 int[] r = linearCopy(x);
992 expectEquals(x.length, r.length);
993 for (int i = 0; i < x.length; i++) {
994 expectEquals(x[i], r[i]);
995 }
996 }
997
Aart Bik22af3be2015-09-10 12:50:58 -0700998 // Linear with non-unit strides.
Aart Bik4a342772015-11-30 10:17:46 -0800999 expectEquals(55, linearByTwo(x));
1000 expectEquals(25, linearByTwoSkip1(x));
1001 expectEquals(25, linearByTwoSkip2(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001002 expectEquals(56, linearWithCompoundStride());
1003 expectEquals(66, linearWithLargePositiveStride());
1004 expectEquals(66, linearWithVeryLargePositiveStride());
1005 expectEquals(66, linearWithLargeNegativeStride());
1006 expectEquals(66, linearWithVeryLargeNegativeStride());
1007
Aart Bikf475bee2015-09-16 12:50:25 -07001008 // Special forms.
Aart Bik9401f532015-09-28 16:25:56 -07001009 expectEquals(55, linearForNEUp());
1010 expectEquals(55, linearForNEDown());
1011 expectEquals(55, linearDoWhileUp());
1012 expectEquals(55, linearDoWhileDown());
Aart Bikf475bee2015-09-16 12:50:25 -07001013 expectEquals(55, linearShort());
Aart Bik4a342772015-11-30 10:17:46 -08001014 expectEquals(55, invariantFromPreLoop(x, 1));
Aart Bikf475bee2015-09-16 12:50:25 -07001015
Aart Bik22af3be2015-09-10 12:50:58 -07001016 // Periodic adds (1, 3), one at the time.
1017 expectEquals(0, periodicIdiom(-1));
1018 for (int tc = 0; tc < 32; tc++) {
1019 int expected = (tc >> 1) << 2;
1020 if ((tc & 1) != 0)
1021 expected += 1;
1022 expectEquals(expected, periodicIdiom(tc));
1023 }
1024
1025 // Periodic adds (1, 3), one at the time.
1026 expectEquals(0, periodicSequence2(-1));
1027 for (int tc = 0; tc < 32; tc++) {
1028 int expected = (tc >> 1) << 2;
1029 if ((tc & 1) != 0)
1030 expected += 1;
1031 expectEquals(expected, periodicSequence2(tc));
1032 }
1033
1034 // Periodic adds (1, 3, 5, 7), all at once.
1035 expectEquals(0, periodicSequence4(-1));
1036 for (int tc = 0; tc < 32; tc++) {
1037 expectEquals(tc * 16, periodicSequence4(tc));
1038 }
1039
Aart Bikf475bee2015-09-16 12:50:25 -07001040 // Large bounds.
1041 expectEquals(55, justRightUp1());
1042 expectEquals(55, justRightUp2());
1043 expectEquals(55, justRightUp3());
1044 expectEquals(55, justRightDown1());
1045 expectEquals(55, justRightDown2());
1046 expectEquals(55, justRightDown3());
1047 sResult = 0;
1048 try {
1049 justOOBUp();
1050 } catch (ArrayIndexOutOfBoundsException e) {
1051 sResult = 1;
1052 }
1053 expectEquals(1, sResult);
1054 sResult = 0;
1055 try {
1056 justOOBDown();
1057 } catch (ArrayIndexOutOfBoundsException e) {
1058 sResult = 1;
1059 }
1060 expectEquals(1, sResult);
1061
Aart Bik22af3be2015-09-10 12:50:58 -07001062 // Lower bound goes OOB.
1063 sResult = 0;
1064 try {
1065 lowerOOB(x);
1066 } catch (ArrayIndexOutOfBoundsException e) {
1067 sResult += 1000;
1068 }
1069 expectEquals(1000, sResult);
1070
1071 // Upper bound goes OOB.
1072 sResult = 0;
1073 try {
1074 upperOOB(x);
1075 } catch (ArrayIndexOutOfBoundsException e) {
1076 sResult += 1000;
1077 }
1078 expectEquals(1055, sResult);
1079
Aart Bik9401f532015-09-28 16:25:56 -07001080 // Do while up goes OOB.
1081 sResult = 0;
1082 try {
1083 doWhileUpOOB();
1084 } catch (ArrayIndexOutOfBoundsException e) {
1085 sResult += 1000;
1086 }
1087 expectEquals(1055, sResult);
1088
1089 // Do while down goes OOB.
1090 sResult = 0;
1091 try {
1092 doWhileDownOOB();
1093 } catch (ArrayIndexOutOfBoundsException e) {
1094 sResult += 1000;
1095 }
1096 expectEquals(1055, sResult);
Aart Bik4a342772015-11-30 10:17:46 -08001097
1098 // Dynamic BCE.
1099 sResult = 0;
1100 try {
1101 linearDynamicBCE1(x, -1, x.length);
1102 } catch (ArrayIndexOutOfBoundsException e) {
1103 sResult += 1000;
1104 }
1105 expectEquals(1000, sResult);
1106 sResult = 0;
1107 linearDynamicBCE1(x, 0, x.length);
1108 expectEquals(55, sResult);
1109 sResult = 0;
1110 try {
1111 linearDynamicBCE1(x, 0, x.length + 1);
1112 } catch (ArrayIndexOutOfBoundsException e) {
1113 sResult += 1000;
1114 }
1115 expectEquals(1055, sResult);
1116
1117 // Dynamic BCE with offset.
1118 sResult = 0;
1119 try {
1120 linearDynamicBCE2(x, 0, x.length, -1);
1121 } catch (ArrayIndexOutOfBoundsException e) {
1122 sResult += 1000;
1123 }
1124 expectEquals(1000, sResult);
1125 sResult = 0;
1126 linearDynamicBCE2(x, 0, x.length, 0);
1127 expectEquals(55, sResult);
1128 sResult = 0;
1129 try {
1130 linearDynamicBCE2(x, 0, x.length, 1);
1131 } catch (ArrayIndexOutOfBoundsException e) {
1132 sResult += 1000;
1133 }
1134 expectEquals(1054, sResult);
1135
1136 // Dynamic BCE candidates.
1137 expectEquals(55, wrapAroundDynamicBCE(x));
1138 expectEquals(15, periodicDynamicBCE(x));
1139 expectEquals(55, dynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1140 expectEquals(55, noDynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1141 expectEquals(55, noDynamicBCEMixedInductionTypes(x, 0, 10));
1142
1143 // Dynamic BCE combined with constant indices.
1144 int[][] a;
1145 a = new int[0][0];
1146 expectEquals(-1, dynamicBCEAndConstantIndices(x, a, 0, 10));
1147 a = new int[100][10];
1148 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1149 for (int i = 0; i < 10; i++) {
1150 expectEquals((i % 10) != 0 ? 1 : 0, a[0][i]);
1151 expectEquals((i % 10) != 0 ? 2 : 0, a[1][i]);
1152 expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]);
1153 }
1154 a = new int[2][10];
1155 sResult = 0;
1156 try {
1157 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1158 } catch (ArrayIndexOutOfBoundsException e) {
1159 sResult = 1;
1160 }
1161 expectEquals(1, sResult);
1162 expectEquals(a[0][1], 1);
1163 expectEquals(a[1][1], 2);
1164
1165 // Dynamic BCE combined with constant indices of all types.
1166 boolean[] x1 = { true };
1167 byte[] x2 = { 2 };
1168 char[] x3 = { 3 };
1169 short[] x4 = { 4 };
1170 int[] x5 = { 5 };
1171 long[] x6 = { 6 };
1172 float[] x7 = { 7 };
1173 double[] x8 = { 8 };
1174 Integer[] x9 = { 9 };
1175 expectEquals(505,
1176 dynamicBCEAndConstantIndicesAllTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, x9, 0, 10));
Aart Bik22af3be2015-09-10 12:50:58 -07001177 }
1178
1179 private static void expectEquals(int expected, int result) {
1180 if (expected != result) {
1181 throw new Error("Expected: " + expected + ", found: " + result);
1182 }
1183 }
1184}