blob: 3cbcebbcb6e1eedddd79283a815e3c7f284713a1 [file] [log] [blame]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001/*
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 public static void assertLongEquals(long expected, long result) {
26 if (expected != result) {
27 throw new Error("Expected: " + expected + ", found: " + result);
28 }
29 }
30
31 /**
32 * Tiny programs exercising optimizations of arithmetic identities.
33 */
34
35 // CHECK-START: long Main.Add0(long) instruction_simplifier (before)
36 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
37 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
38 // CHECK-DAG: [[Add:j\d+]] Add [ [[Const0]] [[Arg]] ]
39 // CHECK-DAG: Return [ [[Add]] ]
40
41 // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
42 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000043 // CHECK-DAG: Return [ [[Arg]] ]
Alexandre Rames74417692015-04-09 15:21:41 +010044 //
45 // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
46 // CHECK-NOT: Add
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000047
48 public static long Add0(long arg) {
49 return 0 + arg;
50 }
51
52 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
53 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
54 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
55 // CHECK-DAG: [[And:i\d+]] And [ [[Arg]] [[ConstF]] ]
56 // CHECK-DAG: Return [ [[And]] ]
57
58 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
59 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000060 // CHECK-DAG: Return [ [[Arg]] ]
61
Alexandre Rames74417692015-04-09 15:21:41 +010062 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
63 // CHECK-NOT: And
64
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000065 public static int AndAllOnes(int arg) {
66 return arg & -1;
67 }
68
69 // CHECK-START: long Main.Div1(long) instruction_simplifier (before)
70 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
71 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1
72 // CHECK-DAG: [[Div:j\d+]] Div [ [[Arg]] [[Const1]] ]
73 // CHECK-DAG: Return [ [[Div]] ]
74
75 // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
76 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000077 // CHECK-DAG: Return [ [[Arg]] ]
78
Alexandre Rames74417692015-04-09 15:21:41 +010079 // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
80 // CHECK-NOT: Div
81
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000082 public static long Div1(long arg) {
83 return arg / 1;
84 }
85
86 // CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
87 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
88 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1
89 // CHECK-DAG: [[Div:i\d+]] Div [ [[Arg]] [[ConstN1]] ]
90 // CHECK-DAG: Return [ [[Div]] ]
91
92 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
93 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
94 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000095 // CHECK-DAG: Return [ [[Neg]] ]
96
Alexandre Rames74417692015-04-09 15:21:41 +010097 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
98 // CHECK-NOT: Div
99
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000100 public static int DivN1(int arg) {
101 return arg / -1;
102 }
103
104 // CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
105 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
106 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1
107 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const1]] ]
108 // CHECK-DAG: Return [ [[Mul]] ]
109
110 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
111 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000112 // CHECK-DAG: Return [ [[Arg]] ]
113
Alexandre Rames74417692015-04-09 15:21:41 +0100114 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
115 // CHECK-NOT: Mul
116
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000117 public static long Mul1(long arg) {
118 return arg * 1;
119 }
120
121 // CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
122 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
123 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1
124 // CHECK-DAG: [[Mul:i\d+]] Mul [ [[Arg]] [[ConstN1]] ]
125 // CHECK-DAG: Return [ [[Mul]] ]
126
127 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
128 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
129 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000130 // CHECK-DAG: Return [ [[Neg]] ]
131
Alexandre Rames74417692015-04-09 15:21:41 +0100132 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
133 // CHECK-NOT: Mul
134
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000135 public static int MulN1(int arg) {
136 return arg * -1;
137 }
138
139 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
140 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
141 // CHECK-DAG: [[Const128:j\d+]] LongConstant 128
142 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const128]] ]
143 // CHECK-DAG: Return [ [[Mul]] ]
144
145 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
146 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
147 // CHECK-DAG: [[Const7:i\d+]] IntConstant 7
148 // CHECK-DAG: [[Shl:j\d+]] Shl [ [[Arg]] [[Const7]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000149 // CHECK-DAG: Return [ [[Shl]] ]
150
Alexandre Rames74417692015-04-09 15:21:41 +0100151 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
152 // CHECK-NOT: Mul
153
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000154 public static long MulPowerOfTwo128(long arg) {
155 return arg * 128;
156 }
157
158 // CHECK-START: int Main.Or0(int) instruction_simplifier (before)
159 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
160 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
161 // CHECK-DAG: [[Or:i\d+]] Or [ [[Arg]] [[Const0]] ]
162 // CHECK-DAG: Return [ [[Or]] ]
163
164 // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
165 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000166 // CHECK-DAG: Return [ [[Arg]] ]
167
Alexandre Rames74417692015-04-09 15:21:41 +0100168 // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
169 // CHECK-NOT: Or
170
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000171 public static int Or0(int arg) {
172 return arg | 0;
173 }
174
175 // CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
176 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
177 // CHECK-DAG: [[Or:j\d+]] Or [ [[Arg]] [[Arg]] ]
178 // CHECK-DAG: Return [ [[Or]] ]
179
180 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
181 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000182 // CHECK-DAG: Return [ [[Arg]] ]
183
Alexandre Rames74417692015-04-09 15:21:41 +0100184 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
185 // CHECK-NOT: Or
186
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000187 public static long OrSame(long arg) {
188 return arg | arg;
189 }
190
191 // CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
192 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
193 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
194 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const0]] ]
195 // CHECK-DAG: Return [ [[Shl]] ]
196
197 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
198 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000199 // CHECK-DAG: Return [ [[Arg]] ]
200
Alexandre Rames74417692015-04-09 15:21:41 +0100201 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
202 // CHECK-NOT: Shl
203
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000204 public static int Shl0(int arg) {
205 return arg << 0;
206 }
207
208 // CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
209 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
210 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
211 // CHECK-DAG: [[Shr:j\d+]] Shr [ [[Arg]] [[Const0]] ]
212 // CHECK-DAG: Return [ [[Shr]] ]
213
214 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
215 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000216 // CHECK-DAG: Return [ [[Arg]] ]
217
Alexandre Rames74417692015-04-09 15:21:41 +0100218 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
219 // CHECK-NOT: Shr
220
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000221 public static long Shr0(long arg) {
222 return arg >> 0;
223 }
224
225 // CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
226 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
227 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
228 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg]] [[Const0]] ]
229 // CHECK-DAG: Return [ [[Sub]] ]
230
231 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
232 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000233 // CHECK-DAG: Return [ [[Arg]] ]
234
Alexandre Rames74417692015-04-09 15:21:41 +0100235 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
236 // CHECK-NOT: Sub
237
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000238 public static long Sub0(long arg) {
239 return arg - 0;
240 }
241
242 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
243 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
244 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
245 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const0]] [[Arg]] ]
246 // CHECK-DAG: Return [ [[Sub]] ]
247
248 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
249 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
250 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000251 // CHECK-DAG: Return [ [[Neg]] ]
252
Alexandre Rames74417692015-04-09 15:21:41 +0100253 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
254 // CHECK-NOT: Sub
255
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000256 public static int SubAliasNeg(int arg) {
257 return 0 - arg;
258 }
259
260 // CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
261 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
262 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
263 // CHECK-DAG: [[UShr:j\d+]] UShr [ [[Arg]] [[Const0]] ]
264 // CHECK-DAG: Return [ [[UShr]] ]
265
266 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
267 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000268 // CHECK-DAG: Return [ [[Arg]] ]
269
Alexandre Rames74417692015-04-09 15:21:41 +0100270 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
271 // CHECK-NOT: UShr
272
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000273 public static long UShr0(long arg) {
274 return arg >>> 0;
275 }
276
277 // CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
278 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
279 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
280 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[Const0]] ]
281 // CHECK-DAG: Return [ [[Xor]] ]
282
283 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
284 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000285 // CHECK-DAG: Return [ [[Arg]] ]
286
Alexandre Rames74417692015-04-09 15:21:41 +0100287 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
288 // CHECK-NOT: Xor
289
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000290 public static int Xor0(int arg) {
291 return arg ^ 0;
292 }
293
294 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
295 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
296 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
297 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[ConstF]] ]
298 // CHECK-DAG: Return [ [[Xor]] ]
299
300 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
301 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
302 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000303 // CHECK-DAG: Return [ [[Not]] ]
304
Alexandre Rames74417692015-04-09 15:21:41 +0100305 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
306 // CHECK-NOT: Xor
307
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000308 public static int XorAllOnes(int arg) {
309 return arg ^ -1;
310 }
311
Alexandre Rames188d4312015-04-09 18:30:21 +0100312 /**
313 * Test that addition or subtraction operation with both inputs negated are
314 * optimized to use a single negation after the operation.
315 * The transformation tested is implemented in
316 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
317 */
318
319 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
320 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
321 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
322 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
323 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
324 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
325 // CHECK-DAG: Return [ [[Add]] ]
326
327 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
328 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
329 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
330 // CHECK-NOT: Neg
331 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
332 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
333 // CHECK-DAG: Return [ [[Neg]] ]
334
335 public static int AddNegs1(int arg1, int arg2) {
336 return -arg1 + -arg2;
337 }
338
339 /**
340 * This is similar to the test-case AddNegs1, but the negations have
341 * multiple uses.
342 * The transformation tested is implemented in
343 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
344 * The current code won't perform the previous optimization. The
345 * transformations do not look at other uses of their inputs. As they don't
346 * know what will happen with other uses, they do not take the risk of
347 * increasing the register pressure by creating or extending live ranges.
348 */
349
350 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
351 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
352 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
353 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
354 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
355 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
356 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
357 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
358 // CHECK-DAG: Return [ [[Or]] ]
359
360 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
361 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
362 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
363 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
364 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
365 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
366 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
367 // CHECK-NOT: Neg
368 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
369 // CHECK-DAG: Return [ [[Or]] ]
370
371 public static int AddNegs2(int arg1, int arg2) {
372 int temp1 = -arg1;
373 int temp2 = -arg2;
374 return (temp1 + temp2) | (temp1 + temp2);
375 }
376
377 /**
378 * This follows test-cases AddNegs1 and AddNegs2.
379 * The transformation tested is implemented in
380 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
381 * The optimization should not happen if it moves an additional instruction in
382 * the loop.
383 */
384
385 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
386 // -------------- Arguments and initial negation operations.
387 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
388 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
389 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
390 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
391 // CHECK: Goto
392 // -------------- Loop
393 // CHECK: SuspendCheck
394 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
395 // CHECK: Goto
396
397 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
398 // -------------- Arguments and initial negation operations.
399 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
400 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
401 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
402 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
403 // CHECK: Goto
404 // -------------- Loop
405 // CHECK: SuspendCheck
406 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
407 // CHECK-NOT: Neg
408 // CHECK: Goto
409
410 public static long AddNegs3(long arg1, long arg2) {
411 long res = 0;
412 long n_arg1 = -arg1;
413 long n_arg2 = -arg2;
414 for (long i = 0; i < 1; i++) {
415 res += n_arg1 + n_arg2 + i;
416 }
417 return res;
418 }
419
420 /**
421 * Test the simplification of an addition with a negated argument into a
422 * subtraction.
423 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
424 */
425
426 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
427 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
428 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
429 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
430 // CHECK-DAG: [[Add:j\d+]] Add [ [[Neg]] [[Arg2]] ]
431 // CHECK-DAG: Return [ [[Add]] ]
432
433 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
434 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
435 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
436 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg2]] [[Arg1]] ]
437 // CHECK-DAG: Return [ [[Sub]] ]
438
439 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
440 // CHECK-NOT: Neg
441 // CHECK-NOT: Add
442
443 public static long AddNeg1(long arg1, long arg2) {
444 return -arg1 + arg2;
445 }
446
447 /**
448 * This is similar to the test-case AddNeg1, but the negation has two uses.
449 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
450 * The current code won't perform the previous optimization. The
451 * transformations do not look at other uses of their inputs. As they don't
452 * know what will happen with other uses, they do not take the risk of
453 * increasing the register pressure by creating or extending live ranges.
454 */
455
456 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
457 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
458 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
459 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
460 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
461 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
462 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
463 // CHECK-DAG: Return [ [[Res]] ]
464
465 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
466 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
467 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
468 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
469 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
470 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
471 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
472 // CHECK-DAG: Return [ [[Res]] ]
473
474 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
475 // CHECK-NOT: Sub
476
477 public static long AddNeg2(long arg1, long arg2) {
478 long temp = -arg2;
479 return (arg1 + temp) | (arg1 + temp);
480 }
481
482 /**
483 * Test simplification of the `-(-var)` pattern.
484 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
485 */
486
487 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
488 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
489 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg]] ]
490 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Neg1]] ]
491 // CHECK-DAG: Return [ [[Neg2]] ]
492
493 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
494 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
495 // CHECK-DAG: Return [ [[Arg]] ]
496
497 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
498 // CHECK-NOT: Neg
499
500 public static long NegNeg1(long arg) {
501 return -(-arg);
502 }
503
504 /**
505 * Test 'multi-step' simplification, where a first transformation yields a
506 * new simplification possibility for the current instruction.
507 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
508 * and in `InstructionSimplifierVisitor::VisitAdd`.
509 */
510
511 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
512 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
513 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg]] ]
514 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Neg1]] ]
515 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
516 // CHECK-DAG: Return [ [[Add]] ]
517
518 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
519 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
520 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg]] [[Arg]] ]
521 // CHECK-DAG: Return [ [[Sub]] ]
522
523 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
524 // CHECK-NOT: Neg
525 // CHECK-NOT: Add
526
527 public static int NegNeg2(int arg) {
528 int temp = -arg;
529 return temp + -temp;
530 }
531
532 /**
533 * Test another 'multi-step' simplification, where a first transformation
534 * yields a new simplification possibility for the current instruction.
535 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
536 * and in `InstructionSimplifierVisitor::VisitSub`.
537 */
538
539 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
540 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
541 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
542 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg]] ]
543 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const0]] [[Neg]] ]
544 // CHECK-DAG: Return [ [[Sub]] ]
545
546 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
547 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
548 // CHECK-DAG: Return [ [[Arg]] ]
549
550 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
551 // CHECK-NOT: Neg
552 // CHECK-NOT: Sub
553
554 public static long NegNeg3(long arg) {
555 return 0 - -arg;
556 }
557
558 /**
559 * Test that a negated subtraction is simplified to a subtraction with its
560 * arguments reversed.
561 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
562 */
563
564 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
565 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
566 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
567 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
568 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Sub]] ]
569 // CHECK-DAG: Return [ [[Neg]] ]
570
571 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
572 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
573 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
574 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg2]] [[Arg1]] ]
575 // CHECK-DAG: Return [ [[Sub]] ]
576
577 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
578 // CHECK-NOT: Neg
579
580 public static int NegSub1(int arg1, int arg2) {
581 return -(arg1 - arg2);
582 }
583
584 /**
585 * This is similar to the test-case NegSub1, but the subtraction has
586 * multiple uses.
587 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
588 * The current code won't perform the previous optimization. The
589 * transformations do not look at other uses of their inputs. As they don't
590 * know what will happen with other uses, they do not take the risk of
591 * increasing the register pressure by creating or extending live ranges.
592 */
593
594 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
595 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
596 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
597 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
598 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
599 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
600 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
601 // CHECK-DAG: Return [ [[Or]] ]
602
603 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
604 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
605 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
606 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
607 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
608 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
609 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
610 // CHECK-DAG: Return [ [[Or]] ]
611
612 public static int NegSub2(int arg1, int arg2) {
613 int temp = arg1 - arg2;
614 return -temp | -temp;
615 }
616
617 /**
618 * Test simplification of the `~~var` pattern.
619 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
620 */
621
622 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
623 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
624 // CHECK-DAG: [[ConstF1:j\d+]] LongConstant -1
625 // CHECK-DAG: [[Xor1:j\d+]] Xor [ [[Arg]] [[ConstF1]] ]
626 // CHECK-DAG: [[Xor2:j\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
627 // CHECK-DAG: Return [ [[Xor2]] ]
628
629 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
630 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
631 // CHECK-DAG: Return [ [[Arg]] ]
632
633 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
634 // CHECK-NOT: Xor
635
636 public static long NotNot1(long arg) {
637 return ~~arg;
638 }
639
640 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
641 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
642 // CHECK-DAG: [[ConstF1:i\d+]] IntConstant -1
643 // CHECK-DAG: [[Xor1:i\d+]] Xor [ [[Arg]] [[ConstF1]] ]
644 // CHECK-DAG: [[Xor2:i\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
645 // CHECK-DAG: [[Add:i\d+]] Add [ [[Xor1]] [[Xor2]] ]
646 // CHECK-DAG: Return [ [[Add]] ]
647
648 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
649 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
650 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
651 // CHECK-DAG: [[Add:i\d+]] Add [ [[Not]] [[Arg]] ]
652 // CHECK-DAG: Return [ [[Add]] ]
653
654 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
655 // CHECK-NOT: Xor
656
657 public static int NotNot2(int arg) {
658 int temp = ~arg;
659 return temp + ~temp;
660 }
661
662 /**
663 * Test the simplification of a subtraction with a negated argument.
664 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
665 */
666
667 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
668 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
669 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
670 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
671 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
672 // CHECK-DAG: Return [ [[Sub]] ]
673
674 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
675 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
676 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
677 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
678 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
679 // CHECK-DAG: Return [ [[Neg]] ]
680
681 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
682 // CHECK-NOT: Sub
683
684 public static int SubNeg1(int arg1, int arg2) {
685 return -arg1 - arg2;
686 }
687
688 /**
689 * This is similar to the test-case SubNeg1, but the negation has
690 * multiple uses.
691 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
692 * The current code won't perform the previous optimization. The
693 * transformations do not look at other uses of their inputs. As they don't
694 * know what will happen with other uses, they do not take the risk of
695 * increasing the register pressure by creating or extending live ranges.
696 */
697
698 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
699 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
700 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
701 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
702 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
703 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
704 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
705 // CHECK-DAG: Return [ [[Or]] ]
706
707 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
708 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
709 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
710 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
711 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
712 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
713 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
714 // CHECK-DAG: Return [ [[Or]] ]
715
716 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
717 // CHECK-NOT: Add
718
719 public static int SubNeg2(int arg1, int arg2) {
720 int temp = -arg1;
721 return (temp - arg2) | (temp - arg2);
722 }
723
724 /**
725 * This follows test-cases SubNeg1 and SubNeg2.
726 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
727 * The optimization should not happen if it moves an additional instruction in
728 * the loop.
729 */
730
731 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
732 // -------------- Arguments and initial negation operation.
733 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
734 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
735 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
736 // CHECK: Goto
737 // -------------- Loop
738 // CHECK: SuspendCheck
739 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
740 // CHECK: Goto
741
742 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
743 // -------------- Arguments and initial negation operation.
744 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
745 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
746 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
747 // CHECK-DAG: Goto
748 // -------------- Loop
749 // CHECK: SuspendCheck
750 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
751 // CHECK-NOT: Neg
752 // CHECK: Goto
753
754 public static long SubNeg3(long arg1, long arg2) {
755 long res = 0;
756 long temp = -arg1;
757 for (long i = 0; i < 1; i++) {
758 res += temp - arg2 - i;
759 }
760 return res;
761 }
762
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000763 public static void main(String[] args) {
764 int arg = 123456;
765
766 assertLongEquals(Add0(arg), arg);
767 assertIntEquals(AndAllOnes(arg), arg);
768 assertLongEquals(Div1(arg), arg);
769 assertIntEquals(DivN1(arg), -arg);
770 assertLongEquals(Mul1(arg), arg);
771 assertIntEquals(MulN1(arg), -arg);
772 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
773 assertIntEquals(Or0(arg), arg);
774 assertLongEquals(OrSame(arg), arg);
775 assertIntEquals(Shl0(arg), arg);
776 assertLongEquals(Shr0(arg), arg);
777 assertLongEquals(Sub0(arg), arg);
778 assertIntEquals(SubAliasNeg(arg), -arg);
779 assertLongEquals(UShr0(arg), arg);
780 assertIntEquals(Xor0(arg), arg);
781 assertIntEquals(XorAllOnes(arg), ~arg);
Alexandre Rames188d4312015-04-09 18:30:21 +0100782 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
783 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
784 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
785 assertLongEquals(AddNeg1(arg, arg + 1), 1);
786 assertLongEquals(AddNeg2(arg, arg + 1), -1);
787 assertLongEquals(NegNeg1(arg), arg);
788 assertIntEquals(NegNeg2(arg), 0);
789 assertLongEquals(NegNeg3(arg), arg);
790 assertIntEquals(NegSub1(arg, arg + 1), 1);
791 assertIntEquals(NegSub2(arg, arg + 1), 1);
792 assertLongEquals(NotNot1(arg), arg);
793 assertIntEquals(NotNot2(arg), -1);
794 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
795 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
796 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000797 }
798}