blob: deff279f7786601c5d3ed51b9215c0521f74aff1 [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)
Aart Bik09e8d5f2016-01-22 16:49:55 -080029 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080030 //
Aart Bik22af3be2015-09-10 12:50:58 -070031 /// CHECK-START: int Main.linear(int[]) BCE (after)
32 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080033 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070034 private static int linear(int[] x) {
35 int result = 0;
36 for (int i = 0; i < x.length; i++) {
37 result += x[i];
38 }
39 return result;
40 }
41
42 /// CHECK-START: int Main.linearDown(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080043 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080044 //
Aart Bik22af3be2015-09-10 12:50:58 -070045 /// CHECK-START: int Main.linearDown(int[]) BCE (after)
46 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080047 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070048 private static int linearDown(int[] x) {
49 int result = 0;
50 for (int i = x.length - 1; i >= 0; i--) {
51 result += x[i];
52 }
53 return result;
54 }
55
56 /// CHECK-START: int Main.linearObscure(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080057 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080058 //
Aart Bik22af3be2015-09-10 12:50:58 -070059 /// CHECK-START: int Main.linearObscure(int[]) BCE (after)
60 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080061 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -070062 private static int linearObscure(int[] x) {
63 int result = 0;
64 for (int i = x.length - 1; i >= 0; i--) {
65 int k = i + 5;
66 result += x[k - 5];
67 }
68 return result;
69 }
70
Aart Bikf475bee2015-09-16 12:50:25 -070071 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080072 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080073 //
Aart Bikf475bee2015-09-16 12:50:25 -070074 /// CHECK-START: int Main.linearVeryObscure(int[]) BCE (after)
75 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -080076 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -070077 private static int linearVeryObscure(int[] x) {
78 int result = 0;
79 for (int i = 0; i < x.length; i++) {
80 int k = (-i) + (i << 5) + i - (32 * i) + 5 + (int) i;
81 result += x[k - 5];
82 }
83 return result;
84 }
85
Aart Bik7d57d7f2015-12-09 14:39:48 -080086 /// CHECK-START: int Main.hiddenStride(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -080087 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -080088 //
89 /// CHECK-START: int Main.hiddenStride(int[]) BCE (after)
90 /// CHECK-NOT: BoundsCheck
91 /// CHECK-NOT: Deoptimize
92 static int hiddenStride(int[] a) {
93 int result = 0;
94 for (int i = 1; i <= 1; i++) {
95 // Obscured unit stride.
96 for (int j = 0; j < a.length; j += i) {
97 result += a[j];
98 }
99 }
100 return result;
101 }
102
Aart Bik22af3be2015-09-10 12:50:58 -0700103 /// CHECK-START: int Main.linearWhile(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800104 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800105 //
Aart Bik22af3be2015-09-10 12:50:58 -0700106 /// CHECK-START: int Main.linearWhile(int[]) BCE (after)
107 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800108 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700109 private static int linearWhile(int[] x) {
110 int i = 0;
111 int result = 0;
112 while (i < x.length) {
113 result += x[i++];
114 }
115 return result;
116 }
117
Aart Bikf475bee2015-09-16 12:50:25 -0700118 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800119 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800120 //
Aart Bikf475bee2015-09-16 12:50:25 -0700121 /// CHECK-START: int Main.linearThreeWayPhi(int[]) BCE (after)
122 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800123 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700124 private static int linearThreeWayPhi(int[] x) {
125 int result = 0;
126 for (int i = 0; i < x.length; ) {
127 if (x[i] == 5) {
128 i++;
129 continue;
130 }
131 result += x[i++];
132 }
133 return result;
134 }
135
136 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800137 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800138 //
Aart Bikf475bee2015-09-16 12:50:25 -0700139 /// CHECK-START: int Main.linearFourWayPhi(int[]) BCE (after)
140 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800141 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700142 private static int linearFourWayPhi(int[] x) {
143 int result = 0;
144 for (int i = 0; i < x.length; ) {
145 if (x[i] == 5) {
146 i++;
147 continue;
148 } else if (x[i] == 6) {
149 i++;
150 result += 7;
151 continue;
152 }
153 result += x[i++];
154 }
155 return result;
156 }
157
Aart Bik22af3be2015-09-10 12:50:58 -0700158 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800159 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800160 //
Aart Bik22af3be2015-09-10 12:50:58 -0700161 /// CHECK-START: int Main.wrapAroundThenLinear(int[]) BCE (after)
162 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800163 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700164 private static int wrapAroundThenLinear(int[] x) {
165 // Loop with wrap around (length - 1, 0, 1, 2, ..).
166 int w = x.length - 1;
167 int result = 0;
168 for (int i = 0; i < x.length; i++) {
169 result += x[w];
170 w = i;
171 }
172 return result;
173 }
174
Aart Bikf475bee2015-09-16 12:50:25 -0700175 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800176 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800177 //
Aart Bikf475bee2015-09-16 12:50:25 -0700178 /// CHECK-START: int Main.wrapAroundThenLinearThreeWayPhi(int[]) BCE (after)
179 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800180 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700181 private static int wrapAroundThenLinearThreeWayPhi(int[] x) {
182 // Loop with wrap around (length - 1, 0, 1, 2, ..).
183 int w = x.length - 1;
184 int result = 0;
185 for (int i = 0; i < x.length; ) {
186 if (x[w] == 1) {
187 w = i++;
188 continue;
189 }
190 result += x[w];
191 w = i++;
192 }
193 return result;
194 }
195
Aart Bik22af3be2015-09-10 12:50:58 -0700196 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800197 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800198 //
Aart Bik22af3be2015-09-10 12:50:58 -0700199 /// CHECK-START: int[] Main.linearWithParameter(int) BCE (after)
200 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800201 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700202 private static int[] linearWithParameter(int n) {
203 int[] x = new int[n];
204 for (int i = 0; i < n; i++) {
205 x[i] = i;
206 }
207 return x;
208 }
209
Aart Bikf475bee2015-09-16 12:50:25 -0700210 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800211 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800212 //
Aart Bikf475bee2015-09-16 12:50:25 -0700213 /// CHECK-START: int[] Main.linearCopy(int[]) BCE (after)
214 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800215 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700216 private static int[] linearCopy(int x[]) {
217 int n = x.length;
218 int y[] = new int[n];
219 for (int i = 0; i < n; i++) {
220 y[i] = x[i];
221 }
222 return y;
223 }
224
Aart Bik4a342772015-11-30 10:17:46 -0800225 /// CHECK-START: int Main.linearByTwo(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800226 /// CHECK-DAG: BoundsCheck
227 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800228 //
Aart Bik4a342772015-11-30 10:17:46 -0800229 /// CHECK-START: int Main.linearByTwo(int[]) BCE (after)
230 /// CHECK-NOT: BoundsCheck
231 /// CHECK-NOT: Deoptimize
232 private static int linearByTwo(int x[]) {
233 int n = x.length / 2;
234 int result = 0;
235 for (int i = 0; i < n; i++) {
236 int ii = i << 1;
237 result += x[ii];
238 result += x[ii + 1];
239 }
240 return result;
241 }
242
243 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800244 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800245 //
Aart Bik4a342772015-11-30 10:17:46 -0800246 /// CHECK-START: int Main.linearByTwoSkip1(int[]) BCE (after)
247 /// CHECK-NOT: BoundsCheck
248 /// CHECK-NOT: Deoptimize
249 private static int linearByTwoSkip1(int x[]) {
250 int result = 0;
251 for (int i = 0; i < x.length / 2; i++) {
252 result += x[2 * i];
253 }
254 return result;
255 }
256
257 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800258 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800259 //
Aart Bik4a342772015-11-30 10:17:46 -0800260 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800261 /// CHECK-DAG: BoundsCheck
262 //
263 /// CHECK-START: int Main.linearByTwoSkip2(int[]) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800264 /// CHECK-NOT: Deoptimize
265 private static int linearByTwoSkip2(int x[]) {
266 int result = 0;
267 // This case is not optimized.
268 for (int i = 0; i < x.length; i+=2) {
269 result += x[i];
270 }
271 return result;
272 }
273
Aart Bik22af3be2015-09-10 12:50:58 -0700274 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800275 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800276 //
Aart Bik22af3be2015-09-10 12:50:58 -0700277 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
278 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800279 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700280 private static int linearWithCompoundStride() {
281 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
282 int result = 0;
283 for (int i = 0; i <= 12; ) {
284 i++;
285 result += x[i];
286 i++;
287 }
288 return result;
289 }
290
291 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800292 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800293 //
Aart Bik22af3be2015-09-10 12:50:58 -0700294 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
295 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800296 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700297 private static int linearWithLargePositiveStride() {
298 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
299 int result = 0;
300 int k = 0;
301 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700302 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700303 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
304 result += x[k++];
305 }
306 return result;
307 }
308
309 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800310 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800311 //
Aart Bik22af3be2015-09-10 12:50:58 -0700312 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800313 /// CHECK-DAG: BoundsCheck
314 //
315 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800316 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700317 private static int linearWithVeryLargePositiveStride() {
318 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
319 int result = 0;
320 int k = 0;
321 // Range analysis conservatively bails due to potential of wrap-around
322 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700323 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700324 result += x[k++];
325 }
326 return result;
327 }
328
329 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800330 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800331 //
Aart Bik22af3be2015-09-10 12:50:58 -0700332 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
333 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800334 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700335 private static int linearWithLargeNegativeStride() {
336 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
337 int result = 0;
338 int k = 0;
339 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700340 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700341 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
342 result += x[k++];
343 }
344 return result;
345 }
346
347 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800348 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800349 //
Aart Bik22af3be2015-09-10 12:50:58 -0700350 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800351 /// CHECK-DAG: BoundsCheck
352 //
353 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800354 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700355 private static int linearWithVeryLargeNegativeStride() {
356 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
357 int result = 0;
358 int k = 0;
359 // Range analysis conservatively bails due to potential of wrap-around
360 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700361 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700362 result += x[k++];
363 }
364 return result;
365 }
366
Aart Bik9401f532015-09-28 16:25:56 -0700367 /// CHECK-START: int Main.linearForNEUp() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800368 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800369 //
Aart Bik9401f532015-09-28 16:25:56 -0700370 /// CHECK-START: int Main.linearForNEUp() BCE (after)
Aart Bikf475bee2015-09-16 12:50:25 -0700371 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800372 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700373 private static int linearForNEUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700374 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
375 int result = 0;
376 for (int i = 0; i != 10; i++) {
377 result += x[i];
378 }
379 return result;
380 }
381
Aart Bik9401f532015-09-28 16:25:56 -0700382 /// CHECK-START: int Main.linearForNEDown() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800383 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800384 //
Aart Bik9401f532015-09-28 16:25:56 -0700385 /// CHECK-START: int Main.linearForNEDown() BCE (after)
386 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800387 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700388 private static int linearForNEDown() {
389 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
390 int result = 0;
391 for (int i = 9; i != -1; i--) {
392 result += x[i];
393 }
394 return result;
395 }
396
397 /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800398 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800399 //
Aart Bik9401f532015-09-28 16:25:56 -0700400 /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
401 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800402 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700403 private static int linearDoWhileUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700404 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
405 int result = 0;
406 int i = 0;
Aart Bikf475bee2015-09-16 12:50:25 -0700407 do {
408 result += x[i++];
409 } while (i < 10);
410 return result;
411 }
412
Aart Bik9401f532015-09-28 16:25:56 -0700413 /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800414 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800415 //
Aart Bik9401f532015-09-28 16:25:56 -0700416 /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
417 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800418 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700419 private static int linearDoWhileDown() {
420 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
421 int result = 0;
422 int i = 9;
423 do {
424 result += x[i--];
425 } while (0 <= i);
426 return result;
427 }
428
Aart Bikf475bee2015-09-16 12:50:25 -0700429 /// CHECK-START: int Main.linearShort() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800430 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800431 //
Aart Bikf475bee2015-09-16 12:50:25 -0700432 /// CHECK-START: int Main.linearShort() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800433 /// CHECK-DAG: BoundsCheck
434 //
435 /// CHECK-START: int Main.linearShort() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800436 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700437 private static int linearShort() {
438 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
439 int result = 0;
440 // TODO: make this work
441 for (short i = 0; i < 10; i++) {
442 result += x[i];
443 }
444 return result;
445 }
446
Aart Bik4a342772015-11-30 10:17:46 -0800447 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800448 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800449 //
Aart Bik4a342772015-11-30 10:17:46 -0800450 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after)
451 /// CHECK-NOT: BoundsCheck
452 /// CHECK-NOT: Deoptimize
453 private static int invariantFromPreLoop(int[] x, int y) {
454 int result = 0;
455 // Strange pre-loop that sets upper bound.
456 int hi;
457 while (true) {
458 y = y % 3;
459 hi = x.length;
460 if (y != 123) break;
461 }
462 for (int i = 0; i < hi; i++) {
463 result += x[i];
464 }
465 return result;
466 }
467
Aart Bikb738d4f2015-12-03 11:23:35 -0800468 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800469 /// CHECK-DAG: BoundsCheck
470 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800471 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800472 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after)
473 /// CHECK-NOT: BoundsCheck
Aart Bikb738d4f2015-12-03 11:23:35 -0800474 /// CHECK-NOT: Deoptimize
475 private static void linearTriangularOnTwoArrayLengths(int n) {
476 int[] a = new int[n];
477 for (int i = 0; i < a.length; i++) {
478 int[] b = new int[i];
479 for (int j = 0; j < b.length; j++) {
480 // Need to know j < b.length < a.length for static bce.
481 a[j] += 1;
482 // Need to know just j < b.length for static bce.
483 b[j] += 1;
484 }
485 verifyTriangular(a, b, i, n);
486 }
487 }
488
489 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800490 /// CHECK-DAG: BoundsCheck
491 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800492 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800493 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (after)
494 /// CHECK-NOT: BoundsCheck
Aart Bikb738d4f2015-12-03 11:23:35 -0800495 /// CHECK-NOT: Deoptimize
496 private static void linearTriangularOnOneArrayLength(int n) {
497 int[] a = new int[n];
498 for (int i = 0; i < a.length; i++) {
499 int[] b = new int[i];
500 for (int j = 0; j < i; j++) {
501 // Need to know j < i < a.length for static bce.
502 a[j] += 1;
503 // Need to know just j < i for static bce.
504 b[j] += 1;
505 }
506 verifyTriangular(a, b, i, n);
507 }
508 }
509
510 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800511 /// CHECK-DAG: BoundsCheck
512 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800513 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800514 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after)
515 /// CHECK-NOT: BoundsCheck
Aart Bikb738d4f2015-12-03 11:23:35 -0800516 /// CHECK-NOT: Deoptimize
517 private static void linearTriangularOnParameter(int n) {
518 int[] a = new int[n];
519 for (int i = 0; i < n; i++) {
520 int[] b = new int[i];
521 for (int j = 0; j < i; j++) {
522 // Need to know j < i < n for static bce.
523 a[j] += 1;
524 // Need to know just j < i for static bce.
525 b[j] += 1;
526 }
527 verifyTriangular(a, b, i, n);
528 }
529 }
530
Aart Bik7d57d7f2015-12-09 14:39:48 -0800531 /// CHECK-START: void Main.linearTriangularVariations(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800532 /// CHECK-DAG: BoundsCheck
533 /// CHECK-DAG: BoundsCheck
534 /// CHECK-DAG: BoundsCheck
535 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800536 //
537 /// CHECK-START: void Main.linearTriangularVariations(int) BCE (after)
538 /// CHECK-NOT: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800539 /// CHECK-NOT: Deoptimize
540 private static void linearTriangularVariations(int n) {
541 int[] a = new int[n];
542 for (int i = 0; i < n; i++) {
543 for (int j = 0; j < i; j++) {
544 a[j] += 1;
545 }
546 for (int j = i - 1; j >= 0; j--) {
547 a[j] += 1;
548 }
549 for (int j = i; j < n; j++) {
550 a[j] += 1;
551 }
552 for (int j = n - 1; j > i - 1; j--) {
553 a[j] += 1;
554 }
555 }
556 verifyTriangular(a);
557 }
558
559 // Verifier for triangular loops.
Aart Bikb738d4f2015-12-03 11:23:35 -0800560 private static void verifyTriangular(int[] a, int[] b, int m, int n) {
561 expectEquals(n, a.length);
562 for (int i = 0, k = m; i < n; i++) {
563 expectEquals(a[i], k);
564 if (k > 0) k--;
565 }
566 expectEquals(m, b.length);
567 for (int i = 0; i < m; i++) {
568 expectEquals(b[i], 1);
569 }
570 }
571
Aart Bik7d57d7f2015-12-09 14:39:48 -0800572 // Verifier for triangular loops.
573 private static void verifyTriangular(int[] a) {
574 int n = a.length;
575 for (int i = 0; i < n; i++) {
576 expectEquals(a[i], n + n);
577 }
578 }
579
Aart Bikb738d4f2015-12-03 11:23:35 -0800580 /// CHECK-START: void Main.bubble(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800581 /// CHECK-DAG: BoundsCheck
582 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800583 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800584 /// CHECK-START: void Main.bubble(int[]) BCE (after)
585 /// CHECK-NOT: BoundsCheck
Aart Bikb738d4f2015-12-03 11:23:35 -0800586 /// CHECK-NOT: Deoptimize
587 private static void bubble(int[] a) {
588 for (int i = a.length; --i >= 0;) {
589 for (int j = 0; j < i; j++) {
590 if (a[j] > a[j+1]) {
591 int tmp = a[j];
592 a[j] = a[j+1];
593 a[j+1] = tmp;
594 }
595 }
596 }
597 }
598
Aart Bik22af3be2015-09-10 12:50:58 -0700599 /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800600 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800601 //
Aart Bik22af3be2015-09-10 12:50:58 -0700602 /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
603 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800604 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700605 private static int periodicIdiom(int tc) {
606 int[] x = { 1, 3 };
607 // Loop with periodic sequence (0, 1).
608 int k = 0;
609 int result = 0;
610 for (int i = 0; i < tc; i++) {
611 result += x[k];
612 k = 1 - k;
613 }
614 return result;
615 }
616
617 /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800618 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800619 //
Aart Bik22af3be2015-09-10 12:50:58 -0700620 /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
621 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800622 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700623 private static int periodicSequence2(int tc) {
624 int[] x = { 1, 3 };
625 // Loop with periodic sequence (0, 1).
626 int k = 0;
627 int l = 1;
628 int result = 0;
629 for (int i = 0; i < tc; i++) {
630 result += x[k];
631 int t = l;
632 l = k;
633 k = t;
634 }
635 return result;
636 }
637
638 /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800639 /// CHECK-DAG: BoundsCheck
640 /// CHECK-DAG: BoundsCheck
641 /// CHECK-DAG: BoundsCheck
642 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800643 //
Aart Bik22af3be2015-09-10 12:50:58 -0700644 /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
645 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800646 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700647 private static int periodicSequence4(int tc) {
648 int[] x = { 1, 3, 5, 7 };
649 // Loop with periodic sequence (0, 1, 2, 3).
650 int k = 0;
651 int l = 1;
652 int m = 2;
653 int n = 3;
654 int result = 0;
655 for (int i = 0; i < tc; i++) {
656 result += x[k] + x[l] + x[m] + x[n]; // all used at once
657 int t = n;
658 n = k;
659 k = l;
660 l = m;
661 m = t;
662 }
663 return result;
664 }
665
Aart Bikf475bee2015-09-16 12:50:25 -0700666 /// CHECK-START: int Main.justRightUp1() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800667 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800668 //
Aart Bikf475bee2015-09-16 12:50:25 -0700669 /// CHECK-START: int Main.justRightUp1() BCE (after)
670 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800671 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700672 private static int justRightUp1() {
673 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
674 int result = 0;
675 for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
676 result += x[k++];
677 }
678 return result;
679 }
680
681 /// CHECK-START: int Main.justRightUp2() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800682 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800683 //
Aart Bikf475bee2015-09-16 12:50:25 -0700684 /// CHECK-START: int Main.justRightUp2() BCE (after)
685 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800686 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700687 private static int justRightUp2() {
688 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
689 int result = 0;
690 for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
691 result += x[i - Integer.MAX_VALUE + 10];
692 }
693 return result;
694 }
695
696 /// CHECK-START: int Main.justRightUp3() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800697 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800698 //
Aart Bikf475bee2015-09-16 12:50:25 -0700699 /// CHECK-START: int Main.justRightUp3() BCE (after)
700 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800701 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700702 private static int justRightUp3() {
703 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
704 int result = 0;
705 for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
706 result += x[k++];
707 }
708 return result;
709 }
710
711 /// CHECK-START: int Main.justOOBUp() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800712 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800713 //
Aart Bikf475bee2015-09-16 12:50:25 -0700714 /// CHECK-START: int Main.justOOBUp() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800715 /// CHECK-DAG: BoundsCheck
716 //
717 /// CHECK-START: int Main.justOOBUp() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800718 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700719 private static int justOOBUp() {
720 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
721 int result = 0;
722 // Infinite loop!
723 for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
724 result += x[k++];
725 }
726 return result;
727 }
728
729 /// CHECK-START: int Main.justRightDown1() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800730 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800731 //
Aart Bikf475bee2015-09-16 12:50:25 -0700732 /// CHECK-START: int Main.justRightDown1() BCE (after)
733 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800734 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700735 private static int justRightDown1() {
736 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
737 int result = 0;
738 for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
739 result += x[k++];
740 }
741 return result;
742 }
743
744 /// CHECK-START: int Main.justRightDown2() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800745 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800746 //
Aart Bikf475bee2015-09-16 12:50:25 -0700747 /// CHECK-START: int Main.justRightDown2() BCE (after)
748 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800749 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700750 private static int justRightDown2() {
751 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
752 int result = 0;
753 for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
754 result += x[Integer.MAX_VALUE + i];
755 }
756 return result;
757 }
758
759 /// CHECK-START: int Main.justRightDown3() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800760 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800761 //
Aart Bikf475bee2015-09-16 12:50:25 -0700762 /// CHECK-START: int Main.justRightDown3() BCE (after)
763 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800764 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700765 private static int justRightDown3() {
766 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
767 int result = 0;
768 for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
769 result += x[k++];
770 }
771 return result;
772 }
773
774 /// CHECK-START: int Main.justOOBDown() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800775 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800776 //
Aart Bikf475bee2015-09-16 12:50:25 -0700777 /// CHECK-START: int Main.justOOBDown() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800778 /// CHECK-DAG: BoundsCheck
779 //
780 /// CHECK-START: int Main.justOOBDown() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800781 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700782 private static int justOOBDown() {
783 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
784 int result = 0;
785 // Infinite loop!
786 for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
787 result += x[k++];
788 }
789 return result;
790 }
791
Aart Bik9401f532015-09-28 16:25:56 -0700792 /// CHECK-START: void Main.lowerOOB(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800793 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800794 //
Aart Bik9401f532015-09-28 16:25:56 -0700795 /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800796 /// CHECK-DAG: BoundsCheck
797 //
798 /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800799 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700800 private static void lowerOOB(int[] x) {
Aart Bik09e8d5f2016-01-22 16:49:55 -0800801 // OOB!
Aart Bik22af3be2015-09-10 12:50:58 -0700802 for (int i = -1; i < x.length; i++) {
803 sResult += x[i];
804 }
805 }
806
Aart Bik9401f532015-09-28 16:25:56 -0700807 /// CHECK-START: void Main.upperOOB(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800808 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800809 //
Aart Bik9401f532015-09-28 16:25:56 -0700810 /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800811 /// CHECK-DAG: BoundsCheck
812 //
813 /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800814 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700815 private static void upperOOB(int[] x) {
Aart Bik09e8d5f2016-01-22 16:49:55 -0800816 // OOB!
Aart Bik22af3be2015-09-10 12:50:58 -0700817 for (int i = 0; i <= x.length; i++) {
818 sResult += x[i];
819 }
820 }
821
Aart Bik9401f532015-09-28 16:25:56 -0700822 /// CHECK-START: void Main.doWhileUpOOB() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800823 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800824 //
Aart Bik9401f532015-09-28 16:25:56 -0700825 /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800826 /// CHECK-DAG: BoundsCheck
827 //
828 /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800829 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700830 private static void doWhileUpOOB() {
831 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
832 int i = 0;
Aart Bik09e8d5f2016-01-22 16:49:55 -0800833 // OOB!
Aart Bik9401f532015-09-28 16:25:56 -0700834 do {
835 sResult += x[i++];
836 } while (i <= x.length);
837 }
838
839 /// CHECK-START: void Main.doWhileDownOOB() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800840 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800841 //
Aart Bik9401f532015-09-28 16:25:56 -0700842 /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800843 /// CHECK-DAG: BoundsCheck
844 //
845 /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -0800846 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700847 private static void doWhileDownOOB() {
848 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
849 int i = x.length - 1;
Aart Bik09e8d5f2016-01-22 16:49:55 -0800850 // OOB!
Aart Bik9401f532015-09-28 16:25:56 -0700851 do {
852 sResult += x[i--];
853 } while (-1 <= i);
854 }
855
Aart Bik7d57d7f2015-12-09 14:39:48 -0800856 /// CHECK-START: int[] Main.multiply1() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800857 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800858 //
859 /// CHECK-START: int[] Main.multiply1() BCE (after)
860 /// CHECK-NOT: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800861 /// CHECK-NOT: Deoptimize
862 private static int[] multiply1() {
863 int[] a = new int[10];
864 try {
865 for (int i = 0; i <= 3; i++) {
866 for (int j = 0; j <= 3; j++) {
867 // Range [0,9]: safe.
868 a[i * j] += 1;
869 }
870 }
871 } catch (Exception e) {
872 a[0] += 1000;
873 }
874 return a;
875 }
876
877 /// CHECK-START: int[] Main.multiply2() BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800878 /// CHECK-DAG: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800879 //
880 /// CHECK-START: int[] Main.multiply2() BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800881 /// CHECK-DAG: BoundsCheck
882 //
883 /// CHECK-START: int[] Main.multiply2() BCE (after)
884 /// CHECK-NOT: Deoptimize
Aart Bik7d57d7f2015-12-09 14:39:48 -0800885 static int[] multiply2() {
886 int[] a = new int[10];
887 try {
888 for (int i = -3; i <= 3; i++) {
889 for (int j = -3; j <= 3; j++) {
890 // Range [-9,9]: unsafe.
Aart Bik09e8d5f2016-01-22 16:49:55 -0800891 a[i * j] += 1;
Aart Bik7d57d7f2015-12-09 14:39:48 -0800892 }
893 }
894 } catch (Exception e) {
895 a[0] += 1000;
896 }
897 return a;
898 }
899
Aart Bik4a342772015-11-30 10:17:46 -0800900 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800901 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
902 /// CHECK-DAG: NullCheck loop:<<Loop>>
903 /// CHECK-DAG: ArrayLength loop:<<Loop>>
904 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -0800905 //
Aart Bik4a342772015-11-30 10:17:46 -0800906 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800907 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
908 /// CHECK-DAG: Deoptimize loop:none
909 //
910 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
911 /// CHECK-NOT: NullCheck loop:{{B\d+}}
912 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
913 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
Aart Bik4a342772015-11-30 10:17:46 -0800914 private static int linearDynamicBCE1(int[] x, int lo, int hi) {
915 int result = 0;
916 for (int i = lo; i < hi; i++) {
917 sResult += x[i];
918 }
919 return result;
920 }
921
922 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800923 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
924 /// CHECK-DAG: NullCheck loop:<<Loop>>
925 /// CHECK-DAG: ArrayLength loop:<<Loop>>
926 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -0800927 //
Aart Bik4a342772015-11-30 10:17:46 -0800928 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800929 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
930 /// CHECK-DAG: Deoptimize loop:none
931 //
932 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
933 /// CHECK-NOT: NullCheck loop:{{B\d+}}
934 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
935 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
Aart Bik4a342772015-11-30 10:17:46 -0800936 private static int linearDynamicBCE2(int[] x, int lo, int hi, int offset) {
937 int result = 0;
938 for (int i = lo; i < hi; i++) {
939 sResult += x[offset + i];
940 }
941 return result;
942 }
943
944 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800945 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
946 /// CHECK-DAG: NullCheck loop:<<Loop>>
947 /// CHECK-DAG: ArrayLength loop:<<Loop>>
948 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -0800949 //
Aart Bik4a342772015-11-30 10:17:46 -0800950 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800951 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
952 /// CHECK-DAG: Deoptimize loop:none
953 //
954 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
955 /// CHECK-NOT: NullCheck loop:{{B\d+}}
956 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
957 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
Aart Bik4a342772015-11-30 10:17:46 -0800958 private static int wrapAroundDynamicBCE(int[] x) {
959 int w = 9;
960 int result = 0;
961 for (int i = 0; i < 10; i++) {
962 result += x[w];
963 w = i;
964 }
965 return result;
966 }
967
968 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800969 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
970 /// CHECK-DAG: NullCheck loop:<<Loop>>
971 /// CHECK-DAG: ArrayLength loop:<<Loop>>
972 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -0800973 //
Aart Bik4a342772015-11-30 10:17:46 -0800974 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800975 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
976 /// CHECK-DAG: Deoptimize loop:none
977 //
978 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
979 /// CHECK-NOT: NullCheck loop:{{B\d+}}
980 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
981 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
Aart Bik4a342772015-11-30 10:17:46 -0800982 private static int periodicDynamicBCE(int[] x) {
983 int k = 0;
984 int result = 0;
985 for (int i = 0; i < 10; i++) {
986 result += x[k];
987 k = 1 - k;
988 }
989 return result;
990 }
991
992 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800993 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
994 /// CHECK-DAG: NullCheck loop:<<Loop>>
995 /// CHECK-DAG: ArrayLength loop:<<Loop>>
996 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -0800997 //
Aart Bik4a342772015-11-30 10:17:46 -0800998 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800999 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
1000 /// CHECK-DAG: Deoptimize loop:none
1001 //
1002 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
1003 /// CHECK-NOT: NullCheck loop:{{B\d+}}
1004 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
1005 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
Aart Bik4a342772015-11-30 10:17:46 -08001006 static int dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
1007 // This loop could be infinite for hi = max int. Since i is also used
1008 // as subscript, however, dynamic bce can proceed.
1009 int result = 0;
1010 for (int i = lo; i <= hi; i++) {
1011 result += x[i];
1012 }
1013 return result;
1014 }
1015
1016 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001017 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1018 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -08001019 //
Aart Bik4a342772015-11-30 10:17:46 -08001020 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001021 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1022 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
1023 //
1024 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -08001025 /// CHECK-NOT: Deoptimize
1026 static int noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
1027 // As above, but now the index is not used as subscript,
1028 // and dynamic bce is not applied.
1029 int result = 0;
1030 for (int k = 0, i = lo; i <= hi; i++) {
1031 result += x[k++];
1032 }
1033 return result;
1034 }
1035
1036 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001037 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1038 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -08001039 //
Aart Bik4a342772015-11-30 10:17:46 -08001040 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001041 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1042 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
1043 //
1044 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
Aart Bik4a342772015-11-30 10:17:46 -08001045 /// CHECK-NOT: Deoptimize
1046 static int noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi) {
1047 int result = 0;
1048 // Mix of int and long induction.
1049 int k = 0;
1050 for (long i = lo; i < hi; i++) {
1051 result += x[k++];
1052 }
1053 return result;
1054 }
1055
1056 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001057 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop:B\d+>>
1058 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
1059 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -08001060 //
Aart Bik4a342772015-11-30 10:17:46 -08001061 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
Aart Bik09e8d5f2016-01-22 16:49:55 -08001062 // Order matters:
1063 /// CHECK: Deoptimize loop:<<Loop:B\d+>>
1064 // CHECK-NOT: Goto loop:<<Loop>>
1065 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
1066 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
1067 /// CHECK-DAG: {{l\d+}} ArrayGet loop:<<Loop>>
1068 /// CHECK: Goto loop:<<Loop>>
1069 //
1070 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
1071 /// CHECK-DAG: Deoptimize loop:none
Aart Bik4a342772015-11-30 10:17:46 -08001072 static int dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi) {
1073 // Deliberately test array length on a before the loop so that only bounds checks
1074 // on constant subscripts remain, making them a viable candidate for hoisting.
1075 if (a.length == 0) {
1076 return -1;
1077 }
1078 // Loop that allows BCE on x[i].
1079 int result = 0;
1080 for (int i = lo; i < hi; i++) {
1081 result += x[i];
1082 if ((i % 10) != 0) {
1083 // None of the subscripts inside a conditional are removed by dynamic bce,
1084 // making them a candidate for deoptimization based on constant indices.
1085 // Compiler should ensure the array loads are not subsequently hoisted
1086 // "above" the deoptimization "barrier" on the bounds.
1087 a[0][i] = 1;
1088 a[1][i] = 2;
1089 a[99][i] = 3;
1090 }
1091 }
1092 return result;
1093 }
1094
Aart Bik09e8d5f2016-01-22 16:49:55 -08001095 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (before)
1096 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1097 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1098 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1099 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1100 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1101 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1102 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1103 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1104 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1105 // For brevity, just test occurrence of at least one of each in the loop:
1106 /// CHECK-DAG: NullCheck loop:<<Loop>>
1107 /// CHECK-DAG: ArrayLength loop:<<Loop>>
1108 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
Aart Bik7d57d7f2015-12-09 14:39:48 -08001109 //
Aart Bik09e8d5f2016-01-22 16:49:55 -08001110 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
1111 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1112 /// CHECK-NOT: ArrayGet loop:<<Loop>>
1113 //
1114 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
1115 /// CHECK-NOT: NullCheck loop:{{B\d+}}
1116 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
1117 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
1118 //
1119 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllPrimTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], int, int) BCE (after)
1120 /// CHECK-DAG: Deoptimize loop:none
1121 static int dynamicBCEAndConstantIndicesAllPrimTypes(int[] q,
1122 boolean[] r,
1123 byte[] s,
1124 char[] t,
1125 short[] u,
1126 int[] v,
1127 long[] w,
1128 float[] x,
1129 double[] y, int lo, int hi) {
Aart Bik4a342772015-11-30 10:17:46 -08001130 int result = 0;
1131 for (int i = lo; i < hi; i++) {
Aart Bik09e8d5f2016-01-22 16:49:55 -08001132 // All constant index array references can be hoisted out of the loop during BCE on q[i].
Aart Bik4a342772015-11-30 10:17:46 -08001133 result += q[i] + (r[0] ? 1 : 0) + (int) s[0] + (int) t[0] + (int) u[0] + (int) v[0] +
Aart Bik09e8d5f2016-01-22 16:49:55 -08001134 (int) w[0] + (int) x[0] + (int) y[0];
1135 }
1136 return result;
1137 }
1138
1139 /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (before)
1140 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1141 /// CHECK-DAG: NullCheck loop:<<Loop>>
1142 /// CHECK-DAG: ArrayLength loop:<<Loop>>
1143 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
1144 /// CHECK-DAG: ArrayGet loop:<<Loop>>
1145 /// CHECK-DAG: NullCheck loop:<<Loop>>
1146 /// CHECK-DAG: ArrayLength loop:<<Loop>>
1147 /// CHECK-DAG: BoundsCheck loop:<<Loop>>
1148 //
1149 /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after)
1150 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>>
1151 /// CHECK-DAG: Deoptimize loop:none
1152 //
1153 /// CHECK-START: int Main.dynamicBCEAndConstantIndexRefType(int[], java.lang.Integer[], int, int) BCE (after)
1154 /// CHECK-NOT: ArrayLength loop:{{B\d+}}
1155 /// CHECK-NOT: BoundsCheck loop:{{B\d+}}
1156 static int dynamicBCEAndConstantIndexRefType(int[] q, Integer[] z, int lo, int hi) {
1157 int result = 0;
1158 for (int i = lo; i < hi; i++) {
1159 // Similar to above, but now implicit call to intValue() may prevent hoisting
1160 // z[0] itself during BCE on q[i]. Therefore, we just check BCE on q[i].
1161 result += q[i] + z[0];
Aart Bik4a342772015-11-30 10:17:46 -08001162 }
1163 return result;
1164 }
1165
Aart Bik22af3be2015-09-10 12:50:58 -07001166 //
1167 // Verifier.
1168 //
1169
1170 public static void main(String[] args) {
1171 int[] empty = { };
1172 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
1173
1174 // Linear and wrap-around.
1175 expectEquals(0, linear(empty));
1176 expectEquals(55, linear(x));
1177 expectEquals(0, linearDown(empty));
1178 expectEquals(55, linearDown(x));
1179 expectEquals(0, linearObscure(empty));
1180 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001181 expectEquals(0, linearVeryObscure(empty));
1182 expectEquals(55, linearVeryObscure(x));
Aart Bik7d57d7f2015-12-09 14:39:48 -08001183 expectEquals(0, hiddenStride(empty));
1184 expectEquals(55, hiddenStride(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001185 expectEquals(0, linearWhile(empty));
1186 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001187 expectEquals(0, linearThreeWayPhi(empty));
1188 expectEquals(50, linearThreeWayPhi(x));
1189 expectEquals(0, linearFourWayPhi(empty));
1190 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001191 expectEquals(0, wrapAroundThenLinear(empty));
1192 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001193 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
1194 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001195
1196 // Linear with parameter.
1197 sResult = 0;
1198 try {
1199 linearWithParameter(-1);
1200 } catch (NegativeArraySizeException e) {
1201 sResult = 1;
1202 }
1203 expectEquals(1, sResult);
1204 for (int n = 0; n < 32; n++) {
1205 int[] r = linearWithParameter(n);
1206 expectEquals(n, r.length);
1207 for (int i = 0; i < n; i++) {
1208 expectEquals(i, r[i]);
1209 }
1210 }
1211
Aart Bikf475bee2015-09-16 12:50:25 -07001212 // Linear copy.
1213 expectEquals(0, linearCopy(empty).length);
1214 {
1215 int[] r = linearCopy(x);
1216 expectEquals(x.length, r.length);
1217 for (int i = 0; i < x.length; i++) {
1218 expectEquals(x[i], r[i]);
1219 }
1220 }
1221
Aart Bik22af3be2015-09-10 12:50:58 -07001222 // Linear with non-unit strides.
Aart Bik4a342772015-11-30 10:17:46 -08001223 expectEquals(55, linearByTwo(x));
1224 expectEquals(25, linearByTwoSkip1(x));
1225 expectEquals(25, linearByTwoSkip2(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001226 expectEquals(56, linearWithCompoundStride());
1227 expectEquals(66, linearWithLargePositiveStride());
1228 expectEquals(66, linearWithVeryLargePositiveStride());
1229 expectEquals(66, linearWithLargeNegativeStride());
1230 expectEquals(66, linearWithVeryLargeNegativeStride());
1231
Aart Bikf475bee2015-09-16 12:50:25 -07001232 // Special forms.
Aart Bik9401f532015-09-28 16:25:56 -07001233 expectEquals(55, linearForNEUp());
1234 expectEquals(55, linearForNEDown());
1235 expectEquals(55, linearDoWhileUp());
1236 expectEquals(55, linearDoWhileDown());
Aart Bikf475bee2015-09-16 12:50:25 -07001237 expectEquals(55, linearShort());
Aart Bik4a342772015-11-30 10:17:46 -08001238 expectEquals(55, invariantFromPreLoop(x, 1));
Aart Bikb738d4f2015-12-03 11:23:35 -08001239 linearTriangularOnTwoArrayLengths(10);
1240 linearTriangularOnOneArrayLength(10);
1241 linearTriangularOnParameter(10);
Aart Bik7d57d7f2015-12-09 14:39:48 -08001242 linearTriangularVariations(10);
Aart Bikb738d4f2015-12-03 11:23:35 -08001243
1244 // Sorting.
1245 int[] sort = { 5, 4, 1, 9, 10, 2, 7, 6, 3, 8 };
1246 bubble(sort);
1247 for (int i = 0; i < 10; i++) {
1248 expectEquals(sort[i], x[i]);
1249 }
Aart Bikf475bee2015-09-16 12:50:25 -07001250
Aart Bik22af3be2015-09-10 12:50:58 -07001251 // Periodic adds (1, 3), one at the time.
1252 expectEquals(0, periodicIdiom(-1));
1253 for (int tc = 0; tc < 32; tc++) {
1254 int expected = (tc >> 1) << 2;
1255 if ((tc & 1) != 0)
1256 expected += 1;
1257 expectEquals(expected, periodicIdiom(tc));
1258 }
1259
1260 // Periodic adds (1, 3), one at the time.
1261 expectEquals(0, periodicSequence2(-1));
1262 for (int tc = 0; tc < 32; tc++) {
1263 int expected = (tc >> 1) << 2;
1264 if ((tc & 1) != 0)
1265 expected += 1;
1266 expectEquals(expected, periodicSequence2(tc));
1267 }
1268
1269 // Periodic adds (1, 3, 5, 7), all at once.
1270 expectEquals(0, periodicSequence4(-1));
1271 for (int tc = 0; tc < 32; tc++) {
1272 expectEquals(tc * 16, periodicSequence4(tc));
1273 }
1274
Aart Bikf475bee2015-09-16 12:50:25 -07001275 // Large bounds.
1276 expectEquals(55, justRightUp1());
1277 expectEquals(55, justRightUp2());
1278 expectEquals(55, justRightUp3());
1279 expectEquals(55, justRightDown1());
1280 expectEquals(55, justRightDown2());
1281 expectEquals(55, justRightDown3());
1282 sResult = 0;
1283 try {
1284 justOOBUp();
1285 } catch (ArrayIndexOutOfBoundsException e) {
1286 sResult = 1;
1287 }
1288 expectEquals(1, sResult);
1289 sResult = 0;
1290 try {
1291 justOOBDown();
1292 } catch (ArrayIndexOutOfBoundsException e) {
1293 sResult = 1;
1294 }
1295 expectEquals(1, sResult);
1296
Aart Bik22af3be2015-09-10 12:50:58 -07001297 // Lower bound goes OOB.
1298 sResult = 0;
1299 try {
1300 lowerOOB(x);
1301 } catch (ArrayIndexOutOfBoundsException e) {
1302 sResult += 1000;
1303 }
1304 expectEquals(1000, sResult);
1305
1306 // Upper bound goes OOB.
1307 sResult = 0;
1308 try {
1309 upperOOB(x);
1310 } catch (ArrayIndexOutOfBoundsException e) {
1311 sResult += 1000;
1312 }
1313 expectEquals(1055, sResult);
1314
Aart Bik9401f532015-09-28 16:25:56 -07001315 // Do while up goes OOB.
1316 sResult = 0;
1317 try {
1318 doWhileUpOOB();
1319 } catch (ArrayIndexOutOfBoundsException e) {
1320 sResult += 1000;
1321 }
1322 expectEquals(1055, sResult);
1323
1324 // Do while down goes OOB.
1325 sResult = 0;
1326 try {
1327 doWhileDownOOB();
1328 } catch (ArrayIndexOutOfBoundsException e) {
1329 sResult += 1000;
1330 }
1331 expectEquals(1055, sResult);
Aart Bik4a342772015-11-30 10:17:46 -08001332
Aart Bik7d57d7f2015-12-09 14:39:48 -08001333 // Multiplication.
1334 {
1335 int[] e1 = { 7, 1, 2, 2, 1, 0, 2, 0, 0, 1 };
1336 int[] a1 = multiply1();
1337 for (int i = 0; i < 10; i++) {
1338 expectEquals(a1[i], e1[i]);
1339 }
1340 int[] e2 = { 1001, 0, 0, 1, 0, 0, 1, 0, 0, 1 };
1341 int[] a2 = multiply2();
1342 for (int i = 0; i < 10; i++) {
1343 expectEquals(a2[i], e2[i]);
1344 }
1345 }
1346
Aart Bik4a342772015-11-30 10:17:46 -08001347 // Dynamic BCE.
1348 sResult = 0;
1349 try {
1350 linearDynamicBCE1(x, -1, x.length);
1351 } catch (ArrayIndexOutOfBoundsException e) {
1352 sResult += 1000;
1353 }
1354 expectEquals(1000, sResult);
1355 sResult = 0;
1356 linearDynamicBCE1(x, 0, x.length);
1357 expectEquals(55, sResult);
1358 sResult = 0;
1359 try {
1360 linearDynamicBCE1(x, 0, x.length + 1);
1361 } catch (ArrayIndexOutOfBoundsException e) {
1362 sResult += 1000;
1363 }
1364 expectEquals(1055, sResult);
1365
1366 // Dynamic BCE with offset.
1367 sResult = 0;
1368 try {
1369 linearDynamicBCE2(x, 0, x.length, -1);
1370 } catch (ArrayIndexOutOfBoundsException e) {
1371 sResult += 1000;
1372 }
1373 expectEquals(1000, sResult);
1374 sResult = 0;
1375 linearDynamicBCE2(x, 0, x.length, 0);
1376 expectEquals(55, sResult);
1377 sResult = 0;
1378 try {
1379 linearDynamicBCE2(x, 0, x.length, 1);
1380 } catch (ArrayIndexOutOfBoundsException e) {
1381 sResult += 1000;
1382 }
1383 expectEquals(1054, sResult);
1384
1385 // Dynamic BCE candidates.
1386 expectEquals(55, wrapAroundDynamicBCE(x));
1387 expectEquals(15, periodicDynamicBCE(x));
1388 expectEquals(55, dynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1389 expectEquals(55, noDynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1390 expectEquals(55, noDynamicBCEMixedInductionTypes(x, 0, 10));
1391
1392 // Dynamic BCE combined with constant indices.
1393 int[][] a;
1394 a = new int[0][0];
1395 expectEquals(-1, dynamicBCEAndConstantIndices(x, a, 0, 10));
1396 a = new int[100][10];
1397 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1398 for (int i = 0; i < 10; i++) {
1399 expectEquals((i % 10) != 0 ? 1 : 0, a[0][i]);
1400 expectEquals((i % 10) != 0 ? 2 : 0, a[1][i]);
1401 expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]);
1402 }
1403 a = new int[2][10];
1404 sResult = 0;
1405 try {
1406 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1407 } catch (ArrayIndexOutOfBoundsException e) {
1408 sResult = 1;
1409 }
1410 expectEquals(1, sResult);
1411 expectEquals(a[0][1], 1);
1412 expectEquals(a[1][1], 2);
1413
1414 // Dynamic BCE combined with constant indices of all types.
1415 boolean[] x1 = { true };
1416 byte[] x2 = { 2 };
1417 char[] x3 = { 3 };
1418 short[] x4 = { 4 };
1419 int[] x5 = { 5 };
1420 long[] x6 = { 6 };
1421 float[] x7 = { 7 };
1422 double[] x8 = { 8 };
Aart Bik09e8d5f2016-01-22 16:49:55 -08001423 expectEquals(415,
1424 dynamicBCEAndConstantIndicesAllPrimTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, 0, 10));
Aart Bik4a342772015-11-30 10:17:46 -08001425 Integer[] x9 = { 9 };
Aart Bik09e8d5f2016-01-22 16:49:55 -08001426 expectEquals(145, dynamicBCEAndConstantIndexRefType(x, x9, 0, 10));
Aart Bik22af3be2015-09-10 12:50:58 -07001427 }
1428
1429 private static void expectEquals(int expected, int result) {
1430 if (expected != result) {
1431 throw new Error("Expected: " + expected + ", found: " + result);
1432 }
1433 }
1434}