blob: 5c789cdd848f7e2c1f394761f6bda673bc69d526 [file] [log] [blame]
Aart Bik281c6812016-08-26 11:31:48 -07001/*
2 * Copyright (C) 2016 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 * Tests on loop optimizations related to induction.
19 */
20public class Main {
21
22 static int[] a = new int[10];
23
24 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (before)
25 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
26 //
27 /// CHECK-START: void Main.deadSingleLoop() loop_optimization (after)
28 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
29 static void deadSingleLoop() {
30 for (int i = 0; i < 4; i++) {
31 }
32 }
33
34 /// CHECK-START: void Main.deadNestedLoops() loop_optimization (before)
35 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
36 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop>>
37 //
38 /// CHECK-START: void Main.deadNestedLoops() loop_optimization (after)
39 /// CHECK-NOT: Phi loop:{{B\d+}}
40 static void deadNestedLoops() {
41 for (int i = 0; i < 4; i++) {
42 for (int j = 0; j < 4; j++) {
43 }
44 }
45 }
46
47 /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (before)
48 /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none
49 /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
50 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>>
51 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop2>>
52 /// CHECK-DAG: Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
53 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:<<Loop3>>
54 /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none
55 //
56 /// CHECK-START: void Main.deadNestedAndFollowingLoops() loop_optimization (after)
57 /// CHECK-NOT: Phi loop:{{B\d+}}
58 static void deadNestedAndFollowingLoops() {
59 for (int i = 0; i < 4; i++) {
60 for (int j = 0; j < 4; j++) {
61 for (int k = 0; k < 4; k++) {
62 }
63 for (int k = 0; k < 4; k++) {
64 }
65 }
66 for (int j = 0; j < 4; j++) {
67 for (int k = 0; k < 4; k++) {
68 }
69 }
70 }
71 for (int i = 0; i < 4; i++) {
72 }
73 }
74
75 /// CHECK-START: void Main.deadInduction() loop_optimization (before)
76 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
77 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
78 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
79 //
80 /// CHECK-START: void Main.deadInduction() loop_optimization (after)
81 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
82 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
83 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
84 static void deadInduction() {
85 int dead = 0;
86 for (int i = 0; i < a.length; i++) {
87 a[i] = 1;
88 dead += 5;
89 }
90 }
91
92 /// CHECK-START: void Main.deadManyInduction() loop_optimization (before)
93 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
94 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
95 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
96 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
97 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
98 //
99 /// CHECK-START: void Main.deadManyInduction() loop_optimization (after)
100 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
101 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
102 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
103 static void deadManyInduction() {
104 int dead1 = 0, dead2 = 1, dead3 = 3;
105 for (int i = 0; i < a.length; i++) {
106 dead1 += 5;
107 a[i] = 2;
108 dead2 += 10;
109 dead3 += 100;
110 }
111 }
112
113 /// CHECK-START: void Main.deadSequence() loop_optimization (before)
114 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
115 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
116 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
117 //
118 /// CHECK-START: void Main.deadSequence() loop_optimization (after)
119 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
120 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
121 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
122 static void deadSequence() {
123 int dead = 0;
124 for (int i = 0; i < a.length; i++) {
125 a[i] = 3;
126 // Increment value defined inside loop,
127 // but sequence itself not used anywhere.
128 dead += i;
129 }
130 }
131
132 /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (before)
133 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
134 /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none
135 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
136 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700137 /// CHECK-NOT: BoundsCheck
Aart Bik281c6812016-08-26 11:31:48 -0700138 //
139 /// CHECK-START: void Main.deadCycleWithException(int) loop_optimization (after)
140 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none
141 /// CHECK-NOT: Phi loop:<<Loop>> outer_loop:none
142 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
Aart Bik482095d2016-10-10 15:39:10 -0700143 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700144 static void deadCycleWithException(int k) {
145 int dead = 0;
146 for (int i = 0; i < a.length; i++) {
147 a[i] = 4;
Aart Bik482095d2016-10-10 15:39:10 -0700148 // Increment value of dead cycle may throw exception. Dynamic
149 // BCE takes care of the bounds check though, which enables
150 // removing the ArrayGet after removing the dead cycle.
Aart Bik281c6812016-08-26 11:31:48 -0700151 dead += a[k];
152 }
153 }
154
155 /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (before)
156 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
157 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
158 /// CHECK-DAG: Return [<<Phi1>>] loop:none
159 //
160 /// CHECK-START: int Main.closedFormInductionUp() loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700161 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700162 /// CHECK-DAG: Return loop:none
163 static int closedFormInductionUp() {
164 int closed = 12345;
165 for (int i = 0; i < 10; i++) {
166 closed += 5;
167 }
168 return closed; // only needs last value
169 }
170
171 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (before)
172 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
173 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
174 /// CHECK-DAG: Return [<<Phi2>>] loop:none
175 //
176 /// CHECK-START: int Main.closedFormInductionInAndDown(int) loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700177 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700178 /// CHECK-DAG: Return loop:none
179 static int closedFormInductionInAndDown(int closed) {
180 for (int i = 0; i < 10; i++) {
181 closed -= 5;
182 }
183 return closed; // only needs last value
184 }
185
Aart Bik482095d2016-10-10 15:39:10 -0700186 /// CHECK-START: int Main.closedFormNested() loop_optimization (before)
187 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
188 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
189 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
190 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
191 /// CHECK-DAG: Return [<<Phi1>>] loop:none
192 //
193 /// CHECK-START: int Main.closedFormNested() loop_optimization (after)
194 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
195 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:loop{{B\d+}}
196 /// CHECK-DAG: Return loop:none
Aart Bik8c4a8542016-10-06 11:36:57 -0700197 static int closedFormNested() {
198 int closed = 0;
199 for (int i = 0; i < 10; i++) {
200 for (int j = 0; j < 10; j++) {
201 closed++;
202 }
203 }
204 return closed; // only needs last-value
205 }
206
Aart Bik482095d2016-10-10 15:39:10 -0700207 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (before)
208 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
209 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
210 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
211 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:<<Loop1>>
212 /// CHECK-DAG: Return [<<Phi1>>] loop:none
213 //
214 /// CHECK-START: int Main.closedFormNestedAlt() loop_optimization (after)
215 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
216 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:loop{{B\d+}}
217 /// CHECK-DAG: Return loop:none
218 static int closedFormNestedAlt() {
219 int closed = 12345;
220 for (int i = 0; i < 17; i++) {
221 for (int j = 0; j < 23; j++) {
222 closed += 7;
223 }
224 }
225 return closed; // only needs last-value
226 }
227
Aart Bik281c6812016-08-26 11:31:48 -0700228 // TODO: taken test around closed form?
229 static int closedFormInductionUpN(int n) {
230 int closed = 12345;
231 for (int i = 0; i < n; i++) {
232 closed += 5;
233 }
234 return closed; // only needs last value
235 }
236
237 // TODO: taken test around closed form?
238 static int closedFormInductionInAndDownN(int closed, int n) {
239 for (int i = 0; i < n; i++) {
240 closed -= 5;
241 }
242 return closed; // only needs last value
243 }
244
245 // TODO: move closed form even further out?
Aart Bik8c4a8542016-10-06 11:36:57 -0700246 static int closedFormNestedN(int n) {
Aart Bik281c6812016-08-26 11:31:48 -0700247 int closed = 0;
248 for (int i = 0; i < n; i++) {
249 for (int j = 0; j < 10; j++) {
250 closed++;
251 }
252 }
253 return closed; // only needs last-value
254 }
255
Aart Bik8c4a8542016-10-06 11:36:57 -0700256 // TODO: move closed form even further out?
Aart Bik482095d2016-10-10 15:39:10 -0700257 static int closedFormNestedNAlt(int n) {
258 int closed = 12345;
Aart Bik8c4a8542016-10-06 11:36:57 -0700259 for (int i = 0; i < n; i++) {
Aart Bik482095d2016-10-10 15:39:10 -0700260 for (int j = 0; j < 23; j++) {
261 closed += 7;
262 }
263 }
264 return closed; // only needs last-value
265 }
266
267 // TODO: move closed form even further out?
268 static int closedFormNestedMN(int m, int n) {
269 int closed = 0;
270 for (int i = 0; i < m; i++) {
Aart Bik8c4a8542016-10-06 11:36:57 -0700271 for (int j = 0; j < n; j++) {
272 closed++;
273 }
274 }
275 return closed; // only needs last-value
276 }
277
Aart Bik482095d2016-10-10 15:39:10 -0700278 // TODO: move closed form even further out?
279 static int closedFormNestedMNAlt(int m, int n) {
280 int closed = 12345;
281 for (int i = 0; i < m; i++) {
282 for (int j = 0; j < n; j++) {
283 closed += 7;
284 }
285 }
286 return closed; // only needs last-value
287 }
288
Aart Bik8c4a8542016-10-06 11:36:57 -0700289 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (before)
290 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:{{B\d+}} outer_loop:none
291 /// CHECK-DAG: Return [<<Phi>>] loop:none
292 //
293 /// CHECK-START: int Main.mainIndexReturned() loop_optimization (after)
294 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
295 /// CHECK-DAG: Return loop:none
296 static int mainIndexReturned() {
Aart Bik281c6812016-08-26 11:31:48 -0700297 int i;
Aart Bik8c4a8542016-10-06 11:36:57 -0700298 for (i = 0; i < 10; i++);
Aart Bik281c6812016-08-26 11:31:48 -0700299 return i;
300 }
301
302 // If ever replaced by closed form, last value should be correct!
Aart Bik8c4a8542016-10-06 11:36:57 -0700303 static int periodicReturned() {
Aart Bik281c6812016-08-26 11:31:48 -0700304 int k = 0;
Aart Bik8c4a8542016-10-06 11:36:57 -0700305 for (int i = 0; i < 9; i++) {
Aart Bik281c6812016-08-26 11:31:48 -0700306 k = 1 - k;
307 }
308 return k;
309 }
310
Aart Bik8c4a8542016-10-06 11:36:57 -0700311 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700312 private static int getSum21() {
313 int k = 0;
314 int sum = 0;
315 for (int i = 0; i < 6; i++) {
316 k++;
317 sum += k;
318 }
319 return sum;
320 }
321
Aart Bik8c4a8542016-10-06 11:36:57 -0700322 // TODO: handle as closed/empty eventually?
323 static int mainIndexReturnedN(int n) {
324 int i;
325 for (i = 0; i < n; i++);
326 return i;
327 }
328
329 // If ever replaced by closed form, last value should be correct!
330 static int periodicReturnedN(int n) {
331 int k = 0;
332 for (int i = 0; i < n; i++) {
333 k = 1 - k;
334 }
335 return k;
336 }
337
338 // If ever replaced by closed form, last value should be correct!
339 private static int getSumN(int n) {
340 int k = 0;
341 int sum = 0;
342 for (int i = 0; i < n; i++) {
343 k++;
344 sum += k;
345 }
346 return sum;
347 }
348
349 // If ever replaced by closed form, last value should be correct!
Aart Bik281c6812016-08-26 11:31:48 -0700350 private static int closedTwice() {
351 int closed = 0;
352 for (int i = 0; i < 10; i++) {
353 closed++;
354 }
355 // Closed form of first loop defines trip count of second loop.
356 int other_closed = 0;
357 for (int i = 0; i < closed; i++) {
358 other_closed++;
359 }
360 return other_closed;
361 }
362
363 /// CHECK-START: int Main.closedFeed() loop_optimization (before)
364 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
365 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
366 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
367 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none
368 /// CHECK-DAG: Return [<<Phi3>>] loop:none
369 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
370 //
371 /// CHECK-START: int Main.closedFeed() loop_optimization (after)
Aart Bik8c4a8542016-10-06 11:36:57 -0700372 /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:none
Aart Bik281c6812016-08-26 11:31:48 -0700373 /// CHECK-DAG: Return loop:none
374 private static int closedFeed() {
375 int closed = 0;
376 for (int i = 0; i < 10; i++) {
377 closed++;
378 }
379 // Closed form of first loop feeds into initial value of second loop,
380 // used when generating closed form for the latter.
381 for (int i = 0; i < 10; i++) {
382 closed++;
383 }
384 return closed;
385 }
386
387 /// CHECK-START: int Main.closedLargeUp() loop_optimization (before)
388 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
389 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
390 /// CHECK-DAG: Return [<<Phi1>>] loop:none
391 //
392 /// CHECK-START: int Main.closedLargeUp() loop_optimization (after)
393 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
394 /// CHECK-DAG: Return loop:none
395 private static int closedLargeUp() {
396 int closed = 0;
397 for (int i = 0; i < 10; i++) {
398 closed += 0x7fffffff;
399 }
400 return closed;
401 }
402
403 /// CHECK-START: int Main.closedLargeDown() loop_optimization (before)
404 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
405 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
406 /// CHECK-DAG: Return [<<Phi1>>] loop:none
407 //
408 /// CHECK-START: int Main.closedLargeDown() loop_optimization (after)
409 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
410 /// CHECK-DAG: Return loop:none
411 private static int closedLargeDown() {
412 int closed = 0;
413 for (int i = 0; i < 10; i++) {
414 closed -= 0x7fffffff;
415 }
416 return closed;
417 }
418
Aart Bik8c4a8542016-10-06 11:36:57 -0700419 /// CHECK-START: int Main.waterFall() loop_optimization (before)
420 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
421 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none
422 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none
423 /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none
424 /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none
425 /// CHECK-DAG: Return [<<Phi5>>] loop:none
426 //
427 /// CHECK-START: int Main.waterFall() loop_optimization (after)
428 /// CHECK-NOT: Phi loop:B\d+ outer_loop:none
429 /// CHECK-DAG: Return loop:none
430 private static int waterFall() {
431 int i = 0;
432 for (; i < 10; i++);
433 for (; i < 20; i++);
434 for (; i < 30; i++);
435 for (; i < 40; i++);
436 for (; i < 50; i++);
437 return i; // this should become just 50
438 }
439
Aart Bik281c6812016-08-26 11:31:48 -0700440 private static int exceptionExitBeforeAdd() {
441 int k = 0;
442 try {
443 for (int i = 0; i < 10; i++) {
444 a[i] = 0;
445 k += 10; // increment last
446 }
447 } catch(Exception e) {
448 // Flag error by returning current
449 // value of k negated.
450 return -k-1;
451 }
452 return k;
453 }
454
455 private static int exceptionExitAfterAdd() {
456 int k = 0;
457 try {
458 for (int i = 0; i < 10; i++) {
459 k += 10; // increment first
460 a[i] = 0;
461 }
462 } catch(Exception e) {
463 // Flag error by returning current
464 // value of k negated.
465 return -k-1;
466 }
467 return k;
468 }
469
470 public static void main(String[] args) {
471 deadSingleLoop();
472 deadNestedLoops();
473 deadNestedAndFollowingLoops();
474
475 deadInduction();
476 for (int i = 0; i < a.length; i++) {
477 expectEquals(1, a[i]);
478 }
479 deadManyInduction();
480 for (int i = 0; i < a.length; i++) {
481 expectEquals(2, a[i]);
482 }
483 deadSequence();
484 for (int i = 0; i < a.length; i++) {
485 expectEquals(3, a[i]);
486 }
487 try {
488 deadCycleWithException(-1);
489 throw new Error("Expected: IOOB exception");
490 } catch (IndexOutOfBoundsException e) {
491 }
492 for (int i = 0; i < a.length; i++) {
493 expectEquals(i == 0 ? 4 : 3, a[i]);
494 }
495 deadCycleWithException(0);
496 for (int i = 0; i < a.length; i++) {
497 expectEquals(4, a[i]);
498 }
499
Aart Bik8c4a8542016-10-06 11:36:57 -0700500 expectEquals(12395, closedFormInductionUp());
501 expectEquals(12295, closedFormInductionInAndDown(12345));
502 expectEquals(10 * 10, closedFormNested());
Aart Bik482095d2016-10-10 15:39:10 -0700503 expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
Aart Bik281c6812016-08-26 11:31:48 -0700504 for (int n = -4; n < 10; n++) {
505 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700506 expectEquals(12345 + tc * 5, closedFormInductionUpN(n));
507 expectEquals(12345 - tc * 5, closedFormInductionInAndDownN(12345, n));
508 expectEquals(tc * 10, closedFormNestedN(n));
Aart Bik482095d2016-10-10 15:39:10 -0700509 expectEquals(12345 + tc * 23 * 7, closedFormNestedNAlt(n));
510 expectEquals(tc * (tc + 1), closedFormNestedMN(n, n + 1));
511 expectEquals(12345 + tc * (tc + 1) * 7, closedFormNestedMNAlt(n, n + 1));
Aart Bik281c6812016-08-26 11:31:48 -0700512 }
513
Aart Bik8c4a8542016-10-06 11:36:57 -0700514 expectEquals(10, mainIndexReturned());
515 expectEquals(1, periodicReturned());
516 expectEquals(21, getSum21());
Aart Bik281c6812016-08-26 11:31:48 -0700517 for (int n = -4; n < 4; n++) {
518 int tc = (n <= 0) ? 0 : n;
Aart Bik8c4a8542016-10-06 11:36:57 -0700519 expectEquals(tc, mainIndexReturnedN(n));
520 expectEquals(tc & 1, periodicReturnedN(n));
521 expectEquals((tc * (tc + 1)) / 2, getSumN(n));
Aart Bik281c6812016-08-26 11:31:48 -0700522 }
Aart Bik8c4a8542016-10-06 11:36:57 -0700523
Aart Bik281c6812016-08-26 11:31:48 -0700524 expectEquals(10, closedTwice());
525 expectEquals(20, closedFeed());
526 expectEquals(-10, closedLargeUp());
527 expectEquals(10, closedLargeDown());
Aart Bik8c4a8542016-10-06 11:36:57 -0700528 expectEquals(50, waterFall());
Aart Bik281c6812016-08-26 11:31:48 -0700529
530 expectEquals(100, exceptionExitBeforeAdd());
531 expectEquals(100, exceptionExitAfterAdd());
532 a = null;
533 expectEquals(-1, exceptionExitBeforeAdd());
534 expectEquals(-11, exceptionExitAfterAdd());
535 a = new int[4];
536 expectEquals(-41, exceptionExitBeforeAdd());
537 expectEquals(-51, exceptionExitAfterAdd());
538
539 System.out.println("passed");
540 }
541
542 private static void expectEquals(int expected, int result) {
543 if (expected != result) {
544 throw new Error("Expected: " + expected + ", found: " + result);
545 }
546 }
547}