blob: 66e1d92cc20a84eefd7de6fa54d4896fe4ab8e5c [file] [log] [blame]
Mingyao Yang0304e182015-01-30 16:41:29 -08001/*
Roland Levillain6a92a032015-07-23 12:15:01 +01002 * 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 */
Mingyao Yang0304e182015-01-30 16:41:29 -080016
17public class Main {
18
David Brazdila06d66a2015-05-28 11:14:54 +010019 /// CHECK-START: int Main.sieve(int) BCE (before)
20 /// CHECK: BoundsCheck
21 /// CHECK: ArraySet
22 /// CHECK: BoundsCheck
23 /// CHECK: ArrayGet
24 /// CHECK: BoundsCheck
25 /// CHECK: ArraySet
Mingyao Yang0304e182015-01-30 16:41:29 -080026
David Brazdila06d66a2015-05-28 11:14:54 +010027 /// CHECK-START: int Main.sieve(int) BCE (after)
28 /// CHECK-NOT: BoundsCheck
29 /// CHECK: ArraySet
30 /// CHECK-NOT: BoundsCheck
31 /// CHECK: ArrayGet
32 /// CHECK: BoundsCheck
33 /// CHECK: ArraySet
Mingyao Yang0304e182015-01-30 16:41:29 -080034
35 static int sieve(int size) {
36 int primeCount = 0;
37 boolean[] flags = new boolean[size + 1];
38 for (int i = 1; i < size; i++) flags[i] = true; // Can eliminate.
39 for (int i = 2; i < size; i++) {
40 if (flags[i]) { // Can eliminate.
41 primeCount++;
42 for (int k = i + 1; k <= size; k += i)
43 flags[k - 1] = false; // Can't eliminate yet due to (k+i) may overflow.
44 }
45 }
46 return primeCount;
47 }
48
Mingyao Yang8c8bad82015-02-09 18:13:26 -080049
David Brazdila06d66a2015-05-28 11:14:54 +010050 /// CHECK-START: void Main.narrow(int[], int) BCE (before)
51 /// CHECK: BoundsCheck
52 /// CHECK: ArraySet
53 /// CHECK: BoundsCheck
54 /// CHECK: ArraySet
55 /// CHECK: BoundsCheck
56 /// CHECK: ArraySet
Mingyao Yang0304e182015-01-30 16:41:29 -080057
David Brazdila06d66a2015-05-28 11:14:54 +010058 /// CHECK-START: void Main.narrow(int[], int) BCE (after)
59 /// CHECK-NOT: BoundsCheck
60 /// CHECK: ArraySet
61 /// CHECK-NOT: BoundsCheck
62 /// CHECK: ArraySet
63 /// CHECK: BoundsCheck
64 /// CHECK: ArraySet
65 /// CHECK-NOT: BoundsCheck
66 /// CHECK: ArraySet
67 /// CHECK: BoundsCheck
68 /// CHECK: ArraySet
Mingyao Yang0304e182015-01-30 16:41:29 -080069
Mingyao Yang8c8bad82015-02-09 18:13:26 -080070 static void narrow(int[] array, int offset) {
Mingyao Yang0304e182015-01-30 16:41:29 -080071 if (offset < 0) {
72 return;
73 }
74 if (offset < array.length) {
75 // offset is in range [0, array.length-1].
76 // Bounds check can be eliminated.
77 array[offset] = 1;
78
79 int biased_offset1 = offset + 1;
80 // biased_offset1 is in range [1, array.length].
81 if (biased_offset1 < array.length) {
82 // biased_offset1 is in range [1, array.length-1].
83 // Bounds check can be eliminated.
84 array[biased_offset1] = 1;
85 }
86
87 int biased_offset2 = offset + 0x70000000;
88 // biased_offset2 is in range [0x70000000, array.length-1+0x70000000].
89 // It may overflow and be negative.
90 if (biased_offset2 < array.length) {
91 // Even with this test, biased_offset2 can be negative so we can't
92 // eliminate this bounds check.
93 array[biased_offset2] = 1;
94 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -080095
96 // offset_sub1 won't underflow since offset is no less than 0.
97 int offset_sub1 = offset - Integer.MAX_VALUE;
98 if (offset_sub1 >= 0) {
99 array[offset_sub1] = 1; // Bounds check can be eliminated.
100 }
101
102 // offset_sub2 can underflow.
103 int offset_sub2 = offset_sub1 - Integer.MAX_VALUE;
104 if (offset_sub2 >= 0) {
105 array[offset_sub2] = 1; // Bounds check can't be eliminated.
106 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800107 }
108 }
109
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800110
David Brazdila06d66a2015-05-28 11:14:54 +0100111 /// CHECK-START: void Main.constantIndexing1(int[]) BCE (before)
112 /// CHECK: BoundsCheck
113 /// CHECK: ArraySet
114 /// CHECK: BoundsCheck
115 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700116
David Brazdila06d66a2015-05-28 11:14:54 +0100117 /// CHECK-START: void Main.constantIndexing1(int[]) BCE (after)
118 /// CHECK-NOT: Deoptimize
119 /// CHECK: BoundsCheck
120 /// CHECK: ArraySet
121 /// CHECK-NOT: BoundsCheck
122 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700123
124 static void constantIndexing1(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800125 // Decreasing order: bc for 5 but not for 4.
126 array[5] = 11;
127 array[4] = 11;
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700128 }
129
130
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000131 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +0100132 /// CHECK: BoundsCheck
133 /// CHECK: ArraySet
134 /// CHECK: BoundsCheck
135 /// CHECK: ArraySet
136 /// CHECK: BoundsCheck
137 /// CHECK: ArraySet
138 /// CHECK: BoundsCheck
139 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800140
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000141 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (after)
Aart Bike5305392016-02-24 10:49:37 -0800142 /// CHECK: Deoptimize
143 /// CHECK-NOT: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100144 /// CHECK: ArraySet
Aart Bike5305392016-02-24 10:49:37 -0800145 /// CHECK-NOT: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100146 /// CHECK: ArraySet
Aart Bike5305392016-02-24 10:49:37 -0800147 /// CHECK-NOT: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100148 /// CHECK: ArraySet
Aart Bike5305392016-02-24 10:49:37 -0800149 /// CHECK-NOT: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100150 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800151
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000152 static void $opt$noinline$constantIndexing2(int[] array) {
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700153 array[1] = 1;
154 array[2] = 1;
155 array[3] = 1;
Mingyao Yange295e6e2015-03-07 06:37:59 -0800156 array[4] = 1;
Aart Bike5305392016-02-24 10:49:37 -0800157 if (array[1] != 1) {
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000158 throw new Error("");
159 }
Mingyao Yange295e6e2015-03-07 06:37:59 -0800160 }
161
Aart Bik1d239822016-02-09 14:26:34 -0800162 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (before)
163 /// CHECK: BoundsCheck
164 /// CHECK: ArraySet
165 /// CHECK: BoundsCheck
166 /// CHECK: ArraySet
167 /// CHECK: BoundsCheck
168 /// CHECK: ArraySet
169 /// CHECK: BoundsCheck
170 /// CHECK: ArraySet
Aart Bike5305392016-02-24 10:49:37 -0800171 /// CHECK: BoundsCheck
172 /// CHECK: ArraySet
Aart Bik1d239822016-02-09 14:26:34 -0800173
174 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (after)
Aart Bike5305392016-02-24 10:49:37 -0800175 /// CHECK-NOT: Deoptimize
176 /// CHECK: BoundsCheck
177 /// CHECK: ArraySet
178 /// CHECK: BoundsCheck
179 /// CHECK: ArraySet
180 /// CHECK: BoundsCheck
181 /// CHECK: ArraySet
182 /// CHECK: BoundsCheck
183 /// CHECK: ArraySet
184 /// CHECK: BoundsCheck
185 /// CHECK: ArraySet
186
187 static void constantIndexing2b(int[] array) {
188 array[0] = 6;
189 array[1] = 6;
190 array[2] = 6;
191 array[3] = 6;
192 array[-1] = 1; // prevents the whole opt on [-1:4]
193 }
194
195 /// CHECK-START: void Main.constantIndexing2c(int[]) BCE (before)
196 /// CHECK: BoundsCheck
197 /// CHECK: ArraySet
198 /// CHECK: BoundsCheck
199 /// CHECK: ArraySet
200 /// CHECK: BoundsCheck
201 /// CHECK: ArraySet
202 /// CHECK: BoundsCheck
203 /// CHECK: ArraySet
204
205 /// CHECK-START: void Main.constantIndexing2c(int[]) BCE (after)
Aart Bik1d239822016-02-09 14:26:34 -0800206 /// CHECK: Deoptimize
207 /// CHECK-NOT: BoundsCheck
208 /// CHECK: ArraySet
209 /// CHECK-NOT: BoundsCheck
210 /// CHECK: ArraySet
211 /// CHECK-NOT: BoundsCheck
212 /// CHECK: ArraySet
213 /// CHECK-NOT: BoundsCheck
214 /// CHECK: ArraySet
215
Aart Bike5305392016-02-24 10:49:37 -0800216 static void constantIndexing2c(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800217 array[0] = 7;
218 array[1] = 7;
219 array[2] = 7;
220 array[3] = 7;
221 }
Mingyao Yange295e6e2015-03-07 06:37:59 -0800222
David Brazdila06d66a2015-05-28 11:14:54 +0100223 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before)
224 /// CHECK: BoundsCheck
225 /// CHECK: ArrayGet
226 /// CHECK: BoundsCheck
227 /// CHECK: ArraySet
228 /// CHECK: BoundsCheck
229 /// CHECK: ArrayGet
230 /// CHECK: BoundsCheck
231 /// CHECK: ArraySet
232 /// CHECK: BoundsCheck
233 /// CHECK: ArrayGet
234 /// CHECK: BoundsCheck
235 /// CHECK: ArraySet
236 /// CHECK: BoundsCheck
237 /// CHECK: ArrayGet
238 /// CHECK: BoundsCheck
239 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700240
David Brazdila06d66a2015-05-28 11:14:54 +0100241 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100242 /// CHECK: Deoptimize
243 /// CHECK-NOT: BoundsCheck
244 /// CHECK: ArrayGet
David Brazdila06d66a2015-05-28 11:14:54 +0100245 /// CHECK: Deoptimize
246 /// CHECK-NOT: BoundsCheck
247 /// CHECK: ArraySet
248 /// CHECK-NOT: BoundsCheck
249 /// CHECK: ArrayGet
250 /// CHECK-NOT: BoundsCheck
251 /// CHECK: ArraySet
252 /// CHECK-NOT: BoundsCheck
253 /// CHECK: ArrayGet
254 /// CHECK-NOT: BoundsCheck
255 /// CHECK: ArraySet
256 /// CHECK-NOT: BoundsCheck
257 /// CHECK: ArrayGet
258 /// CHECK-NOT: BoundsCheck
259 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700260
261 static int[] constantIndexing3(int[] array1, int[] array2, boolean copy) {
262 if (!copy) {
263 return array1;
264 }
265 array2[0] = array1[0];
266 array2[1] = array1[1];
267 array2[2] = array1[2];
268 array2[3] = array1[3];
269 return array2;
270 }
271
272
David Brazdila06d66a2015-05-28 11:14:54 +0100273 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (before)
274 /// CHECK: BoundsCheck
275 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700276
David Brazdila06d66a2015-05-28 11:14:54 +0100277 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (after)
Aart Bik1d239822016-02-09 14:26:34 -0800278 /// CHECK-NOT: Deoptimize
David Brazdila06d66a2015-05-28 11:14:54 +0100279 /// CHECK: BoundsCheck
280 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700281
282 // There is only one array access. It's not beneficial
283 // to create a compare with deoptimization instruction.
284 static void constantIndexing4(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800285 array[0] = -1;
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700286 }
287
288
David Brazdila06d66a2015-05-28 11:14:54 +0100289 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (before)
290 /// CHECK: BoundsCheck
291 /// CHECK: ArraySet
292 /// CHECK: BoundsCheck
293 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700294
David Brazdila06d66a2015-05-28 11:14:54 +0100295 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (after)
296 /// CHECK-NOT: Deoptimize
297 /// CHECK: BoundsCheck
298 /// CHECK: ArraySet
299 /// CHECK: BoundsCheck
300 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700301
302 static void constantIndexing5(int[] array) {
303 // We don't apply the deoptimization for very large constant index
304 // since it's likely to be an anomaly and will throw AIOOBE.
305 array[Integer.MAX_VALUE - 1000] = 1;
306 array[Integer.MAX_VALUE - 999] = 1;
307 array[Integer.MAX_VALUE - 998] = 1;
308 }
309
Andreas Gampe639bdd12015-06-03 11:22:45 -0700310 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (before)
311 /// CHECK: BoundsCheck
312 /// CHECK: ArraySet
313 /// CHECK: BoundsCheck
314 /// CHECK: ArraySet
315
316 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (after)
317 /// CHECK: Deoptimize
Aart Bik1d239822016-02-09 14:26:34 -0800318 /// CHECK-NOT: BoundsCheck
319 /// CHECK: ArraySet
320 /// CHECK-NOT: BoundsCheck
321 /// CHECK: ArraySet
Andreas Gampe639bdd12015-06-03 11:22:45 -0700322
323 static void constantIndexing6(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800324 array[3] = 111;
325 array[4] = 111;
326 }
327
328 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (before)
329 /// CHECK: BoundsCheck
330 /// CHECK: ArraySet
331 /// CHECK: BoundsCheck
332 /// CHECK: ArraySet
333 /// CHECK: BoundsCheck
334 /// CHECK: ArraySet
335 /// CHECK: BoundsCheck
336 /// CHECK: ArraySet
337
338 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (after)
339 /// CHECK: Deoptimize
340 /// CHECK: Deoptimize
341 /// CHECK-NOT: BoundsCheck
342 /// CHECK: ArraySet
343 /// CHECK-NOT: BoundsCheck
344 /// CHECK: ArraySet
345 /// CHECK-NOT: BoundsCheck
346 /// CHECK: ArraySet
347 /// CHECK-NOT: BoundsCheck
348 /// CHECK: ArraySet
349
350 static void constantIndexing7(int[] array, int base) {
351 // With constant offsets to symbolic base.
352 array[base] = 10;
353 array[base + 1] = 20;
354 array[base + 2] = 30;
355 array[base + 3] = 40;
356 }
357
358 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (before)
359 /// CHECK: BoundsCheck
360 /// CHECK: ArraySet
361 /// CHECK: BoundsCheck
362 /// CHECK: ArraySet
363 /// CHECK: BoundsCheck
364 /// CHECK: ArraySet
365 /// CHECK: BoundsCheck
366 /// CHECK: ArraySet
367
368 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (after)
369 /// CHECK: Deoptimize
370 /// CHECK: Deoptimize
371 /// CHECK-NOT: BoundsCheck
372 /// CHECK: ArraySet
373 /// CHECK-NOT: BoundsCheck
374 /// CHECK: ArraySet
375 /// CHECK-NOT: BoundsCheck
376 /// CHECK: ArraySet
377 /// CHECK-NOT: BoundsCheck
378 /// CHECK: ArraySet
379
380 static void constantIndexing8(int[] array, int base) {
381 // With constant offsets "both ways" to symbolic base.
382 array[base - 1] = 100;
383 array[base] = 200;
384 array[base + 1] = 300;
385 array[base + 2] = 400;
386 }
387
388 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (before)
389 /// CHECK: BoundsCheck
390 /// CHECK: ArraySet
391 /// CHECK: BoundsCheck
392 /// CHECK: ArraySet
393 /// CHECK: BoundsCheck
394 /// CHECK: ArraySet
395 /// CHECK: BoundsCheck
396 /// CHECK: ArraySet
397
398 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (after)
399 /// CHECK: Deoptimize
400 /// CHECK: Deoptimize
401 /// CHECK-NOT: BoundsCheck
402 /// CHECK: ArraySet
403 /// CHECK-NOT: BoundsCheck
404 /// CHECK: ArraySet
405 /// CHECK-NOT: BoundsCheck
406 /// CHECK: ArraySet
407 /// CHECK-NOT: BoundsCheck
408 /// CHECK: ArraySet
409 /// CHECK-NOT: BoundsCheck
410
411 static void constantIndexing9(int[] array, int base) {
412 // Final range is base..base+3 so conditional
413 // references may be included in the end.
414 array[base] = 0;
415 if (base != 12345)
416 array[base + 2] = 2;
417 array[base + 3] = 3;
418 if (base != 67890)
419 array[base + 1] = 1;
420 }
421
Aart Bikbf3f1cf2016-02-22 16:22:33 -0800422 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (before)
423 /// CHECK: BoundsCheck
424 /// CHECK: ArraySet
425 /// CHECK: BoundsCheck
426 /// CHECK: ArraySet
427 /// CHECK: BoundsCheck
428 /// CHECK: ArraySet
429 /// CHECK: BoundsCheck
430 /// CHECK: ArraySet
431
432 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (after)
433 /// CHECK: Deoptimize
434 /// CHECK: Deoptimize
435 /// CHECK-NOT: BoundsCheck
436 /// CHECK: ArraySet
437 /// CHECK-NOT: BoundsCheck
438 /// CHECK: ArraySet
439 /// CHECK-NOT: BoundsCheck
440 /// CHECK: ArraySet
441 /// CHECK-NOT: BoundsCheck
442 /// CHECK: ArraySet
443
444 static void constantIndexing10(int[] array, int base) {
445 // Offset hidden in incremented base.
446 array[base] = 1;
447 array[++base] = 2;
448 array[++base] = 3;
449 array[++base] = 4;
450 }
451
Aart Bik1d239822016-02-09 14:26:34 -0800452 static void runAllConstantIndices() {
453 int[] a1 = { 0 };
454 int[] a6 = { 0, 0, 0, 0, 0, 0 };
455
456 boolean caught = false;
457 try {
458 constantIndexing1(a1);
459 } catch (ArrayIndexOutOfBoundsException e) {
460 caught = true;
461 }
462 if (!caught) {
463 System.out.println("constant indices 1 failed!");
464 }
465
466 constantIndexing1(a6);
467 if (a6[4] != 11 || a6[5] != 11) {
468 System.out.println("constant indices 1 failed!");
469 }
470
Aart Bike5305392016-02-24 10:49:37 -0800471 $opt$noinline$constantIndexing2(a6);
472 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 1 ||
473 a6[3] != 1 || a6[4] != 1 || a6[5] != 11) {
Aart Bik1d239822016-02-09 14:26:34 -0800474 System.out.println("constant indices 2 failed!");
475 }
476
477 caught = false;
478 try {
Aart Bike5305392016-02-24 10:49:37 -0800479 constantIndexing2b(a6);
480 } catch (ArrayIndexOutOfBoundsException e) {
481 caught = true;
482 }
483 if (!caught || a6[0] != 6 || a6[1] != 6 || a6[2] != 6 ||
484 a6[3] != 6 || a6[4] != 1 || a6[5] != 11) {
485 System.out.println("constant indices 2b failed!");
486 }
487
488 caught = false;
489 try {
490 constantIndexing2c(a1);
Aart Bik1d239822016-02-09 14:26:34 -0800491 } catch (ArrayIndexOutOfBoundsException e) {
492 caught = true;
493 }
494 if (!caught || a1[0] != 7) {
Aart Bike5305392016-02-24 10:49:37 -0800495 System.out.println("constant indices 2c failed!");
Aart Bik1d239822016-02-09 14:26:34 -0800496 }
497
Aart Bike5305392016-02-24 10:49:37 -0800498 constantIndexing2c(a6);
Aart Bik1d239822016-02-09 14:26:34 -0800499 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
500 a6[3] != 7 || a6[4] != 1 || a6[5] != 11) {
Aart Bike5305392016-02-24 10:49:37 -0800501 System.out.println("constant indices 2c failed!");
Aart Bik1d239822016-02-09 14:26:34 -0800502 }
503
504 int[] b4 = new int[4];
505 constantIndexing3(a6, b4, true);
506 if (b4[0] != 7 || b4[1] != 7 || b4[2] != 7 || b4[3] != 7) {
507 System.out.println("constant indices 3 failed!");
508 }
509
510 constantIndexing4(a1);
511 if (a1[0] != -1) {
512 System.out.println("constant indices 4 failed!");
513 }
514
515 caught = false;
516 try {
517 constantIndexing5(a6);
518 } catch (ArrayIndexOutOfBoundsException e) {
519 caught = true;
520 }
521 if (!caught) {
522 System.out.println("constant indices 5 failed!");
523 }
524
525 constantIndexing6(a6);
526 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
527 a6[3] != 111 || a6[4] != 111 || a6[5] != 11) {
528 System.out.println("constant indices 6 failed!");
529 }
530
531 constantIndexing7(a6, 1);
532 if (a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
533 a6[3] != 30 || a6[4] != 40 || a6[5] != 11) {
534 System.out.println("constant indices 7 failed!");
535 }
536
537 caught = false;
538 try {
539 constantIndexing7(a6, 5);
540 } catch (ArrayIndexOutOfBoundsException e) {
541 caught = true;
542 }
543 if (!caught || a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
544 a6[3] != 30 || a6[4] != 40 || a6[5] != 10) {
545 System.out.println("constant indices 7 failed!");
546 }
547
548 constantIndexing8(a6, 1);
549 if (a6[0] != 100 || a6[1] != 200 || a6[2] != 300 ||
550 a6[3] != 400 || a6[4] != 40 || a6[5] != 10) {
551 System.out.println("constant indices 8 failed!");
552 }
553
554 caught = false;
555 try {
556 constantIndexing8(a6, 0);
557 } catch (ArrayIndexOutOfBoundsException e) {
558 caught = true;
559 }
560 if (!caught || a6[0] != 100) {
561 System.out.println("constant indices 8 failed!");
562 }
563
564 constantIndexing9(a6, 0);
565 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 2 ||
566 a6[3] != 3 || a6[4] != 40 || a6[5] != 10) {
567 System.out.println("constant indices 9 failed!");
568 }
Aart Bikbf3f1cf2016-02-22 16:22:33 -0800569
570 constantIndexing10(a6, 0);
571 if (a6[0] != 1 || a6[1] != 2 || a6[2] != 3 ||
572 a6[3] != 4 || a6[4] != 40 || a6[5] != 10) {
573 System.out.println("constant indices 10 failed!");
574 }
Andreas Gampe639bdd12015-06-03 11:22:45 -0700575 }
576
577 // A helper into which the actual throwing function should be inlined.
578 static void constantIndexingForward6(int[] array) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700579 assertIsManaged();
Andreas Gampe639bdd12015-06-03 11:22:45 -0700580 constantIndexing6(array);
581 }
582
David Brazdila06d66a2015-05-28 11:14:54 +0100583 /// CHECK-START: void Main.loopPattern1(int[]) BCE (before)
584 /// CHECK: BoundsCheck
585 /// CHECK: ArraySet
586 /// CHECK: BoundsCheck
587 /// CHECK: ArraySet
588 /// CHECK: BoundsCheck
589 /// CHECK: ArraySet
590 /// CHECK: BoundsCheck
591 /// CHECK: ArraySet
592 /// CHECK: BoundsCheck
593 /// CHECK: ArraySet
594 /// CHECK: BoundsCheck
595 /// CHECK: ArraySet
596 /// CHECK: BoundsCheck
597 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800598
David Brazdila06d66a2015-05-28 11:14:54 +0100599 /// CHECK-START: void Main.loopPattern1(int[]) BCE (after)
600 /// CHECK-NOT: BoundsCheck
601 /// CHECK: ArraySet
602 /// CHECK-NOT: BoundsCheck
603 /// CHECK: ArraySet
604 /// CHECK-NOT: BoundsCheck
605 /// CHECK: ArraySet
606 /// CHECK: BoundsCheck
607 /// CHECK: ArraySet
608 /// CHECK: BoundsCheck
609 /// CHECK: ArraySet
610 /// CHECK: BoundsCheck
611 /// CHECK: ArraySet
612 /// CHECK-NOT: BoundsCheck
613 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800614
615 static void loopPattern1(int[] array) {
616 for (int i = 0; i < array.length; i++) {
617 array[i] = 1; // Bounds check can be eliminated.
618 }
619
620 for (int i = 1; i < array.length; i++) {
621 array[i] = 1; // Bounds check can be eliminated.
622 }
623
624 for (int i = 1; i < array.length - 1; i++) {
625 array[i] = 1; // Bounds check can be eliminated.
626 }
627
628 for (int i = -1; i < array.length; i++) {
629 array[i] = 1; // Bounds check can't be eliminated.
630 }
631
632 for (int i = 0; i <= array.length; i++) {
633 array[i] = 1; // Bounds check can't be eliminated.
634 }
635
636 for (int i = 0; i < array.length; i += 2) {
637 // We don't have any assumption on max array length yet.
638 // Bounds check can't be eliminated due to overflow concern.
639 array[i] = 1;
640 }
641
642 for (int i = 1; i < array.length; i += 2) {
643 // Bounds check can be eliminated since i is odd so the last
644 // i that's less than array.length is at most (Integer.MAX_VALUE - 2).
645 array[i] = 1;
646 }
647 }
648
649
David Brazdila06d66a2015-05-28 11:14:54 +0100650 /// CHECK-START: void Main.loopPattern2(int[]) BCE (before)
651 /// CHECK: BoundsCheck
652 /// CHECK: ArraySet
653 /// CHECK: BoundsCheck
654 /// CHECK: ArraySet
655 /// CHECK: BoundsCheck
656 /// CHECK: ArraySet
657 /// CHECK: BoundsCheck
658 /// CHECK: ArraySet
659 /// CHECK: BoundsCheck
660 /// CHECK: ArraySet
661 /// CHECK: BoundsCheck
662 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800663
David Brazdila06d66a2015-05-28 11:14:54 +0100664 /// CHECK-START: void Main.loopPattern2(int[]) BCE (after)
665 /// CHECK-NOT: BoundsCheck
666 /// CHECK: ArraySet
667 /// CHECK-NOT: BoundsCheck
668 /// CHECK: ArraySet
669 /// CHECK-NOT: BoundsCheck
670 /// CHECK: ArraySet
671 /// CHECK: BoundsCheck
672 /// CHECK: ArraySet
673 /// CHECK: BoundsCheck
674 /// CHECK: ArraySet
675 /// CHECK-NOT: BoundsCheck
676 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800677
678 static void loopPattern2(int[] array) {
679 for (int i = array.length - 1; i >= 0; i--) {
680 array[i] = 1; // Bounds check can be eliminated.
681 }
682
683 for (int i = array.length; i > 0; i--) {
684 array[i - 1] = 1; // Bounds check can be eliminated.
685 }
686
687 for (int i = array.length - 1; i > 0; i--) {
688 array[i] = 1; // Bounds check can be eliminated.
689 }
690
691 for (int i = array.length; i >= 0; i--) {
692 array[i] = 1; // Bounds check can't be eliminated.
693 }
694
695 for (int i = array.length; i >= 0; i--) {
696 array[i - 1] = 1; // Bounds check can't be eliminated.
697 }
698
699 for (int i = array.length; i > 0; i -= 20) {
700 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow.
701 array[i - 1] = 1; // Bounds check can be eliminated.
702 }
703 }
704
705
David Brazdila06d66a2015-05-28 11:14:54 +0100706 /// CHECK-START: void Main.loopPattern3(int[]) BCE (before)
707 /// CHECK: BoundsCheck
708 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800709
David Brazdila06d66a2015-05-28 11:14:54 +0100710 /// CHECK-START: void Main.loopPattern3(int[]) BCE (after)
711 /// CHECK: BoundsCheck
712 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800713
714 static void loopPattern3(int[] array) {
715 java.util.Random random = new java.util.Random();
716 for (int i = 0; ; i++) {
717 if (random.nextInt() % 1000 == 0 && i < array.length) {
718 // Can't eliminate the bound check since not every i++ is
719 // matched with a array length check, so there is some chance that i
720 // overflows and is negative.
721 array[i] = 1;
722 }
723 }
724 }
725
726
David Brazdila06d66a2015-05-28 11:14:54 +0100727 /// CHECK-START: void Main.constantNewArray() BCE (before)
728 /// CHECK: BoundsCheck
729 /// CHECK: ArraySet
730 /// CHECK: BoundsCheck
731 /// CHECK: ArraySet
732 /// CHECK: BoundsCheck
733 /// CHECK: ArraySet
734 /// CHECK: BoundsCheck
735 /// CHECK: ArraySet
736 /// CHECK: BoundsCheck
737 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800738
David Brazdila06d66a2015-05-28 11:14:54 +0100739 /// CHECK-START: void Main.constantNewArray() BCE (after)
740 /// CHECK-NOT: BoundsCheck
741 /// CHECK: ArraySet
742 /// CHECK: BoundsCheck
743 /// CHECK: ArraySet
744 /// CHECK-NOT: BoundsCheck
745 /// CHECK: ArraySet
746 /// CHECK-NOT: BoundsCheck
747 /// CHECK: ArraySet
748 /// CHECK: BoundsCheck
749 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800750
751 static void constantNewArray() {
752 int[] array = new int[10];
753 for (int i = 0; i < 10; i++) {
754 array[i] = 1; // Bounds check can be eliminated.
755 }
756
757 for (int i = 0; i <= 10; i++) {
758 array[i] = 1; // Bounds check can't be eliminated.
759 }
760
761 array[0] = 1; // Bounds check can be eliminated.
762 array[9] = 1; // Bounds check can be eliminated.
763 array[10] = 1; // Bounds check can't be eliminated.
764 }
765
Mingyao Yang4559f002015-02-27 14:43:53 -0800766
767 static byte readData() {
768 return 1;
769 }
770
David Brazdila06d66a2015-05-28 11:14:54 +0100771 /// CHECK-START: void Main.circularBufferProducer() BCE (before)
772 /// CHECK: BoundsCheck
773 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800774
David Brazdila06d66a2015-05-28 11:14:54 +0100775 /// CHECK-START: void Main.circularBufferProducer() BCE (after)
776 /// CHECK-NOT: BoundsCheck
777 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800778
779 static void circularBufferProducer() {
780 byte[] array = new byte[4096];
781 int i = 0;
782 while (true) {
783 array[i & (array.length - 1)] = readData();
784 i++;
785 }
786 }
787
788
David Brazdila06d66a2015-05-28 11:14:54 +0100789 /// CHECK-START: void Main.pyramid1(int[]) BCE (before)
790 /// CHECK: BoundsCheck
791 /// CHECK: ArraySet
792 /// CHECK: BoundsCheck
793 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800794
David Brazdila06d66a2015-05-28 11:14:54 +0100795 /// CHECK-START: void Main.pyramid1(int[]) BCE (after)
796 /// CHECK-NOT: BoundsCheck
797 /// CHECK: ArraySet
798 /// CHECK-NOT: BoundsCheck
799 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800800
801 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
802 static void pyramid1(int[] array) {
803 for (int i = 0; i < (array.length + 1) / 2; i++) {
804 array[i] = i;
805 array[array.length - 1 - i] = i;
806 }
807 }
808
809
David Brazdila06d66a2015-05-28 11:14:54 +0100810 /// CHECK-START: void Main.pyramid2(int[]) BCE (before)
811 /// CHECK: BoundsCheck
812 /// CHECK: ArraySet
813 /// CHECK: BoundsCheck
814 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800815
David Brazdila06d66a2015-05-28 11:14:54 +0100816 /// CHECK-START: void Main.pyramid2(int[]) BCE (after)
817 /// CHECK-NOT: BoundsCheck
818 /// CHECK: ArraySet
819 /// CHECK-NOT: BoundsCheck
820 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800821
822 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
823 static void pyramid2(int[] array) {
824 for (int i = 0; i < (array.length + 1) >> 1; i++) {
825 array[i] = i;
826 array[array.length - 1 - i] = i;
827 }
828 }
829
830
David Brazdila06d66a2015-05-28 11:14:54 +0100831 /// CHECK-START: void Main.pyramid3(int[]) BCE (before)
832 /// CHECK: BoundsCheck
833 /// CHECK: ArraySet
834 /// CHECK: BoundsCheck
835 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800836
David Brazdila06d66a2015-05-28 11:14:54 +0100837 /// CHECK-START: void Main.pyramid3(int[]) BCE (after)
838 /// CHECK-NOT: BoundsCheck
839 /// CHECK: ArraySet
840 /// CHECK-NOT: BoundsCheck
841 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800842
843 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
844 static void pyramid3(int[] array) {
845 for (int i = 0; i < (array.length + 1) >>> 1; i++) {
846 array[i] = i;
847 array[array.length - 1 - i] = i;
848 }
849 }
850
851
David Brazdila06d66a2015-05-28 11:14:54 +0100852 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
853 /// CHECK: BoundsCheck
854 /// CHECK: ArrayGet
855 /// CHECK: BoundsCheck
856 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800857
David Brazdila06d66a2015-05-28 11:14:54 +0100858 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
859 /// CHECK-NOT: BoundsCheck
860 /// CHECK: ArrayGet
861 /// CHECK-NOT: BoundsCheck
862 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800863
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800864 static boolean isPyramid(int[] array) {
865 int i = 0;
866 int j = array.length - 1;
867 while (i <= j) {
868 if (array[i] != i) {
869 return false;
870 }
871 if (array[j] != i) {
872 return false;
873 }
874 i++; j--;
875 }
876 return true;
877 }
878
879
David Brazdila06d66a2015-05-28 11:14:54 +0100880 /// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
881 /// CHECK: BoundsCheck
882 /// CHECK: ArrayGet
883 /// CHECK: BoundsCheck
884 /// CHECK: ArrayGet
885 /// CHECK: BoundsCheck
886 /// CHECK: ArrayGet
887 /// CHECK: BoundsCheck
888 /// CHECK: ArrayGet
889 /// CHECK: BoundsCheck
890 /// CHECK: ArraySet
891 /// CHECK: BoundsCheck
892 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800893
David Brazdila06d66a2015-05-28 11:14:54 +0100894 /// CHECK-START: void Main.bubbleSort(int[]) GVN (after)
895 /// CHECK: BoundsCheck
896 /// CHECK: ArrayGet
897 /// CHECK: BoundsCheck
898 /// CHECK: ArrayGet
899 /// CHECK-NOT: ArrayGet
900 /// CHECK-NOT: ArrayGet
901 /// CHECK-NOT: BoundsCheck
902 /// CHECK: ArraySet
903 /// CHECK-NOT: BoundsCheck
904 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800905
David Brazdila06d66a2015-05-28 11:14:54 +0100906 /// CHECK-START: void Main.bubbleSort(int[]) BCE (after)
907 /// CHECK-NOT: BoundsCheck
908 /// CHECK: ArrayGet
909 /// CHECK-NOT: BoundsCheck
910 /// CHECK: ArrayGet
911 /// CHECK-NOT: ArrayGet
912 /// CHECK-NOT: ArrayGet
913 /// CHECK-NOT: BoundsCheck
914 /// CHECK: ArraySet
915 /// CHECK-NOT: BoundsCheck
916 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800917
918 static void bubbleSort(int[] array) {
919 for (int i = 0; i < array.length - 1; i++) {
920 for (int j = 0; j < array.length - i - 1; j++) {
921 if (array[j] > array[j + 1]) {
922 int temp = array[j + 1];
923 array[j + 1] = array[j];
924 array[j] = temp;
925 }
926 }
927 }
928 }
929
Aart Bik5d75afe2015-12-14 11:57:01 -0800930 static int[][] mA;
931
932 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800933 // Array references mA[i] and ..[j] both in inner loop.
934 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Bounds1:i\d+>>] loop:<<InnerLoop:B\d+>>
935 /// CHECK-DAG: <<Array1>> NullCheck [<<Field1:l\d+>>] loop:<<InnerLoop>>
936 /// CHECK-DAG: <<Len1:i\d+>> ArrayLength [<<Array1>>] loop:<<InnerLoop>>
937 /// CHECK-DAG: <<Bounds1>> BoundsCheck [<<Index1:i\d+>>,<<Len1>>] loop:<<InnerLoop>>
938 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Bounds2:i\d+>>] loop:<<InnerLoop>>
939 /// CHECK-DAG: <<Array2>> NullCheck [<<Get1>>] loop:<<InnerLoop>>
940 /// CHECK-DAG: <<Len2:i\d+>> ArrayLength [<<Array2>>] loop:<<InnerLoop>>
941 /// CHECK-DAG: <<Bounds2>> BoundsCheck [<<Index2:i\d+>>,<<Len2>>] loop:<<InnerLoop>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000942 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
943 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800944 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
945 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop:B\d+>>
946 /// CHECK-DAG: <<Field1>> StaticFieldGet loop:none
947 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
948 //
949 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
950 // Array reference mA[i] hoisted to same level as deopt.
951 /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>>
952 /// CHECK-DAG: ArrayLength loop:<<OuterLoop>>
953 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Index1:i\d+>>] loop:<<OuterLoop>>
954 // Array reference ..[j] still in inner loop, with a direct index.
955 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Index2:i\d+>>] loop:<<InnerLoop:B\d+>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000956 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
957 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800958 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
959 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop>>
960 // Synthetic phi.
961 /// CHECK-DAG: <<Array2>> Phi loop:<<OuterLoop>>
962 /// CHECK-DAG: <<Array1>> StaticFieldGet loop:none
963 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
964 //
Aart Bik5d75afe2015-12-14 11:57:01 -0800965 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
966 /// CHECK-NOT: NullCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800967 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800968 static void dynamicBCEAndIntrinsic(int n) {
969 for (int i = 0; i < n; i++) {
970 for (int j = 0; j < n; j++) {
971 // Since intrinsic call cannot modify fields or arrays,
972 // dynamic BCE and hoisting can be applied to the inner loop.
973 mA[i][j] = Math.abs(mA[i][j]);
974 }
975 }
976 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800977
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700978 static int foo() {
979 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700980 assertIsManaged();
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700981 // This will cause AIOOBE.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000982 $opt$noinline$constantIndexing2(new int[3]);
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700983 } catch (ArrayIndexOutOfBoundsException e) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700984 assertIsManaged(); // This is to ensure that single-frame deoptimization works.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000985 // Will need to be updated if $opt$noinline$constantIndexing2 is inlined.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700986 try {
987 // This will cause AIOOBE.
988 constantIndexingForward6(new int[3]);
989 } catch (ArrayIndexOutOfBoundsException e2) {
David Brazdil95177982015-10-30 12:56:58 -0500990 // Having deopted, we expect to be running interpreted at this point.
991 // Does not apply to debuggable, however, since we do not inline.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700992 return 99;
993 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700994 }
995 return 0;
996 }
997
998
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700999 int sum;
1000
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001001 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001002 /// CHECK: BoundsCheck
1003 /// CHECK: ArraySet
1004 /// CHECK-NOT: BoundsCheck
1005 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001006
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001007 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001008 /// CHECK: Phi
1009 /// CHECK-NOT: BoundsCheck
1010 /// CHECK: ArraySet
1011 /// CHECK-NOT: BoundsCheck
1012 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001013 // Added blocks at end for deoptimization.
1014 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001015 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001016 /// CHECK: Deoptimize
1017 /// CHECK: Deoptimize
1018 /// CHECK: Deoptimize
1019 /// CHECK-NOT: Deoptimize
1020 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001021 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001022 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001023
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001024 void foo1(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001025 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001026 // and one for null check on array (to hoist null
1027 // check and array.length out of loop).
1028 for (int i = start ; i < end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001029 if (expectInterpreter) {
1030 assertIsInterpreted();
1031 } else {
1032 assertIsManaged();
1033 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001034 array[i] = 1;
1035 sum += array[i];
1036 }
1037 }
1038
1039
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001040 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001041 /// CHECK: BoundsCheck
1042 /// CHECK: ArraySet
1043 /// CHECK-NOT: BoundsCheck
1044 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001045 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001046 /// CHECK: Phi
1047 /// CHECK-NOT: BoundsCheck
1048 /// CHECK: ArraySet
1049 /// CHECK-NOT: BoundsCheck
1050 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001051 // Added blocks at end for deoptimization.
1052 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001053 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001054 /// CHECK: Deoptimize
1055 /// CHECK: Deoptimize
1056 /// CHECK: Deoptimize
1057 /// CHECK-NOT: Deoptimize
1058 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001059 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001060 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001061
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001062 void foo2(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001063 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001064 // and one for null check on array (to hoist null
1065 // check and array.length out of loop).
1066 for (int i = start ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001067 if (expectInterpreter) {
1068 assertIsInterpreted();
1069 } else {
1070 assertIsManaged();
1071 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001072 array[i] = 1;
1073 sum += array[i];
1074 }
1075 }
1076
1077
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001078 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001079 /// CHECK: BoundsCheck
1080 /// CHECK: ArraySet
1081 /// CHECK-NOT: BoundsCheck
1082 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001083 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001084 /// CHECK: Phi
1085 /// CHECK-NOT: BoundsCheck
1086 /// CHECK: ArraySet
1087 /// CHECK-NOT: BoundsCheck
1088 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001089 // Added blocks at end for deoptimization.
1090 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001091 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001092 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001093 /// CHECK: Deoptimize
1094 /// CHECK: Deoptimize
1095 /// CHECK-NOT: Deoptimize
1096 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001097 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001098 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001099
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001100 void foo3(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001101 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001102 // and one for null check on array (to hoist null check
1103 // and array.length out of loop).
1104 for (int i = 3 ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001105 if (expectInterpreter) {
1106 assertIsInterpreted();
1107 } else {
1108 assertIsManaged();
1109 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001110 array[i] = 1;
1111 sum += array[i];
1112 }
1113 }
1114
Mingyao Yang3584bce2015-05-19 16:01:59 -07001115
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001116 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001117 /// CHECK: BoundsCheck
1118 /// CHECK: ArraySet
1119 /// CHECK-NOT: BoundsCheck
1120 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001121
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001122 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001123 /// CHECK: Phi
1124 /// CHECK-NOT: BoundsCheck
1125 /// CHECK: ArraySet
1126 /// CHECK-NOT: BoundsCheck
1127 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001128 // Added blocks at end for deoptimization.
1129 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001130 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001131 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001132 /// CHECK: Deoptimize
1133 /// CHECK: Deoptimize
1134 /// CHECK-NOT: Deoptimize
1135 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001136 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001137 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001138
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001139 void foo4(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001140 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001141 // and one for null check on array (to hoist null check
1142 // and array.length out of loop).
1143 for (int i = end ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001144 if (expectInterpreter) {
1145 assertIsInterpreted();
1146 } else {
1147 assertIsManaged();
1148 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001149 array[i - 1] = 1;
1150 sum += array[i - 1];
1151 }
1152 }
1153
1154
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001155 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001156 /// CHECK: BoundsCheck
1157 /// CHECK: ArraySet
1158 /// CHECK: BoundsCheck
1159 /// CHECK: ArrayGet
1160 /// CHECK: BoundsCheck
1161 /// CHECK: ArrayGet
1162 /// CHECK: BoundsCheck
1163 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001164
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001165 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001166 /// CHECK-NOT: BoundsCheck
1167 /// CHECK: ArraySet
David Brazdila06d66a2015-05-28 11:14:54 +01001168 /// CHECK: Phi
1169 /// CHECK-NOT: BoundsCheck
1170 /// CHECK: ArrayGet
1171 /// CHECK-NOT: BoundsCheck
1172 /// CHECK: ArrayGet
1173 /// CHECK-NOT: BoundsCheck
1174 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001175 // Added blocks at end for deoptimization.
1176 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001177 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001178 /// CHECK: Deoptimize
1179 /// CHECK: Deoptimize
1180 /// CHECK: Deoptimize
1181 /// CHECK: Deoptimize
1182 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001183 /// CHECK: Deoptimize
1184 /// CHECK-NOT: Deoptimize
1185 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001186 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001187 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001188
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001189 void foo5(int[] array, int end, boolean expectInterpreter) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001190 // Bounds check in this loop can be eliminated without deoptimization.
1191 for (int i = array.length - 1 ; i >= 0; i--) {
1192 array[i] = 1;
1193 }
Aart Bik4a342772015-11-30 10:17:46 -08001194 // Several HDeoptimize will be added. Two for each index.
1195 // The null check is not necessary.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001196 for (int i = end - 2 ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001197 if (expectInterpreter) {
1198 assertIsInterpreted();
1199 } else {
1200 assertIsManaged();
1201 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001202 sum += array[i - 1];
1203 sum += array[i];
1204 sum += array[i + 1];
1205 }
1206 }
1207
1208
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001209 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001210 /// CHECK: BoundsCheck
1211 /// CHECK: ArrayGet
1212 /// CHECK: BoundsCheck
1213 /// CHECK: ArrayGet
1214 /// CHECK: BoundsCheck
1215 /// CHECK: ArrayGet
1216 /// CHECK: BoundsCheck
1217 /// CHECK: ArrayGet
1218 /// CHECK: BoundsCheck
1219 /// CHECK: ArrayGet
1220 /// CHECK-NOT: BoundsCheck
1221 /// CHECK: ArraySet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001222 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001223 /// CHECK: Phi
1224 /// CHECK-NOT: BoundsCheck
1225 /// CHECK: ArrayGet
1226 /// CHECK-NOT: BoundsCheck
1227 /// CHECK: ArrayGet
1228 /// CHECK-NOT: BoundsCheck
1229 /// CHECK: ArrayGet
1230 /// CHECK-NOT: BoundsCheck
1231 /// CHECK: ArrayGet
1232 /// CHECK-NOT: BoundsCheck
1233 /// CHECK: ArrayGet
1234 /// CHECK-NOT: BoundsCheck
1235 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001236 // Added blocks at end for deoptimization.
1237 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001238 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001239 /// CHECK: Deoptimize
1240 /// CHECK: Deoptimize
1241 /// CHECK: Deoptimize
1242 /// CHECK: Deoptimize
1243 /// CHECK: Deoptimize
1244 /// CHECK: Deoptimize
1245 /// CHECK: Deoptimize
1246 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001247 /// CHECK: Deoptimize
1248 /// CHECK: Deoptimize
1249 /// CHECK: Deoptimize
1250 /// CHECK-NOT: Deoptimize
1251 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001252 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001253 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001254
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001255 void foo6(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001256 // Several HDeoptimize will be added.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001257 for (int i = end; i >= start; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001258 if (expectInterpreter) {
1259 assertIsInterpreted();
1260 } else {
1261 assertIsManaged();
1262 }
Aart Bik591ad292016-03-01 10:39:25 -08001263 array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001264 }
1265 }
1266
1267
David Brazdila06d66a2015-05-28 11:14:54 +01001268 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
1269 /// CHECK: BoundsCheck
1270 /// CHECK: ArrayGet
1271 /// CHECK: BoundsCheck
1272 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001273
David Brazdila06d66a2015-05-28 11:14:54 +01001274 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001275 /// CHECK: Phi
1276 /// CHECK: BoundsCheck
1277 /// CHECK: ArrayGet
1278 /// CHECK-NOT: BoundsCheck
1279 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001280 // Added blocks at end for deoptimization.
1281 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001282 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001283 /// CHECK: Deoptimize
1284 /// CHECK: Deoptimize
1285 /// CHECK: Deoptimize
1286 /// CHECK-NOT: Deoptimize
1287 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001288 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001289 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001290
1291 void foo7(int[] array, int start, int end, boolean lowEnd) {
Aart Bik4a342772015-11-30 10:17:46 -08001292 // Three HDeoptimize will be added. One for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001293 // and one for null check on array (to hoist null
1294 // check and array.length out of loop).
1295 for (int i = start ; i < end; i++) {
1296 if (lowEnd) {
1297 // This array access isn't certain. So we don't
1298 // use +1000 offset in decision making for deoptimization
1299 // conditions.
1300 sum += array[i + 1000];
1301 }
1302 sum += array[i];
1303 }
1304 }
1305
1306
Mingyao Yang3584bce2015-05-19 16:01:59 -07001307 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (before)
1308 /// CHECK: BoundsCheck
1309 /// CHECK: ArrayGet
1310 /// CHECK: BoundsCheck
1311 /// CHECK: ArraySet
1312
1313 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (after)
1314 /// CHECK: Phi
1315 /// CHECK-NOT: BoundsCheck
1316 /// CHECK: ArrayGet
1317 /// CHECK: Phi
1318 /// CHECK-NOT: BoundsCheck
1319 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001320 // Added blocks at end for deoptimization.
1321 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001322 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001323 /// CHECK: Deoptimize
1324 /// CHECK: Deoptimize
1325 /// CHECK: Deoptimize
Aart Bikd59c7062015-11-21 05:21:52 +00001326 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001327 /// CHECK: Goto
1328 /// CHECK: Goto
1329 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001330 /// CHECK: Deoptimize
1331 /// CHECK: Deoptimize
1332 /// CHECK: Deoptimize
1333 /// CHECK-NOT: Deoptimize
1334 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001335 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001336 /// CHECK: Goto
1337
1338 void foo8(int[][] matrix, int start, int end) {
Aart Bik4a342772015-11-30 10:17:46 -08001339 // Three HDeoptimize will be added for the outer loop,
1340 // two for the index, and null check on matrix. Same
1341 // for the inner loop.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001342 for (int i = start; i < end; i++) {
1343 int[] row = matrix[i];
1344 for (int j = start; j < end; j++) {
1345 row[j] = 1;
1346 }
1347 }
1348 }
1349
1350
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001351 /// CHECK-START: void Main.foo9(int[], boolean) BCE (before)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001352 /// CHECK: NullCheck
1353 /// CHECK: BoundsCheck
1354 /// CHECK: ArrayGet
1355
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001356 /// CHECK-START: void Main.foo9(int[], boolean) BCE (after)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001357 // The loop is guaranteed to be entered. No need to transform the
1358 // loop for loop body entry test.
1359 /// CHECK: Deoptimize
1360 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001361 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001362 /// CHECK-NOT: Deoptimize
1363 /// CHECK: Phi
1364 /// CHECK-NOT: NullCheck
1365 /// CHECK-NOT: BoundsCheck
1366 /// CHECK: ArrayGet
1367
Aart Bik4a342772015-11-30 10:17:46 -08001368 /// CHECK-START: void Main.foo9(int[], boolean) instruction_simplifier_after_bce (after)
1369 // Simplification removes the redundant check
1370 /// CHECK: Deoptimize
1371 /// CHECK: Deoptimize
1372 /// CHECK-NOT: Deoptimize
1373
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001374 void foo9(int[] array, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001375 // Two HDeoptimize will be added. Two for the index
1376 // and one for null check on array.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001377 for (int i = 0 ; i < 10; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001378 if (expectInterpreter) {
1379 assertIsInterpreted();
1380 } else {
1381 assertIsManaged();
1382 }
Mingyao Yang3584bce2015-05-19 16:01:59 -07001383 sum += array[i];
1384 }
1385 }
1386
1387
David Brazdila06d66a2015-05-28 11:14:54 +01001388 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
1389 /// CHECK: BoundsCheck
1390 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001391
David Brazdila06d66a2015-05-28 11:14:54 +01001392 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
1393 /// CHECK-NOT: Deoptimize
1394 /// CHECK: BoundsCheck
1395 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001396
1397 void partialLooping(int[] array, int start, int end) {
1398 // This loop doesn't cover the full range of [start, end) so
1399 // adding deoptimization is too aggressive, since end can be
1400 // greater than array.length but the loop is never going to work on
1401 // more than 2 elements.
1402 for (int i = start; i < end; i++) {
1403 if (i == 2) {
1404 return;
1405 }
1406 array[i] = 1;
1407 }
1408 }
1409
1410
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001411 static void testUnknownBounds() {
1412 boolean caught = false;
Aart Bik1d239822016-02-09 14:26:34 -08001413
1414 runAllConstantIndices();
1415
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001416 Main main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001417 main.foo1(new int[10], 0, 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001418 if (main.sum != 10) {
1419 System.out.println("foo1 failed!");
1420 }
1421
1422 caught = false;
1423 main = new Main();
1424 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001425 main.foo1(new int[10], 0, 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001426 } catch (ArrayIndexOutOfBoundsException e) {
1427 caught = true;
1428 }
1429 if (!caught || main.sum != 10) {
1430 System.out.println("foo1 exception failed!");
1431 }
1432
1433 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001434 main.foo2(new int[10], 0, 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001435 if (main.sum != 10) {
1436 System.out.println("foo2 failed!");
1437 }
1438
1439 caught = false;
1440 main = new Main();
1441 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001442 main.foo2(new int[10], 0, 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001443 } catch (ArrayIndexOutOfBoundsException e) {
1444 caught = true;
1445 }
1446 if (!caught || main.sum != 10) {
1447 System.out.println("foo2 exception failed!");
1448 }
1449
1450 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001451 main.foo3(new int[10], 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001452 if (main.sum != 7) {
1453 System.out.println("foo3 failed!");
1454 }
1455
1456 caught = false;
1457 main = new Main();
1458 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001459 main.foo3(new int[10], 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001460 } catch (ArrayIndexOutOfBoundsException e) {
1461 caught = true;
1462 }
1463 if (!caught || main.sum != 7) {
1464 System.out.println("foo3 exception failed!");
1465 }
1466
1467 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001468 main.foo4(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001469 if (main.sum != 10) {
1470 System.out.println("foo4 failed!");
1471 }
1472
1473 caught = false;
1474 main = new Main();
1475 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001476 main.foo4(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001477 } catch (ArrayIndexOutOfBoundsException e) {
1478 caught = true;
1479 }
1480 if (!caught || main.sum != 0) {
1481 System.out.println("foo4 exception failed!");
1482 }
1483
1484 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001485 main.foo5(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001486 if (main.sum != 24) {
1487 System.out.println("foo5 failed!");
1488 }
1489
1490 caught = false;
1491 main = new Main();
1492 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001493 main.foo5(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001494 } catch (ArrayIndexOutOfBoundsException e) {
1495 caught = true;
1496 }
1497 if (!caught || main.sum != 2) {
1498 System.out.println("foo5 exception failed!");
1499 }
1500
1501 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001502 main.foo6(new int[10], 2, 7, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001503
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001504 main = new Main();
Mingyao Yang3584bce2015-05-19 16:01:59 -07001505 int[] array9 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001506 main.foo9(array9, false);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001507 if (main.sum != 45) {
1508 System.out.println("foo9 failed!");
1509 }
1510
1511 main = new Main();
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001512 int[] array = new int[4];
1513 main.partialLooping(new int[3], 0, 4);
1514 if ((array[0] != 1) && (array[1] != 1) &&
1515 (array[2] != 0) && (array[3] != 0)) {
1516 System.out.println("partialLooping failed!");
1517 }
1518
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001519 caught = false;
1520 main = new Main();
1521 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001522 main.foo6(new int[10], 2, 8, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001523 } catch (ArrayIndexOutOfBoundsException e) {
1524 caught = true;
1525 }
1526 if (!caught) {
1527 System.out.println("foo6 exception failed!");
1528 }
1529
1530 caught = false;
1531 main = new Main();
1532 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001533 main.foo6(new int[10], 1, 7, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001534 } catch (ArrayIndexOutOfBoundsException e) {
1535 caught = true;
1536 }
1537 if (!caught) {
1538 System.out.println("foo6 exception failed!");
1539 }
1540
1541 }
1542
Mingyao Yang718493c2015-07-22 15:56:34 -07001543 public void testExceptionMessage() {
1544 short[] B1 = new short[5];
1545 int[] B2 = new int[5];
1546 Exception err = null;
1547 try {
1548 testExceptionMessage1(B1, B2, null, -1, 6);
1549 } catch (Exception e) {
1550 err = e;
1551 }
1552 System.out.println(err);
1553 }
1554
1555 void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) {
1556 int j = finish + 77;
1557 // Bug: 22665511
1558 // A deoptimization will be triggered here right before the loop. Need to make
1559 // sure the value of j is preserved for the interpreter.
1560 for (int i = start; i <= finish; i++) {
1561 a2[j - 1] = a1[i + 1];
1562 }
1563 }
1564
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001565 // Make sure this method is compiled with optimizing.
David Brazdila06d66a2015-05-28 11:14:54 +01001566 /// CHECK-START: void Main.main(java.lang.String[]) register (after)
1567 /// CHECK: ParallelMove
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001568
Mingyao Yang0304e182015-01-30 16:41:29 -08001569 public static void main(String[] args) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001570 System.loadLibrary(args[0]);
1571
1572 if (!compiledWithOptimizing() ||
1573 !hasOatFile() ||
1574 runtimeIsSoftFail() ||
1575 isInterpreted()) {
1576 disableStackFrameAsserts();
1577 }
1578
Mingyao Yang0304e182015-01-30 16:41:29 -08001579 sieve(20);
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001580
1581 int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
1582 bubbleSort(array);
1583 for (int i = 0; i < 8; i++) {
1584 if (array[i] != i) {
1585 System.out.println("bubble sort failed!");
1586 }
1587 }
1588
Aart Bik5d75afe2015-12-14 11:57:01 -08001589 mA = new int[4][4];
1590 for (int i = 0; i < 4; i++) {
1591 for (int j = 0; j < 4; j++) {
1592 mA[i][j] = -1;
1593 }
1594 }
1595 dynamicBCEAndIntrinsic(4);
1596 for (int i = 0; i < 4; i++) {
1597 for (int j = 0; j < 4; j++) {
1598 if (mA[i][i] != 1) {
1599 System.out.println("dynamic bce failed!");
1600 }
1601 }
1602 }
1603
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001604 array = new int[7];
1605 pyramid1(array);
1606 if (!isPyramid(array)) {
1607 System.out.println("pyramid1 failed!");
1608 }
1609
1610 array = new int[8];
1611 pyramid2(array);
1612 if (!isPyramid(array)) {
1613 System.out.println("pyramid2 failed!");
1614 }
1615
1616 java.util.Arrays.fill(array, -1);
1617 pyramid3(array);
1618 if (!isPyramid(array)) {
1619 System.out.println("pyramid3 failed!");
1620 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001621
1622 // Make sure this value is kept after deoptimization.
1623 int i = 1;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001624 if (foo() + i != 100) {
1625 System.out.println("foo failed!");
1626 };
1627
1628 testUnknownBounds();
Mingyao Yang718493c2015-07-22 15:56:34 -07001629 new Main().testExceptionMessage();
Mingyao Yang0304e182015-01-30 16:41:29 -08001630 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001631
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001632 public static native boolean compiledWithOptimizing();
1633 public static native void disableStackFrameAsserts();
1634 public static native void assertIsManaged();
1635 public static native void assertIsInterpreted();
1636 public static native boolean hasOatFile();
1637 public static native boolean runtimeIsSoftFail();
1638 public static native boolean isInterpreted();
Mingyao Yang0304e182015-01-30 16:41:29 -08001639}