blob: 58c92f1ea4ef06fa5dfe5e1c7d1f102144af3033 [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
32 private static int linear(int[] x) {
33 int result = 0;
34 for (int i = 0; i < x.length; i++) {
35 result += x[i];
36 }
37 return result;
38 }
39
40 /// CHECK-START: int Main.linearDown(int[]) BCE (before)
41 /// CHECK-DAG: BoundsCheck
42 /// CHECK-START: int Main.linearDown(int[]) BCE (after)
43 /// CHECK-NOT: BoundsCheck
44 private static int linearDown(int[] x) {
45 int result = 0;
46 for (int i = x.length - 1; i >= 0; i--) {
47 result += x[i];
48 }
49 return result;
50 }
51
52 /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
53 /// CHECK-DAG: BoundsCheck
54 /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
55 /// CHECK-NOT: BoundsCheck
56 private static int linearObscure(int[] x) {
57 int result = 0;
58 for (int i = x.length - 1; i >= 0; i--) {
59 int k = i + 5;
60 result += x[k - 5];
61 }
62 return result;
63 }
64
Aart Bikf475bee2015-09-16 12:50:25 -070065 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
66 /// CHECK-DAG: BoundsCheck
67 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
68 /// CHECK-NOT: BoundsCheck
69 private static int linearVeryObscure(int[] x) {
70 int result = 0;
71 for (int i = 0; i < x.length; i++) {
72 int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
73 result += x[k - 5];
74 }
75 return result;
76 }
77
Aart Bik22af3be2015-09-10 12:50:58 -070078 /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
79 /// CHECK-DAG: BoundsCheck
80 /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
81 /// CHECK-NOT: BoundsCheck
82 private static int linearWhile(int[] x) {
83 int i = 0;
84 int result = 0;
85 while (i < x.length) {
86 result += x[i++];
87 }
88 return result;
89 }
90
Aart Bikf475bee2015-09-16 12:50:25 -070091 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
92 /// CHECK-DAG: BoundsCheck
93 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
94 /// CHECK-NOT: BoundsCheck
95 private static int linearThreeWayPhi(int[] x) {
96 int result = 0;
97 for (int i = 0; i < x.length; ) {
98 if (x[i] == 5) {
99 i++;
100 continue;
101 }
102 result += x[i++];
103 }
104 return result;
105 }
106
107 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
108 /// CHECK-DAG: BoundsCheck
109 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
110 /// CHECK-NOT: BoundsCheck
111 private static int linearFourWayPhi(int[] x) {
112 int result = 0;
113 for (int i = 0; i < x.length; ) {
114 if (x[i] == 5) {
115 i++;
116 continue;
117 } else if (x[i] == 6) {
118 i++;
119 result += 7;
120 continue;
121 }
122 result += x[i++];
123 }
124 return result;
125 }
126
Aart Bik22af3be2015-09-10 12:50:58 -0700127 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
128 /// CHECK-DAG: BoundsCheck
129 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
130 /// CHECK-NOT: BoundsCheck
131 private static int wrapAroundThenLinear(int[] x) {
132 // Loop with wrap around (length - 1, 0, 1, 2, ..).
133 int w = x.length - 1;
134 int result = 0;
135 for (int i = 0; i < x.length; i++) {
136 result += x[w];
137 w = i;
138 }
139 return result;
140 }
141
Aart Bikf475bee2015-09-16 12:50:25 -0700142 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
143 /// CHECK-DAG: BoundsCheck
144 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
145 /// CHECK-NOT: BoundsCheck
146 private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
147 // Loop with wrap around (length - 1, 0, 1, 2, ..).
148 int w = x.length - 1;
149 int result = 0;
150 for (int i = 0; i < x.length; ) {
151 if (x[w] == 1) {
152 w = i++;
153 continue;
154 }
155 result += x[w];
156 w = i++;
157 }
158 return result;
159 }
160
Aart Bik22af3be2015-09-10 12:50:58 -0700161 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
162 /// CHECK-DAG: BoundsCheck
163 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
164 /// CHECK-NOT: BoundsCheck
165 private static int[] linearWithParameter(int n) {
166 int[] x = new int[n];
167 for (int i = 0; i < n; i++) {
168 x[i] = i;
169 }
170 return x;
171 }
172
Aart Bikf475bee2015-09-16 12:50:25 -0700173 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
174 /// CHECK-DAG: BoundsCheck
175 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
176 /// CHECK-NOT: BoundsCheck
177 private static int[] linearCopy(int x[]) {
178 int n = x.length;
179 int y[] = new int[n];
180 for (int i = 0; i < n; i++) {
181 y[i] = x[i];
182 }
183 return y;
184 }
185
Aart Bik22af3be2015-09-10 12:50:58 -0700186 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
187 /// CHECK-DAG: BoundsCheck
188 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
189 /// CHECK-NOT: BoundsCheck
190 private static int linearWithCompoundStride() {
191 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
192 int result = 0;
193 for (int i = 0; i <= 12; ) {
194 i++;
195 result += x[i];
196 i++;
197 }
198 return result;
199 }
200
201 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
202 /// CHECK-DAG: BoundsCheck
203 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
204 /// CHECK-NOT: BoundsCheck
205 private static int linearWithLargePositiveStride() {
206 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
207 int result = 0;
208 int k = 0;
209 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700210 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700211 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
212 result += x[k++];
213 }
214 return result;
215 }
216
217 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
218 /// CHECK-DAG: BoundsCheck
219 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
220 /// CHECK-DAG: BoundsCheck
221 private static int linearWithVeryLargePositiveStride() {
222 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
223 int result = 0;
224 int k = 0;
225 // Range analysis conservatively bails due to potential of wrap-around
226 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700227 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700228 result += x[k++];
229 }
230 return result;
231 }
232
233 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
234 /// CHECK-DAG: BoundsCheck
235 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
236 /// CHECK-NOT: BoundsCheck
237 private static int linearWithLargeNegativeStride() {
238 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
239 int result = 0;
240 int k = 0;
241 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700242 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700243 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
244 result += x[k++];
245 }
246 return result;
247 }
248
249 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
250 /// CHECK-DAG: BoundsCheck
251 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
252 /// CHECK-DAG: BoundsCheck
253 private static int linearWithVeryLargeNegativeStride() {
254 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
255 int result = 0;
256 int k = 0;
257 // Range analysis conservatively bails due to potential of wrap-around
258 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700259 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700260 result += x[k++];
261 }
262 return result;
263 }
264
Aart Bik9401f532015-09-28 16:25:56 -0700265 /// CHECK-START: int Main.linearForNEUp() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700266 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700267 /// CHECK-START: int Main.linearForNEUp() BCE (after)
Aart Bikf475bee2015-09-16 12:50:25 -0700268 /// CHECK-NOT: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700269 private static int linearForNEUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700270 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
271 int result = 0;
272 for (int i = 0; i != 10; i++) {
273 result += x[i];
274 }
275 return result;
276 }
277
Aart Bik9401f532015-09-28 16:25:56 -0700278 /// CHECK-START: int Main.linearForNEDown() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700279 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700280 /// CHECK-START: int Main.linearForNEDown() BCE (after)
281 /// CHECK-NOT: BoundsCheck
282 private static int linearForNEDown() {
283 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
284 int result = 0;
285 for (int i = 9; i != -1; i--) {
286 result += x[i];
287 }
288 return result;
289 }
290
291 /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
Aart Bikf475bee2015-09-16 12:50:25 -0700292 /// CHECK-DAG: BoundsCheck
Aart Bik9401f532015-09-28 16:25:56 -0700293 /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
294 /// CHECK-NOT: BoundsCheck
295 private static int linearDoWhileUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700296 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
297 int result = 0;
298 int i = 0;
Aart Bikf475bee2015-09-16 12:50:25 -0700299 do {
300 result += x[i++];
301 } while (i < 10);
302 return result;
303 }
304
Aart Bik9401f532015-09-28 16:25:56 -0700305 /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
306 /// CHECK-DAG: BoundsCheck
307 /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
308 /// CHECK-NOT: BoundsCheck
309 private static int linearDoWhileDown() {
310 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
311 int result = 0;
312 int i = 9;
313 do {
314 result += x[i--];
315 } while (0 <= i);
316 return result;
317 }
318
Aart Bikf475bee2015-09-16 12:50:25 -0700319 /// CHECK-START: int Main.linearShort() BCE (before)
320 /// CHECK-DAG: BoundsCheck
321 /// CHECK-START: int Main.linearShort() BCE (after)
322 /// CHECK-DAG: BoundsCheck
323 private static int linearShort() {
324 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
325 int result = 0;
326 // TODO: make this work
327 for (short i = 0; i < 10; i++) {
328 result += x[i];
329 }
330 return result;
331 }
332
Aart Bik22af3be2015-09-10 12:50:58 -0700333 /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
334 /// CHECK-DAG: BoundsCheck
335 /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
336 /// CHECK-NOT: BoundsCheck
337 private static int periodicIdiom(int tc) {
338 int[] x = { 1, 3 };
339 // Loop with periodic sequence (0, 1).
340 int k = 0;
341 int result = 0;
342 for (int i = 0; i < tc; i++) {
343 result += x[k];
344 k = 1 - k;
345 }
346 return result;
347 }
348
349 /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
350 /// CHECK-DAG: BoundsCheck
351 /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
352 /// CHECK-NOT: BoundsCheck
353 private static int periodicSequence2(int tc) {
354 int[] x = { 1, 3 };
355 // Loop with periodic sequence (0, 1).
356 int k = 0;
357 int l = 1;
358 int result = 0;
359 for (int i = 0; i < tc; i++) {
360 result += x[k];
361 int t = l;
362 l = k;
363 k = t;
364 }
365 return result;
366 }
367
368 /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
369 /// CHECK-DAG: BoundsCheck
370 /// CHECK-DAG: BoundsCheck
371 /// CHECK-DAG: BoundsCheck
372 /// CHECK-DAG: BoundsCheck
373 /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
374 /// CHECK-NOT: BoundsCheck
375 private static int periodicSequence4(int tc) {
376 int[] x = { 1, 3, 5, 7 };
377 // Loop with periodic sequence (0, 1, 2, 3).
378 int k = 0;
379 int l = 1;
380 int m = 2;
381 int n = 3;
382 int result = 0;
383 for (int i = 0; i < tc; i++) {
384 result += x[k] + x[l] + x[m] + x[n]; // all used at once
385 int t = n;
386 n = k;
387 k = l;
388 l = m;
389 m = t;
390 }
391 return result;
392 }
393
Aart Bikf475bee2015-09-16 12:50:25 -0700394 /// CHECK-START: int Main.justRightUp1() BCE (before)
395 /// CHECK-DAG: BoundsCheck
396 /// CHECK-START: int Main.justRightUp1() BCE (after)
397 /// CHECK-NOT: BoundsCheck
398 private static int justRightUp1() {
399 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
400 int result = 0;
401 for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
402 result += x[k++];
403 }
404 return result;
405 }
406
407 /// CHECK-START: int Main.justRightUp2() BCE (before)
408 /// CHECK-DAG: BoundsCheck
409 /// CHECK-START: int Main.justRightUp2() BCE (after)
410 /// CHECK-NOT: BoundsCheck
411 private static int justRightUp2() {
412 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
413 int result = 0;
414 for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
415 result += x[i - Integer.MAX_VALUE + 10];
416 }
417 return result;
418 }
419
420 /// CHECK-START: int Main.justRightUp3() BCE (before)
421 /// CHECK-DAG: BoundsCheck
422 /// CHECK-START: int Main.justRightUp3() BCE (after)
423 /// CHECK-NOT: BoundsCheck
424 private static int justRightUp3() {
425 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
426 int result = 0;
427 for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
428 result += x[k++];
429 }
430 return result;
431 }
432
433 /// CHECK-START: int Main.justOOBUp() BCE (before)
434 /// CHECK-DAG: BoundsCheck
435 /// CHECK-START: int Main.justOOBUp() BCE (after)
436 /// CHECK-DAG: BoundsCheck
437 private static int justOOBUp() {
438 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
439 int result = 0;
440 // Infinite loop!
441 for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
442 result += x[k++];
443 }
444 return result;
445 }
446
447 /// CHECK-START: int Main.justRightDown1() BCE (before)
448 /// CHECK-DAG: BoundsCheck
449 /// CHECK-START: int Main.justRightDown1() BCE (after)
450 /// CHECK-NOT: BoundsCheck
451 private static int justRightDown1() {
452 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
453 int result = 0;
454 for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
455 result += x[k++];
456 }
457 return result;
458 }
459
460 /// CHECK-START: int Main.justRightDown2() BCE (before)
461 /// CHECK-DAG: BoundsCheck
462 /// CHECK-START: int Main.justRightDown2() BCE (after)
463 /// CHECK-NOT: BoundsCheck
464 private static int justRightDown2() {
465 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
466 int result = 0;
467 for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
468 result += x[Integer.MAX_VALUE + i];
469 }
470 return result;
471 }
472
473 /// CHECK-START: int Main.justRightDown3() BCE (before)
474 /// CHECK-DAG: BoundsCheck
475 /// CHECK-START: int Main.justRightDown3() BCE (after)
476 /// CHECK-NOT: BoundsCheck
477 private static int justRightDown3() {
478 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
479 int result = 0;
480 for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
481 result += x[k++];
482 }
483 return result;
484 }
485
486 /// CHECK-START: int Main.justOOBDown() BCE (before)
487 /// CHECK-DAG: BoundsCheck
488 /// CHECK-START: int Main.justOOBDown() BCE (after)
489 /// CHECK-DAG: BoundsCheck
490 private static int justOOBDown() {
491 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
492 int result = 0;
493 // Infinite loop!
494 for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
495 result += x[k++];
496 }
497 return result;
498 }
499
Aart Bik9401f532015-09-28 16:25:56 -0700500 /// CHECK-START: void Main.lowerOOB(int[]) BCE (before)
501 /// CHECK-DAG: BoundsCheck
502 /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
503 /// CHECK-DAG: BoundsCheck
Aart Bik22af3be2015-09-10 12:50:58 -0700504 private static void lowerOOB(int[] x) {
505 for (int i = -1; i < x.length; i++) {
506 sResult += x[i];
507 }
508 }
509
Aart Bik9401f532015-09-28 16:25:56 -0700510 /// CHECK-START: void Main.upperOOB(int[]) BCE (before)
511 /// CHECK-DAG: BoundsCheck
512 /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
513 /// CHECK-DAG: BoundsCheck
Aart Bik22af3be2015-09-10 12:50:58 -0700514 private static void upperOOB(int[] x) {
515 for (int i = 0; i <= x.length; i++) {
516 sResult += x[i];
517 }
518 }
519
Aart Bik9401f532015-09-28 16:25:56 -0700520 /// CHECK-START: void Main.doWhileUpOOB() BCE (before)
521 /// CHECK-DAG: BoundsCheck
522 /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
523 /// CHECK-DAG: BoundsCheck
524 private static void doWhileUpOOB() {
525 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
526 int i = 0;
527 do {
528 sResult += x[i++];
529 } while (i <= x.length);
530 }
531
532 /// CHECK-START: void Main.doWhileDownOOB() BCE (before)
533 /// CHECK-DAG: BoundsCheck
534 /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
535 /// CHECK-DAG: BoundsCheck
536 private static void doWhileDownOOB() {
537 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
538 int i = x.length - 1;
539 do {
540 sResult += x[i--];
541 } while (-1 <= i);
542 }
543
Aart Bik22af3be2015-09-10 12:50:58 -0700544 //
545 // Verifier.
546 //
547
548 public static void main(String[] args) {
549 int[] empty = { };
550 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
551
552 // Linear and wrap-around.
553 expectEquals(0, linear(empty));
554 expectEquals(55, linear(x));
555 expectEquals(0, linearDown(empty));
556 expectEquals(55, linearDown(x));
557 expectEquals(0, linearObscure(empty));
558 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700559 expectEquals(0, linearVeryObscure(empty));
560 expectEquals(55, linearVeryObscure(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700561 expectEquals(0, linearWhile(empty));
562 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700563 expectEquals(0, linearThreeWayPhi(empty));
564 expectEquals(50, linearThreeWayPhi(x));
565 expectEquals(0, linearFourWayPhi(empty));
566 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700567 expectEquals(0, wrapAroundThenLinear(empty));
568 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -0700569 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
570 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -0700571
572 // Linear with parameter.
573 sResult = 0;
574 try {
575 linearWithParameter(-1);
576 } catch (NegativeArraySizeException e) {
577 sResult = 1;
578 }
579 expectEquals(1, sResult);
580 for (int n = 0; n < 32; n++) {
581 int[] r = linearWithParameter(n);
582 expectEquals(n, r.length);
583 for (int i = 0; i < n; i++) {
584 expectEquals(i, r[i]);
585 }
586 }
587
Aart Bikf475bee2015-09-16 12:50:25 -0700588 // Linear copy.
589 expectEquals(0, linearCopy(empty).length);
590 {
591 int[] r = linearCopy(x);
592 expectEquals(x.length, r.length);
593 for (int i = 0; i < x.length; i++) {
594 expectEquals(x[i], r[i]);
595 }
596 }
597
Aart Bik22af3be2015-09-10 12:50:58 -0700598 // Linear with non-unit strides.
599 expectEquals(56, linearWithCompoundStride());
600 expectEquals(66, linearWithLargePositiveStride());
601 expectEquals(66, linearWithVeryLargePositiveStride());
602 expectEquals(66, linearWithLargeNegativeStride());
603 expectEquals(66, linearWithVeryLargeNegativeStride());
604
Aart Bikf475bee2015-09-16 12:50:25 -0700605 // Special forms.
Aart Bik9401f532015-09-28 16:25:56 -0700606 expectEquals(55, linearForNEUp());
607 expectEquals(55, linearForNEDown());
608 expectEquals(55, linearDoWhileUp());
609 expectEquals(55, linearDoWhileDown());
Aart Bikf475bee2015-09-16 12:50:25 -0700610 expectEquals(55, linearShort());
611
Aart Bik22af3be2015-09-10 12:50:58 -0700612 // Periodic adds (1, 3), one at the time.
613 expectEquals(0, periodicIdiom(-1));
614 for (int tc = 0; tc < 32; tc++) {
615 int expected = (tc >> 1) << 2;
616 if ((tc & 1) != 0)
617 expected += 1;
618 expectEquals(expected, periodicIdiom(tc));
619 }
620
621 // Periodic adds (1, 3), one at the time.
622 expectEquals(0, periodicSequence2(-1));
623 for (int tc = 0; tc < 32; tc++) {
624 int expected = (tc >> 1) << 2;
625 if ((tc & 1) != 0)
626 expected += 1;
627 expectEquals(expected, periodicSequence2(tc));
628 }
629
630 // Periodic adds (1, 3, 5, 7), all at once.
631 expectEquals(0, periodicSequence4(-1));
632 for (int tc = 0; tc < 32; tc++) {
633 expectEquals(tc * 16, periodicSequence4(tc));
634 }
635
Aart Bikf475bee2015-09-16 12:50:25 -0700636 // Large bounds.
637 expectEquals(55, justRightUp1());
638 expectEquals(55, justRightUp2());
639 expectEquals(55, justRightUp3());
640 expectEquals(55, justRightDown1());
641 expectEquals(55, justRightDown2());
642 expectEquals(55, justRightDown3());
643 sResult = 0;
644 try {
645 justOOBUp();
646 } catch (ArrayIndexOutOfBoundsException e) {
647 sResult = 1;
648 }
649 expectEquals(1, sResult);
650 sResult = 0;
651 try {
652 justOOBDown();
653 } catch (ArrayIndexOutOfBoundsException e) {
654 sResult = 1;
655 }
656 expectEquals(1, sResult);
657
Aart Bik22af3be2015-09-10 12:50:58 -0700658 // Lower bound goes OOB.
659 sResult = 0;
660 try {
661 lowerOOB(x);
662 } catch (ArrayIndexOutOfBoundsException e) {
663 sResult += 1000;
664 }
665 expectEquals(1000, sResult);
666
667 // Upper bound goes OOB.
668 sResult = 0;
669 try {
670 upperOOB(x);
671 } catch (ArrayIndexOutOfBoundsException e) {
672 sResult += 1000;
673 }
674 expectEquals(1055, sResult);
675
Aart Bik9401f532015-09-28 16:25:56 -0700676 // Do while up goes OOB.
677 sResult = 0;
678 try {
679 doWhileUpOOB();
680 } catch (ArrayIndexOutOfBoundsException e) {
681 sResult += 1000;
682 }
683 expectEquals(1055, sResult);
684
685 // Do while down goes OOB.
686 sResult = 0;
687 try {
688 doWhileDownOOB();
689 } catch (ArrayIndexOutOfBoundsException e) {
690 sResult += 1000;
691 }
692 expectEquals(1055, sResult);
Aart Bik22af3be2015-09-10 12:50:58 -0700693 }
694
695 private static void expectEquals(int expected, int result) {
696 if (expected != result) {
697 throw new Error("Expected: " + expected + ", found: " + result);
698 }
699 }
700}