blob: f1d9a37c88d7c1cd5fdd11e53558e56deb2eadf0 [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 Bik5d75afe2015-12-14 11:57:01 -080029 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -080043 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -080057 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -080072 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -080087 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800104 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800119 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800137 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800159 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800176 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800197 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800211 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800226 /// CHECK: BoundsCheck
227 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800244 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800258 /// CHECK: 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 Bik5d75afe2015-12-14 11:57:01 -0800261 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800262 /// CHECK-NOT: Deoptimize
263 private static int linearByTwoSkip2(int x[]) {
264 int result = 0;
265 // This case is not optimized.
266 for (int i = 0; i < x.length; i+=2) {
267 result += x[i];
268 }
269 return result;
270 }
271
Aart Bik22af3be2015-09-10 12:50:58 -0700272 /// CHECK-START: int Main.linearWithCompoundStride() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800273 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800274 //
Aart Bik22af3be2015-09-10 12:50:58 -0700275 /// CHECK-START: int Main.linearWithCompoundStride() BCE (after)
276 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800277 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700278 private static int linearWithCompoundStride() {
279 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
280 int result = 0;
281 for (int i = 0; i <= 12; ) {
282 i++;
283 result += x[i];
284 i++;
285 }
286 return result;
287 }
288
289 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800290 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800291 //
Aart Bik22af3be2015-09-10 12:50:58 -0700292 /// CHECK-START: int Main.linearWithLargePositiveStride() BCE (after)
293 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800294 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700295 private static int linearWithLargePositiveStride() {
296 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
297 int result = 0;
298 int k = 0;
299 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700300 // reasonably large positive stride far away from upper bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700301 for (int i = 1; i <= 10 * 10000000 + 1; i += 10000000) {
302 result += x[k++];
303 }
304 return result;
305 }
306
307 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800308 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800309 //
Aart Bik22af3be2015-09-10 12:50:58 -0700310 /// CHECK-START: int Main.linearWithVeryLargePositiveStride() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800311 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800312 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700313 private static int linearWithVeryLargePositiveStride() {
314 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
315 int result = 0;
316 int k = 0;
317 // Range analysis conservatively bails due to potential of wrap-around
318 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700319 for (int i = 1; i < Integer.MAX_VALUE; i += 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700320 result += x[k++];
321 }
322 return result;
323 }
324
325 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800326 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800327 //
Aart Bik22af3be2015-09-10 12:50:58 -0700328 /// CHECK-START: int Main.linearWithLargeNegativeStride() BCE (after)
329 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800330 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700331 private static int linearWithLargeNegativeStride() {
332 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
333 int result = 0;
334 int k = 0;
335 // Range analysis has no problem with a trip-count defined by a
Aart Bikf475bee2015-09-16 12:50:25 -0700336 // reasonably large negative stride far away from lower bound.
Aart Bik22af3be2015-09-10 12:50:58 -0700337 for (int i = -1; i >= -10 * 10000000 - 1; i -= 10000000) {
338 result += x[k++];
339 }
340 return result;
341 }
342
343 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800344 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800345 //
Aart Bik22af3be2015-09-10 12:50:58 -0700346 /// CHECK-START: int Main.linearWithVeryLargeNegativeStride() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800347 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800348 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700349 private static int linearWithVeryLargeNegativeStride() {
350 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
351 int result = 0;
352 int k = 0;
353 // Range analysis conservatively bails due to potential of wrap-around
354 // arithmetic while computing the trip-count for this very large stride.
Aart Bikf475bee2015-09-16 12:50:25 -0700355 for (int i = -2; i > Integer.MIN_VALUE; i -= 195225786) {
Aart Bik22af3be2015-09-10 12:50:58 -0700356 result += x[k++];
357 }
358 return result;
359 }
360
Aart Bik9401f532015-09-28 16:25:56 -0700361 /// CHECK-START: int Main.linearForNEUp() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800362 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800363 //
Aart Bik9401f532015-09-28 16:25:56 -0700364 /// CHECK-START: int Main.linearForNEUp() BCE (after)
Aart Bikf475bee2015-09-16 12:50:25 -0700365 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800366 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700367 private static int linearForNEUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700368 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
369 int result = 0;
370 for (int i = 0; i != 10; i++) {
371 result += x[i];
372 }
373 return result;
374 }
375
Aart Bik9401f532015-09-28 16:25:56 -0700376 /// CHECK-START: int Main.linearForNEDown() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800377 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800378 //
Aart Bik9401f532015-09-28 16:25:56 -0700379 /// CHECK-START: int Main.linearForNEDown() BCE (after)
380 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800381 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700382 private static int linearForNEDown() {
383 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
384 int result = 0;
385 for (int i = 9; i != -1; i--) {
386 result += x[i];
387 }
388 return result;
389 }
390
391 /// CHECK-START: int Main.linearDoWhileUp() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800392 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800393 //
Aart Bik9401f532015-09-28 16:25:56 -0700394 /// CHECK-START: int Main.linearDoWhileUp() BCE (after)
395 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800396 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700397 private static int linearDoWhileUp() {
Aart Bikf475bee2015-09-16 12:50:25 -0700398 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
399 int result = 0;
400 int i = 0;
Aart Bikf475bee2015-09-16 12:50:25 -0700401 do {
402 result += x[i++];
403 } while (i < 10);
404 return result;
405 }
406
Aart Bik9401f532015-09-28 16:25:56 -0700407 /// CHECK-START: int Main.linearDoWhileDown() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800408 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800409 //
Aart Bik9401f532015-09-28 16:25:56 -0700410 /// CHECK-START: int Main.linearDoWhileDown() BCE (after)
411 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800412 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700413 private static int linearDoWhileDown() {
414 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
415 int result = 0;
416 int i = 9;
417 do {
418 result += x[i--];
419 } while (0 <= i);
420 return result;
421 }
422
Aart Bikf475bee2015-09-16 12:50:25 -0700423 /// CHECK-START: int Main.linearShort() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800424 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800425 //
Aart Bikf475bee2015-09-16 12:50:25 -0700426 /// CHECK-START: int Main.linearShort() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800427 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800428 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700429 private static int linearShort() {
430 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
431 int result = 0;
432 // TODO: make this work
433 for (short i = 0; i < 10; i++) {
434 result += x[i];
435 }
436 return result;
437 }
438
Aart Bik4a342772015-11-30 10:17:46 -0800439 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800440 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800441 //
Aart Bik4a342772015-11-30 10:17:46 -0800442 /// CHECK-START: int Main.invariantFromPreLoop(int[], int) BCE (after)
443 /// CHECK-NOT: BoundsCheck
444 /// CHECK-NOT: Deoptimize
445 private static int invariantFromPreLoop(int[] x, int y) {
446 int result = 0;
447 // Strange pre-loop that sets upper bound.
448 int hi;
449 while (true) {
450 y = y % 3;
451 hi = x.length;
452 if (y != 123) break;
453 }
454 for (int i = 0; i < hi; i++) {
455 result += x[i];
456 }
457 return result;
458 }
459
Aart Bikb738d4f2015-12-03 11:23:35 -0800460 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800461 /// CHECK: BoundsCheck
462 /// CHECK: ArrayGet
463 /// CHECK: ArraySet
464 /// CHECK: BoundsCheck
465 /// CHECK: ArrayGet
466 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800467 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800468 /// CHECK-START: void Main.linearTriangularOnTwoArrayLengths(int) BCE (after)
469 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800470 /// CHECK: ArrayGet
471 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800472 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800473 /// CHECK: ArrayGet
474 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800475 /// CHECK-NOT: Deoptimize
476 private static void linearTriangularOnTwoArrayLengths(int n) {
477 int[] a = new int[n];
478 for (int i = 0; i < a.length; i++) {
479 int[] b = new int[i];
480 for (int j = 0; j < b.length; j++) {
481 // Need to know j < b.length < a.length for static bce.
482 a[j] += 1;
483 // Need to know just j < b.length for static bce.
484 b[j] += 1;
485 }
486 verifyTriangular(a, b, i, n);
487 }
488 }
489
490 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800491 /// CHECK: BoundsCheck
492 /// CHECK: ArrayGet
493 /// CHECK: ArraySet
494 /// CHECK: BoundsCheck
495 /// CHECK: ArrayGet
496 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800497 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800498 /// CHECK-START: void Main.linearTriangularOnOneArrayLength(int) BCE (after)
499 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800500 /// CHECK: ArrayGet
501 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800502 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800503 /// CHECK: ArrayGet
504 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800505 /// CHECK-NOT: Deoptimize
506 private static void linearTriangularOnOneArrayLength(int n) {
507 int[] a = new int[n];
508 for (int i = 0; i < a.length; i++) {
509 int[] b = new int[i];
510 for (int j = 0; j < i; j++) {
511 // Need to know j < i < a.length for static bce.
512 a[j] += 1;
513 // Need to know just j < i for static bce.
514 b[j] += 1;
515 }
516 verifyTriangular(a, b, i, n);
517 }
518 }
519
520 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800521 /// CHECK: BoundsCheck
522 /// CHECK: ArrayGet
523 /// CHECK: ArraySet
524 /// CHECK: BoundsCheck
525 /// CHECK: ArrayGet
526 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800527 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800528 /// CHECK-START: void Main.linearTriangularOnParameter(int) BCE (after)
529 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800530 /// CHECK: ArrayGet
531 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800532 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800533 /// CHECK: ArrayGet
534 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800535 /// CHECK-NOT: Deoptimize
536 private static void linearTriangularOnParameter(int n) {
537 int[] a = new int[n];
538 for (int i = 0; i < n; i++) {
539 int[] b = new int[i];
540 for (int j = 0; j < i; j++) {
541 // Need to know j < i < n for static bce.
542 a[j] += 1;
543 // Need to know just j < i for static bce.
544 b[j] += 1;
545 }
546 verifyTriangular(a, b, i, n);
547 }
548 }
549
Aart Bik7d57d7f2015-12-09 14:39:48 -0800550 /// CHECK-START: void Main.linearTriangularVariations(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800551 /// CHECK: BoundsCheck
552 /// CHECK: ArrayGet
553 /// CHECK: ArraySet
554 /// CHECK: BoundsCheck
555 /// CHECK: ArrayGet
556 /// CHECK: ArraySet
557 /// CHECK: BoundsCheck
558 /// CHECK: ArrayGet
559 /// CHECK: ArraySet
560 /// CHECK: BoundsCheck
561 /// CHECK: ArrayGet
562 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800563 //
564 /// CHECK-START: void Main.linearTriangularVariations(int) BCE (after)
565 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800566 /// CHECK: ArrayGet
567 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800568 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800569 /// CHECK: ArrayGet
570 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800571 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800572 /// CHECK: ArrayGet
573 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800574 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800575 /// CHECK: ArrayGet
576 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800577 /// CHECK-NOT: Deoptimize
578 private static void linearTriangularVariations(int n) {
579 int[] a = new int[n];
580 for (int i = 0; i < n; i++) {
581 for (int j = 0; j < i; j++) {
582 a[j] += 1;
583 }
584 for (int j = i - 1; j >= 0; j--) {
585 a[j] += 1;
586 }
587 for (int j = i; j < n; j++) {
588 a[j] += 1;
589 }
590 for (int j = n - 1; j > i - 1; j--) {
591 a[j] += 1;
592 }
593 }
594 verifyTriangular(a);
595 }
596
597 // Verifier for triangular loops.
Aart Bikb738d4f2015-12-03 11:23:35 -0800598 private static void verifyTriangular(int[] a, int[] b, int m, int n) {
599 expectEquals(n, a.length);
600 for (int i = 0, k = m; i < n; i++) {
601 expectEquals(a[i], k);
602 if (k > 0) k--;
603 }
604 expectEquals(m, b.length);
605 for (int i = 0; i < m; i++) {
606 expectEquals(b[i], 1);
607 }
608 }
609
Aart Bik7d57d7f2015-12-09 14:39:48 -0800610 // Verifier for triangular loops.
611 private static void verifyTriangular(int[] a) {
612 int n = a.length;
613 for (int i = 0; i < n; i++) {
614 expectEquals(a[i], n + n);
615 }
616 }
617
Aart Bikb738d4f2015-12-03 11:23:35 -0800618 /// CHECK-START: void Main.bubble(int[]) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800619 /// CHECK: BoundsCheck
620 /// CHECK: ArrayGet
621 /// CHECK: BoundsCheck
622 /// CHECK: ArrayGet
623 /// CHECK: If
624 /// CHECK: ArraySet
625 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800626 //
Aart Bikb738d4f2015-12-03 11:23:35 -0800627 /// CHECK-START: void Main.bubble(int[]) BCE (after)
628 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800629 /// CHECK: ArrayGet
Aart Bikb738d4f2015-12-03 11:23:35 -0800630 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800631 /// CHECK: ArrayGet
632 /// CHECK: If
633 /// CHECK: ArraySet
634 /// CHECK: ArraySet
Aart Bikb738d4f2015-12-03 11:23:35 -0800635 /// CHECK-NOT: Deoptimize
636 private static void bubble(int[] a) {
637 for (int i = a.length; --i >= 0;) {
638 for (int j = 0; j < i; j++) {
639 if (a[j] > a[j+1]) {
640 int tmp = a[j];
641 a[j] = a[j+1];
642 a[j+1] = tmp;
643 }
644 }
645 }
646 }
647
Aart Bik22af3be2015-09-10 12:50:58 -0700648 /// CHECK-START: int Main.periodicIdiom(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800649 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800650 //
Aart Bik22af3be2015-09-10 12:50:58 -0700651 /// CHECK-START: int Main.periodicIdiom(int) BCE (after)
652 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800653 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700654 private static int periodicIdiom(int tc) {
655 int[] x = { 1, 3 };
656 // Loop with periodic sequence (0, 1).
657 int k = 0;
658 int result = 0;
659 for (int i = 0; i < tc; i++) {
660 result += x[k];
661 k = 1 - k;
662 }
663 return result;
664 }
665
666 /// CHECK-START: int Main.periodicSequence2(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800667 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800668 //
Aart Bik22af3be2015-09-10 12:50:58 -0700669 /// CHECK-START: int Main.periodicSequence2(int) BCE (after)
670 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800671 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700672 private static int periodicSequence2(int tc) {
673 int[] x = { 1, 3 };
674 // Loop with periodic sequence (0, 1).
675 int k = 0;
676 int l = 1;
677 int result = 0;
678 for (int i = 0; i < tc; i++) {
679 result += x[k];
680 int t = l;
681 l = k;
682 k = t;
683 }
684 return result;
685 }
686
687 /// CHECK-START: int Main.periodicSequence4(int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800688 /// CHECK: BoundsCheck
689 /// CHECK: BoundsCheck
690 /// CHECK: BoundsCheck
691 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800692 //
Aart Bik22af3be2015-09-10 12:50:58 -0700693 /// CHECK-START: int Main.periodicSequence4(int) BCE (after)
694 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800695 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700696 private static int periodicSequence4(int tc) {
697 int[] x = { 1, 3, 5, 7 };
698 // Loop with periodic sequence (0, 1, 2, 3).
699 int k = 0;
700 int l = 1;
701 int m = 2;
702 int n = 3;
703 int result = 0;
704 for (int i = 0; i < tc; i++) {
705 result += x[k] + x[l] + x[m] + x[n]; // all used at once
706 int t = n;
707 n = k;
708 k = l;
709 l = m;
710 m = t;
711 }
712 return result;
713 }
714
Aart Bikf475bee2015-09-16 12:50:25 -0700715 /// CHECK-START: int Main.justRightUp1() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800716 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800717 //
Aart Bikf475bee2015-09-16 12:50:25 -0700718 /// CHECK-START: int Main.justRightUp1() BCE (after)
719 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800720 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700721 private static int justRightUp1() {
722 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
723 int result = 0;
724 for (int i = Integer.MAX_VALUE - 10, k = 0; i < Integer.MAX_VALUE; i++) {
725 result += x[k++];
726 }
727 return result;
728 }
729
730 /// CHECK-START: int Main.justRightUp2() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800731 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800732 //
Aart Bikf475bee2015-09-16 12:50:25 -0700733 /// CHECK-START: int Main.justRightUp2() BCE (after)
734 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800735 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700736 private static int justRightUp2() {
737 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
738 int result = 0;
739 for (int i = Integer.MAX_VALUE - 10; i < Integer.MAX_VALUE; i++) {
740 result += x[i - Integer.MAX_VALUE + 10];
741 }
742 return result;
743 }
744
745 /// CHECK-START: int Main.justRightUp3() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800746 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800747 //
Aart Bikf475bee2015-09-16 12:50:25 -0700748 /// CHECK-START: int Main.justRightUp3() BCE (after)
749 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800750 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700751 private static int justRightUp3() {
752 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
753 int result = 0;
754 for (int i = Integer.MAX_VALUE - 10, k = 0; i <= Integer.MAX_VALUE - 1; i++) {
755 result += x[k++];
756 }
757 return result;
758 }
759
760 /// CHECK-START: int Main.justOOBUp() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800761 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800762 //
Aart Bikf475bee2015-09-16 12:50:25 -0700763 /// CHECK-START: int Main.justOOBUp() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800764 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800765 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700766 private static int justOOBUp() {
767 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
768 int result = 0;
769 // Infinite loop!
770 for (int i = Integer.MAX_VALUE - 9, k = 0; i <= Integer.MAX_VALUE; i++) {
771 result += x[k++];
772 }
773 return result;
774 }
775
776 /// CHECK-START: int Main.justRightDown1() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800777 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800778 //
Aart Bikf475bee2015-09-16 12:50:25 -0700779 /// CHECK-START: int Main.justRightDown1() BCE (after)
780 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800781 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700782 private static int justRightDown1() {
783 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
784 int result = 0;
785 for (int i = Integer.MIN_VALUE + 10, k = 0; i > Integer.MIN_VALUE; i--) {
786 result += x[k++];
787 }
788 return result;
789 }
790
791 /// CHECK-START: int Main.justRightDown2() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800792 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800793 //
Aart Bikf475bee2015-09-16 12:50:25 -0700794 /// CHECK-START: int Main.justRightDown2() BCE (after)
795 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800796 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700797 private static int justRightDown2() {
798 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
799 int result = 0;
800 for (int i = Integer.MIN_VALUE + 10; i > Integer.MIN_VALUE; i--) {
801 result += x[Integer.MAX_VALUE + i];
802 }
803 return result;
804 }
805
806 /// CHECK-START: int Main.justRightDown3() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800807 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800808 //
Aart Bikf475bee2015-09-16 12:50:25 -0700809 /// CHECK-START: int Main.justRightDown3() BCE (after)
810 /// CHECK-NOT: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800811 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700812 private static int justRightDown3() {
813 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
814 int result = 0;
815 for (int i = Integer.MIN_VALUE + 10, k = 0; i >= Integer.MIN_VALUE + 1; i--) {
816 result += x[k++];
817 }
818 return result;
819 }
820
821 /// CHECK-START: int Main.justOOBDown() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800822 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800823 //
Aart Bikf475bee2015-09-16 12:50:25 -0700824 /// CHECK-START: int Main.justOOBDown() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800825 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800826 /// CHECK-NOT: Deoptimize
Aart Bikf475bee2015-09-16 12:50:25 -0700827 private static int justOOBDown() {
828 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
829 int result = 0;
830 // Infinite loop!
831 for (int i = Integer.MIN_VALUE + 9, k = 0; i >= Integer.MIN_VALUE; i--) {
832 result += x[k++];
833 }
834 return result;
835 }
836
Aart Bik9401f532015-09-28 16:25:56 -0700837 /// CHECK-START: void Main.lowerOOB(int[]) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800838 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800839 //
Aart Bik9401f532015-09-28 16:25:56 -0700840 /// CHECK-START: void Main.lowerOOB(int[]) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800841 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800842 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700843 private static void lowerOOB(int[] x) {
844 for (int i = -1; i < x.length; i++) {
845 sResult += x[i];
846 }
847 }
848
Aart Bik9401f532015-09-28 16:25:56 -0700849 /// CHECK-START: void Main.upperOOB(int[]) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800850 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800851 //
Aart Bik9401f532015-09-28 16:25:56 -0700852 /// CHECK-START: void Main.upperOOB(int[]) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800853 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800854 /// CHECK-NOT: Deoptimize
Aart Bik22af3be2015-09-10 12:50:58 -0700855 private static void upperOOB(int[] x) {
856 for (int i = 0; i <= x.length; i++) {
857 sResult += x[i];
858 }
859 }
860
Aart Bik9401f532015-09-28 16:25:56 -0700861 /// CHECK-START: void Main.doWhileUpOOB() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800862 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800863 //
Aart Bik9401f532015-09-28 16:25:56 -0700864 /// CHECK-START: void Main.doWhileUpOOB() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800865 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800866 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700867 private static void doWhileUpOOB() {
868 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
869 int i = 0;
870 do {
871 sResult += x[i++];
872 } while (i <= x.length);
873 }
874
875 /// CHECK-START: void Main.doWhileDownOOB() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800876 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -0800877 //
Aart Bik9401f532015-09-28 16:25:56 -0700878 /// CHECK-START: void Main.doWhileDownOOB() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800879 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -0800880 /// CHECK-NOT: Deoptimize
Aart Bik9401f532015-09-28 16:25:56 -0700881 private static void doWhileDownOOB() {
882 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
883 int i = x.length - 1;
884 do {
885 sResult += x[i--];
886 } while (-1 <= i);
887 }
888
Aart Bik7d57d7f2015-12-09 14:39:48 -0800889 /// CHECK-START: int[] Main.multiply1() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800890 /// CHECK: BoundsCheck
891 /// CHECK: ArrayGet
892 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800893 //
894 /// CHECK-START: int[] Main.multiply1() BCE (after)
895 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800896 /// CHECK: ArrayGet
897 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800898 /// CHECK-NOT: Deoptimize
899 private static int[] multiply1() {
900 int[] a = new int[10];
901 try {
902 for (int i = 0; i <= 3; i++) {
903 for (int j = 0; j <= 3; j++) {
904 // Range [0,9]: safe.
905 a[i * j] += 1;
906 }
907 }
908 } catch (Exception e) {
909 a[0] += 1000;
910 }
911 return a;
912 }
913
914 /// CHECK-START: int[] Main.multiply2() BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800915 /// CHECK: BoundsCheck
916 /// CHECK: ArrayGet
917 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800918 //
919 /// CHECK-START: int[] Main.multiply2() BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800920 /// CHECK: BoundsCheck
921 /// CHECK: ArrayGet
922 /// CHECK: ArraySet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800923 static int[] multiply2() {
924 int[] a = new int[10];
925 try {
926 for (int i = -3; i <= 3; i++) {
927 for (int j = -3; j <= 3; j++) {
928 // Range [-9,9]: unsafe.
929 a[i * j] += 1;
930 }
931 }
932 } catch (Exception e) {
933 a[0] += 1000;
934 }
935 return a;
936 }
937
Aart Bik4a342772015-11-30 10:17:46 -0800938 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800939 /// CHECK: StaticFieldGet
940 /// CHECK: NullCheck
941 /// CHECK: ArrayLength
942 /// CHECK: BoundsCheck
943 /// CHECK: ArrayGet
944 /// CHECK: StaticFieldSet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800945 //
Aart Bik4a342772015-11-30 10:17:46 -0800946 /// CHECK-START: int Main.linearDynamicBCE1(int[], int, int) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800947 /// CHECK: StaticFieldGet
Aart Bik4a342772015-11-30 10:17:46 -0800948 /// CHECK-NOT: NullCheck
949 /// CHECK-NOT: ArrayLength
950 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800951 /// CHECK: ArrayGet
952 /// CHECK: StaticFieldSet
953 /// CHECK: Exit
954 /// CHECK: Deoptimize
955 /// CHECK: Deoptimize
956 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -0800957 private static int linearDynamicBCE1(int[] x, int lo, int hi) {
958 int result = 0;
959 for (int i = lo; i < hi; i++) {
960 sResult += x[i];
961 }
962 return result;
963 }
964
965 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800966 /// CHECK: StaticFieldGet
967 /// CHECK: NullCheck
968 /// CHECK: ArrayLength
969 /// CHECK: BoundsCheck
970 /// CHECK: ArrayGet
971 /// CHECK: StaticFieldSet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800972 //
Aart Bik4a342772015-11-30 10:17:46 -0800973 /// CHECK-START: int Main.linearDynamicBCE2(int[], int, int, int) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800974 /// CHECK: StaticFieldGet
Aart Bik4a342772015-11-30 10:17:46 -0800975 /// CHECK-NOT: NullCheck
976 /// CHECK-NOT: ArrayLength
977 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800978 /// CHECK: ArrayGet
979 /// CHECK: StaticFieldSet
980 /// CHECK: Exit
981 /// CHECK: Deoptimize
982 /// CHECK: Deoptimize
983 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -0800984 private static int linearDynamicBCE2(int[] x, int lo, int hi, int offset) {
985 int result = 0;
986 for (int i = lo; i < hi; i++) {
987 sResult += x[offset + i];
988 }
989 return result;
990 }
991
992 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -0800993 /// CHECK: NullCheck
994 /// CHECK: ArrayLength
995 /// CHECK: BoundsCheck
996 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -0800997 //
Aart Bik4a342772015-11-30 10:17:46 -0800998 /// CHECK-START: int Main.wrapAroundDynamicBCE(int[]) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -0800999 /// CHECK: Deoptimize
1000 /// CHECK: Deoptimize
1001 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001002 /// CHECK-NOT: NullCheck
1003 /// CHECK-NOT: ArrayLength
1004 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -08001005 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001006 private static int wrapAroundDynamicBCE(int[] x) {
1007 int w = 9;
1008 int result = 0;
1009 for (int i = 0; i < 10; i++) {
1010 result += x[w];
1011 w = i;
1012 }
1013 return result;
1014 }
1015
1016 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001017 /// CHECK: NullCheck
1018 /// CHECK: ArrayLength
1019 /// CHECK: BoundsCheck
1020 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -08001021 //
Aart Bik4a342772015-11-30 10:17:46 -08001022 /// CHECK-START: int Main.periodicDynamicBCE(int[]) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -08001023 /// CHECK: Deoptimize
1024 /// CHECK: Deoptimize
1025 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001026 /// CHECK-NOT: NullCheck
1027 /// CHECK-NOT: ArrayLength
1028 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -08001029 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001030 private static int periodicDynamicBCE(int[] x) {
1031 int k = 0;
1032 int result = 0;
1033 for (int i = 0; i < 10; i++) {
1034 result += x[k];
1035 k = 1 - k;
1036 }
1037 return result;
1038 }
1039
1040 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001041 /// CHECK: NullCheck
1042 /// CHECK: ArrayLength
1043 /// CHECK: BoundsCheck
1044 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -08001045 //
Aart Bik4a342772015-11-30 10:17:46 -08001046 /// CHECK-START: int Main.dynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
1047 /// CHECK-NOT: NullCheck
1048 /// CHECK-NOT: ArrayLength
1049 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -08001050 /// CHECK: ArrayGet
1051 /// CHECK: Exit
1052 /// CHECK: Deoptimize
1053 /// CHECK: Deoptimize
1054 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001055 static int dynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
1056 // This loop could be infinite for hi = max int. Since i is also used
1057 // as subscript, however, dynamic bce can proceed.
1058 int result = 0;
1059 for (int i = lo; i <= hi; i++) {
1060 result += x[i];
1061 }
1062 return result;
1063 }
1064
1065 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001066 /// CHECK: NullCheck
1067 /// CHECK: ArrayLength
1068 /// CHECK: BoundsCheck
1069 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -08001070 //
Aart Bik4a342772015-11-30 10:17:46 -08001071 /// CHECK-START: int Main.noDynamicBCEPossiblyInfiniteLoop(int[], int, int) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -08001072 /// CHECK: NullCheck
1073 /// CHECK: ArrayLength
1074 /// CHECK: BoundsCheck
1075 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001076 /// CHECK-NOT: Deoptimize
1077 static int noDynamicBCEPossiblyInfiniteLoop(int[] x, int lo, int hi) {
1078 // As above, but now the index is not used as subscript,
1079 // and dynamic bce is not applied.
1080 int result = 0;
1081 for (int k = 0, i = lo; i <= hi; i++) {
1082 result += x[k++];
1083 }
1084 return result;
1085 }
1086
1087 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001088 /// CHECK: NullCheck
1089 /// CHECK: ArrayLength
1090 /// CHECK: BoundsCheck
1091 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -08001092 //
Aart Bik4a342772015-11-30 10:17:46 -08001093 /// CHECK-START: int Main.noDynamicBCEMixedInductionTypes(int[], long, long) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -08001094 /// CHECK: NullCheck
1095 /// CHECK: ArrayLength
1096 /// CHECK: BoundsCheck
1097 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001098 /// CHECK-NOT: Deoptimize
1099 static int noDynamicBCEMixedInductionTypes(int[] x, long lo, long hi) {
1100 int result = 0;
1101 // Mix of int and long induction.
1102 int k = 0;
1103 for (long i = lo; i < hi; i++) {
1104 result += x[k++];
1105 }
1106 return result;
1107 }
1108
1109 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001110 /// CHECK: NullCheck
1111 /// CHECK: ArrayLength
1112 /// CHECK: NotEqual
1113 /// CHECK: If
1114 /// CHECK: If
1115 /// CHECK: NullCheck
1116 /// CHECK: ArrayLength
1117 /// CHECK: BoundsCheck
1118 /// CHECK: ArrayGet
1119 /// CHECK: If
1120 /// CHECK: BoundsCheck
1121 /// CHECK: BoundsCheck
1122 /// CHECK: BoundsCheck
1123 /// CHECK: BoundsCheck
1124 /// CHECK: BoundsCheck
1125 /// CHECK: BoundsCheck
Aart Bik7d57d7f2015-12-09 14:39:48 -08001126 //
Aart Bik4a342772015-11-30 10:17:46 -08001127 /// CHECK-START: int Main.dynamicBCEAndConstantIndices(int[], int[][], int, int) BCE (after)
Aart Bik5d75afe2015-12-14 11:57:01 -08001128 /// CHECK: NullCheck
1129 /// CHECK: ArrayLength
1130 /// CHECK: NotEqual
1131 /// CHECK: If
1132 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001133 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -08001134 /// CHECK: ArrayGet
1135 /// CHECK: If
1136 /// CHECK: Deoptimize
1137 /// CHECK: BoundsCheck
1138 /// CHECK: BoundsCheck
1139 /// CHECK: BoundsCheck
Aart Bik4a342772015-11-30 10:17:46 -08001140 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -08001141 /// CHECK: Exit
1142 /// CHECK: Deoptimize
1143 /// CHECK: Deoptimize
1144 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001145 /// CHECK-NOT: ArrayGet
1146 static int dynamicBCEAndConstantIndices(int[] x, int[][] a, int lo, int hi) {
1147 // Deliberately test array length on a before the loop so that only bounds checks
1148 // on constant subscripts remain, making them a viable candidate for hoisting.
1149 if (a.length == 0) {
1150 return -1;
1151 }
1152 // Loop that allows BCE on x[i].
1153 int result = 0;
1154 for (int i = lo; i < hi; i++) {
1155 result += x[i];
1156 if ((i % 10) != 0) {
1157 // None of the subscripts inside a conditional are removed by dynamic bce,
1158 // making them a candidate for deoptimization based on constant indices.
1159 // Compiler should ensure the array loads are not subsequently hoisted
1160 // "above" the deoptimization "barrier" on the bounds.
1161 a[0][i] = 1;
1162 a[1][i] = 2;
1163 a[99][i] = 3;
1164 }
1165 }
1166 return result;
1167 }
1168
1169 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], java.lang.Integer[], int, int) BCE (before)
Aart Bik5d75afe2015-12-14 11:57:01 -08001170 /// CHECK: If
1171 /// CHECK: BoundsCheck
1172 /// CHECK: ArrayGet
1173 /// CHECK: BoundsCheck
1174 /// CHECK: ArrayGet
1175 /// CHECK: BoundsCheck
1176 /// CHECK: ArrayGet
1177 /// CHECK: BoundsCheck
1178 /// CHECK: ArrayGet
1179 /// CHECK: BoundsCheck
1180 /// CHECK: ArrayGet
1181 /// CHECK: BoundsCheck
1182 /// CHECK: ArrayGet
1183 /// CHECK: BoundsCheck
1184 /// CHECK: ArrayGet
1185 /// CHECK: BoundsCheck
1186 /// CHECK: ArrayGet
1187 /// CHECK: BoundsCheck
1188 /// CHECK: ArrayGet
1189 /// CHECK: BoundsCheck
1190 /// CHECK: ArrayGet
Aart Bik7d57d7f2015-12-09 14:39:48 -08001191 //
Aart Bik4a342772015-11-30 10:17:46 -08001192 /// CHECK-START: int Main.dynamicBCEAndConstantIndicesAllTypes(int[], boolean[], byte[], char[], short[], int[], long[], float[], double[], java.lang.Integer[], int, int) BCE (after)
Aart Bik684cf252015-12-30 15:46:27 -08001193 /// CHECK-DAG: If
Aart Bik4a342772015-11-30 10:17:46 -08001194 /// CHECK-NOT: BoundsCheck
Aart Bik684cf252015-12-30 15:46:27 -08001195 /// CHECK-DAG: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001196 /// CHECK-NOT: BoundsCheck
1197 /// CHECK-NOT: ArrayGet
Aart Bik684cf252015-12-30 15:46:27 -08001198 /// CHECK-DAG: Exit
1199 /// CHECK-DAG: Deoptimize
1200 /// CHECK-DAG: Deoptimize
1201 /// CHECK-DAG: Deoptimize
1202 /// CHECK-DAG: Deoptimize
1203 /// CHECK-DAG: Deoptimize
1204 /// CHECK-DAG: ArrayGet
1205 /// CHECK-DAG: Deoptimize
1206 /// CHECK-DAG: Deoptimize
1207 /// CHECK-DAG: ArrayGet
1208 /// CHECK-DAG: Deoptimize
1209 /// CHECK-DAG: Deoptimize
1210 /// CHECK-DAG: ArrayGet
1211 /// CHECK-DAG: Deoptimize
1212 /// CHECK-DAG: Deoptimize
1213 /// CHECK-DAG: ArrayGet
1214 /// CHECK-DAG: Deoptimize
1215 /// CHECK-DAG: Deoptimize
1216 /// CHECK-DAG: ArrayGet
1217 /// CHECK-DAG: Deoptimize
1218 /// CHECK-DAG: Deoptimize
1219 /// CHECK-DAG: ArrayGet
1220 /// CHECK-DAG: Deoptimize
1221 /// CHECK-DAG: Deoptimize
1222 /// CHECK-DAG: ArrayGet
1223 /// CHECK-DAG: Deoptimize
1224 /// CHECK-DAG: Deoptimize
1225 /// CHECK-DAG: ArrayGet
1226 /// CHECK-DAG: Deoptimize
1227 /// CHECK-DAG: Deoptimize
1228 /// CHECK-DAG: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001229 static int dynamicBCEAndConstantIndicesAllTypes(int[] q,
1230 boolean[] r,
1231 byte[] s,
1232 char[] t,
1233 short[] u,
1234 int[] v,
1235 long[] w,
1236 float[] x,
1237 double[] y,
1238 Integer[] z, int lo, int hi) {
1239 int result = 0;
1240 for (int i = lo; i < hi; i++) {
1241 result += q[i] + (r[0] ? 1 : 0) + (int) s[0] + (int) t[0] + (int) u[0] + (int) v[0] +
1242 (int) w[0] + (int) x[0] + (int) y[0] + (int) z[0];
1243 }
1244 return result;
1245 }
1246
Aart Bik22af3be2015-09-10 12:50:58 -07001247 //
1248 // Verifier.
1249 //
1250
1251 public static void main(String[] args) {
1252 int[] empty = { };
1253 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
1254
1255 // Linear and wrap-around.
1256 expectEquals(0, linear(empty));
1257 expectEquals(55, linear(x));
1258 expectEquals(0, linearDown(empty));
1259 expectEquals(55, linearDown(x));
1260 expectEquals(0, linearObscure(empty));
1261 expectEquals(55, linearObscure(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001262 expectEquals(0, linearVeryObscure(empty));
1263 expectEquals(55, linearVeryObscure(x));
Aart Bik7d57d7f2015-12-09 14:39:48 -08001264 expectEquals(0, hiddenStride(empty));
1265 expectEquals(55, hiddenStride(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001266 expectEquals(0, linearWhile(empty));
1267 expectEquals(55, linearWhile(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001268 expectEquals(0, linearThreeWayPhi(empty));
1269 expectEquals(50, linearThreeWayPhi(x));
1270 expectEquals(0, linearFourWayPhi(empty));
1271 expectEquals(51, linearFourWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001272 expectEquals(0, wrapAroundThenLinear(empty));
1273 expectEquals(55, wrapAroundThenLinear(x));
Aart Bikf475bee2015-09-16 12:50:25 -07001274 expectEquals(0, wrapAroundThenLinearThreeWayPhi(empty));
1275 expectEquals(54, wrapAroundThenLinearThreeWayPhi(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001276
1277 // Linear with parameter.
1278 sResult = 0;
1279 try {
1280 linearWithParameter(-1);
1281 } catch (NegativeArraySizeException e) {
1282 sResult = 1;
1283 }
1284 expectEquals(1, sResult);
1285 for (int n = 0; n < 32; n++) {
1286 int[] r = linearWithParameter(n);
1287 expectEquals(n, r.length);
1288 for (int i = 0; i < n; i++) {
1289 expectEquals(i, r[i]);
1290 }
1291 }
1292
Aart Bikf475bee2015-09-16 12:50:25 -07001293 // Linear copy.
1294 expectEquals(0, linearCopy(empty).length);
1295 {
1296 int[] r = linearCopy(x);
1297 expectEquals(x.length, r.length);
1298 for (int i = 0; i < x.length; i++) {
1299 expectEquals(x[i], r[i]);
1300 }
1301 }
1302
Aart Bik22af3be2015-09-10 12:50:58 -07001303 // Linear with non-unit strides.
Aart Bik4a342772015-11-30 10:17:46 -08001304 expectEquals(55, linearByTwo(x));
1305 expectEquals(25, linearByTwoSkip1(x));
1306 expectEquals(25, linearByTwoSkip2(x));
Aart Bik22af3be2015-09-10 12:50:58 -07001307 expectEquals(56, linearWithCompoundStride());
1308 expectEquals(66, linearWithLargePositiveStride());
1309 expectEquals(66, linearWithVeryLargePositiveStride());
1310 expectEquals(66, linearWithLargeNegativeStride());
1311 expectEquals(66, linearWithVeryLargeNegativeStride());
1312
Aart Bikf475bee2015-09-16 12:50:25 -07001313 // Special forms.
Aart Bik9401f532015-09-28 16:25:56 -07001314 expectEquals(55, linearForNEUp());
1315 expectEquals(55, linearForNEDown());
1316 expectEquals(55, linearDoWhileUp());
1317 expectEquals(55, linearDoWhileDown());
Aart Bikf475bee2015-09-16 12:50:25 -07001318 expectEquals(55, linearShort());
Aart Bik4a342772015-11-30 10:17:46 -08001319 expectEquals(55, invariantFromPreLoop(x, 1));
Aart Bikb738d4f2015-12-03 11:23:35 -08001320 linearTriangularOnTwoArrayLengths(10);
1321 linearTriangularOnOneArrayLength(10);
1322 linearTriangularOnParameter(10);
Aart Bik7d57d7f2015-12-09 14:39:48 -08001323 linearTriangularVariations(10);
Aart Bikb738d4f2015-12-03 11:23:35 -08001324
1325 // Sorting.
1326 int[] sort = { 5, 4, 1, 9, 10, 2, 7, 6, 3, 8 };
1327 bubble(sort);
1328 for (int i = 0; i < 10; i++) {
1329 expectEquals(sort[i], x[i]);
1330 }
Aart Bikf475bee2015-09-16 12:50:25 -07001331
Aart Bik22af3be2015-09-10 12:50:58 -07001332 // Periodic adds (1, 3), one at the time.
1333 expectEquals(0, periodicIdiom(-1));
1334 for (int tc = 0; tc < 32; tc++) {
1335 int expected = (tc >> 1) << 2;
1336 if ((tc & 1) != 0)
1337 expected += 1;
1338 expectEquals(expected, periodicIdiom(tc));
1339 }
1340
1341 // Periodic adds (1, 3), one at the time.
1342 expectEquals(0, periodicSequence2(-1));
1343 for (int tc = 0; tc < 32; tc++) {
1344 int expected = (tc >> 1) << 2;
1345 if ((tc & 1) != 0)
1346 expected += 1;
1347 expectEquals(expected, periodicSequence2(tc));
1348 }
1349
1350 // Periodic adds (1, 3, 5, 7), all at once.
1351 expectEquals(0, periodicSequence4(-1));
1352 for (int tc = 0; tc < 32; tc++) {
1353 expectEquals(tc * 16, periodicSequence4(tc));
1354 }
1355
Aart Bikf475bee2015-09-16 12:50:25 -07001356 // Large bounds.
1357 expectEquals(55, justRightUp1());
1358 expectEquals(55, justRightUp2());
1359 expectEquals(55, justRightUp3());
1360 expectEquals(55, justRightDown1());
1361 expectEquals(55, justRightDown2());
1362 expectEquals(55, justRightDown3());
1363 sResult = 0;
1364 try {
1365 justOOBUp();
1366 } catch (ArrayIndexOutOfBoundsException e) {
1367 sResult = 1;
1368 }
1369 expectEquals(1, sResult);
1370 sResult = 0;
1371 try {
1372 justOOBDown();
1373 } catch (ArrayIndexOutOfBoundsException e) {
1374 sResult = 1;
1375 }
1376 expectEquals(1, sResult);
1377
Aart Bik22af3be2015-09-10 12:50:58 -07001378 // Lower bound goes OOB.
1379 sResult = 0;
1380 try {
1381 lowerOOB(x);
1382 } catch (ArrayIndexOutOfBoundsException e) {
1383 sResult += 1000;
1384 }
1385 expectEquals(1000, sResult);
1386
1387 // Upper bound goes OOB.
1388 sResult = 0;
1389 try {
1390 upperOOB(x);
1391 } catch (ArrayIndexOutOfBoundsException e) {
1392 sResult += 1000;
1393 }
1394 expectEquals(1055, sResult);
1395
Aart Bik9401f532015-09-28 16:25:56 -07001396 // Do while up goes OOB.
1397 sResult = 0;
1398 try {
1399 doWhileUpOOB();
1400 } catch (ArrayIndexOutOfBoundsException e) {
1401 sResult += 1000;
1402 }
1403 expectEquals(1055, sResult);
1404
1405 // Do while down goes OOB.
1406 sResult = 0;
1407 try {
1408 doWhileDownOOB();
1409 } catch (ArrayIndexOutOfBoundsException e) {
1410 sResult += 1000;
1411 }
1412 expectEquals(1055, sResult);
Aart Bik4a342772015-11-30 10:17:46 -08001413
Aart Bik7d57d7f2015-12-09 14:39:48 -08001414 // Multiplication.
1415 {
1416 int[] e1 = { 7, 1, 2, 2, 1, 0, 2, 0, 0, 1 };
1417 int[] a1 = multiply1();
1418 for (int i = 0; i < 10; i++) {
1419 expectEquals(a1[i], e1[i]);
1420 }
1421 int[] e2 = { 1001, 0, 0, 1, 0, 0, 1, 0, 0, 1 };
1422 int[] a2 = multiply2();
1423 for (int i = 0; i < 10; i++) {
1424 expectEquals(a2[i], e2[i]);
1425 }
1426 }
1427
Aart Bik4a342772015-11-30 10:17:46 -08001428 // Dynamic BCE.
1429 sResult = 0;
1430 try {
1431 linearDynamicBCE1(x, -1, x.length);
1432 } catch (ArrayIndexOutOfBoundsException e) {
1433 sResult += 1000;
1434 }
1435 expectEquals(1000, sResult);
1436 sResult = 0;
1437 linearDynamicBCE1(x, 0, x.length);
1438 expectEquals(55, sResult);
1439 sResult = 0;
1440 try {
1441 linearDynamicBCE1(x, 0, x.length + 1);
1442 } catch (ArrayIndexOutOfBoundsException e) {
1443 sResult += 1000;
1444 }
1445 expectEquals(1055, sResult);
1446
1447 // Dynamic BCE with offset.
1448 sResult = 0;
1449 try {
1450 linearDynamicBCE2(x, 0, x.length, -1);
1451 } catch (ArrayIndexOutOfBoundsException e) {
1452 sResult += 1000;
1453 }
1454 expectEquals(1000, sResult);
1455 sResult = 0;
1456 linearDynamicBCE2(x, 0, x.length, 0);
1457 expectEquals(55, sResult);
1458 sResult = 0;
1459 try {
1460 linearDynamicBCE2(x, 0, x.length, 1);
1461 } catch (ArrayIndexOutOfBoundsException e) {
1462 sResult += 1000;
1463 }
1464 expectEquals(1054, sResult);
1465
1466 // Dynamic BCE candidates.
1467 expectEquals(55, wrapAroundDynamicBCE(x));
1468 expectEquals(15, periodicDynamicBCE(x));
1469 expectEquals(55, dynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1470 expectEquals(55, noDynamicBCEPossiblyInfiniteLoop(x, 0, 9));
1471 expectEquals(55, noDynamicBCEMixedInductionTypes(x, 0, 10));
1472
1473 // Dynamic BCE combined with constant indices.
1474 int[][] a;
1475 a = new int[0][0];
1476 expectEquals(-1, dynamicBCEAndConstantIndices(x, a, 0, 10));
1477 a = new int[100][10];
1478 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1479 for (int i = 0; i < 10; i++) {
1480 expectEquals((i % 10) != 0 ? 1 : 0, a[0][i]);
1481 expectEquals((i % 10) != 0 ? 2 : 0, a[1][i]);
1482 expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]);
1483 }
1484 a = new int[2][10];
1485 sResult = 0;
1486 try {
1487 expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10));
1488 } catch (ArrayIndexOutOfBoundsException e) {
1489 sResult = 1;
1490 }
1491 expectEquals(1, sResult);
1492 expectEquals(a[0][1], 1);
1493 expectEquals(a[1][1], 2);
1494
1495 // Dynamic BCE combined with constant indices of all types.
1496 boolean[] x1 = { true };
1497 byte[] x2 = { 2 };
1498 char[] x3 = { 3 };
1499 short[] x4 = { 4 };
1500 int[] x5 = { 5 };
1501 long[] x6 = { 6 };
1502 float[] x7 = { 7 };
1503 double[] x8 = { 8 };
1504 Integer[] x9 = { 9 };
1505 expectEquals(505,
1506 dynamicBCEAndConstantIndicesAllTypes(x, x1, x2, x3, x4, x5, x6, x7, x8, x9, 0, 10));
Aart Bik22af3be2015-09-10 12:50:58 -07001507 }
1508
1509 private static void expectEquals(int expected, int result) {
1510 if (expected != result) {
1511 throw new Error("Expected: " + expected + ", found: " + result);
1512 }
1513 }
1514}