blob: efb7b83e333e160afce2ec7aa82de09295e1f409 [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
Mark Mendellba56d062015-05-05 21:34:03 -0400226 // CHECK-START: int Main.Shl1(int) instruction_simplifier (before)
227 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
228 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
229 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const1]] ]
230 // CHECK-DAG: Return [ [[Shl]] ]
231
232 // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
233 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
234 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg]] [[Arg]] ]
235 // CHECK-DAG: Return [ [[Add]] ]
236
237 // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
238 // CHECK-NOT: Shl
239
240 public static int Shl1(int arg) {
241 return arg << 1;
242 }
243
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000244 // CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
245 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
246 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
247 // CHECK-DAG: [[Shr:j\d+]] Shr [ [[Arg]] [[Const0]] ]
248 // CHECK-DAG: Return [ [[Shr]] ]
249
250 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
251 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000252 // CHECK-DAG: Return [ [[Arg]] ]
253
Alexandre Rames74417692015-04-09 15:21:41 +0100254 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
255 // CHECK-NOT: Shr
256
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000257 public static long Shr0(long arg) {
258 return arg >> 0;
259 }
260
261 // CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
262 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
263 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
264 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg]] [[Const0]] ]
265 // CHECK-DAG: Return [ [[Sub]] ]
266
267 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
268 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000269 // CHECK-DAG: Return [ [[Arg]] ]
270
Alexandre Rames74417692015-04-09 15:21:41 +0100271 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
272 // CHECK-NOT: Sub
273
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000274 public static long Sub0(long arg) {
275 return arg - 0;
276 }
277
278 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
279 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
280 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
281 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const0]] [[Arg]] ]
282 // CHECK-DAG: Return [ [[Sub]] ]
283
284 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
285 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
286 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000287 // CHECK-DAG: Return [ [[Neg]] ]
288
Alexandre Rames74417692015-04-09 15:21:41 +0100289 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
290 // CHECK-NOT: Sub
291
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000292 public static int SubAliasNeg(int arg) {
293 return 0 - arg;
294 }
295
296 // CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
297 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
298 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
299 // CHECK-DAG: [[UShr:j\d+]] UShr [ [[Arg]] [[Const0]] ]
300 // CHECK-DAG: Return [ [[UShr]] ]
301
302 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
303 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000304 // CHECK-DAG: Return [ [[Arg]] ]
305
Alexandre Rames74417692015-04-09 15:21:41 +0100306 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
307 // CHECK-NOT: UShr
308
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000309 public static long UShr0(long arg) {
310 return arg >>> 0;
311 }
312
313 // CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
314 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
315 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
316 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[Const0]] ]
317 // CHECK-DAG: Return [ [[Xor]] ]
318
319 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
320 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000321 // CHECK-DAG: Return [ [[Arg]] ]
322
Alexandre Rames74417692015-04-09 15:21:41 +0100323 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
324 // CHECK-NOT: Xor
325
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000326 public static int Xor0(int arg) {
327 return arg ^ 0;
328 }
329
330 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
331 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
332 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1
333 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[ConstF]] ]
334 // CHECK-DAG: Return [ [[Xor]] ]
335
336 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
337 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
338 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000339 // CHECK-DAG: Return [ [[Not]] ]
340
Alexandre Rames74417692015-04-09 15:21:41 +0100341 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
342 // CHECK-NOT: Xor
343
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000344 public static int XorAllOnes(int arg) {
345 return arg ^ -1;
346 }
347
Alexandre Rames188d4312015-04-09 18:30:21 +0100348 /**
349 * Test that addition or subtraction operation with both inputs negated are
350 * optimized to use a single negation after the operation.
351 * The transformation tested is implemented in
352 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
353 */
354
355 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
356 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
357 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
358 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
359 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
360 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
361 // CHECK-DAG: Return [ [[Add]] ]
362
363 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
364 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
365 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
366 // CHECK-NOT: Neg
367 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
368 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
369 // CHECK-DAG: Return [ [[Neg]] ]
370
371 public static int AddNegs1(int arg1, int arg2) {
372 return -arg1 + -arg2;
373 }
374
375 /**
376 * This is similar to the test-case AddNegs1, but the negations have
377 * multiple uses.
378 * The transformation tested is implemented in
379 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
380 * The current code won't perform the previous optimization. The
381 * transformations do not look at other uses of their inputs. As they don't
382 * know what will happen with other uses, they do not take the risk of
383 * increasing the register pressure by creating or extending live ranges.
384 */
385
386 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
387 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
388 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
389 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
390 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
391 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
392 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
393 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
394 // CHECK-DAG: Return [ [[Or]] ]
395
396 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
397 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
398 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
399 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
400 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
401 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
402 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
403 // CHECK-NOT: Neg
404 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ]
405 // CHECK-DAG: Return [ [[Or]] ]
406
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100407 // CHECK-START: int Main.AddNegs2(int, int) GVN (after)
408 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
409 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
410 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ]
411 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ]
412 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
413 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add]] [[Add]] ]
414 // CHECK-DAG: Return [ [[Or]] ]
415
Alexandre Rames188d4312015-04-09 18:30:21 +0100416 public static int AddNegs2(int arg1, int arg2) {
417 int temp1 = -arg1;
418 int temp2 = -arg2;
419 return (temp1 + temp2) | (temp1 + temp2);
420 }
421
422 /**
423 * This follows test-cases AddNegs1 and AddNegs2.
424 * The transformation tested is implemented in
425 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
426 * The optimization should not happen if it moves an additional instruction in
427 * the loop.
428 */
429
430 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
431 // -------------- Arguments and initial negation operations.
432 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
433 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
434 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
435 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
436 // CHECK: Goto
437 // -------------- Loop
438 // CHECK: SuspendCheck
439 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
440 // CHECK: Goto
441
442 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
443 // -------------- Arguments and initial negation operations.
444 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
445 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
446 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ]
447 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ]
448 // CHECK: Goto
449 // -------------- Loop
450 // CHECK: SuspendCheck
451 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ]
452 // CHECK-NOT: Neg
453 // CHECK: Goto
454
455 public static long AddNegs3(long arg1, long arg2) {
456 long res = 0;
457 long n_arg1 = -arg1;
458 long n_arg2 = -arg2;
459 for (long i = 0; i < 1; i++) {
460 res += n_arg1 + n_arg2 + i;
461 }
462 return res;
463 }
464
465 /**
466 * Test the simplification of an addition with a negated argument into a
467 * subtraction.
468 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
469 */
470
471 // CHECK-START: long Main.AddNeg1(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 [ [[Arg1]] ]
475 // CHECK-DAG: [[Add:j\d+]] Add [ [[Neg]] [[Arg2]] ]
476 // CHECK-DAG: Return [ [[Add]] ]
477
478 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
479 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
480 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
481 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg2]] [[Arg1]] ]
482 // CHECK-DAG: Return [ [[Sub]] ]
483
484 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
485 // CHECK-NOT: Neg
486 // CHECK-NOT: Add
487
488 public static long AddNeg1(long arg1, long arg2) {
489 return -arg1 + arg2;
490 }
491
492 /**
493 * This is similar to the test-case AddNeg1, but the negation has two uses.
494 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
495 * The current code won't perform the previous optimization. The
496 * transformations do not look at other uses of their inputs. As they don't
497 * know what will happen with other uses, they do not take the risk of
498 * increasing the register pressure by creating or extending live ranges.
499 */
500
501 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
502 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
503 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
504 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
505 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
506 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
507 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
508 // CHECK-DAG: Return [ [[Res]] ]
509
510 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
511 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
512 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
513 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ]
514 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ]
515 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ]
516 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ]
517 // CHECK-DAG: Return [ [[Res]] ]
518
519 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
520 // CHECK-NOT: Sub
521
522 public static long AddNeg2(long arg1, long arg2) {
523 long temp = -arg2;
524 return (arg1 + temp) | (arg1 + temp);
525 }
526
527 /**
528 * Test simplification of the `-(-var)` pattern.
529 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
530 */
531
532 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
533 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
534 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg]] ]
535 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Neg1]] ]
536 // CHECK-DAG: Return [ [[Neg2]] ]
537
538 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
539 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
540 // CHECK-DAG: Return [ [[Arg]] ]
541
542 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
543 // CHECK-NOT: Neg
544
545 public static long NegNeg1(long arg) {
546 return -(-arg);
547 }
548
549 /**
550 * Test 'multi-step' simplification, where a first transformation yields a
551 * new simplification possibility for the current instruction.
552 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
553 * and in `InstructionSimplifierVisitor::VisitAdd`.
554 */
555
556 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
557 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
558 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg]] ]
559 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Neg1]] ]
560 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ]
561 // CHECK-DAG: Return [ [[Add]] ]
562
563 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
564 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
565 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg]] [[Arg]] ]
566 // CHECK-DAG: Return [ [[Sub]] ]
567
568 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
569 // CHECK-NOT: Neg
570 // CHECK-NOT: Add
571
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100572 // CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
573 // CHECK: [[Const0:i\d+]] IntConstant 0
574 // CHECK-NOT: Neg
575 // CHECK-NOT: Add
576 // CHECK: Return [ [[Const0]] ]
577
Alexandre Rames188d4312015-04-09 18:30:21 +0100578 public static int NegNeg2(int arg) {
579 int temp = -arg;
580 return temp + -temp;
581 }
582
583 /**
584 * Test another 'multi-step' simplification, where a first transformation
585 * yields a new simplification possibility for the current instruction.
586 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
587 * and in `InstructionSimplifierVisitor::VisitSub`.
588 */
589
590 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
591 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
592 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0
593 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg]] ]
594 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const0]] [[Neg]] ]
595 // CHECK-DAG: Return [ [[Sub]] ]
596
597 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
598 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
599 // CHECK-DAG: Return [ [[Arg]] ]
600
601 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
602 // CHECK-NOT: Neg
603 // CHECK-NOT: Sub
604
605 public static long NegNeg3(long arg) {
606 return 0 - -arg;
607 }
608
609 /**
610 * Test that a negated subtraction is simplified to a subtraction with its
611 * arguments reversed.
612 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
613 */
614
615 // CHECK-START: int Main.NegSub1(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: [[Neg:i\d+]] Neg [ [[Sub]] ]
620 // CHECK-DAG: Return [ [[Neg]] ]
621
622 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
623 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
624 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
625 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg2]] [[Arg1]] ]
626 // CHECK-DAG: Return [ [[Sub]] ]
627
628 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
629 // CHECK-NOT: Neg
630
631 public static int NegSub1(int arg1, int arg2) {
632 return -(arg1 - arg2);
633 }
634
635 /**
636 * This is similar to the test-case NegSub1, but the subtraction has
637 * multiple uses.
638 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
639 * The current code won't perform the previous optimization. The
640 * transformations do not look at other uses of their inputs. As they don't
641 * know what will happen with other uses, they do not take the risk of
642 * increasing the register pressure by creating or extending live ranges.
643 */
644
645 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
646 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
647 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
648 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
649 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
650 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
651 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
652 // CHECK-DAG: Return [ [[Or]] ]
653
654 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
655 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
656 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
657 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ]
658 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ]
659 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ]
660 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ]
661 // CHECK-DAG: Return [ [[Or]] ]
662
663 public static int NegSub2(int arg1, int arg2) {
664 int temp = arg1 - arg2;
665 return -temp | -temp;
666 }
667
668 /**
669 * Test simplification of the `~~var` pattern.
670 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
671 */
672
673 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
674 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
675 // CHECK-DAG: [[ConstF1:j\d+]] LongConstant -1
676 // CHECK-DAG: [[Xor1:j\d+]] Xor [ [[Arg]] [[ConstF1]] ]
677 // CHECK-DAG: [[Xor2:j\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
678 // CHECK-DAG: Return [ [[Xor2]] ]
679
680 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
681 // CHECK-DAG: [[Arg:j\d+]] ParameterValue
682 // CHECK-DAG: Return [ [[Arg]] ]
683
684 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
685 // CHECK-NOT: Xor
686
687 public static long NotNot1(long arg) {
688 return ~~arg;
689 }
690
691 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
692 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
693 // CHECK-DAG: [[ConstF1:i\d+]] IntConstant -1
694 // CHECK-DAG: [[Xor1:i\d+]] Xor [ [[Arg]] [[ConstF1]] ]
695 // CHECK-DAG: [[Xor2:i\d+]] Xor [ [[Xor1]] [[ConstF1]] ]
696 // CHECK-DAG: [[Add:i\d+]] Add [ [[Xor1]] [[Xor2]] ]
697 // CHECK-DAG: Return [ [[Add]] ]
698
699 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
700 // CHECK-DAG: [[Arg:i\d+]] ParameterValue
701 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ]
702 // CHECK-DAG: [[Add:i\d+]] Add [ [[Not]] [[Arg]] ]
703 // CHECK-DAG: Return [ [[Add]] ]
704
705 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
706 // CHECK-NOT: Xor
707
708 public static int NotNot2(int arg) {
709 int temp = ~arg;
710 return temp + ~temp;
711 }
712
713 /**
714 * Test the simplification of a subtraction with a negated argument.
715 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
716 */
717
718 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
719 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
720 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
721 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
722 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
723 // CHECK-DAG: Return [ [[Sub]] ]
724
725 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
726 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
727 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
728 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ]
729 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ]
730 // CHECK-DAG: Return [ [[Neg]] ]
731
732 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
733 // CHECK-NOT: Sub
734
735 public static int SubNeg1(int arg1, int arg2) {
736 return -arg1 - arg2;
737 }
738
739 /**
740 * This is similar to the test-case SubNeg1, but the negation has
741 * multiple uses.
742 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
743 * The current code won't perform the previous optimization. The
744 * transformations do not look at other uses of their inputs. As they don't
745 * know what will happen with other uses, they do not take the risk of
746 * increasing the register pressure by creating or extending live ranges.
747 */
748
749 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
750 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
751 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
752 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
753 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
754 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
755 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
756 // CHECK-DAG: Return [ [[Or]] ]
757
758 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
759 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue
760 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue
761 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ]
762 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
763 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ]
764 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ]
765 // CHECK-DAG: Return [ [[Or]] ]
766
767 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
768 // CHECK-NOT: Add
769
770 public static int SubNeg2(int arg1, int arg2) {
771 int temp = -arg1;
772 return (temp - arg2) | (temp - arg2);
773 }
774
775 /**
776 * This follows test-cases SubNeg1 and SubNeg2.
777 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
778 * The optimization should not happen if it moves an additional instruction in
779 * the loop.
780 */
781
782 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
783 // -------------- Arguments and initial negation operation.
784 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
785 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
786 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
787 // CHECK: Goto
788 // -------------- Loop
789 // CHECK: SuspendCheck
790 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
791 // CHECK: Goto
792
793 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
794 // -------------- Arguments and initial negation operation.
795 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue
796 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue
797 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ]
798 // CHECK-DAG: Goto
799 // -------------- Loop
800 // CHECK: SuspendCheck
801 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ]
802 // CHECK-NOT: Neg
803 // CHECK: Goto
804
805 public static long SubNeg3(long arg1, long arg2) {
806 long res = 0;
807 long temp = -arg1;
808 for (long i = 0; i < 1; i++) {
809 res += temp - arg2 - i;
810 }
811 return res;
812 }
813
David Brazdil0d13fee2015-04-17 14:52:19 +0100814 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
815 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
816 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
817 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const1]] ]
818 // CHECK-DAG: If [ [[Cond]] ]
819
820 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
821 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
822 // CHECK-DAG: If [ [[Arg]] ]
823
824 public static int EqualTrueRhs(boolean arg) {
825 return (arg != true) ? 3 : 5;
826 }
827
828 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
829 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
830 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
831 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const1]] [[Arg]] ]
832 // CHECK-DAG: If [ [[Cond]] ]
833
834 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
835 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
836 // CHECK-DAG: If [ [[Arg]] ]
837
838 public static int EqualTrueLhs(boolean arg) {
839 return (true != arg) ? 3 : 5;
840 }
841
842 // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
843 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
844 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
845 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const0]] ]
846 // CHECK-DAG: If [ [[Cond]] ]
847
848 // CHECK-START: int Main.EqualFalseRhs(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 EqualFalseRhs(boolean arg) {
854 return (arg != false) ? 3 : 5;
855 }
856
857 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
858 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
859 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
860 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const0]] [[Arg]] ]
861 // CHECK-DAG: If [ [[Cond]] ]
862
863 // CHECK-START: int Main.EqualFalseLhs(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 EqualFalseLhs(boolean arg) {
869 return (false != arg) ? 3 : 5;
870 }
871
872 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
873 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
874 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
875 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const1]] ]
876 // CHECK-DAG: If [ [[Cond]] ]
877
878 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
879 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
880 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
881 // CHECK-DAG: If [ [[NotArg]] ]
882
883 public static int NotEqualTrueRhs(boolean arg) {
884 return (arg == true) ? 3 : 5;
885 }
886
887 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
888 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
889 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
890 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const1]] [[Arg]] ]
891 // CHECK-DAG: If [ [[Cond]] ]
892
893 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
894 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
895 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
896 // CHECK-DAG: If [ [[NotArg]] ]
897
898 public static int NotEqualTrueLhs(boolean arg) {
899 return (true == arg) ? 3 : 5;
900 }
901
902 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
903 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
904 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
905 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const0]] ]
906 // CHECK-DAG: If [ [[Cond]] ]
907
908 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
909 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
910 // CHECK-DAG: If [ [[Arg]] ]
911
912 public static int NotEqualFalseRhs(boolean arg) {
913 return (arg == false) ? 3 : 5;
914 }
915
916 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
917 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
918 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
919 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const0]] [[Arg]] ]
920 // CHECK-DAG: If [ [[Cond]] ]
921
922 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
923 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
924 // CHECK-DAG: If [ [[Arg]] ]
925
926 public static int NotEqualFalseLhs(boolean arg) {
927 return (false == arg) ? 3 : 5;
928 }
929
930 /*
931 * Test simplification of double Boolean negation. Note that sometimes
932 * both negations can be removed but we only expect the simplifier to
933 * remove the second.
934 */
935
936 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
937 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
938 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ]
939 // CHECK-DAG: [[NotNotArg:z\d+]] BooleanNot [ [[NotArg]] ]
940 // CHECK-DAG: Return [ [[NotNotArg]] ]
941
942 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
943 // CHECK-DAG: [[Arg:z\d+]] ParameterValue
944 // CHECK-DAG: BooleanNot [ [[Arg]] ]
945 // CHECK-DAG: Return [ [[Arg]] ]
946
947 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
948 // CHECK: BooleanNot
949 // CHECK-NOT: BooleanNot
950
David Brazdil769c9e52015-04-27 13:54:09 +0100951 public static boolean NegateValue(boolean arg) {
952 return !arg;
953 }
954
David Brazdil0d13fee2015-04-17 14:52:19 +0100955 public static boolean NotNotBool(boolean arg) {
David Brazdil769c9e52015-04-27 13:54:09 +0100956 return !(NegateValue(arg));
David Brazdil0d13fee2015-04-17 14:52:19 +0100957 }
958
Nicolas Geoffray0d221842015-04-27 08:53:46 +0000959 // CHECK-START: float Main.Div2(float) instruction_simplifier (before)
960 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
961 // CHECK-DAG: [[Const2:f\d+]] FloatConstant 2
962 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[Const2]] ]
963 // CHECK-DAG: Return [ [[Div]] ]
964
965 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
966 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
967 // CHECK-DAG: [[ConstP5:f\d+]] FloatConstant 0.5
968 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstP5]] ]
969 // CHECK-DAG: Return [ [[Mul]] ]
970
971 // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
972 // CHECK-NOT: Div
973
974 public static float Div2(float arg) {
975 return arg / 2.0f;
976 }
977
978 // CHECK-START: double Main.Div2(double) instruction_simplifier (before)
979 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
980 // CHECK-DAG: [[Const2:d\d+]] DoubleConstant 2
981 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[Const2]] ]
982 // CHECK-DAG: Return [ [[Div]] ]
983
984 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
985 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
986 // CHECK-DAG: [[ConstP5:d\d+]] DoubleConstant 0.5
987 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstP5]] ]
988 // CHECK-DAG: Return [ [[Mul]] ]
989
990 // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
991 // CHECK-NOT: Div
992 public static double Div2(double arg) {
993 return arg / 2.0;
994 }
995
996 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
997 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
998 // CHECK-DAG: [[ConstMP25:f\d+]] FloatConstant -0.25
999 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[ConstMP25]] ]
1000 // CHECK-DAG: Return [ [[Div]] ]
1001
1002 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1003 // CHECK-DAG: [[Arg:f\d+]] ParameterValue
1004 // CHECK-DAG: [[ConstM4:f\d+]] FloatConstant -4
1005 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstM4]] ]
1006 // CHECK-DAG: Return [ [[Mul]] ]
1007
1008 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1009 // CHECK-NOT: Div
1010
1011 public static float DivMP25(float arg) {
1012 return arg / -0.25f;
1013 }
1014
1015 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
1016 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
1017 // CHECK-DAG: [[ConstMP25:d\d+]] DoubleConstant -0.25
1018 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[ConstMP25]] ]
1019 // CHECK-DAG: Return [ [[Div]] ]
1020
1021 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1022 // CHECK-DAG: [[Arg:d\d+]] ParameterValue
1023 // CHECK-DAG: [[ConstM4:d\d+]] DoubleConstant -4
1024 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstM4]] ]
1025 // CHECK-DAG: Return [ [[Mul]] ]
1026
1027 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1028 // CHECK-NOT: Div
1029 public static double DivMP25(double arg) {
1030 return arg / -0.25f;
1031 }
1032
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001033 public static void main(String[] args) {
1034 int arg = 123456;
1035
1036 assertLongEquals(Add0(arg), arg);
1037 assertIntEquals(AndAllOnes(arg), arg);
1038 assertLongEquals(Div1(arg), arg);
1039 assertIntEquals(DivN1(arg), -arg);
1040 assertLongEquals(Mul1(arg), arg);
1041 assertIntEquals(MulN1(arg), -arg);
1042 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
1043 assertIntEquals(Or0(arg), arg);
1044 assertLongEquals(OrSame(arg), arg);
1045 assertIntEquals(Shl0(arg), arg);
1046 assertLongEquals(Shr0(arg), arg);
1047 assertLongEquals(Sub0(arg), arg);
1048 assertIntEquals(SubAliasNeg(arg), -arg);
1049 assertLongEquals(UShr0(arg), arg);
1050 assertIntEquals(Xor0(arg), arg);
1051 assertIntEquals(XorAllOnes(arg), ~arg);
Alexandre Rames188d4312015-04-09 18:30:21 +01001052 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
1053 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
1054 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
1055 assertLongEquals(AddNeg1(arg, arg + 1), 1);
1056 assertLongEquals(AddNeg2(arg, arg + 1), -1);
1057 assertLongEquals(NegNeg1(arg), arg);
1058 assertIntEquals(NegNeg2(arg), 0);
1059 assertLongEquals(NegNeg3(arg), arg);
1060 assertIntEquals(NegSub1(arg, arg + 1), 1);
1061 assertIntEquals(NegSub2(arg, arg + 1), 1);
1062 assertLongEquals(NotNot1(arg), arg);
1063 assertIntEquals(NotNot2(arg), -1);
1064 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
1065 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
1066 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
David Brazdil0d13fee2015-04-17 14:52:19 +01001067 assertIntEquals(EqualTrueRhs(true), 5);
1068 assertIntEquals(EqualTrueLhs(true), 5);
1069 assertIntEquals(EqualFalseRhs(true), 3);
1070 assertIntEquals(EqualFalseLhs(true), 3);
1071 assertIntEquals(NotEqualTrueRhs(true), 3);
1072 assertIntEquals(NotEqualTrueLhs(true), 3);
1073 assertIntEquals(NotEqualFalseRhs(true), 5);
1074 assertIntEquals(NotEqualFalseLhs(true), 5);
1075 assertBooleanEquals(NotNotBool(true), true);
1076 assertBooleanEquals(NotNotBool(false), false);
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001077 assertFloatEquals(Div2(100.0f), 50.0f);
1078 assertDoubleEquals(Div2(150.0), 75.0);
1079 assertFloatEquals(DivMP25(100.0f), -400.0f);
1080 assertDoubleEquals(DivMP25(150.0), -600.0);
Mark Mendellba56d062015-05-05 21:34:03 -04001081 assertLongEquals(Shl1(100), 200);
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001082 }
1083}