blob: 6b21fed66c41e470d3c4c151397ce3dd7baefc7a [file] [log] [blame]
David Brazdilee690a32014-12-01 17:04:16 +00001/*
2* Copyright (C) 2014 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
David Brazdil4846d132015-01-15 19:07:08 +000017public class Main {
David Brazdilee690a32014-12-01 17:04:16 +000018
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000019 public static void assertIntEquals(int expected, int result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
25 public static void assertLongEquals(long expected, long result) {
26 if (expected != result) {
27 throw new Error("Expected: " + expected + ", found: " + result);
28 }
29 }
30
David Brazdilee690a32014-12-01 17:04:16 +000031 /**
32 * Tiny three-register program exercising int constant folding
33 * on negation.
34 */
35
David Brazdil4846d132015-01-15 19:07:08 +000036 // CHECK-START: int Main.IntNegation() constant_folding (before)
David Brazdilbe0cc082014-12-31 11:49:30 +000037 // CHECK-DAG: [[Const42:i\d+]] IntConstant 42
38 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Const42]] ]
39 // CHECK-DAG: Return [ [[Neg]] ]
David Brazdilee690a32014-12-01 17:04:16 +000040
David Brazdil4846d132015-01-15 19:07:08 +000041 // CHECK-START: int Main.IntNegation() constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +000042 // CHECK-DAG: [[ConstN42:i\d+]] IntConstant -42
43 // CHECK-DAG: Return [ [[ConstN42]] ]
David Brazdilee690a32014-12-01 17:04:16 +000044
45 public static int IntNegation() {
46 int x, y;
47 x = 42;
48 y = -x;
49 return y;
50 }
51
52 /**
53 * Tiny three-register program exercising int constant folding
54 * on addition.
55 */
56
David Brazdil4846d132015-01-15 19:07:08 +000057 // CHECK-START: int Main.IntAddition1() constant_folding (before)
David Brazdilbe0cc082014-12-31 11:49:30 +000058 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
59 // CHECK-DAG: [[Const2:i\d+]] IntConstant 2
60 // CHECK-DAG: [[Add:i\d+]] Add [ [[Const1]] [[Const2]] ]
61 // CHECK-DAG: Return [ [[Add]] ]
David Brazdilee690a32014-12-01 17:04:16 +000062
David Brazdil4846d132015-01-15 19:07:08 +000063 // CHECK-START: int Main.IntAddition1() constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +000064 // CHECK-DAG: [[Const3:i\d+]] IntConstant 3
65 // CHECK-DAG: Return [ [[Const3]] ]
David Brazdilee690a32014-12-01 17:04:16 +000066
67 public static int IntAddition1() {
68 int a, b, c;
69 a = 1;
70 b = 2;
71 c = a + b;
72 return c;
73 }
74
75 /**
76 * Small three-register program exercising int constant folding
77 * on addition.
78 */
79
David Brazdil4846d132015-01-15 19:07:08 +000080 // CHECK-START: int Main.IntAddition2() constant_folding (before)
David Brazdilbe0cc082014-12-31 11:49:30 +000081 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
82 // CHECK-DAG: [[Const2:i\d+]] IntConstant 2
83 // CHECK-DAG: [[Const5:i\d+]] IntConstant 5
84 // CHECK-DAG: [[Const6:i\d+]] IntConstant 6
85 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Const1]] [[Const2]] ]
86 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Const5]] [[Const6]] ]
87 // CHECK-DAG: [[Add3:i\d+]] Add [ [[Add1]] [[Add2]] ]
88 // CHECK-DAG: Return [ [[Add3]] ]
David Brazdilee690a32014-12-01 17:04:16 +000089
David Brazdil4846d132015-01-15 19:07:08 +000090 // CHECK-START: int Main.IntAddition2() constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +000091 // CHECK-DAG: [[Const14:i\d+]] IntConstant 14
92 // CHECK-DAG: Return [ [[Const14]] ]
David Brazdilee690a32014-12-01 17:04:16 +000093
94 public static int IntAddition2() {
95 int a, b, c;
96 a = 1;
97 b = 2;
98 a += b;
99 b = 5;
100 c = 6;
101 b += c;
102 c = a + b;
103 return c;
104 }
105
106 /**
107 * Tiny three-register program exercising int constant folding
108 * on subtraction.
109 */
110
David Brazdil4846d132015-01-15 19:07:08 +0000111 // CHECK-START: int Main.IntSubtraction() constant_folding (before)
112 // CHECK-DAG: [[Const6:i\d+]] IntConstant 6
David Brazdilbe0cc082014-12-31 11:49:30 +0000113 // CHECK-DAG: [[Const2:i\d+]] IntConstant 2
David Brazdil4846d132015-01-15 19:07:08 +0000114 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const6]] [[Const2]] ]
David Brazdilbe0cc082014-12-31 11:49:30 +0000115 // CHECK-DAG: Return [ [[Sub]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000116
David Brazdil4846d132015-01-15 19:07:08 +0000117 // CHECK-START: int Main.IntSubtraction() constant_folding (after)
118 // CHECK-DAG: [[Const4:i\d+]] IntConstant 4
119 // CHECK-DAG: Return [ [[Const4]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000120
121 public static int IntSubtraction() {
122 int a, b, c;
David Brazdil4846d132015-01-15 19:07:08 +0000123 a = 6;
David Brazdilee690a32014-12-01 17:04:16 +0000124 b = 2;
125 c = a - b;
126 return c;
127 }
128
129 /**
130 * Tiny three-register program exercising long constant folding
131 * on addition.
132 */
133
David Brazdil4846d132015-01-15 19:07:08 +0000134 // CHECK-START: long Main.LongAddition() constant_folding (before)
David Brazdilbe0cc082014-12-31 11:49:30 +0000135 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1
136 // CHECK-DAG: [[Const2:j\d+]] LongConstant 2
137 // CHECK-DAG: [[Add:j\d+]] Add [ [[Const1]] [[Const2]] ]
138 // CHECK-DAG: Return [ [[Add]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000139
David Brazdil4846d132015-01-15 19:07:08 +0000140 // CHECK-START: long Main.LongAddition() constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +0000141 // CHECK-DAG: [[Const3:j\d+]] LongConstant 3
142 // CHECK-DAG: Return [ [[Const3]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000143
144 public static long LongAddition() {
145 long a, b, c;
146 a = 1L;
147 b = 2L;
148 c = a + b;
149 return c;
150 }
151
152 /**
153 * Tiny three-register program exercising long constant folding
154 * on subtraction.
155 */
156
David Brazdil4846d132015-01-15 19:07:08 +0000157 // CHECK-START: long Main.LongSubtraction() constant_folding (before)
158 // CHECK-DAG: [[Const6:j\d+]] LongConstant 6
David Brazdilbe0cc082014-12-31 11:49:30 +0000159 // CHECK-DAG: [[Const2:j\d+]] LongConstant 2
David Brazdil4846d132015-01-15 19:07:08 +0000160 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const6]] [[Const2]] ]
David Brazdilbe0cc082014-12-31 11:49:30 +0000161 // CHECK-DAG: Return [ [[Sub]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000162
David Brazdil4846d132015-01-15 19:07:08 +0000163 // CHECK-START: long Main.LongSubtraction() constant_folding (after)
164 // CHECK-DAG: [[Const4:j\d+]] LongConstant 4
165 // CHECK-DAG: Return [ [[Const4]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000166
167 public static long LongSubtraction() {
168 long a, b, c;
David Brazdil4846d132015-01-15 19:07:08 +0000169 a = 6L;
David Brazdilee690a32014-12-01 17:04:16 +0000170 b = 2L;
171 c = a - b;
172 return c;
173 }
174
175 /**
176 * Three-register program with a constant (static) condition.
177 */
178
David Brazdil4846d132015-01-15 19:07:08 +0000179 // CHECK-START: int Main.StaticCondition() constant_folding (before)
180 // CHECK-DAG: [[Const7:i\d+]] IntConstant 7
David Brazdilbe0cc082014-12-31 11:49:30 +0000181 // CHECK-DAG: [[Const2:i\d+]] IntConstant 2
David Brazdil4846d132015-01-15 19:07:08 +0000182 // CHECK-DAG: [[Cond:z\d+]] GreaterThanOrEqual [ [[Const7]] [[Const2]] ]
David Brazdilbe0cc082014-12-31 11:49:30 +0000183 // CHECK-DAG: If [ [[Cond]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000184
David Brazdil4846d132015-01-15 19:07:08 +0000185 // CHECK-START: int Main.StaticCondition() constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +0000186 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
187 // CHECK-DAG: If [ [[Const1]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000188
189 public static int StaticCondition() {
190 int a, b, c;
David Brazdil4846d132015-01-15 19:07:08 +0000191 a = 7;
David Brazdilee690a32014-12-01 17:04:16 +0000192 b = 2;
193 if (a < b)
194 c = a + b;
195 else
196 c = a - b;
197 return c;
198 }
199
200 /**
201 * Four-variable program with jumps leading to the creation of many
202 * blocks.
203 *
204 * The intent of this test is to ensure that all constant expressions
205 * are actually evaluated at compile-time, thanks to the reverse
206 * (forward) post-order traversal of the the dominator tree.
207 */
208
David Brazdil4846d132015-01-15 19:07:08 +0000209 // CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (before)
David Brazdilbe0cc082014-12-31 11:49:30 +0000210 // CHECK-DAG: [[Const2:i\d+]] IntConstant 2
211 // CHECK-DAG: [[Const5:i\d+]] IntConstant 5
212 // CHECK-DAG: [[Add:i\d+]] Add [ [[Const5]] [[Const2]] ]
213 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const5]] [[Const2]] ]
214 // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Add]] [[Sub]] ]
215 // CHECK-DAG: Return [ [[Phi]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000216
David Brazdil4846d132015-01-15 19:07:08 +0000217 // CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
David Brazdilbe0cc082014-12-31 11:49:30 +0000218 // CHECK-DAG: [[Const3:i\d+]] IntConstant 3
219 // CHECK-DAG: [[Const7:i\d+]] IntConstant 7
220 // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const7]] [[Const3]] ]
221 // CHECK-DAG: Return [ [[Phi]] ]
David Brazdilee690a32014-12-01 17:04:16 +0000222
223 public static int JumpsAndConditionals(boolean cond) {
224 int a, b, c;
225 a = 5;
226 b = 2;
227 if (cond)
228 c = a + b;
229 else
230 c = a - b;
231 return c;
232 }
David Brazdil4846d132015-01-15 19:07:08 +0000233
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000234 /**
235 * Test optimizations of arithmetic identities yielding a constant result.
236 */
237
238 // CHECK-START: int Main.And0(int) constant_folding (before)
239 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
240 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
241 // CHECK-DAG: [[And:i\d+]] And [ [[Arg]] [[Const0]] ]
242 // CHECK-DAG: Return [ [[And]] ]
243
244 // CHECK-START: int Main.And0(int) constant_folding (after)
245 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
246 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
247 // CHECK-NOT: And
248 // CHECK-DAG: Return [ [[Const0]] ]
249
250 public static int And0(int arg) {
251 return arg & 0;
252 }
253
254 // CHECK-START: long Main.Mul0(long) constant_folding (before)
255 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
256 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
257 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const0]] ]
258 // CHECK-DAG: Return [ [[Mul]] ]
259
260 // CHECK-START: long Main.Mul0(long) constant_folding (after)
261 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
262 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
263 // CHECK-NOT: Mul
264 // CHECK-DAG: Return [ [[Const0]] ]
265
266 public static long Mul0(long arg) {
267 return arg * 0;
268 }
269
270 // CHECK-START: int Main.OrAllOnes(int) constant_folding (before)
271 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
272 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
273 // CHECK-DAG: [[Or:i\d+]] Or [ [[Arg]] [[ConstF]] ]
274 // CHECK-DAG: Return [ [[Or]] ]
275
276 // CHECK-START: int Main.OrAllOnes(int) constant_folding (after)
277 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
278 // CHECK-NOT: Or
279 // CHECK-DAG: Return [ [[ConstF]] ]
280
281 public static int OrAllOnes(int arg) {
282 return arg | -1;
283 }
284
285 // CHECK-START: long Main.Rem0(long) constant_folding (before)
286 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
287 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
288 // CHECK-DAG: [[DivZeroCheck:j\d+]] DivZeroCheck [ [[Arg]] ]
289 // CHECK-DAG: [[Rem:j\d+]] Rem [ [[Const0]] [[DivZeroCheck]] ]
290 // CHECK-DAG: Return [ [[Rem]] ]
291
292 // CHECK-START: long Main.Rem0(long) constant_folding (after)
293 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
294 // CHECK-NOT: Rem
295 // CHECK-DAG: Return [ [[Const0]] ]
296
297 public static long Rem0(long arg) {
298 return 0 % arg;
299 }
300
301 // CHECK-START: int Main.Rem1(int) constant_folding (before)
302 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
303 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
304 // CHECK-DAG: [[Rem:i\d+]] Rem [ [[Arg]] [[Const1]] ]
305 // CHECK-DAG: Return [ [[Rem]] ]
306
307 // CHECK-START: int Main.Rem1(int) constant_folding (after)
308 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
309 // CHECK-NOT: Rem
310 // CHECK-DAG: Return [ [[Const0]] ]
311
312 public static int Rem1(int arg) {
313 return arg % 1;
314 }
315
316 // CHECK-START: long Main.RemN1(long) constant_folding (before)
317 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
318 // CHECK-DAG: [[ConstN1:j\d+]] LongConstant -1
319 // CHECK-DAG: [[DivZeroCheck:j\d+]] DivZeroCheck [ [[Arg]] ]
320 // CHECK-DAG: [[Rem:j\d+]] Rem [ [[Arg]] [[DivZeroCheck]] ]
321 // CHECK-DAG: Return [ [[Rem]] ]
322
323 // CHECK-START: long Main.RemN1(long) constant_folding (after)
324 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
325 // CHECK-NOT: Rem
326 // CHECK-DAG: Return [ [[Const0]] ]
327
328 public static long RemN1(long arg) {
329 return arg % -1;
330 }
331
332 // CHECK-START: int Main.Shl0(int) constant_folding (before)
333 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
334 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
335 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Const0]] [[Arg]] ]
336 // CHECK-DAG: Return [ [[Shl]] ]
337
338 // CHECK-START: int Main.Shl0(int) constant_folding (after)
339 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
340 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
341 // CHECK-NOT: Shl
342 // CHECK-DAG: Return [ [[Const0]] ]
343
344 public static int Shl0(int arg) {
345 return 0 << arg;
346 }
347
348 // CHECK-START: long Main.Shr0(int) constant_folding (before)
349 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
350 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
351 // CHECK-DAG: [[Shr:j\d+]] Shr [ [[Const0]] [[Arg]] ]
352 // CHECK-DAG: Return [ [[Shr]] ]
353
354 // CHECK-START: long Main.Shr0(int) constant_folding (after)
355 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
356 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
357 // CHECK-NOT: Shr
358 // CHECK-DAG: Return [ [[Const0]] ]
359
360 public static long Shr0(int arg) {
361 return (long)0 >> arg;
362 }
363
364 // CHECK-START: long Main.SubSameLong(long) constant_folding (before)
365 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
366 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg]] [[Arg]] ]
367 // CHECK-DAG: Return [ [[Sub]] ]
368
369 // CHECK-START: long Main.SubSameLong(long) constant_folding (after)
370 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
371 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
372 // CHECK-NOT: Sub
373 // CHECK-DAG: Return [ [[Const0]] ]
374
375 public static long SubSameLong(long arg) {
376 return arg - arg;
377 }
378
379 // CHECK-START: int Main.UShr0(int) constant_folding (before)
380 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
381 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
382 // CHECK-DAG: [[UShr:i\d+]] UShr [ [[Const0]] [[Arg]] ]
383 // CHECK-DAG: Return [ [[UShr]] ]
384
385 // CHECK-START: int Main.UShr0(int) constant_folding (after)
386 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
387 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
388 // CHECK-NOT: UShr
389 // CHECK-DAG: Return [ [[Const0]] ]
390
391 public static int UShr0(int arg) {
392 return 0 >>> arg;
393 }
394
395 // CHECK-START: int Main.XorSameInt(int) constant_folding (before)
396 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
397 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[Arg]] ]
398 // CHECK-DAG: Return [ [[Xor]] ]
399
400 // CHECK-START: int Main.XorSameInt(int) constant_folding (after)
401 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
402 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
403 // CHECK-NOT: Xor
404 // CHECK-DAG: Return [ [[Const0]] ]
405
406 public static int XorSameInt(int arg) {
407 return arg ^ arg;
408 }
409
David Brazdil4846d132015-01-15 19:07:08 +0000410 public static void main(String[] args) {
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000411 assertIntEquals(IntNegation(), -42);
412 assertIntEquals(IntAddition1(), 3);
413 assertIntEquals(IntAddition2(), 14);
414 assertIntEquals(IntSubtraction(), 4);
415 assertLongEquals(LongAddition(), 3L);
416 assertLongEquals(LongSubtraction(), 4L);
417 assertIntEquals(StaticCondition(), 5);
418 assertIntEquals(JumpsAndConditionals(true), 7);
419 assertIntEquals(JumpsAndConditionals(false), 3);
420 int random = 123456; // Chosen randomly.
421 assertIntEquals(And0(random), 0);
422 assertLongEquals(Mul0(random), 0);
423 assertIntEquals(OrAllOnes(random), -1);
424 assertLongEquals(Rem0(random), 0);
425 assertIntEquals(Rem1(random), 0);
426 assertLongEquals(RemN1(random), 0);
427 assertIntEquals(Shl0(random), 0);
428 assertLongEquals(Shr0(random), 0);
429 assertLongEquals(SubSameLong(random), 0);
430 assertIntEquals(UShr0(random), 0);
431 assertIntEquals(XorSameInt(random), 0);
David Brazdil4846d132015-01-15 19:07:08 +0000432 }
David Brazdilee690a32014-12-01 17:04:16 +0000433}