• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Tests on bounds check elimination in loops that use intrinsics.
19  * All bounds checks below should be statically eliminated.
20  */
21 public class Main {
22 
23   /// CHECK-START: int Main.oneArray(int[]) BCE (before)
24   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
25   //
26   /// CHECK-START: int Main.oneArray(int[]) BCE (after)
27   /// CHECK-NOT: BoundsCheck
28   /// CHECK-NOT: Deoptimize
oneArray(int[] a)29   static int oneArray(int[] a) {
30     int x = 0;
31     for (int i = 0; i < a.length; i++) {
32       x += a[i];
33     }
34     return x;
35   }
36 
37   /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (before)
38   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
39   //
40   /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (after)
41   /// CHECK-NOT: BoundsCheck
42   /// CHECK-NOT: Deoptimize
oneArrayAbs(int[] a, int[] b)43   static int oneArrayAbs(int[] a, int[] b) {
44     int x = 0;
45     for (int i = Math.abs(b.length); i < a.length; i++) {
46       x += a[i];
47     }
48     return x;
49   }
50 
51 
52   /// CHECK-START: int Main.twoArrays(int[], int[]) BCE (before)
53   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
54   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
55   //
56   /// CHECK-START: int Main.twoArrays(int[], int[]) BCE (after)
57   /// CHECK-NOT: BoundsCheck
58   /// CHECK-NOT: Deoptimize
twoArrays(int[] a, int[] b)59   static int twoArrays(int[] a, int[] b) {
60     int x = 0;
61     for (int i = 0; i < Math.min(a.length, b.length); i++) {
62       x += a[i] + b[i];
63     }
64     return x;
65   }
66 
67   /// CHECK-START: int Main.threeArrays(int[], int[], int[]) BCE (before)
68   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
69   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
70   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
71   //
72   /// CHECK-START: int Main.threeArrays(int[], int[], int[]) BCE (after)
73   /// CHECK-NOT: BoundsCheck
74   /// CHECK-NOT: Deoptimize
threeArrays(int[] a, int[] b, int[] c)75   static int threeArrays(int[] a, int[] b, int[] c) {
76     int x = 0;
77     for (int i = 0; i < Math.min(Math.min(a.length, b.length), c.length); i++) {
78       x += a[i] + b[i] + c[i];
79     }
80     return x;
81   }
82 
83   /// CHECK-START: int Main.fourArrays(int[], int[], int[], int[]) BCE (before)
84   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
85   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
86   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
87   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
88   //
89   /// CHECK-START: int Main.fourArrays(int[], int[], int[], int[]) BCE (after)
90   /// CHECK-NOT: BoundsCheck
91   /// CHECK-NOT: Deoptimize
fourArrays(int[] a, int[] b, int[] c, int[] d)92   static int fourArrays(int[] a, int[] b, int[] c, int[] d) {
93     int x = 0;
94     for (int i = 0; i < Math.min(Math.min(a.length, b.length), Math.min(c.length, d.length)); i++) {
95       x += a[i] + b[i] + c[i] + d[i];
96     }
97     return x;
98   }
99 
100   /// CHECK-START: int Main.oneArrayWithCleanup(int[]) BCE (before)
101   /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none
102   /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none
103   //
104   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
105   //
106   /// CHECK-START: int Main.oneArrayWithCleanup(int[]) BCE (after)
107   /// CHECK-NOT: BoundsCheck
108   /// CHECK-NOT: Deoptimize
oneArrayWithCleanup(int[] a)109   static int oneArrayWithCleanup(int[] a) {
110     int x = 0;
111     int n = Math.min(4, a.length);
112     for (int i = 0; i < n; i++) {
113       x += a[i];
114     }
115     for (int i = n; i < a.length; i++) {
116       x += a[i] * 10;
117     }
118     return x;
119   }
120 
121   /// CHECK-START: int Main.twoArraysWithCleanup(int[], int[]) BCE (before)
122   /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none
123   /// CHECK-DAG: BoundsCheck loop:<<Loop1>>      outer_loop:none
124   /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none
125   //
126   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
127   //
128   /// CHECK-START: int Main.twoArraysWithCleanup(int[], int[]) BCE (after)
129   /// CHECK-NOT: BoundsCheck
130   /// CHECK-NOT: Deoptimize
twoArraysWithCleanup(int[] a, int[] b)131   static int twoArraysWithCleanup(int[] a, int[] b) {
132     int x = 0;
133     int n = Math.min(a.length, b.length);
134     for (int i = n - 1; i >= 0; i--) {
135       x += a[i] + b[i];
136     }
137     for (int i = n; i < a.length; i++) {
138       x += a[i];
139     }
140     return x;
141   }
142 
143   /// CHECK-START: int Main.threeArraysWithCleanup(int[], int[], int[]) BCE (before)
144   /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none
145   /// CHECK-DAG: BoundsCheck loop:<<Loop1>>      outer_loop:none
146   /// CHECK-DAG: BoundsCheck loop:<<Loop1>>      outer_loop:none
147   /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none
148   //
149   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
150   //
151   /// CHECK-START: int Main.threeArraysWithCleanup(int[], int[], int[]) BCE (after)
152   /// CHECK-NOT: BoundsCheck
153   /// CHECK-NOT: Deoptimize
threeArraysWithCleanup(int[] a, int[] b, int[] c)154   static int threeArraysWithCleanup(int[] a, int[] b, int[] c) {
155     int x = 0;
156     int n = Math.min(a.length, Math.min(b.length, c.length));
157     for (int i = n - 1; i >= 0; i--) {
158       x += a[i] + b[i] + c[i];
159     }
160     for (int i = n; i < a.length; i++) {
161       x += a[i];
162     }
163     return x;
164   }
165 
166   /// CHECK-START: int Main.altLoopLogic(int[], int[]) BCE (before)
167   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
168   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
169   //
170   /// CHECK-START: int Main.altLoopLogic(int[], int[]) BCE (after)
171   /// CHECK-NOT: BoundsCheck
172   /// CHECK-NOT: Deoptimize
altLoopLogic(int[] a, int[] b)173   static int altLoopLogic(int[] a, int[] b) {
174     int x = 0;
175     int n = Math.min(a.length, b.length);
176     for (int i = n; i-- > 0;) {
177       x += a[i] + b[i];
178     }
179     return x;
180   }
181 
182   /// CHECK-START: int Main.hiddenMin(int[], int[]) BCE (before)
183   /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
184   /// CHECK-DAG: BoundsCheck loop:<<Loop>>      outer_loop:none
185   //
186   /// CHECK-START: int Main.hiddenMin(int[], int[]) BCE (after)
187   //
188   // TODO: make this so
hiddenMin(int[] a, int[] b)189   static int hiddenMin(int[] a, int[] b) {
190     int x = 0;
191     for (int i = 0; i < a.length && i < b.length; i++) {
192       x += a[i] + b[i];
193     }
194     return x;
195   }
196 
197   /// CHECK-START: int Main.hiddenMinWithCleanup(int[], int[]) BCE (before)
198   /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none
199   /// CHECK-DAG: BoundsCheck loop:<<Loop1>>      outer_loop:none
200   /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none
201   //
202   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
203   //
204   /// CHECK-START: int Main.hiddenMinWithCleanup(int[], int[]) BCE (after)
205   //
206   // TODO: make this so
hiddenMinWithCleanup(int[] a, int[] b)207   static int hiddenMinWithCleanup(int[] a, int[] b) {
208     int x = 0;
209     int i = 0;
210     for (; i < a.length && i < b.length; i++) {
211       x += a[i] + b[i];
212     }
213     for (; i < a.length; i++) {
214       x += a[i];
215     }
216     return x;
217   }
218 
main(String[] args)219   public static void main(String[] args) {
220     int[] a = { 1, 2, 3, 4, 5 };
221     int[] b = { 6, 7, 8, 9, 4, 2 };
222     int[] c = { 1, 2, 3 };
223     int[] d = { 8, 5, 3, 2 };
224     int[] e = { };
225 
226     expectEquals(15, oneArray(a));
227     expectEquals(36, oneArray(b));
228     expectEquals(6,  oneArray(c));
229     expectEquals(18, oneArray(d));
230 
231     expectEquals(15, oneArrayAbs(a, e));
232     expectEquals(5,  oneArrayAbs(a, d));
233 
234     expectEquals(30, twoArrays(a, a));
235     expectEquals(49, twoArrays(a, b));
236     expectEquals(12, twoArrays(a, c));
237     expectEquals(28, twoArrays(a, d));
238 
239     expectEquals(45, threeArrays(a, a, a));
240     expectEquals(33, threeArrays(a, b, c));
241     expectEquals(58, threeArrays(a, b, d));
242     expectEquals(28, threeArrays(a, c, d));
243 
244     expectEquals(60, fourArrays(a, a, a, a));
245     expectEquals(49, fourArrays(a, b, c, d));
246 
247     expectEquals(60, oneArrayWithCleanup(a));
248     expectEquals(90, oneArrayWithCleanup(b));
249     expectEquals(6,  oneArrayWithCleanup(c));
250     expectEquals(18, oneArrayWithCleanup(d));
251 
252     expectEquals(30, twoArraysWithCleanup(a, a));
253     expectEquals(49, twoArraysWithCleanup(a, b));
254     expectEquals(21, twoArraysWithCleanup(a, c));
255     expectEquals(33, twoArraysWithCleanup(a, d));
256 
257     expectEquals(45, threeArraysWithCleanup(a, a, a));
258     expectEquals(42, threeArraysWithCleanup(a, b, c));
259     expectEquals(63, threeArraysWithCleanup(a, b, d));
260     expectEquals(37, threeArraysWithCleanup(a, c, d));
261 
262     expectEquals(30, altLoopLogic(a, a));
263     expectEquals(49, altLoopLogic(a, b));
264     expectEquals(12, altLoopLogic(a, c));
265     expectEquals(28, altLoopLogic(a, d));
266 
267     expectEquals(30, hiddenMin(a, a));
268     expectEquals(49, hiddenMin(a, b));
269     expectEquals(12, hiddenMin(a, c));
270     expectEquals(28, hiddenMin(a, d));
271 
272     expectEquals(30, hiddenMinWithCleanup(a, a));
273     expectEquals(49, hiddenMinWithCleanup(a, b));
274     expectEquals(21, hiddenMinWithCleanup(a, c));
275     expectEquals(33, hiddenMinWithCleanup(a, d));
276 
277     System.out.println("passed");
278   }
279 
expectEquals(int expected, int result)280   private static void expectEquals(int expected, int result) {
281     if (expected != result) {
282       throw new Error("Expected: " + expected + ", found: " + result);
283     }
284   }
285 }
286