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