blob: a5caa7bce0ede996d5856c323ce262780e2bd4e6 [file] [log] [blame]
Alexandre Ramese6dbf482015-10-19 10:10:41 +01001/*
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
17public class Main {
18
19 public static void assertIntEquals(int expected, int result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
25 /**
26 * Test that HArrayGet with a constant index is not split.
27 */
28
29 /// CHECK-START-ARM64: int Main.constantIndexGet(int[]) instruction_simplifier_arm64 (before)
30 /// CHECK: <<Array:l\d+>> NullCheck
31 /// CHECK: <<Index:i\d+>> BoundsCheck
32 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
33
34 /// CHECK-START-ARM64: int Main.constantIndexGet(int[]) instruction_simplifier_arm64 (after)
35 /// CHECK: <<Array:l\d+>> NullCheck
36 /// CHECK: <<Index:i\d+>> BoundsCheck
Artem Serov328429f2016-07-06 16:23:04 +010037 /// CHECK-NOT: IntermediateAddress
Alexandre Ramese6dbf482015-10-19 10:10:41 +010038 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
39
Artem Serov328429f2016-07-06 16:23:04 +010040
41 /// CHECK-START-ARM: int Main.constantIndexGet(int[]) instruction_simplifier_arm (before)
42 /// CHECK: <<Array:l\d+>> NullCheck
43 /// CHECK: <<Index:i\d+>> BoundsCheck
44 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
45
46 /// CHECK-START-ARM: int Main.constantIndexGet(int[]) instruction_simplifier_arm (after)
47 /// CHECK: <<Array:l\d+>> NullCheck
48 /// CHECK: <<Index:i\d+>> BoundsCheck
49 /// CHECK-NOT: IntermediateAddress
50 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
51
Alexandre Ramese6dbf482015-10-19 10:10:41 +010052 public static int constantIndexGet(int array[]) {
53 return array[1];
54 }
55
56 /**
57 * Test that HArraySet with a constant index is not split.
58 */
59
60 /// CHECK-START-ARM64: void Main.constantIndexSet(int[]) instruction_simplifier_arm64 (before)
61 /// CHECK: <<Const2:i\d+>> IntConstant 2
62 /// CHECK: <<Array:l\d+>> NullCheck
63 /// CHECK: <<Index:i\d+>> BoundsCheck
64 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Const2>>]
65
66 /// CHECK-START-ARM64: void Main.constantIndexSet(int[]) instruction_simplifier_arm64 (after)
67 /// CHECK: <<Const2:i\d+>> IntConstant 2
68 /// CHECK: <<Array:l\d+>> NullCheck
69 /// CHECK: <<Index:i\d+>> BoundsCheck
Artem Serov328429f2016-07-06 16:23:04 +010070 /// CHECK-NOT: IntermediateAddress
Alexandre Ramese6dbf482015-10-19 10:10:41 +010071 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Const2>>]
72
73
Artem Serov328429f2016-07-06 16:23:04 +010074 /// CHECK-START-ARM: void Main.constantIndexSet(int[]) instruction_simplifier_arm (before)
75 /// CHECK: <<Const2:i\d+>> IntConstant 2
76 /// CHECK: <<Array:l\d+>> NullCheck
77 /// CHECK: <<Index:i\d+>> BoundsCheck
78 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Const2>>]
79
80 /// CHECK-START-ARM: void Main.constantIndexSet(int[]) instruction_simplifier_arm (after)
81 /// CHECK: <<Const2:i\d+>> IntConstant 2
82 /// CHECK: <<Array:l\d+>> NullCheck
83 /// CHECK: <<Index:i\d+>> BoundsCheck
84 /// CHECK-NOT: IntermediateAddress
85 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Const2>>]
86
Alexandre Ramese6dbf482015-10-19 10:10:41 +010087 public static void constantIndexSet(int array[]) {
88 array[1] = 2;
89 }
90
91 /**
92 * Test basic splitting of HArrayGet.
93 */
94
95 /// CHECK-START-ARM64: int Main.get(int[], int) instruction_simplifier_arm64 (before)
96 /// CHECK: <<Array:l\d+>> NullCheck
97 /// CHECK: <<Index:i\d+>> BoundsCheck
98 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
99
100 /// CHECK-START-ARM64: int Main.get(int[], int) instruction_simplifier_arm64 (after)
101 /// CHECK: <<DataOffset:i\d+>> IntConstant
102 /// CHECK: <<Array:l\d+>> NullCheck
103 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100104 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100105 /// CHECK-NEXT: ArrayGet [<<Address>>,<<Index>>]
106
107
108 /// CHECK-START-ARM: int Main.get(int[], int) instruction_simplifier_arm (before)
109 /// CHECK: <<Array:l\d+>> NullCheck
110 /// CHECK: <<Index:i\d+>> BoundsCheck
111 /// CHECK: ArrayGet [<<Array>>,<<Index>>]
112
113 /// CHECK-START-ARM: int Main.get(int[], int) instruction_simplifier_arm (after)
114 /// CHECK: <<DataOffset:i\d+>> IntConstant
115 /// CHECK: <<Array:l\d+>> NullCheck
116 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100117 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100118 /// CHECK-NEXT: ArrayGet [<<Address>>,<<Index>>]
119
120 public static int get(int array[], int index) {
121 return array[index];
122 }
123
124 /**
125 * Test basic splitting of HArraySet.
126 */
127
128 /// CHECK-START-ARM64: void Main.set(int[], int, int) instruction_simplifier_arm64 (before)
129 /// CHECK: ParameterValue
130 /// CHECK: ParameterValue
131 /// CHECK: <<Arg:i\d+>> ParameterValue
132 /// CHECK: <<Array:l\d+>> NullCheck
133 /// CHECK: <<Index:i\d+>> BoundsCheck
134 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Arg>>]
135
136 /// CHECK-START-ARM64: void Main.set(int[], int, int) instruction_simplifier_arm64 (after)
137 /// CHECK: ParameterValue
138 /// CHECK: ParameterValue
139 /// CHECK: <<Arg:i\d+>> ParameterValue
140 /// CHECK: <<DataOffset:i\d+>> IntConstant
141 /// CHECK: <<Array:l\d+>> NullCheck
142 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100143 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100144 /// CHECK-NEXT: ArraySet [<<Address>>,<<Index>>,<<Arg>>]
145
146
147 /// CHECK-START-ARM: void Main.set(int[], int, int) instruction_simplifier_arm (before)
148 /// CHECK: ParameterValue
149 /// CHECK: ParameterValue
150 /// CHECK: <<Arg:i\d+>> ParameterValue
151 /// CHECK: <<Array:l\d+>> NullCheck
152 /// CHECK: <<Index:i\d+>> BoundsCheck
153 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Arg>>]
154
155 /// CHECK-START-ARM: void Main.set(int[], int, int) instruction_simplifier_arm (after)
156 /// CHECK: ParameterValue
157 /// CHECK: ParameterValue
158 /// CHECK: <<Arg:i\d+>> ParameterValue
159 /// CHECK: <<DataOffset:i\d+>> IntConstant
160 /// CHECK: <<Array:l\d+>> NullCheck
161 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100162 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100163 /// CHECK-NEXT: ArraySet [<<Address>>,<<Index>>,<<Arg>>]
164
165 public static void set(int array[], int index, int value) {
166 array[index] = value;
167 }
168
169 /**
170 * Check that the intermediate address can be shared after GVN.
171 */
172
173 /// CHECK-START-ARM64: void Main.getSet(int[], int) instruction_simplifier_arm64 (before)
174 /// CHECK: <<Const1:i\d+>> IntConstant 1
175 /// CHECK: <<Array:l\d+>> NullCheck
176 /// CHECK: <<Index:i\d+>> BoundsCheck
177 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
178 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
179 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Add>>]
180
181 /// CHECK-START-ARM64: void Main.getSet(int[], int) instruction_simplifier_arm64 (after)
182 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
183 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
184 /// CHECK: <<Array:l\d+>> NullCheck
185 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100186 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100187 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
188 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100189 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100190 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
191
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700192 /// CHECK-START-ARM64: void Main.getSet(int[], int) GVN$after_arch (after)
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100193 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
194 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
195 /// CHECK: <<Array:l\d+>> NullCheck
196 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100197 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100198 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address>>,<<Index>>]
199 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
Artem Serov328429f2016-07-06 16:23:04 +0100200 /// CHECK-NOT: IntermediateAddress
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100201 /// CHECK: ArraySet [<<Address>>,<<Index>>,<<Add>>]
202
Artem Serov328429f2016-07-06 16:23:04 +0100203
204 /// CHECK-START-ARM: void Main.getSet(int[], int) instruction_simplifier_arm (before)
205 /// CHECK: <<Const1:i\d+>> IntConstant 1
206 /// CHECK: <<Array:l\d+>> NullCheck
207 /// CHECK: <<Index:i\d+>> BoundsCheck
208 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
209 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
210 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Add>>]
211
212 /// CHECK-START-ARM: void Main.getSet(int[], int) instruction_simplifier_arm (after)
213 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
214 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
215 /// CHECK: <<Array:l\d+>> NullCheck
216 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100217 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100218 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
219 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100220 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100221 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
222
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700223 /// CHECK-START-ARM: void Main.getSet(int[], int) GVN$after_arch (after)
Artem Serov328429f2016-07-06 16:23:04 +0100224 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
225 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
226 /// CHECK: <<Array:l\d+>> NullCheck
227 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100228 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100229 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address>>,<<Index>>]
230 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
231 /// CHECK-NOT: IntermediateAddress
232 /// CHECK: ArraySet [<<Address>>,<<Index>>,<<Add>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100233 public static void getSet(int array[], int index) {
234 array[index] = array[index] + 1;
235 }
236
237 /**
238 * Check that the intermediate address computation is not reordered or merged
239 * across IRs that can trigger GC.
240 */
241
242 /// CHECK-START-ARM64: int[] Main.accrossGC(int[], int) instruction_simplifier_arm64 (before)
243 /// CHECK: <<Const1:i\d+>> IntConstant 1
244 /// CHECK: <<Array:l\d+>> NullCheck
245 /// CHECK: <<Index:i\d+>> BoundsCheck
246 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
247 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
248 /// CHECK: NewArray
249 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Add>>]
250
251 /// CHECK-START-ARM64: int[] Main.accrossGC(int[], int) instruction_simplifier_arm64 (after)
252 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
253 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
254 /// CHECK: <<Array:l\d+>> NullCheck
255 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100256 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100257 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
258 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
259 /// CHECK: NewArray
Alexandre Rames91a65162016-09-19 13:54:30 +0100260 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100261 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
262
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700263 /// CHECK-START-ARM64: int[] Main.accrossGC(int[], int) GVN$after_arch (after)
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100264 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
265 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
266 /// CHECK: <<Array:l\d+>> NullCheck
267 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100268 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100269 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
270 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
271 /// CHECK: NewArray
Alexandre Rames91a65162016-09-19 13:54:30 +0100272 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100273 /// CHECK: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
274
275
276 /// CHECK-START-ARM: int[] Main.accrossGC(int[], int) instruction_simplifier_arm (before)
277 /// CHECK: <<Const1:i\d+>> IntConstant 1
278 /// CHECK: <<Array:l\d+>> NullCheck
279 /// CHECK: <<Index:i\d+>> BoundsCheck
280 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
281 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
282 /// CHECK: NewArray
283 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Add>>]
284
285 /// CHECK-START-ARM: int[] Main.accrossGC(int[], int) instruction_simplifier_arm (after)
286 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
287 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
288 /// CHECK: <<Array:l\d+>> NullCheck
289 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100290 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100291 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
292 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
293 /// CHECK: NewArray
Alexandre Rames91a65162016-09-19 13:54:30 +0100294 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100295 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
296
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700297 /// CHECK-START-ARM: int[] Main.accrossGC(int[], int) GVN$after_arch (after)
Artem Serov328429f2016-07-06 16:23:04 +0100298 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
299 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant
300 /// CHECK: <<Array:l\d+>> NullCheck
301 /// CHECK: <<Index:i\d+>> BoundsCheck
Alexandre Rames91a65162016-09-19 13:54:30 +0100302 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100303 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
304 /// CHECK: <<Add:i\d+>> Add [<<ArrayGet>>,<<Const1>>]
305 /// CHECK: NewArray
Alexandre Rames91a65162016-09-19 13:54:30 +0100306 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100307 /// CHECK: ArraySet [<<Address2>>,<<Index>>,<<Add>>]
308
309 public static int[] accrossGC(int array[], int index) {
310 int tmp = array[index] + 1;
311 int[] new_array = new int[1];
312 array[index] = tmp;
313 return new_array;
314 }
315
316 /**
317 * Test that the intermediate address is shared between array accesses after
318 * the bounds check have been removed by BCE.
319 */
Artem Serov328429f2016-07-06 16:23:04 +0100320 // For checker tests `instruction_simplifier_<arch> (after)` below, by the time we reach
321 // the architecture-specific instruction simplifier, BCE has removed the bounds checks in
322 // the loop.
323
324 // Note that we do not care that the `DataOffset` is `12`. But if we do not
325 // specify it and any other `IntConstant` appears before that instruction,
326 // checker will match the previous `IntConstant`, and we will thus fail the
327 // check.
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100328
329 /// CHECK-START-ARM64: int Main.canMergeAfterBCE1() instruction_simplifier_arm64 (before)
Aart Bika5b9af12017-03-22 16:33:11 -0700330 /// CHECK: <<Const7:i\d+>> IntConstant 7
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100331 /// CHECK: <<Array:l\d+>> NewArray
332 /// CHECK: <<Index:i\d+>> Phi
333 /// CHECK: If
334 // -------------- Loop
335 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700336 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
337 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Div>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100338
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100339 /// CHECK-START-ARM64: int Main.canMergeAfterBCE1() instruction_simplifier_arm64 (after)
Aart Bika5b9af12017-03-22 16:33:11 -0700340 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100341 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
342 /// CHECK: <<Array:l\d+>> NewArray
343 /// CHECK: <<Index:i\d+>> Phi
344 /// CHECK: If
345 // -------------- Loop
Alexandre Rames91a65162016-09-19 13:54:30 +0100346 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100347 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700348 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100349 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700350 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Div>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100351
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700352 /// CHECK-START-ARM64: int Main.canMergeAfterBCE1() GVN$after_arch (after)
Aart Bika5b9af12017-03-22 16:33:11 -0700353 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100354 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
355 /// CHECK: <<Array:l\d+>> NewArray
356 /// CHECK: <<Index:i\d+>> Phi
357 /// CHECK: If
358 // -------------- Loop
Alexandre Rames91a65162016-09-19 13:54:30 +0100359 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100360 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700361 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
Artem Serov328429f2016-07-06 16:23:04 +0100362 /// CHECK-NOT: IntermediateAddress
Aart Bika5b9af12017-03-22 16:33:11 -0700363 /// CHECK: ArraySet [<<Address>>,<<Index>>,<<Div>>]
Artem Serov328429f2016-07-06 16:23:04 +0100364
365
366 /// CHECK-START-ARM: int Main.canMergeAfterBCE1() instruction_simplifier_arm (before)
Aart Bika5b9af12017-03-22 16:33:11 -0700367 /// CHECK: <<Const7:i\d+>> IntConstant 7
Artem Serov328429f2016-07-06 16:23:04 +0100368 /// CHECK: <<Array:l\d+>> NewArray
369 /// CHECK: <<Index:i\d+>> Phi
370 /// CHECK: If
371 // -------------- Loop
372 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Array>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700373 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
374 /// CHECK: ArraySet [<<Array>>,<<Index>>,<<Div>>]
Artem Serov328429f2016-07-06 16:23:04 +0100375
376 /// CHECK-START-ARM: int Main.canMergeAfterBCE1() instruction_simplifier_arm (after)
Aart Bika5b9af12017-03-22 16:33:11 -0700377 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
Artem Serov328429f2016-07-06 16:23:04 +0100378 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
379 /// CHECK: <<Array:l\d+>> NewArray
380 /// CHECK: <<Index:i\d+>> Phi
381 /// CHECK: If
382 // -------------- Loop
Alexandre Rames91a65162016-09-19 13:54:30 +0100383 /// CHECK: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100384 /// CHECK-NEXT: <<ArrayGet:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700385 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100386 /// CHECK: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700387 /// CHECK-NEXT: ArraySet [<<Address2>>,<<Index>>,<<Div>>]
Artem Serov328429f2016-07-06 16:23:04 +0100388
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700389 /// CHECK-START-ARM: int Main.canMergeAfterBCE1() GVN$after_arch (after)
Aart Bika5b9af12017-03-22 16:33:11 -0700390 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
Artem Serov328429f2016-07-06 16:23:04 +0100391 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
392 /// CHECK: <<Array:l\d+>> NewArray
393 /// CHECK: <<Index:i\d+>> Phi
394 /// CHECK: If
395 // -------------- Loop
Alexandre Rames91a65162016-09-19 13:54:30 +0100396 /// CHECK: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100397 /// CHECK: <<ArrayGet:i\d+>> ArrayGet [<<Address>>,<<Index>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700398 /// CHECK: <<Div:i\d+>> Div [<<ArrayGet>>,<<Const7>>]
Artem Serov328429f2016-07-06 16:23:04 +0100399 /// CHECK-NOT: IntermediateAddress
Aart Bika5b9af12017-03-22 16:33:11 -0700400 /// CHECK: ArraySet [<<Address>>,<<Index>>,<<Div>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100401
402 public static int canMergeAfterBCE1() {
Aart Bika5b9af12017-03-22 16:33:11 -0700403 int[] array = {0, 7, 14, 21};
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100404 for (int i = 0; i < array.length; i++) {
Aart Bika5b9af12017-03-22 16:33:11 -0700405 array[i] = array[i] / 7;
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100406 }
407 return array[array.length - 1];
408 }
409
410 /**
411 * This test case is similar to `canMergeAfterBCE1`, but with different
412 * indexes for the accesses.
413 */
414
415 /// CHECK-START-ARM64: int Main.canMergeAfterBCE2() instruction_simplifier_arm64 (before)
416 /// CHECK: <<Const1:i\d+>> IntConstant 1
417 /// CHECK: <<Array:l\d+>> NewArray
418 /// CHECK: <<Index:i\d+>> Phi
419 /// CHECK: If
420 // -------------- Loop
421 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
422 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Array>>,<<Index>>]
423 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Array>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700424 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
425 /// CHECK: ArraySet [<<Array>>,<<Index1>>,<<Shl>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100426
427 // Note that we do not care that the `DataOffset` is `12`. But if we do not
428 // specify it and any other `IntConstant` appears before that instruction,
429 // checker will match the previous `IntConstant`, and we will thus fail the
430 // check.
431
432 /// CHECK-START-ARM64: int Main.canMergeAfterBCE2() instruction_simplifier_arm64 (after)
433 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
434 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
435 /// CHECK: <<Array:l\d+>> NewArray
436 /// CHECK: <<Index:i\d+>> Phi
437 /// CHECK: If
438 // -------------- Loop
439 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100440 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100441 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100442 /// CHECK-DAG: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100443 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Address2>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700444 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100445 /// CHECK: <<Address3:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700446 /// CHECK: ArraySet [<<Address3>>,<<Index1>>,<<Shl>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100447
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700448 /// CHECK-START-ARM64: int Main.canMergeAfterBCE2() GVN$after_arch (after)
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100449 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
450 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
451 /// CHECK: <<Array:l\d+>> NewArray
452 /// CHECK: <<Index:i\d+>> Phi
453 /// CHECK: If
454 // -------------- Loop
455 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100456 /// CHECK-DAG: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100457 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Address>>,<<Index>>]
458 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Address>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700459 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
460 /// CHECK: ArraySet [<<Address>>,<<Index1>>,<<Shl>>]
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100461
462 // There should be only one intermediate address computation in the loop.
463
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700464 /// CHECK-START-ARM64: int Main.canMergeAfterBCE2() GVN$after_arch (after)
Artem Serov328429f2016-07-06 16:23:04 +0100465 /// CHECK: IntermediateAddress
466 /// CHECK-NOT: IntermediateAddress
467
468
469 /// CHECK-START-ARM: int Main.canMergeAfterBCE2() instruction_simplifier_arm (before)
470 /// CHECK: <<Const1:i\d+>> IntConstant 1
471 /// CHECK: <<Array:l\d+>> NewArray
472 /// CHECK: <<Index:i\d+>> Phi
473 /// CHECK: If
474 // -------------- Loop
475 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
476 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Array>>,<<Index>>]
477 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Array>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700478 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
479 /// CHECK: ArraySet [<<Array>>,<<Index1>>,<<Shl>>]
Artem Serov328429f2016-07-06 16:23:04 +0100480
481 /// CHECK-START-ARM: int Main.canMergeAfterBCE2() instruction_simplifier_arm (after)
482 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
483 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
484 /// CHECK: <<Array:l\d+>> NewArray
485 /// CHECK: <<Index:i\d+>> Phi
486 /// CHECK: If
487 // -------------- Loop
488 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100489 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100490 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Address1>>,<<Index>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100491 /// CHECK-DAG: <<Address2:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100492 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Address2>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700493 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100494 /// CHECK: <<Address3:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700495 /// CHECK: ArraySet [<<Address3>>,<<Index1>>,<<Shl>>]
Artem Serov328429f2016-07-06 16:23:04 +0100496
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700497 /// CHECK-START-ARM: int Main.canMergeAfterBCE2() GVN$after_arch (after)
Artem Serov328429f2016-07-06 16:23:04 +0100498 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
499 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12
500 /// CHECK: <<Array:l\d+>> NewArray
501 /// CHECK: <<Index:i\d+>> Phi
502 /// CHECK: If
503 // -------------- Loop
504 /// CHECK-DAG: <<Index1:i\d+>> Add [<<Index>>,<<Const1>>]
Alexandre Rames91a65162016-09-19 13:54:30 +0100505 /// CHECK-DAG: <<Address:i\d+>> IntermediateAddress [<<Array>>,<<DataOffset>>]
Artem Serov328429f2016-07-06 16:23:04 +0100506 /// CHECK-DAG: <<ArrayGetI:i\d+>> ArrayGet [<<Address>>,<<Index>>]
507 /// CHECK-DAG: <<ArrayGetI1:i\d+>> ArrayGet [<<Address>>,<<Index1>>]
Aart Bika5b9af12017-03-22 16:33:11 -0700508 /// CHECK: <<Shl:i\d+>> Shl [<<ArrayGetI>>,<<ArrayGetI1>>]
509 /// CHECK: ArraySet [<<Address>>,<<Index1>>,<<Shl>>]
Artem Serov328429f2016-07-06 16:23:04 +0100510
Wojciech Staszkiewicz5319d3c2016-08-01 17:48:59 -0700511 /// CHECK-START-ARM: int Main.canMergeAfterBCE2() GVN$after_arch (after)
Artem Serov328429f2016-07-06 16:23:04 +0100512 /// CHECK: IntermediateAddress
513 /// CHECK-NOT: IntermediateAddress
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100514
515 public static int canMergeAfterBCE2() {
Aart Bika5b9af12017-03-22 16:33:11 -0700516 int[] array = {64, 8, 4, 2 };
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100517 for (int i = 0; i < array.length - 1; i++) {
Aart Bika5b9af12017-03-22 16:33:11 -0700518 array[i + 1] = array[i] << array[i + 1];
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100519 }
520 return array[array.length - 1];
521 }
522
Artem Serov328429f2016-07-06 16:23:04 +0100523 /// CHECK-START-ARM: int Main.checkLongFloatDouble() instruction_simplifier_arm (before)
524 /// CHECK-DAG: <<Array1:l\d+>> NewArray
525 /// CHECK-DAG: <<Array2:l\d+>> NewArray
526 /// CHECK-DAG: <<Array3:l\d+>> NewArray
527 /// CHECK-DAG: <<Index:i\d+>> Phi
528 /// CHECK-DAG: ArrayGet [<<Array1>>,<<Index>>]
529 /// CHECK-DAG: ArrayGet [<<Array2>>,<<Index>>]
530 /// CHECK-DAG: ArrayGet [<<Array3>>,<<Index>>]
531
532 /// CHECK-START-ARM: int Main.checkLongFloatDouble() instruction_simplifier_arm (after)
533 /// CHECK-DAG: <<Array1:l\d+>> NewArray
534 /// CHECK-DAG: <<Array2:l\d+>> NewArray
535 /// CHECK-DAG: <<Array3:l\d+>> NewArray
536 /// CHECK-DAG: <<Index:i\d+>> Phi
537 /// CHECK-DAG: ArrayGet [<<Array1>>,<<Index>>]
538 /// CHECK-DAG: ArrayGet [<<Array2>>,<<Index>>]
539 /// CHECK-DAG: ArrayGet [<<Array3>>,<<Index>>]
540
541 /// CHECK-START-ARM: int Main.checkLongFloatDouble() instruction_simplifier_arm (after)
542 /// CHECK-NOT: IntermediateAddress
543 public static int checkLongFloatDouble() {
544 long[] array_long = {0, 1, 2, 3};
545 float[] array_float = {(float)0.0, (float)1.0, (float)2.0, (float)3.0};
546 double[] array_double = {0.0, 1.0, 2.0, 3.0};
547 double s = 0.0;
548
549 for (int i = 0; i < 4; i++) {
550 s += (double)array_long[i] + (double)array_float[i] + array_double[i];
551 }
552 return (int)s;
553 }
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100554
555 public static void main(String[] args) {
556 int[] array = {123, 456, 789};
557
558 assertIntEquals(456, constantIndexGet(array));
559
560 constantIndexSet(array);
561 assertIntEquals(2, array[1]);
562
563 assertIntEquals(789, get(array, 2));
564
565 set(array, 1, 456);
566 assertIntEquals(456, array[1]);
567
568 getSet(array, 0);
569 assertIntEquals(124, array[0]);
570
571 accrossGC(array, 0);
572 assertIntEquals(125, array[0]);
573
Aart Bika5b9af12017-03-22 16:33:11 -0700574 assertIntEquals(3, canMergeAfterBCE1());
575 assertIntEquals(1048576, canMergeAfterBCE2());
Artem Serov328429f2016-07-06 16:23:04 +0100576
577 assertIntEquals(18, checkLongFloatDouble());
Alexandre Ramese6dbf482015-10-19 10:10:41 +0100578 }
579}