blob: 5d5a6b3627901a7387e92de079fbb59da644f60e [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
Nicolas Geoffray0d221842015-04-27 08:53:46 +000037 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
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100389 // CHECK-START: int Main.AddNegs2(int, int) GVN (after)
390 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
391 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
392 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
393 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
394 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
395 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add]] [[Add]] ]
396 // CHECK-DAG: Return [ [[Or]] ]
397
Alexandre Rames188d4312015-04-09 18:30:21 +0100398 public static int AddNegs2(int arg1, int arg2) {
399 int temp1 = -arg1;
400 int temp2 = -arg2;
401 return (temp1 + temp2) | (temp1 + temp2);
402 }
403
404 /**
405 * This follows test-cases AddNegs1 and AddNegs2.
406 * The transformation tested is implemented in
407 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
408 * The optimization should not happen if it moves an additional instruction in
409 * the loop.
410 */
411
412 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
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: Goto
423
424 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
425 // -------------- Arguments and initial negation operations.
426 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
427 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
428 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
429 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
430 // CHECK: Goto
431 // -------------- Loop
432 // CHECK: SuspendCheck
433 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
434 // CHECK-NOT: Neg
435 // CHECK: Goto
436
437 public static long AddNegs3(long arg1, long arg2) {
438 long res = 0;
439 long n_arg1 = -arg1;
440 long n_arg2 = -arg2;
441 for (long i = 0; i < 1; i++) {
442 res += n_arg1 + n_arg2 + i;
443 }
444 return res;
445 }
446
447 /**
448 * Test the simplification of an addition with a negated argument into a
449 * subtraction.
450 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
451 */
452
453 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
454 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
455 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
456 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
457 // CHECK-DAG: [[Add:j\d+]] Add [ [[Neg]] [[Arg2]] ]
458 // CHECK-DAG: Return [ [[Add]] ]
459
460 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
461 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
462 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
463 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg2]] [[Arg1]] ]
464 // CHECK-DAG: Return [ [[Sub]] ]
465
466 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
467 // CHECK-NOT: Neg
468 // CHECK-NOT: Add
469
470 public static long AddNeg1(long arg1, long arg2) {
471 return -arg1 + arg2;
472 }
473
474 /**
475 * This is similar to the test-case AddNeg1, but the negation has two uses.
476 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
477 * The current code won't perform the previous optimization. The
478 * transformations do not look at other uses of their inputs. As they don't
479 * know what will happen with other uses, they do not take the risk of
480 * increasing the register pressure by creating or extending live ranges.
481 */
482
483 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
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-DAG: [[Arg1:j\d+]] ParameterValue
494 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
495 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
496 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
497 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
498 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
499 // CHECK-DAG: Return [ [[Res]] ]
500
501 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
502 // CHECK-NOT: Sub
503
504 public static long AddNeg2(long arg1, long arg2) {
505 long temp = -arg2;
506 return (arg1 + temp) | (arg1 + temp);
507 }
508
509 /**
510 * Test simplification of the `-(-var)` pattern.
511 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
512 */
513
514 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
515 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
516 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg]] ]
517 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Neg1]] ]
518 // CHECK-DAG: Return [ [[Neg2]] ]
519
520 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
521 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
522 // CHECK-DAG: Return [ [[Arg]] ]
523
524 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
525 // CHECK-NOT: Neg
526
527 public static long NegNeg1(long arg) {
528 return -(-arg);
529 }
530
531 /**
532 * Test 'multi-step' simplification, where a first transformation yields a
533 * new simplification possibility for the current instruction.
534 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
535 * and in `InstructionSimplifierVisitor::VisitAdd`.
536 */
537
538 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
539 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
540 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg]] ]
541 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Neg1]] ]
542 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
543 // CHECK-DAG: Return [ [[Add]] ]
544
545 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
546 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
547 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg]] [[Arg]] ]
548 // CHECK-DAG: Return [ [[Sub]] ]
549
550 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
551 // CHECK-NOT: Neg
552 // CHECK-NOT: Add
553
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100554 // CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
555 // CHECK: [[Const0:i\d+]] IntConstant 0
556 // CHECK-NOT: Neg
557 // CHECK-NOT: Add
558 // CHECK: Return [ [[Const0]] ]
559
Alexandre Rames188d4312015-04-09 18:30:21 +0100560 public static int NegNeg2(int arg) {
561 int temp = -arg;
562 return temp + -temp;
563 }
564
565 /**
566 * Test another 'multi-step' simplification, where a first transformation
567 * yields a new simplification possibility for the current instruction.
568 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
569 * and in `InstructionSimplifierVisitor::VisitSub`.
570 */
571
572 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
573 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
574 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
575 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg]] ]
576 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const0]] [[Neg]] ]
577 // CHECK-DAG: Return [ [[Sub]] ]
578
579 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
580 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
581 // CHECK-DAG: Return [ [[Arg]] ]
582
583 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
584 // CHECK-NOT: Neg
585 // CHECK-NOT: Sub
586
587 public static long NegNeg3(long arg) {
588 return 0 - -arg;
589 }
590
591 /**
592 * Test that a negated subtraction is simplified to a subtraction with its
593 * arguments reversed.
594 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
595 */
596
597 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
598 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
599 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
600 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
601 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Sub]] ]
602 // CHECK-DAG: Return [ [[Neg]] ]
603
604 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
605 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
606 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
607 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg2]] [[Arg1]] ]
608 // CHECK-DAG: Return [ [[Sub]] ]
609
610 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
611 // CHECK-NOT: Neg
612
613 public static int NegSub1(int arg1, int arg2) {
614 return -(arg1 - arg2);
615 }
616
617 /**
618 * This is similar to the test-case NegSub1, but the subtraction has
619 * multiple uses.
620 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
621 * The current code won't perform the previous optimization. The
622 * transformations do not look at other uses of their inputs. As they don't
623 * know what will happen with other uses, they do not take the risk of
624 * increasing the register pressure by creating or extending live ranges.
625 */
626
627 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
628 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
629 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
630 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
631 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
632 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
633 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
634 // CHECK-DAG: Return [ [[Or]] ]
635
636 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
637 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
638 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
639 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
640 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
641 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
642 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
643 // CHECK-DAG: Return [ [[Or]] ]
644
645 public static int NegSub2(int arg1, int arg2) {
646 int temp = arg1 - arg2;
647 return -temp | -temp;
648 }
649
650 /**
651 * Test simplification of the `~~var` pattern.
652 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
653 */
654
655 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
656 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
657 // CHECK-DAG: [[ConstF1:j\d+]] LongConstant -1
658 // CHECK-DAG: [[Xor1:j\d+]] Xor [ [[Arg]] [[ConstF1]] ]
659 // CHECK-DAG: [[Xor2:j\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
660 // CHECK-DAG: Return [ [[Xor2]] ]
661
662 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
663 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
664 // CHECK-DAG: Return [ [[Arg]] ]
665
666 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
667 // CHECK-NOT: Xor
668
669 public static long NotNot1(long arg) {
670 return ~~arg;
671 }
672
673 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
674 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
675 // CHECK-DAG: [[ConstF1:i\d+]] IntConstant -1
676 // CHECK-DAG: [[Xor1:i\d+]] Xor [ [[Arg]] [[ConstF1]] ]
677 // CHECK-DAG: [[Xor2:i\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
678 // CHECK-DAG: [[Add:i\d+]] Add [ [[Xor1]] [[Xor2]] ]
679 // CHECK-DAG: Return [ [[Add]] ]
680
681 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
682 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
683 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
684 // CHECK-DAG: [[Add:i\d+]] Add [ [[Not]] [[Arg]] ]
685 // CHECK-DAG: Return [ [[Add]] ]
686
687 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
688 // CHECK-NOT: Xor
689
690 public static int NotNot2(int arg) {
691 int temp = ~arg;
692 return temp + ~temp;
693 }
694
695 /**
696 * Test the simplification of a subtraction with a negated argument.
697 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
698 */
699
700 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
701 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
702 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
703 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
704 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
705 // CHECK-DAG: Return [ [[Sub]] ]
706
707 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
708 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
709 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
710 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
711 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
712 // CHECK-DAG: Return [ [[Neg]] ]
713
714 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
715 // CHECK-NOT: Sub
716
717 public static int SubNeg1(int arg1, int arg2) {
718 return -arg1 - arg2;
719 }
720
721 /**
722 * This is similar to the test-case SubNeg1, but the negation has
723 * multiple uses.
724 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
725 * The current code won't perform the previous optimization. The
726 * transformations do not look at other uses of their inputs. As they don't
727 * know what will happen with other uses, they do not take the risk of
728 * increasing the register pressure by creating or extending live ranges.
729 */
730
731 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
732 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
733 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
734 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
735 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
736 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
737 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
738 // CHECK-DAG: Return [ [[Or]] ]
739
740 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
741 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
742 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
743 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
744 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
745 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
746 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
747 // CHECK-DAG: Return [ [[Or]] ]
748
749 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
750 // CHECK-NOT: Add
751
752 public static int SubNeg2(int arg1, int arg2) {
753 int temp = -arg1;
754 return (temp - arg2) | (temp - arg2);
755 }
756
757 /**
758 * This follows test-cases SubNeg1 and SubNeg2.
759 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
760 * The optimization should not happen if it moves an additional instruction in
761 * the loop.
762 */
763
764 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
765 // -------------- Arguments and initial negation operation.
766 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
767 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
768 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
769 // CHECK: Goto
770 // -------------- Loop
771 // CHECK: SuspendCheck
772 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
773 // CHECK: Goto
774
775 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
776 // -------------- Arguments and initial negation operation.
777 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
778 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
779 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
780 // CHECK-DAG: Goto
781 // -------------- Loop
782 // CHECK: SuspendCheck
783 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
784 // CHECK-NOT: Neg
785 // CHECK: Goto
786
787 public static long SubNeg3(long arg1, long arg2) {
788 long res = 0;
789 long temp = -arg1;
790 for (long i = 0; i < 1; i++) {
791 res += temp - arg2 - i;
792 }
793 return res;
794 }
795
David Brazdil0d13fee2015-04-17 14:52:19 +0100796 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
797 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
798 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
799 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const1]] ]
800 // CHECK-DAG: If [ [[Cond]] ]
801
802 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
803 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
804 // CHECK-DAG: If [ [[Arg]] ]
805
806 public static int EqualTrueRhs(boolean arg) {
807 return (arg != true) ? 3 : 5;
808 }
809
810 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
811 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
812 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
813 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const1]] [[Arg]] ]
814 // CHECK-DAG: If [ [[Cond]] ]
815
816 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
817 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
818 // CHECK-DAG: If [ [[Arg]] ]
819
820 public static int EqualTrueLhs(boolean arg) {
821 return (true != arg) ? 3 : 5;
822 }
823
824 // CHECK-START: int Main.EqualFalseRhs(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 [ [[Arg]] [[Const0]] ]
828 // CHECK-DAG: If [ [[Cond]] ]
829
830 // CHECK-START: int Main.EqualFalseRhs(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 EqualFalseRhs(boolean arg) {
836 return (arg != false) ? 3 : 5;
837 }
838
839 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
840 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
841 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
842 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const0]] [[Arg]] ]
843 // CHECK-DAG: If [ [[Cond]] ]
844
845 // CHECK-START: int Main.EqualFalseLhs(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 EqualFalseLhs(boolean arg) {
851 return (false != arg) ? 3 : 5;
852 }
853
854 // CHECK-START: int Main.NotEqualTrueRhs(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 [ [[Arg]] [[Const1]] ]
858 // CHECK-DAG: If [ [[Cond]] ]
859
860 // CHECK-START: int Main.NotEqualTrueRhs(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 NotEqualTrueRhs(boolean arg) {
866 return (arg == true) ? 3 : 5;
867 }
868
869 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
870 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
871 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
872 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const1]] [[Arg]] ]
873 // CHECK-DAG: If [ [[Cond]] ]
874
875 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
876 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
877 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
878 // CHECK-DAG: If [ [[NotArg]] ]
879
880 public static int NotEqualTrueLhs(boolean arg) {
881 return (true == arg) ? 3 : 5;
882 }
883
884 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
885 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
886 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
887 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const0]] ]
888 // CHECK-DAG: If [ [[Cond]] ]
889
890 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
891 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
892 // CHECK-DAG: If [ [[Arg]] ]
893
894 public static int NotEqualFalseRhs(boolean arg) {
895 return (arg == false) ? 3 : 5;
896 }
897
898 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
899 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
900 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
901 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const0]] [[Arg]] ]
902 // CHECK-DAG: If [ [[Cond]] ]
903
904 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
905 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
906 // CHECK-DAG: If [ [[Arg]] ]
907
908 public static int NotEqualFalseLhs(boolean arg) {
909 return (false == arg) ? 3 : 5;
910 }
911
912 /*
913 * Test simplification of double Boolean negation. Note that sometimes
914 * both negations can be removed but we only expect the simplifier to
915 * remove the second.
916 */
917
918 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
919 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
920 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
921 // CHECK-DAG: [[NotNotArg:z\d+]] BooleanNot [ [[NotArg]] ]
922 // CHECK-DAG: Return [ [[NotNotArg]] ]
923
924 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
925 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
926 // CHECK-DAG: BooleanNot [ [[Arg]] ]
927 // CHECK-DAG: Return [ [[Arg]] ]
928
929 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
930 // CHECK: BooleanNot
931 // CHECK-NOT: BooleanNot
932
David Brazdil769c9e52015-04-27 13:54:09 +0100933 public static boolean NegateValue(boolean arg) {
934 return !arg;
935 }
936
David Brazdil0d13fee2015-04-17 14:52:19 +0100937 public static boolean NotNotBool(boolean arg) {
David Brazdil769c9e52015-04-27 13:54:09 +0100938 return !(NegateValue(arg));
David Brazdil0d13fee2015-04-17 14:52:19 +0100939 }
940
Nicolas Geoffray0d221842015-04-27 08:53:46 +0000941 // CHECK-START: float Main.Div2(float) instruction_simplifier (before)
942 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
943 // CHECK-DAG: [[Const2:f\d+]] FloatConstant 2
944 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[Const2]] ]
945 // CHECK-DAG: Return [ [[Div]] ]
946
947 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
948 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
949 // CHECK-DAG: [[ConstP5:f\d+]] FloatConstant 0.5
950 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstP5]] ]
951 // CHECK-DAG: Return [ [[Mul]] ]
952
953 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
954 // CHECK-NOT: Div
955
956 public static float Div2(float arg) {
957 return arg / 2.0f;
958 }
959
960 // CHECK-START: double Main.Div2(double) instruction_simplifier (before)
961 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
962 // CHECK-DAG: [[Const2:d\d+]] DoubleConstant 2
963 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[Const2]] ]
964 // CHECK-DAG: Return [ [[Div]] ]
965
966 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
967 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
968 // CHECK-DAG: [[ConstP5:d\d+]] DoubleConstant 0.5
969 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstP5]] ]
970 // CHECK-DAG: Return [ [[Mul]] ]
971
972 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
973 // CHECK-NOT: Div
974 public static double Div2(double arg) {
975 return arg / 2.0;
976 }
977
978 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
979 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
980 // CHECK-DAG: [[ConstMP25:f\d+]] FloatConstant -0.25
981 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[ConstMP25]] ]
982 // CHECK-DAG: Return [ [[Div]] ]
983
984 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
985 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
986 // CHECK-DAG: [[ConstM4:f\d+]] FloatConstant -4
987 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstM4]] ]
988 // CHECK-DAG: Return [ [[Mul]] ]
989
990 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
991 // CHECK-NOT: Div
992
993 public static float DivMP25(float arg) {
994 return arg / -0.25f;
995 }
996
997 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
998 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
999 // CHECK-DAG: [[ConstMP25:d\d+]] DoubleConstant -0.25
1000 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[ConstMP25]] ]
1001 // CHECK-DAG: Return [ [[Div]] ]
1002
1003 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1004 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
1005 // CHECK-DAG: [[ConstM4:d\d+]] DoubleConstant -4
1006 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstM4]] ]
1007 // CHECK-DAG: Return [ [[Mul]] ]
1008
1009 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1010 // CHECK-NOT: Div
1011 public static double DivMP25(double arg) {
1012 return arg / -0.25f;
1013 }
1014
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001015 public static void main(String[] args) {
1016 int arg = 123456;
1017
1018 assertLongEquals(Add0(arg), arg);
1019 assertIntEquals(AndAllOnes(arg), arg);
1020 assertLongEquals(Div1(arg), arg);
1021 assertIntEquals(DivN1(arg), -arg);
1022 assertLongEquals(Mul1(arg), arg);
1023 assertIntEquals(MulN1(arg), -arg);
1024 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
1025 assertIntEquals(Or0(arg), arg);
1026 assertLongEquals(OrSame(arg), arg);
1027 assertIntEquals(Shl0(arg), arg);
1028 assertLongEquals(Shr0(arg), arg);
1029 assertLongEquals(Sub0(arg), arg);
1030 assertIntEquals(SubAliasNeg(arg), -arg);
1031 assertLongEquals(UShr0(arg), arg);
1032 assertIntEquals(Xor0(arg), arg);
1033 assertIntEquals(XorAllOnes(arg), ~arg);
Alexandre Rames188d4312015-04-09 18:30:21 +01001034 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
1035 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
1036 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
1037 assertLongEquals(AddNeg1(arg, arg + 1), 1);
1038 assertLongEquals(AddNeg2(arg, arg + 1), -1);
1039 assertLongEquals(NegNeg1(arg), arg);
1040 assertIntEquals(NegNeg2(arg), 0);
1041 assertLongEquals(NegNeg3(arg), arg);
1042 assertIntEquals(NegSub1(arg, arg + 1), 1);
1043 assertIntEquals(NegSub2(arg, arg + 1), 1);
1044 assertLongEquals(NotNot1(arg), arg);
1045 assertIntEquals(NotNot2(arg), -1);
1046 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
1047 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
1048 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
David Brazdil0d13fee2015-04-17 14:52:19 +01001049 assertIntEquals(EqualTrueRhs(true), 5);
1050 assertIntEquals(EqualTrueLhs(true), 5);
1051 assertIntEquals(EqualFalseRhs(true), 3);
1052 assertIntEquals(EqualFalseLhs(true), 3);
1053 assertIntEquals(NotEqualTrueRhs(true), 3);
1054 assertIntEquals(NotEqualTrueLhs(true), 3);
1055 assertIntEquals(NotEqualFalseRhs(true), 5);
1056 assertIntEquals(NotEqualFalseLhs(true), 5);
1057 assertBooleanEquals(NotNotBool(true), true);
1058 assertBooleanEquals(NotNotBool(false), false);
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001059 assertFloatEquals(Div2(100.0f), 50.0f);
1060 assertDoubleEquals(Div2(150.0), 75.0);
1061 assertFloatEquals(DivMP25(100.0f), -400.0f);
1062 assertDoubleEquals(DivMP25(150.0), -600.0);
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001063 }
1064}