blob: f26e0b1a8a95514ceffdb003381c8a2aefef7184 [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
David Brazdil0d13fee2015-04-17 14:52:19 +010019 public static void assertBooleanEquals(boolean expected, boolean result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000025 public static void assertIntEquals(int expected, int result) {
26 if (expected != result) {
27 throw new Error("Expected: " + expected + ", found: " + result);
28 }
29 }
30
31 public static void assertLongEquals(long expected, long result) {
32 if (expected != result) {
33 throw new Error("Expected: " + expected + ", found: " + result);
34 }
35 }
36
Mark Mendellb0bd8912015-04-15 19:57:22 -040037 public static void assertFloatEquals(float expected, float result) {
38 if (expected != result) {
39 throw new Error("Expected: " + expected + ", found: " + result);
40 }
41 }
42
43 public static void assertDoubleEquals(double expected, double result) {
44 if (expected != result) {
45 throw new Error("Expected: " + expected + ", found: " + result);
46 }
47 }
48
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000049 /**
50 * Tiny programs exercising optimizations of arithmetic identities.
51 */
52
53 // CHECK-START: long Main.Add0(long) instruction_simplifier (before)
54 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
55 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
56 // CHECK-DAG: [[Add:j\d+]] Add [ [[Const0]] [[Arg]] ]
57 // CHECK-DAG: Return [ [[Add]] ]
58
59 // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
60 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000061 // CHECK-DAG: Return [ [[Arg]] ]
David Brazdil0d13fee2015-04-17 14:52:19 +010062
Alexandre Rames74417692015-04-09 15:21:41 +010063 // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
64 // CHECK-NOT: Add
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000065
66 public static long Add0(long arg) {
67 return 0 + arg;
68 }
69
70 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
71 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
72 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
73 // CHECK-DAG: [[And:i\d+]] And [ [[Arg]] [[ConstF]] ]
74 // CHECK-DAG: Return [ [[And]] ]
75
76 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
77 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000078 // CHECK-DAG: Return [ [[Arg]] ]
79
Alexandre Rames74417692015-04-09 15:21:41 +010080 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
81 // CHECK-NOT: And
82
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000083 public static int AndAllOnes(int arg) {
84 return arg & -1;
85 }
86
87 // CHECK-START: long Main.Div1(long) instruction_simplifier (before)
88 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
89 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1
90 // CHECK-DAG: [[Div:j\d+]] Div [ [[Arg]] [[Const1]] ]
91 // CHECK-DAG: Return [ [[Div]] ]
92
93 // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
94 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000095 // CHECK-DAG: Return [ [[Arg]] ]
96
Alexandre Rames74417692015-04-09 15:21:41 +010097 // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
98 // CHECK-NOT: Div
99
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000100 public static long Div1(long arg) {
101 return arg / 1;
102 }
103
104 // CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
105 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
106 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1
107 // CHECK-DAG: [[Div:i\d+]] Div [ [[Arg]] [[ConstN1]] ]
108 // CHECK-DAG: Return [ [[Div]] ]
109
110 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
111 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
112 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000113 // CHECK-DAG: Return [ [[Neg]] ]
114
Alexandre Rames74417692015-04-09 15:21:41 +0100115 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
116 // CHECK-NOT: Div
117
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000118 public static int DivN1(int arg) {
119 return arg / -1;
120 }
121
122 // CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
123 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
124 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1
125 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const1]] ]
126 // CHECK-DAG: Return [ [[Mul]] ]
127
128 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
129 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000130 // CHECK-DAG: Return [ [[Arg]] ]
131
Alexandre Rames74417692015-04-09 15:21:41 +0100132 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
133 // CHECK-NOT: Mul
134
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000135 public static long Mul1(long arg) {
136 return arg * 1;
137 }
138
139 // CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
140 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
141 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1
142 // CHECK-DAG: [[Mul:i\d+]] Mul [ [[Arg]] [[ConstN1]] ]
143 // CHECK-DAG: Return [ [[Mul]] ]
144
145 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
146 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
147 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000148 // CHECK-DAG: Return [ [[Neg]] ]
149
Alexandre Rames74417692015-04-09 15:21:41 +0100150 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
151 // CHECK-NOT: Mul
152
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000153 public static int MulN1(int arg) {
154 return arg * -1;
155 }
156
157 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
158 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
159 // CHECK-DAG: [[Const128:j\d+]] LongConstant 128
160 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const128]] ]
161 // CHECK-DAG: Return [ [[Mul]] ]
162
163 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
164 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
165 // CHECK-DAG: [[Const7:i\d+]] IntConstant 7
166 // CHECK-DAG: [[Shl:j\d+]] Shl [ [[Arg]] [[Const7]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000167 // CHECK-DAG: Return [ [[Shl]] ]
168
Alexandre Rames74417692015-04-09 15:21:41 +0100169 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
170 // CHECK-NOT: Mul
171
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000172 public static long MulPowerOfTwo128(long arg) {
173 return arg * 128;
174 }
175
176 // CHECK-START: int Main.Or0(int) instruction_simplifier (before)
177 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
178 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
179 // CHECK-DAG: [[Or:i\d+]] Or [ [[Arg]] [[Const0]] ]
180 // CHECK-DAG: Return [ [[Or]] ]
181
182 // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
183 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000184 // CHECK-DAG: Return [ [[Arg]] ]
185
Alexandre Rames74417692015-04-09 15:21:41 +0100186 // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
187 // CHECK-NOT: Or
188
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000189 public static int Or0(int arg) {
190 return arg | 0;
191 }
192
193 // CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
194 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
195 // CHECK-DAG: [[Or:j\d+]] Or [ [[Arg]] [[Arg]] ]
196 // CHECK-DAG: Return [ [[Or]] ]
197
198 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
199 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000200 // CHECK-DAG: Return [ [[Arg]] ]
201
Alexandre Rames74417692015-04-09 15:21:41 +0100202 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
203 // CHECK-NOT: Or
204
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000205 public static long OrSame(long arg) {
206 return arg | arg;
207 }
208
209 // CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
210 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
211 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
212 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const0]] ]
213 // CHECK-DAG: Return [ [[Shl]] ]
214
215 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
216 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000217 // CHECK-DAG: Return [ [[Arg]] ]
218
Alexandre Rames74417692015-04-09 15:21:41 +0100219 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
220 // CHECK-NOT: Shl
221
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000222 public static int Shl0(int arg) {
223 return arg << 0;
224 }
225
226 // CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
227 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
228 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
229 // CHECK-DAG: [[Shr:j\d+]] Shr [ [[Arg]] [[Const0]] ]
230 // CHECK-DAG: Return [ [[Shr]] ]
231
232 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
233 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000234 // CHECK-DAG: Return [ [[Arg]] ]
235
Alexandre Rames74417692015-04-09 15:21:41 +0100236 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
237 // CHECK-NOT: Shr
238
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000239 public static long Shr0(long arg) {
240 return arg >> 0;
241 }
242
243 // CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
244 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
245 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
246 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg]] [[Const0]] ]
247 // CHECK-DAG: Return [ [[Sub]] ]
248
249 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
250 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000251 // CHECK-DAG: Return [ [[Arg]] ]
252
Alexandre Rames74417692015-04-09 15:21:41 +0100253 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
254 // CHECK-NOT: Sub
255
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000256 public static long Sub0(long arg) {
257 return arg - 0;
258 }
259
260 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
261 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
262 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
263 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const0]] [[Arg]] ]
264 // CHECK-DAG: Return [ [[Sub]] ]
265
266 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
267 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
268 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000269 // CHECK-DAG: Return [ [[Neg]] ]
270
Alexandre Rames74417692015-04-09 15:21:41 +0100271 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
272 // CHECK-NOT: Sub
273
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000274 public static int SubAliasNeg(int arg) {
275 return 0 - arg;
276 }
277
278 // CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
279 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
280 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
281 // CHECK-DAG: [[UShr:j\d+]] UShr [ [[Arg]] [[Const0]] ]
282 // CHECK-DAG: Return [ [[UShr]] ]
283
284 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
285 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000286 // CHECK-DAG: Return [ [[Arg]] ]
287
Alexandre Rames74417692015-04-09 15:21:41 +0100288 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
289 // CHECK-NOT: UShr
290
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000291 public static long UShr0(long arg) {
292 return arg >>> 0;
293 }
294
295 // CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
296 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
297 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
298 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[Const0]] ]
299 // CHECK-DAG: Return [ [[Xor]] ]
300
301 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
302 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000303 // CHECK-DAG: Return [ [[Arg]] ]
304
Alexandre Rames74417692015-04-09 15:21:41 +0100305 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
306 // CHECK-NOT: Xor
307
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000308 public static int Xor0(int arg) {
309 return arg ^ 0;
310 }
311
312 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
313 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
314 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
315 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[ConstF]] ]
316 // CHECK-DAG: Return [ [[Xor]] ]
317
318 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
319 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
320 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000321 // CHECK-DAG: Return [ [[Not]] ]
322
Alexandre Rames74417692015-04-09 15:21:41 +0100323 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
324 // CHECK-NOT: Xor
325
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000326 public static int XorAllOnes(int arg) {
327 return arg ^ -1;
328 }
329
Alexandre Rames188d4312015-04-09 18:30:21 +0100330 /**
331 * Test that addition or subtraction operation with both inputs negated are
332 * optimized to use a single negation after the operation.
333 * The transformation tested is implemented in
334 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
335 */
336
337 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
338 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
339 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
340 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
341 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
342 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
343 // CHECK-DAG: Return [ [[Add]] ]
344
345 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
346 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
347 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
348 // CHECK-NOT: Neg
349 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
350 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
351 // CHECK-DAG: Return [ [[Neg]] ]
352
353 public static int AddNegs1(int arg1, int arg2) {
354 return -arg1 + -arg2;
355 }
356
357 /**
358 * This is similar to the test-case AddNegs1, but the negations have
359 * multiple uses.
360 * The transformation tested is implemented in
361 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
362 * The current code won't perform the previous optimization. The
363 * transformations do not look at other uses of their inputs. As they don't
364 * know what will happen with other uses, they do not take the risk of
365 * increasing the register pressure by creating or extending live ranges.
366 */
367
368 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
369 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
370 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
371 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
372 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
373 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
374 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
375 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
376 // CHECK-DAG: Return [ [[Or]] ]
377
378 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
379 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
380 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
381 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
382 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
383 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
384 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
385 // CHECK-NOT: Neg
386 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
387 // CHECK-DAG: Return [ [[Or]] ]
388
389 public static int AddNegs2(int arg1, int arg2) {
390 int temp1 = -arg1;
391 int temp2 = -arg2;
392 return (temp1 + temp2) | (temp1 + temp2);
393 }
394
395 /**
396 * This follows test-cases AddNegs1 and AddNegs2.
397 * The transformation tested is implemented in
398 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
399 * The optimization should not happen if it moves an additional instruction in
400 * the loop.
401 */
402
403 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
404 // -------------- Arguments and initial negation operations.
405 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
406 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
407 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
408 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
409 // CHECK: Goto
410 // -------------- Loop
411 // CHECK: SuspendCheck
412 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
413 // CHECK: Goto
414
415 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
416 // -------------- Arguments and initial negation operations.
417 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
418 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
419 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
420 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
421 // CHECK: Goto
422 // -------------- Loop
423 // CHECK: SuspendCheck
424 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
425 // CHECK-NOT: Neg
426 // CHECK: Goto
427
428 public static long AddNegs3(long arg1, long arg2) {
429 long res = 0;
430 long n_arg1 = -arg1;
431 long n_arg2 = -arg2;
432 for (long i = 0; i < 1; i++) {
433 res += n_arg1 + n_arg2 + i;
434 }
435 return res;
436 }
437
438 /**
439 * Test the simplification of an addition with a negated argument into a
440 * subtraction.
441 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
442 */
443
444 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
445 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
446 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
447 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
448 // CHECK-DAG: [[Add:j\d+]] Add [ [[Neg]] [[Arg2]] ]
449 // CHECK-DAG: Return [ [[Add]] ]
450
451 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
452 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
453 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
454 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg2]] [[Arg1]] ]
455 // CHECK-DAG: Return [ [[Sub]] ]
456
457 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
458 // CHECK-NOT: Neg
459 // CHECK-NOT: Add
460
461 public static long AddNeg1(long arg1, long arg2) {
462 return -arg1 + arg2;
463 }
464
465 /**
466 * This is similar to the test-case AddNeg1, but the negation has two uses.
467 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
468 * The current code won't perform the previous optimization. The
469 * transformations do not look at other uses of their inputs. As they don't
470 * know what will happen with other uses, they do not take the risk of
471 * increasing the register pressure by creating or extending live ranges.
472 */
473
474 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
475 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
476 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
477 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
478 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
479 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
480 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
481 // CHECK-DAG: Return [ [[Res]] ]
482
483 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
484 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
485 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
486 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
487 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
488 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
489 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
490 // CHECK-DAG: Return [ [[Res]] ]
491
492 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
493 // CHECK-NOT: Sub
494
495 public static long AddNeg2(long arg1, long arg2) {
496 long temp = -arg2;
497 return (arg1 + temp) | (arg1 + temp);
498 }
499
500 /**
501 * Test simplification of the `-(-var)` pattern.
502 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
503 */
504
505 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
506 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
507 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg]] ]
508 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Neg1]] ]
509 // CHECK-DAG: Return [ [[Neg2]] ]
510
511 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
512 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
513 // CHECK-DAG: Return [ [[Arg]] ]
514
515 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
516 // CHECK-NOT: Neg
517
518 public static long NegNeg1(long arg) {
519 return -(-arg);
520 }
521
522 /**
523 * Test 'multi-step' simplification, where a first transformation yields a
524 * new simplification possibility for the current instruction.
525 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
526 * and in `InstructionSimplifierVisitor::VisitAdd`.
527 */
528
529 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
530 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
531 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg]] ]
532 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Neg1]] ]
533 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
534 // CHECK-DAG: Return [ [[Add]] ]
535
536 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
537 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
538 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg]] [[Arg]] ]
539 // CHECK-DAG: Return [ [[Sub]] ]
540
541 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
542 // CHECK-NOT: Neg
543 // CHECK-NOT: Add
544
545 public static int NegNeg2(int arg) {
546 int temp = -arg;
547 return temp + -temp;
548 }
549
550 /**
551 * Test another 'multi-step' simplification, where a first transformation
552 * yields a new simplification possibility for the current instruction.
553 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
554 * and in `InstructionSimplifierVisitor::VisitSub`.
555 */
556
557 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
558 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
559 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
560 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg]] ]
561 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const0]] [[Neg]] ]
562 // CHECK-DAG: Return [ [[Sub]] ]
563
564 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
565 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
566 // CHECK-DAG: Return [ [[Arg]] ]
567
568 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
569 // CHECK-NOT: Neg
570 // CHECK-NOT: Sub
571
572 public static long NegNeg3(long arg) {
573 return 0 - -arg;
574 }
575
576 /**
577 * Test that a negated subtraction is simplified to a subtraction with its
578 * arguments reversed.
579 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
580 */
581
582 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
583 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
584 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
585 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
586 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Sub]] ]
587 // CHECK-DAG: Return [ [[Neg]] ]
588
589 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
590 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
591 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
592 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg2]] [[Arg1]] ]
593 // CHECK-DAG: Return [ [[Sub]] ]
594
595 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
596 // CHECK-NOT: Neg
597
598 public static int NegSub1(int arg1, int arg2) {
599 return -(arg1 - arg2);
600 }
601
602 /**
603 * This is similar to the test-case NegSub1, but the subtraction has
604 * multiple uses.
605 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
606 * The current code won't perform the previous optimization. The
607 * transformations do not look at other uses of their inputs. As they don't
608 * know what will happen with other uses, they do not take the risk of
609 * increasing the register pressure by creating or extending live ranges.
610 */
611
612 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
613 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
614 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
615 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
616 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
617 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
618 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
619 // CHECK-DAG: Return [ [[Or]] ]
620
621 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
622 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
623 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
624 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
625 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
626 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
627 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
628 // CHECK-DAG: Return [ [[Or]] ]
629
630 public static int NegSub2(int arg1, int arg2) {
631 int temp = arg1 - arg2;
632 return -temp | -temp;
633 }
634
635 /**
636 * Test simplification of the `~~var` pattern.
637 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
638 */
639
640 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
641 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
642 // CHECK-DAG: [[ConstF1:j\d+]] LongConstant -1
643 // CHECK-DAG: [[Xor1:j\d+]] Xor [ [[Arg]] [[ConstF1]] ]
644 // CHECK-DAG: [[Xor2:j\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
645 // CHECK-DAG: Return [ [[Xor2]] ]
646
647 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
648 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
649 // CHECK-DAG: Return [ [[Arg]] ]
650
651 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
652 // CHECK-NOT: Xor
653
654 public static long NotNot1(long arg) {
655 return ~~arg;
656 }
657
658 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
659 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
660 // CHECK-DAG: [[ConstF1:i\d+]] IntConstant -1
661 // CHECK-DAG: [[Xor1:i\d+]] Xor [ [[Arg]] [[ConstF1]] ]
662 // CHECK-DAG: [[Xor2:i\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
663 // CHECK-DAG: [[Add:i\d+]] Add [ [[Xor1]] [[Xor2]] ]
664 // CHECK-DAG: Return [ [[Add]] ]
665
666 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
667 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
668 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
669 // CHECK-DAG: [[Add:i\d+]] Add [ [[Not]] [[Arg]] ]
670 // CHECK-DAG: Return [ [[Add]] ]
671
672 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
673 // CHECK-NOT: Xor
674
675 public static int NotNot2(int arg) {
676 int temp = ~arg;
677 return temp + ~temp;
678 }
679
680 /**
681 * Test the simplification of a subtraction with a negated argument.
682 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
683 */
684
685 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
686 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
687 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
688 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
689 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
690 // CHECK-DAG: Return [ [[Sub]] ]
691
692 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
693 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
694 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
695 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
696 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
697 // CHECK-DAG: Return [ [[Neg]] ]
698
699 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
700 // CHECK-NOT: Sub
701
702 public static int SubNeg1(int arg1, int arg2) {
703 return -arg1 - arg2;
704 }
705
706 /**
707 * This is similar to the test-case SubNeg1, but the negation has
708 * multiple uses.
709 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
710 * The current code won't perform the previous optimization. The
711 * transformations do not look at other uses of their inputs. As they don't
712 * know what will happen with other uses, they do not take the risk of
713 * increasing the register pressure by creating or extending live ranges.
714 */
715
716 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
717 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
718 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
719 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
720 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
721 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
722 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
723 // CHECK-DAG: Return [ [[Or]] ]
724
725 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
726 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
727 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
728 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
729 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
730 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
731 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
732 // CHECK-DAG: Return [ [[Or]] ]
733
734 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
735 // CHECK-NOT: Add
736
737 public static int SubNeg2(int arg1, int arg2) {
738 int temp = -arg1;
739 return (temp - arg2) | (temp - arg2);
740 }
741
742 /**
743 * This follows test-cases SubNeg1 and SubNeg2.
744 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
745 * The optimization should not happen if it moves an additional instruction in
746 * the loop.
747 */
748
749 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
750 // -------------- Arguments and initial negation operation.
751 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
752 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
753 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
754 // CHECK: Goto
755 // -------------- Loop
756 // CHECK: SuspendCheck
757 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
758 // CHECK: Goto
759
760 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
761 // -------------- Arguments and initial negation operation.
762 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
763 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
764 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
765 // CHECK-DAG: Goto
766 // -------------- Loop
767 // CHECK: SuspendCheck
768 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
769 // CHECK-NOT: Neg
770 // CHECK: Goto
771
772 public static long SubNeg3(long arg1, long arg2) {
773 long res = 0;
774 long temp = -arg1;
775 for (long i = 0; i < 1; i++) {
776 res += temp - arg2 - i;
777 }
778 return res;
779 }
780
David Brazdil0d13fee2015-04-17 14:52:19 +0100781 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
782 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
783 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
784 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const1]] ]
785 // CHECK-DAG: If [ [[Cond]] ]
786
787 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
788 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
789 // CHECK-DAG: If [ [[Arg]] ]
790
791 public static int EqualTrueRhs(boolean arg) {
792 return (arg != true) ? 3 : 5;
793 }
794
795 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
796 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
797 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
798 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const1]] [[Arg]] ]
799 // CHECK-DAG: If [ [[Cond]] ]
800
801 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
802 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
803 // CHECK-DAG: If [ [[Arg]] ]
804
805 public static int EqualTrueLhs(boolean arg) {
806 return (true != arg) ? 3 : 5;
807 }
808
809 // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
810 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
811 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
812 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const0]] ]
813 // CHECK-DAG: If [ [[Cond]] ]
814
815 // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
816 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
817 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
818 // CHECK-DAG: If [ [[NotArg]] ]
819
820 public static int EqualFalseRhs(boolean arg) {
821 return (arg != false) ? 3 : 5;
822 }
823
824 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
825 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
826 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
827 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const0]] [[Arg]] ]
828 // CHECK-DAG: If [ [[Cond]] ]
829
830 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
831 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
832 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
833 // CHECK-DAG: If [ [[NotArg]] ]
834
835 public static int EqualFalseLhs(boolean arg) {
836 return (false != arg) ? 3 : 5;
837 }
838
839 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
840 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
841 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
842 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const1]] ]
843 // CHECK-DAG: If [ [[Cond]] ]
844
845 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
846 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
847 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
848 // CHECK-DAG: If [ [[NotArg]] ]
849
850 public static int NotEqualTrueRhs(boolean arg) {
851 return (arg == true) ? 3 : 5;
852 }
853
854 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
855 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
856 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
857 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const1]] [[Arg]] ]
858 // CHECK-DAG: If [ [[Cond]] ]
859
860 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
861 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
862 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
863 // CHECK-DAG: If [ [[NotArg]] ]
864
865 public static int NotEqualTrueLhs(boolean arg) {
866 return (true == arg) ? 3 : 5;
867 }
868
869 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
870 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
871 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
872 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const0]] ]
873 // CHECK-DAG: If [ [[Cond]] ]
874
875 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
876 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
877 // CHECK-DAG: If [ [[Arg]] ]
878
879 public static int NotEqualFalseRhs(boolean arg) {
880 return (arg == false) ? 3 : 5;
881 }
882
883 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
884 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
885 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
886 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const0]] [[Arg]] ]
887 // CHECK-DAG: If [ [[Cond]] ]
888
889 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
890 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
891 // CHECK-DAG: If [ [[Arg]] ]
892
893 public static int NotEqualFalseLhs(boolean arg) {
894 return (false == arg) ? 3 : 5;
895 }
896
897 /*
898 * Test simplification of double Boolean negation. Note that sometimes
899 * both negations can be removed but we only expect the simplifier to
900 * remove the second.
901 */
902
903 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
904 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
905 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
906 // CHECK-DAG: [[NotNotArg:z\d+]] BooleanNot [ [[NotArg]] ]
907 // CHECK-DAG: Return [ [[NotNotArg]] ]
908
909 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
910 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
911 // CHECK-DAG: BooleanNot [ [[Arg]] ]
912 // CHECK-DAG: Return [ [[Arg]] ]
913
914 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
915 // CHECK: BooleanNot
916 // CHECK-NOT: BooleanNot
917
918 public static boolean NotNotBool(boolean arg) {
919 return !(!arg);
920 }
921
Mark Mendellb0bd8912015-04-15 19:57:22 -0400922 // CHECK-START: float Main.Div2(float) instruction_simplifier (before)
923 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
924 // CHECK-DAG: [[Const2:f\d+]] FloatConstant 2
925 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[Const2]] ]
926 // CHECK-DAG: Return [ [[Div]] ]
927
928 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
929 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
930 // CHECK-DAG: [[ConstP5:f\d+]] FloatConstant 0.5
931 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstP5]] ]
932 // CHECK-DAG: Return [ [[Mul]] ]
933
934 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
935 // CHECK-NOT: Div
936
937 public static float Div2(float arg) {
938 return arg / 2.0f;
939 }
940
941 // CHECK-START: double Main.Div2(double) instruction_simplifier (before)
942 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
943 // CHECK-DAG: [[Const2:d\d+]] DoubleConstant 2
944 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[Const2]] ]
945 // CHECK-DAG: Return [ [[Div]] ]
946
947 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
948 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
949 // CHECK-DAG: [[ConstP5:d\d+]] DoubleConstant 0.5
950 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstP5]] ]
951 // CHECK-DAG: Return [ [[Mul]] ]
952
953 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
954 // CHECK-NOT: Div
955 public static double Div2(double arg) {
956 return arg / 2.0;
957 }
958
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000959 public static void main(String[] args) {
960 int arg = 123456;
961
962 assertLongEquals(Add0(arg), arg);
963 assertIntEquals(AndAllOnes(arg), arg);
964 assertLongEquals(Div1(arg), arg);
965 assertIntEquals(DivN1(arg), -arg);
966 assertLongEquals(Mul1(arg), arg);
967 assertIntEquals(MulN1(arg), -arg);
968 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
969 assertIntEquals(Or0(arg), arg);
970 assertLongEquals(OrSame(arg), arg);
971 assertIntEquals(Shl0(arg), arg);
972 assertLongEquals(Shr0(arg), arg);
973 assertLongEquals(Sub0(arg), arg);
974 assertIntEquals(SubAliasNeg(arg), -arg);
975 assertLongEquals(UShr0(arg), arg);
976 assertIntEquals(Xor0(arg), arg);
977 assertIntEquals(XorAllOnes(arg), ~arg);
Alexandre Rames188d4312015-04-09 18:30:21 +0100978 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
979 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
980 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
981 assertLongEquals(AddNeg1(arg, arg + 1), 1);
982 assertLongEquals(AddNeg2(arg, arg + 1), -1);
983 assertLongEquals(NegNeg1(arg), arg);
984 assertIntEquals(NegNeg2(arg), 0);
985 assertLongEquals(NegNeg3(arg), arg);
986 assertIntEquals(NegSub1(arg, arg + 1), 1);
987 assertIntEquals(NegSub2(arg, arg + 1), 1);
988 assertLongEquals(NotNot1(arg), arg);
989 assertIntEquals(NotNot2(arg), -1);
990 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
991 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
992 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
David Brazdil0d13fee2015-04-17 14:52:19 +0100993 assertIntEquals(EqualTrueRhs(true), 5);
994 assertIntEquals(EqualTrueLhs(true), 5);
995 assertIntEquals(EqualFalseRhs(true), 3);
996 assertIntEquals(EqualFalseLhs(true), 3);
997 assertIntEquals(NotEqualTrueRhs(true), 3);
998 assertIntEquals(NotEqualTrueLhs(true), 3);
999 assertIntEquals(NotEqualFalseRhs(true), 5);
1000 assertIntEquals(NotEqualFalseLhs(true), 5);
1001 assertBooleanEquals(NotNotBool(true), true);
1002 assertBooleanEquals(NotNotBool(false), false);
Mark Mendellb0bd8912015-04-15 19:57:22 -04001003 assertFloatEquals(Div2(100.0f), 50.0f);
1004 assertDoubleEquals(Div2(150.0), 75.0);
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001005 }
1006}