1 /*
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
17 import java.lang.reflect.Method;
18
19 public class Main {
20
assertBooleanEquals(boolean expected, boolean result)21 public static void assertBooleanEquals(boolean expected, boolean result) {
22 if (expected != result) {
23 throw new Error("Expected: " + expected + ", found: " + result);
24 }
25 }
26
assertIntEquals(int expected, int result)27 public static void assertIntEquals(int expected, int result) {
28 if (expected != result) {
29 throw new Error("Expected: " + expected + ", found: " + result);
30 }
31 }
32
assertLongEquals(long expected, long result)33 public static void assertLongEquals(long expected, long result) {
34 if (expected != result) {
35 throw new Error("Expected: " + expected + ", found: " + result);
36 }
37 }
38
assertFloatEquals(float expected, float result)39 public static void assertFloatEquals(float expected, float result) {
40 if (expected != result) {
41 throw new Error("Expected: " + expected + ", found: " + result);
42 }
43 }
44
assertDoubleEquals(double expected, double result)45 public static void assertDoubleEquals(double expected, double result) {
46 if (expected != result) {
47 throw new Error("Expected: " + expected + ", found: " + result);
48 }
49 }
50
assertStringEquals(String expected, String result)51 public static void assertStringEquals(String expected, String result) {
52 if (expected == null ? result != null : !expected.equals(result)) {
53 throw new Error("Expected: " + expected + ", found: " + result);
54 }
55 }
56
57 /**
58 * Tiny programs exercising optimizations of arithmetic identities.
59 */
60
61 /// CHECK-START: long Main.Add0(long) instruction_simplifier (before)
62 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
63 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
64 /// CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>]
65 /// CHECK-DAG: Return [<<Add>>]
66
67 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
68 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
69 /// CHECK-DAG: Return [<<Arg>>]
70
71 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
72 /// CHECK-NOT: Add
73
Add0(long arg)74 public static long Add0(long arg) {
75 return 0 + arg;
76 }
77
78 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
79 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
80 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
81 /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>]
82 /// CHECK-DAG: Return [<<And>>]
83
84 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
85 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
86 /// CHECK-DAG: Return [<<Arg>>]
87
88 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
89 /// CHECK-NOT: And
90
AndAllOnes(int arg)91 public static int AndAllOnes(int arg) {
92 return arg & -1;
93 }
94
95 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (before)
96 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
97 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
98 /// CHECK-DAG: <<Const15:i\d+>> IntConstant 15
99 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
100 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const15>>]
101 /// CHECK-DAG: Return [<<And>>]
102
103 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after)
104 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
105 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
106 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
107 /// CHECK-DAG: Return [<<UShr>>]
108
109 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after)
110 /// CHECK-NOT: And
111
UShr28And15(int arg)112 public static int UShr28And15(int arg) {
113 return (arg >>> 28) & 15;
114 }
115
116 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (before)
117 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
118 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
119 /// CHECK-DAG: <<Const15:j\d+>> LongConstant 15
120 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
121 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const15>>]
122 /// CHECK-DAG: Return [<<And>>]
123
124 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after)
125 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
126 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
127 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
128 /// CHECK-DAG: Return [<<UShr>>]
129
130 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after)
131 /// CHECK-NOT: And
132
UShr60And15(long arg)133 public static long UShr60And15(long arg) {
134 return (arg >>> 60) & 15;
135 }
136
137 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (before)
138 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
139 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
140 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
141 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
142 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>]
143 /// CHECK-DAG: Return [<<And>>]
144
145 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (after)
146 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
147 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
148 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
149 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
150 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>]
151 /// CHECK-DAG: Return [<<And>>]
152
UShr28And7(int arg)153 public static int UShr28And7(int arg) {
154 return (arg >>> 28) & 7;
155 }
156
157 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (before)
158 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
159 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
160 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7
161 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
162 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>]
163 /// CHECK-DAG: Return [<<And>>]
164
165 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (after)
166 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
167 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
168 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7
169 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
170 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>]
171 /// CHECK-DAG: Return [<<And>>]
172
UShr60And7(long arg)173 public static long UShr60And7(long arg) {
174 return (arg >>> 60) & 7;
175 }
176
177 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (before)
178 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
179 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
180 /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255
181 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
182 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const255>>]
183 /// CHECK-DAG: Return [<<And>>]
184
185 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after)
186 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
187 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
188 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const24>>]
189 /// CHECK-DAG: Return [<<UShr>>]
190
191 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after)
192 /// CHECK-NOT: Shr
193 /// CHECK-NOT: And
194
Shr24And255(int arg)195 public static int Shr24And255(int arg) {
196 return (arg >> 24) & 255;
197 }
198
199 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (before)
200 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
201 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
202 /// CHECK-DAG: <<Const255:j\d+>> LongConstant 255
203 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
204 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const255>>]
205 /// CHECK-DAG: Return [<<And>>]
206
207 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after)
208 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
209 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
210 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const56>>]
211 /// CHECK-DAG: Return [<<UShr>>]
212
213 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after)
214 /// CHECK-NOT: Shr
215 /// CHECK-NOT: And
216
Shr56And255(long arg)217 public static long Shr56And255(long arg) {
218 return (arg >> 56) & 255;
219 }
220
221 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (before)
222 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
223 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
224 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127
225 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
226 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>]
227 /// CHECK-DAG: Return [<<And>>]
228
229 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (after)
230 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
231 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
232 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127
233 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
234 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>]
235 /// CHECK-DAG: Return [<<And>>]
236
Shr24And127(int arg)237 public static int Shr24And127(int arg) {
238 return (arg >> 24) & 127;
239 }
240
241 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (before)
242 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
243 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
244 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127
245 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
246 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>]
247 /// CHECK-DAG: Return [<<And>>]
248
249 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (after)
250 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
251 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
252 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127
253 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
254 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>]
255 /// CHECK-DAG: Return [<<And>>]
256
Shr56And127(long arg)257 public static long Shr56And127(long arg) {
258 return (arg >> 56) & 127;
259 }
260
261 /// CHECK-START: long Main.Div1(long) instruction_simplifier (before)
262 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
263 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
264 /// CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>]
265 /// CHECK-DAG: Return [<<Div>>]
266
267 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
268 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
269 /// CHECK-DAG: Return [<<Arg>>]
270
271 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
272 /// CHECK-NOT: Div
273
Div1(long arg)274 public static long Div1(long arg) {
275 return arg / 1;
276 }
277
278 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
279 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
280 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
281 /// CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>]
282 /// CHECK-DAG: Return [<<Div>>]
283
284 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
285 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
286 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
287 /// CHECK-DAG: Return [<<Neg>>]
288
289 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
290 /// CHECK-NOT: Div
291
DivN1(int arg)292 public static int DivN1(int arg) {
293 return arg / -1;
294 }
295
296 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
297 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
298 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
299 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const1>>,<<Arg>>]
300 /// CHECK-DAG: Return [<<Mul>>]
301
302 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
303 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
304 /// CHECK-DAG: Return [<<Arg>>]
305
306 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
307 /// CHECK-NOT: Mul
308
Mul1(long arg)309 public static long Mul1(long arg) {
310 return arg * 1;
311 }
312
313 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
314 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
315 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
316 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>]
317 /// CHECK-DAG: Return [<<Mul>>]
318
319 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
320 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
321 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
322 /// CHECK-DAG: Return [<<Neg>>]
323
324 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
325 /// CHECK-NOT: Mul
326
MulN1(int arg)327 public static int MulN1(int arg) {
328 return arg * -1;
329 }
330
331 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
332 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
333 /// CHECK-DAG: <<Const128:j\d+>> LongConstant 128
334 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const128>>,<<Arg>>]
335 /// CHECK-DAG: Return [<<Mul>>]
336
337 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
338 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
339 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
340 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>]
341 /// CHECK-DAG: Return [<<Shl>>]
342
343 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
344 /// CHECK-NOT: Mul
345
MulPowerOfTwo128(long arg)346 public static long MulPowerOfTwo128(long arg) {
347 return arg * 128;
348 }
349
350 /// CHECK-START: int Main.Or0(int) instruction_simplifier (before)
351 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
352 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
353 /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>]
354 /// CHECK-DAG: Return [<<Or>>]
355
356 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
357 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
358 /// CHECK-DAG: Return [<<Arg>>]
359
360 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
361 /// CHECK-NOT: Or
362
Or0(int arg)363 public static int Or0(int arg) {
364 return arg | 0;
365 }
366
367 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
368 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
369 /// CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>]
370 /// CHECK-DAG: Return [<<Or>>]
371
372 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
373 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
374 /// CHECK-DAG: Return [<<Arg>>]
375
376 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
377 /// CHECK-NOT: Or
378
OrSame(long arg)379 public static long OrSame(long arg) {
380 return arg | arg;
381 }
382
383 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
384 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
385 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
386 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>]
387 /// CHECK-DAG: Return [<<Shl>>]
388
389 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
390 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
391 /// CHECK-DAG: Return [<<Arg>>]
392
393 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
394 /// CHECK-NOT: Shl
395
Shl0(int arg)396 public static int Shl0(int arg) {
397 return arg << 0;
398 }
399
400 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
401 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
402 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
403 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>]
404 /// CHECK-DAG: Return [<<Shr>>]
405
406 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
407 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
408 /// CHECK-DAG: Return [<<Arg>>]
409
410 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
411 /// CHECK-NOT: Shr
412
Shr0(long arg)413 public static long Shr0(long arg) {
414 return arg >> 0;
415 }
416
417 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (before)
418 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
419 /// CHECK-DAG: <<Const64:i\d+>> IntConstant 64
420 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const64>>]
421 /// CHECK-DAG: Return [<<Shr>>]
422
423 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after)
424 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
425 /// CHECK-DAG: Return [<<Arg>>]
426
427 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after)
428 /// CHECK-NOT: Shr
429
Shr64(long arg)430 public static long Shr64(long arg) {
431 return arg >> 64;
432 }
433
434 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
435 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
436 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
437 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>]
438 /// CHECK-DAG: Return [<<Sub>>]
439
440 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
441 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
442 /// CHECK-DAG: Return [<<Arg>>]
443
444 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
445 /// CHECK-NOT: Sub
446
Sub0(long arg)447 public static long Sub0(long arg) {
448 return arg - 0;
449 }
450
451 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
452 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
453 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
454 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>]
455 /// CHECK-DAG: Return [<<Sub>>]
456
457 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
458 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
459 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
460 /// CHECK-DAG: Return [<<Neg>>]
461
462 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
463 /// CHECK-NOT: Sub
464
SubAliasNeg(int arg)465 public static int SubAliasNeg(int arg) {
466 return 0 - arg;
467 }
468
469 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
470 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
471 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
472 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>]
473 /// CHECK-DAG: Return [<<UShr>>]
474
475 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
476 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
477 /// CHECK-DAG: Return [<<Arg>>]
478
479 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
480 /// CHECK-NOT: UShr
481
UShr0(long arg)482 public static long UShr0(long arg) {
483 return arg >>> 0;
484 }
485
486 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
487 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
488 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
489 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>]
490 /// CHECK-DAG: Return [<<Xor>>]
491
492 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
493 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
494 /// CHECK-DAG: Return [<<Arg>>]
495
496 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
497 /// CHECK-NOT: Xor
498
Xor0(int arg)499 public static int Xor0(int arg) {
500 return arg ^ 0;
501 }
502
503 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
504 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
505 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
506 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>]
507 /// CHECK-DAG: Return [<<Xor>>]
508
509 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
510 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
511 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
512 /// CHECK-DAG: Return [<<Not>>]
513
514 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
515 /// CHECK-NOT: Xor
516
XorAllOnes(int arg)517 public static int XorAllOnes(int arg) {
518 return arg ^ -1;
519 }
520
521 /**
522 * Test that addition or subtraction operation with both inputs negated are
523 * optimized to use a single negation after the operation.
524 * The transformation tested is implemented in
525 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
526 */
527
528 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
529 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
530 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
531 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
532 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
533 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
534 /// CHECK-DAG: Return [<<Add>>]
535
536 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
537 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
538 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
539 /// CHECK-NOT: Neg
540 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
541 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
542 /// CHECK-DAG: Return [<<Neg>>]
543
AddNegs1(int arg1, int arg2)544 public static int AddNegs1(int arg1, int arg2) {
545 return -arg1 + -arg2;
546 }
547
548 /**
549 * This is similar to the test-case AddNegs1, but the negations have
550 * multiple uses.
551 * The transformation tested is implemented in
552 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
553 * The current code won't perform the previous optimization. The
554 * transformations do not look at other uses of their inputs. As they don't
555 * know what will happen with other uses, they do not take the risk of
556 * increasing the register pressure by creating or extending live ranges.
557 */
558
559 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
560 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
561 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
562 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
563 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
564 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
565 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
566 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
567 /// CHECK-DAG: Return [<<Or>>]
568
569 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
570 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
571 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
572 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
573 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
574 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
575 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
576 /// CHECK-NOT: Neg
577 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
578 /// CHECK-DAG: Return [<<Or>>]
579
580 /// CHECK-START: int Main.AddNegs2(int, int) GVN (after)
581 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
582 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
583 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
584 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
585 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
586 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>]
587 /// CHECK-DAG: Return [<<Or>>]
588
AddNegs2(int arg1, int arg2)589 public static int AddNegs2(int arg1, int arg2) {
590 int temp1 = -arg1;
591 int temp2 = -arg2;
592 return (temp1 + temp2) | (temp1 + temp2);
593 }
594
595 /**
596 * This follows test-cases AddNegs1 and AddNegs2.
597 * The transformation tested is implemented in
598 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
599 * The optimization should not happen if it moves an additional instruction in
600 * the loop.
601 */
602
603 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
604 // -------------- Arguments and initial negation operations.
605 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
606 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
607 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
608 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
609 /// CHECK: Goto
610 // -------------- Loop
611 /// CHECK: SuspendCheck
612 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
613 /// CHECK: Goto
614
615 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
616 // -------------- Arguments and initial negation operations.
617 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
618 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
619 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
620 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
621 /// CHECK: Goto
622 // -------------- Loop
623 /// CHECK: SuspendCheck
624 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
625 /// CHECK-NOT: Neg
626 /// CHECK: Goto
627
AddNegs3(long arg1, long arg2)628 public static long AddNegs3(long arg1, long arg2) {
629 long res = 0;
630 long n_arg1 = -arg1;
631 long n_arg2 = -arg2;
632 for (long i = 0; i < 1; i++) {
633 res += n_arg1 + n_arg2 + i;
634 }
635 return res;
636 }
637
638 /**
639 * Test the simplification of an addition with a negated argument into a
640 * subtraction.
641 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
642 */
643
644 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
645 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
646 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
647 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
648 /// CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>]
649 /// CHECK-DAG: Return [<<Add>>]
650
651 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
652 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
653 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
654 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>]
655 /// CHECK-DAG: Return [<<Sub>>]
656
657 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
658 /// CHECK-NOT: Neg
659 /// CHECK-NOT: Add
660
AddNeg1(long arg1, long arg2)661 public static long AddNeg1(long arg1, long arg2) {
662 return -arg1 + arg2;
663 }
664
665 /**
666 * This is similar to the test-case AddNeg1, but the negation has two uses.
667 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
668 * The current code won't perform the previous optimization. The
669 * transformations do not look at other uses of their inputs. As they don't
670 * know what will happen with other uses, they do not take the risk of
671 * increasing the register pressure by creating or extending live ranges.
672 */
673
674 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
675 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
676 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
677 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
678 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
679 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
680 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
681 /// CHECK-DAG: Return [<<Res>>]
682
683 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
684 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
685 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
686 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
687 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
688 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
689 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
690 /// CHECK-DAG: Return [<<Res>>]
691
692 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
693 /// CHECK-NOT: Sub
694
AddNeg2(long arg1, long arg2)695 public static long AddNeg2(long arg1, long arg2) {
696 long temp = -arg2;
697 return (arg1 + temp) | (arg1 + temp);
698 }
699
700 /**
701 * Test simplification of the `-(-var)` pattern.
702 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
703 */
704
705 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
706 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
707 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>]
708 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>]
709 /// CHECK-DAG: Return [<<Neg2>>]
710
711 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
712 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
713 /// CHECK-DAG: Return [<<Arg>>]
714
715 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
716 /// CHECK-NOT: Neg
717
NegNeg1(long arg)718 public static long NegNeg1(long arg) {
719 return -(-arg);
720 }
721
722 /**
723 * Test 'multi-step' simplification, where a first transformation yields a
724 * new simplification possibility for the current instruction.
725 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
726 * and in `InstructionSimplifierVisitor::VisitAdd`.
727 */
728
729 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
730 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
731 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>]
732 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>]
733 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg2>>,<<Neg1>>]
734 /// CHECK-DAG: Return [<<Add>>]
735
736 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
737 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
738 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>]
739 /// CHECK-DAG: Return [<<Sub>>]
740
741 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
742 /// CHECK-NOT: Neg
743 /// CHECK-NOT: Add
744
745 /// CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
746 /// CHECK: <<Const0:i\d+>> IntConstant 0
747 /// CHECK-NOT: Neg
748 /// CHECK-NOT: Add
749 /// CHECK: Return [<<Const0>>]
750
NegNeg2(int arg)751 public static int NegNeg2(int arg) {
752 int temp = -arg;
753 return temp + -temp;
754 }
755
756 /**
757 * Test another 'multi-step' simplification, where a first transformation
758 * yields a new simplification possibility for the current instruction.
759 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
760 * and in `InstructionSimplifierVisitor::VisitSub`.
761 */
762
763 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
764 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
765 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
766 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>]
767 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>]
768 /// CHECK-DAG: Return [<<Sub>>]
769
770 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
771 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
772 /// CHECK-DAG: Return [<<Arg>>]
773
774 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
775 /// CHECK-NOT: Neg
776 /// CHECK-NOT: Sub
777
NegNeg3(long arg)778 public static long NegNeg3(long arg) {
779 return 0 - -arg;
780 }
781
782 /**
783 * Test that a negated subtraction is simplified to a subtraction with its
784 * arguments reversed.
785 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
786 */
787
788 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
789 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
790 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
791 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
792 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>]
793 /// CHECK-DAG: Return [<<Neg>>]
794
795 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
796 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
797 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
798 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>]
799 /// CHECK-DAG: Return [<<Sub>>]
800
801 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
802 /// CHECK-NOT: Neg
803
NegSub1(int arg1, int arg2)804 public static int NegSub1(int arg1, int arg2) {
805 return -(arg1 - arg2);
806 }
807
808 /**
809 * This is similar to the test-case NegSub1, but the subtraction has
810 * multiple uses.
811 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
812 * The current code won't perform the previous optimization. The
813 * transformations do not look at other uses of their inputs. As they don't
814 * know what will happen with other uses, they do not take the risk of
815 * increasing the register pressure by creating or extending live ranges.
816 */
817
818 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
819 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
820 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
821 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
822 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
823 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
824 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
825 /// CHECK-DAG: Return [<<Or>>]
826
827 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
828 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
829 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
830 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
831 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
832 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
833 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
834 /// CHECK-DAG: Return [<<Or>>]
835
NegSub2(int arg1, int arg2)836 public static int NegSub2(int arg1, int arg2) {
837 int temp = arg1 - arg2;
838 return -temp | -temp;
839 }
840
841 /**
842 * Test simplification of the `~~var` pattern.
843 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
844 */
845
846 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
847 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
848 /// CHECK-DAG: <<Not1:j\d+>> Not [<<Arg>>]
849 /// CHECK-DAG: <<Not2:j\d+>> Not [<<Not1>>]
850 /// CHECK-DAG: Return [<<Not2>>]
851
852 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
853 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
854 /// CHECK-DAG: Return [<<Arg>>]
855
856 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
857 /// CHECK-NOT: Not
858
NotNot1(long arg)859 public static long NotNot1(long arg) {
860 return ~~arg;
861 }
862
863 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
864 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
865 /// CHECK-DAG: <<Not1:i\d+>> Not [<<Arg>>]
866 /// CHECK-DAG: <<Not2:i\d+>> Not [<<Not1>>]
867 /// CHECK-DAG: <<Add:i\d+>> Add [<<Not2>>,<<Not1>>]
868 /// CHECK-DAG: Return [<<Add>>]
869
870 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
871 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
872 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
873 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Not>>]
874 /// CHECK-DAG: Return [<<Add>>]
875
876 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
877 /// CHECK: Not
878 /// CHECK-NOT: Not
879
NotNot2(int arg)880 public static int NotNot2(int arg) {
881 int temp = ~arg;
882 return temp + ~temp;
883 }
884
885 /**
886 * Test the simplification of a subtraction with a negated argument.
887 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
888 */
889
890 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
891 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
892 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
893 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
894 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>]
895 /// CHECK-DAG: Return [<<Sub>>]
896
897 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
898 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
899 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
900 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
901 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
902 /// CHECK-DAG: Return [<<Neg>>]
903
904 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
905 /// CHECK-NOT: Sub
906
SubNeg1(int arg1, int arg2)907 public static int SubNeg1(int arg1, int arg2) {
908 return -arg1 - arg2;
909 }
910
911 /**
912 * This is similar to the test-case SubNeg1, but the negation has
913 * multiple uses.
914 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
915 * The current code won't perform the previous optimization. The
916 * transformations do not look at other uses of their inputs. As they don't
917 * know what will happen with other uses, they do not take the risk of
918 * increasing the register pressure by creating or extending live ranges.
919 */
920
921 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
922 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
923 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
924 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
925 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
926 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
927 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
928 /// CHECK-DAG: Return [<<Or>>]
929
930 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
931 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
932 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
933 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
934 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
935 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
936 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
937 /// CHECK-DAG: Return [<<Or>>]
938
939 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
940 /// CHECK-NOT: Add
941
SubNeg2(int arg1, int arg2)942 public static int SubNeg2(int arg1, int arg2) {
943 int temp = -arg1;
944 return (temp - arg2) | (temp - arg2);
945 }
946
947 /**
948 * This follows test-cases SubNeg1 and SubNeg2.
949 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
950 * The optimization should not happen if it moves an additional instruction in
951 * the loop.
952 */
953
954 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
955 // -------------- Arguments and initial negation operation.
956 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
957 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
958 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
959 /// CHECK: Goto
960 // -------------- Loop
961 /// CHECK: SuspendCheck
962 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
963 /// CHECK: Goto
964
965 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
966 // -------------- Arguments and initial negation operation.
967 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
968 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
969 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
970 /// CHECK-DAG: Goto
971 // -------------- Loop
972 /// CHECK: SuspendCheck
973 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
974 /// CHECK-NOT: Neg
975 /// CHECK: Goto
976
SubNeg3(long arg1, long arg2)977 public static long SubNeg3(long arg1, long arg2) {
978 long res = 0;
979 long temp = -arg1;
980 for (long i = 0; i < 1; i++) {
981 res += temp - arg2 - i;
982 }
983 return res;
984 }
985
986 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
987 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
988 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
989 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
990 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
991 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>]
992 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<NotArg>>,<<Const2>>]
993 /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>]
994 /// CHECK-DAG: Return [<<NotCond>>]
995
996 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
997 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
998 /// CHECK-DAG: Return [<<True>>]
999
EqualBoolVsIntConst(boolean arg)1000 public static boolean EqualBoolVsIntConst(boolean arg) {
1001 return (arg ? 0 : 1) != 2;
1002 }
1003
1004 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
1005 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1006 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1007 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1008 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
1009 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>]
1010 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<NotArg>>,<<Const2>>]
1011 /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>]
1012 /// CHECK-DAG: Return [<<NotCond>>]
1013
1014 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
1015 /// CHECK-DAG: <<False:i\d+>> IntConstant 0
1016 /// CHECK-DAG: Return [<<False>>]
1017
NotEqualBoolVsIntConst(boolean arg)1018 public static boolean NotEqualBoolVsIntConst(boolean arg) {
1019 return (arg ? 0 : 1) == 2;
1020 }
1021
1022 /*
1023 * Test simplification of double Boolean negation. Note that sometimes
1024 * both negations can be removed but we only expect the simplifier to
1025 * remove the second.
1026 */
1027
1028 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (before)
1029 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1030 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1031 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1032 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>]
1033 /// CHECK-DAG: <<NotNotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<NotArg>>]
1034 /// CHECK-DAG: Return [<<NotNotArg>>]
1035
1036 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (after)
1037 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1038 /// CHECK-DAG: Return [<<Arg>>]
1039
NegateValue(boolean arg)1040 public static boolean NegateValue(boolean arg) {
1041 return !arg;
1042 }
1043
NotNotBool(boolean arg)1044 public static boolean NotNotBool(boolean arg) {
1045 return !(NegateValue(arg));
1046 }
1047
1048 /// CHECK-START: float Main.Div2(float) instruction_simplifier (before)
1049 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1050 /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
1051 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>]
1052 /// CHECK-DAG: Return [<<Div>>]
1053
1054 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
1055 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1056 /// CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5
1057 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>]
1058 /// CHECK-DAG: Return [<<Mul>>]
1059
1060 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
1061 /// CHECK-NOT: Div
1062
Div2(float arg)1063 public static float Div2(float arg) {
1064 return arg / 2.0f;
1065 }
1066
1067 /// CHECK-START: double Main.Div2(double) instruction_simplifier (before)
1068 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1069 /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
1070 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>]
1071 /// CHECK-DAG: Return [<<Div>>]
1072
1073 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
1074 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1075 /// CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5
1076 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>]
1077 /// CHECK-DAG: Return [<<Mul>>]
1078
1079 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
1080 /// CHECK-NOT: Div
Div2(double arg)1081 public static double Div2(double arg) {
1082 return arg / 2.0;
1083 }
1084
1085 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
1086 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1087 /// CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25
1088 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>]
1089 /// CHECK-DAG: Return [<<Div>>]
1090
1091 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1092 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1093 /// CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4
1094 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>]
1095 /// CHECK-DAG: Return [<<Mul>>]
1096
1097 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1098 /// CHECK-NOT: Div
1099
DivMP25(float arg)1100 public static float DivMP25(float arg) {
1101 return arg / -0.25f;
1102 }
1103
1104 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
1105 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1106 /// CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25
1107 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>]
1108 /// CHECK-DAG: Return [<<Div>>]
1109
1110 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1111 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1112 /// CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4
1113 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>]
1114 /// CHECK-DAG: Return [<<Mul>>]
1115
1116 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1117 /// CHECK-NOT: Div
DivMP25(double arg)1118 public static double DivMP25(double arg) {
1119 return arg / -0.25f;
1120 }
1121
1122 /**
1123 * Test strength reduction of factors of the form (2^n + 1).
1124 */
1125
1126 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (before)
1127 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1128 /// CHECK-DAG: <<Const9:i\d+>> IntConstant 9
1129 /// CHECK: Mul [<<Arg>>,<<Const9>>]
1130
1131 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (after)
1132 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1133 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
1134 /// CHECK: <<Shift:i\d+>> Shl [<<Arg>>,<<Const3>>]
1135 /// CHECK-NEXT: Add [<<Arg>>,<<Shift>>]
1136
mulPow2Plus1(int arg)1137 public static int mulPow2Plus1(int arg) {
1138 return arg * 9;
1139 }
1140
1141 /**
1142 * Test strength reduction of factors of the form (2^n - 1).
1143 */
1144
1145 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (before)
1146 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1147 /// CHECK-DAG: <<Const31:j\d+>> LongConstant 31
1148 /// CHECK: Mul [<<Const31>>,<<Arg>>]
1149
1150 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (after)
1151 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1152 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
1153 /// CHECK: <<Shift:j\d+>> Shl [<<Arg>>,<<Const5>>]
1154 /// CHECK-NEXT: Sub [<<Shift>>,<<Arg>>]
1155
mulPow2Minus1(long arg)1156 public static long mulPow2Minus1(long arg) {
1157 return arg * 31;
1158 }
1159
1160 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (before)
1161 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1162 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1163 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1164 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1165 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Field>>,<<Const1>>]
1166 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>]
1167 /// CHECK-DAG: Return [<<Select>>]
1168
1169 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (after)
1170 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1171 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1172 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1173 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>]
1174 /// CHECK-DAG: Return [<<Select>>]
1175
booleanFieldNotEqualOne()1176 public static int booleanFieldNotEqualOne() {
1177 return (booleanField == $inline$true()) ? 13 : 54;
1178 }
1179
1180 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (before)
1181 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1182 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1183 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1184 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1185 /// CHECK-DAG: <<NE:z\d+>> Equal [<<Field>>,<<Const0>>]
1186 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>]
1187 /// CHECK-DAG: Return [<<Select>>]
1188
1189 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (after)
1190 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1191 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1192 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1193 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>]
1194 /// CHECK-DAG: Return [<<Select>>]
1195
booleanFieldEqualZero()1196 public static int booleanFieldEqualZero() {
1197 return (booleanField != $inline$false()) ? 13 : 54;
1198 }
1199
1200 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (before)
1201 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1202 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1203 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1204 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1205 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1206 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1207 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1208 /// CHECK-DAG: <<GT:i\d+>> Select [<<Const1>>,<<Const0>>,<<LE>>]
1209 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<GT>>,<<Const1>>]
1210 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>]
1211 /// CHECK-DAG: Return [<<Result>>]
1212
1213 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (after)
1214 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1215 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1216 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1217 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1218 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE:z\d+>>]
1219 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1220 /// CHECK-DAG: Return [<<Result>>]
1221 // Note that we match `LE` from Select because there are two identical
1222 // LessThanOrEqual instructions.
1223
intConditionNotEqualOne(int i)1224 public static int intConditionNotEqualOne(int i) {
1225 return ((i > 42) == $inline$true()) ? 13 : 54;
1226 }
1227
1228 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (before)
1229 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1230 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1231 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1232 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1233 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1234 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1235 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1236 /// CHECK-DAG: <<GT:i\d+>> Select [<<Const1>>,<<Const0>>,<<LE>>]
1237 /// CHECK-DAG: <<NE:z\d+>> Equal [<<GT>>,<<Const0>>]
1238 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>]
1239 /// CHECK-DAG: Return [<<Result>>]
1240
1241 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (after)
1242 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1243 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1244 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1245 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1246 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE:z\d+>>]
1247 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1248 /// CHECK-DAG: Return [<<Result>>]
1249 // Note that we match `LE` from Select because there are two identical
1250 // LessThanOrEqual instructions.
1251
intConditionEqualZero(int i)1252 public static int intConditionEqualZero(int i) {
1253 return ((i > 42) != $inline$false()) ? 13 : 54;
1254 }
1255
1256 // Test that conditions on float/double are not flipped.
1257
1258 /// CHECK-START: int Main.floatConditionNotEqualOne(float) builder (after)
1259 /// CHECK: LessThanOrEqual
1260
1261 /// CHECK-START: int Main.floatConditionNotEqualOne(float) instruction_simplifier_before_codegen (after)
1262 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1263 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1264 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1265 /// CHECK-DAG: <<Const42:f\d+>> FloatConstant 42
1266 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1267 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>]
1268 /// CHECK-DAG: Return [<<Select>>]
1269
floatConditionNotEqualOne(float f)1270 public static int floatConditionNotEqualOne(float f) {
1271 return ((f > 42.0f) == true) ? 13 : 54;
1272 }
1273
1274 /// CHECK-START: int Main.doubleConditionEqualZero(double) builder (after)
1275 /// CHECK: LessThanOrEqual
1276
1277 /// CHECK-START: int Main.doubleConditionEqualZero(double) instruction_simplifier_before_codegen (after)
1278 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1279 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13
1280 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54
1281 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42
1282 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1283 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>]
1284 /// CHECK-DAG: Return [<<Select>>]
1285
doubleConditionEqualZero(double d)1286 public static int doubleConditionEqualZero(double d) {
1287 return ((d > 42.0) != false) ? 13 : 54;
1288 }
1289
1290 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (before)
1291 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1292 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1293 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>]
1294 /// CHECK-DAG: Return [<<Int>>]
1295
1296 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after)
1297 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1298 /// CHECK-DAG: Return [<<Arg>>]
1299
1300 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after)
1301 /// CHECK-NOT: TypeConversion
1302
intToDoubleToInt(int value)1303 public static int intToDoubleToInt(int value) {
1304 // Lossless conversion followed by a conversion back.
1305 return (int) (double) value;
1306 }
1307
1308 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (before)
1309 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1310 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1311 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>]
1312
1313 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after)
1314 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1315 /// CHECK-DAG: {{d\d+}} TypeConversion [<<Arg>>]
1316
1317 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after)
1318 /// CHECK-DAG: TypeConversion
1319 /// CHECK-NOT: TypeConversion
1320
intToDoubleToIntPrint(int value)1321 public static String intToDoubleToIntPrint(int value) {
1322 // Lossless conversion followed by a conversion back
1323 // with another use of the intermediate result.
1324 double d = (double) value;
1325 int i = (int) d;
1326 return "d=" + d + ", i=" + i;
1327 }
1328
1329 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (before)
1330 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue
1331 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1332 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>]
1333 /// CHECK-DAG: Return [<<Int>>]
1334
1335 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after)
1336 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue
1337 /// CHECK-DAG: Return [<<Arg>>]
1338
1339 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after)
1340 /// CHECK-NOT: TypeConversion
1341
byteToDoubleToInt(byte value)1342 public static int byteToDoubleToInt(byte value) {
1343 // Lossless conversion followed by another conversion, use implicit conversion.
1344 return (int) (double) value;
1345 }
1346
1347 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (before)
1348 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1349 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1350 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>]
1351 /// CHECK-DAG: Return [<<Int>>]
1352
1353 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after)
1354 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1355 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1356 /// CHECK-DAG: Return [<<Int>>]
1357
1358 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after)
1359 /// CHECK-DAG: TypeConversion
1360 /// CHECK-NOT: TypeConversion
1361
floatToDoubleToInt(float value)1362 public static int floatToDoubleToInt(float value) {
1363 // Lossless conversion followed by another conversion.
1364 return (int) (double) value;
1365 }
1366
1367 /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (before)
1368 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1369 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1370 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>]
1371
1372 /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (after)
1373 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1374 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1375 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>]
1376
floatToDoubleToIntPrint(float value)1377 public static String floatToDoubleToIntPrint(float value) {
1378 // Lossless conversion followed by another conversion with
1379 // an extra use of the intermediate result.
1380 double d = (double) value;
1381 int i = (int) d;
1382 return "d=" + d + ", i=" + i;
1383 }
1384
1385 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (before)
1386 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue
1387 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1388 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>]
1389 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>]
1390 /// CHECK-DAG: Return [<<Short>>]
1391
1392 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after)
1393 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue
1394 /// CHECK-DAG: Return [<<Arg>>]
1395
1396 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after)
1397 /// CHECK-NOT: TypeConversion
1398
byteToDoubleToShort(byte value)1399 public static short byteToDoubleToShort(byte value) {
1400 // Originally, this is byte->double->int->short. The first conversion is lossless,
1401 // so we merge this with the second one to byte->int which we omit as it's an implicit
1402 // conversion. Then we eliminate the resulting byte->short as an implicit conversion.
1403 return (short) (double) value;
1404 }
1405
1406 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (before)
1407 /// CHECK-DAG: <<Arg:c\d+>> ParameterValue
1408 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1409 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>]
1410 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>]
1411 /// CHECK-DAG: Return [<<Short>>]
1412
1413 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after)
1414 /// CHECK-DAG: <<Arg:c\d+>> ParameterValue
1415 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Arg>>]
1416 /// CHECK-DAG: Return [<<Short>>]
1417
1418 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after)
1419 /// CHECK-DAG: TypeConversion
1420 /// CHECK-NOT: TypeConversion
1421
charToDoubleToShort(char value)1422 public static short charToDoubleToShort(char value) {
1423 // Originally, this is char->double->int->short. The first conversion is lossless,
1424 // so we merge this with the second one to char->int which we omit as it's an implicit
1425 // conversion. Then we are left with the resulting char->short conversion.
1426 return (short) (double) value;
1427 }
1428
1429 /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (before)
1430 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1431 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1432 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>]
1433 /// CHECK-DAG: Return [<<Short>>]
1434
1435 /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (after)
1436 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1437 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1438 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>]
1439 /// CHECK-DAG: Return [<<Short>>]
1440
floatToIntToShort(float value)1441 public static short floatToIntToShort(float value) {
1442 // Lossy FP to integral conversion followed by another conversion: no simplification.
1443 return (short) value;
1444 }
1445
1446 /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (before)
1447 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1448 /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>]
1449 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>]
1450 /// CHECK-DAG: Return [<<Int>>]
1451
1452 /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (after)
1453 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1454 /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>]
1455 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>]
1456 /// CHECK-DAG: Return [<<Int>>]
1457
intToFloatToInt(int value)1458 public static int intToFloatToInt(int value) {
1459 // Lossy integral to FP conversion followed another conversion: no simplification.
1460 return (int) (float) value;
1461 }
1462
1463 /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (before)
1464 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1465 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1466 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>]
1467 /// CHECK-DAG: Return [<<Double>>]
1468
1469 /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (after)
1470 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1471 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1472 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>]
1473 /// CHECK-DAG: Return [<<Double>>]
1474
longToIntToDouble(long value)1475 public static double longToIntToDouble(long value) {
1476 // Lossy long-to-int conversion followed an integral to FP conversion: no simplification.
1477 return (double) (int) value;
1478 }
1479
1480 /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (before)
1481 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1482 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1483 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>]
1484 /// CHECK-DAG: Return [<<Long>>]
1485
1486 /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (after)
1487 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1488 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>]
1489 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>]
1490 /// CHECK-DAG: Return [<<Long>>]
1491
longToIntToLong(long value)1492 public static long longToIntToLong(long value) {
1493 // Lossy long-to-int conversion followed an int-to-long conversion: no simplification.
1494 return (long) (int) value;
1495 }
1496
1497 /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (before)
1498 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1499 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>]
1500 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Char>>]
1501 /// CHECK-DAG: Return [<<Short>>]
1502
1503 /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (after)
1504 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1505 /// CHECK-DAG: Return [<<Arg>>]
1506
shortToCharToShort(short value)1507 public static short shortToCharToShort(short value) {
1508 // Integral conversion followed by non-widening integral conversion to original type.
1509 return (short) (char) value;
1510 }
1511
1512 /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (before)
1513 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1514 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Arg>>]
1515 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Long>>]
1516 /// CHECK-DAG: Return [<<Int>>]
1517
1518 /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (after)
1519 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1520 /// CHECK-DAG: Return [<<Arg>>]
1521
shortToLongToInt(short value)1522 public static int shortToLongToInt(short value) {
1523 // Integral conversion followed by non-widening integral conversion, use implicit conversion.
1524 return (int) (long) value;
1525 }
1526
1527 /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (before)
1528 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1529 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>]
1530 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Char>>]
1531 /// CHECK-DAG: Return [<<Byte>>]
1532
1533 /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (after)
1534 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1535 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>]
1536 /// CHECK-DAG: Return [<<Byte>>]
1537
shortToCharToByte(short value)1538 public static byte shortToCharToByte(short value) {
1539 // Integral conversion followed by non-widening integral conversion losing bits
1540 // from the original type. Simplify to use only one conversion.
1541 return (byte) (char) value;
1542 }
1543
1544 /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (before)
1545 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1546 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>]
1547 /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>]
1548
1549 /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (after)
1550 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1551 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>]
1552 /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>]
1553
shortToCharToBytePrint(short value)1554 public static String shortToCharToBytePrint(short value) {
1555 // Integral conversion followed by non-widening integral conversion losing bits
1556 // from the original type with an extra use of the intermediate result.
1557 char c = (char) value;
1558 byte b = (byte) c;
1559 return "c=" + ((int) c) + ", b=" + ((int) b); // implicit conversions.
1560 }
1561
1562 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (before)
1563 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1564 /// CHECK-DAG: <<Mask:j\d+>> LongConstant 255
1565 /// CHECK-DAG: <<And:j\d+>> And [<<Mask>>,<<Arg>>]
1566 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<And>>]
1567 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Int>>]
1568 /// CHECK-DAG: Return [<<Byte>>]
1569
1570 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after)
1571 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1572 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>]
1573 /// CHECK-DAG: Return [<<Byte>>]
1574
1575 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after)
1576 /// CHECK-NOT: And
1577
longAnd0xffToByte(long value)1578 public static byte longAnd0xffToByte(long value) {
1579 return (byte) (value & 0xff);
1580 }
1581
1582 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (before)
1583 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1584 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 131071
1585 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>]
1586 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<And>>]
1587 /// CHECK-DAG: Return [<<Char>>]
1588
1589 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after)
1590 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1591 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>]
1592 /// CHECK-DAG: Return [<<Char>>]
1593
1594 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after)
1595 /// CHECK-NOT: And
1596
intAnd0x1ffffToChar(int value)1597 public static char intAnd0x1ffffToChar(int value) {
1598 // Keeping all significant bits and one more.
1599 return (char) (value & 0x1ffff);
1600 }
1601
1602 /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (before)
1603 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1604 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303
1605 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>]
1606 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>]
1607 /// CHECK-DAG: Return [<<Short>>]
1608
1609 /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (after)
1610 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1611 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303
1612 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>]
1613 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>]
1614 /// CHECK-DAG: Return [<<Short>>]
1615
intAnd0x17fffToShort(int value)1616 public static short intAnd0x17fffToShort(int value) {
1617 // No simplification: clearing a significant bit.
1618 return (short) (value & 0x17fff);
1619 }
1620
1621 /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (before)
1622 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1623 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 65535
1624 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>]
1625 /// CHECK-DAG: <<Same:s\d+>> TypeConversion [<<And>>]
1626 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Same>>]
1627 /// CHECK-DAG: Return [<<Double>>]
1628
1629 /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (after)
1630 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue
1631 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>]
1632 /// CHECK-DAG: Return [<<Double>>]
1633
shortAnd0xffffToShortToDouble(short value)1634 public static double shortAnd0xffffToShortToDouble(short value) {
1635 short same = (short) (value & 0xffff);
1636 return (double) same;
1637 }
1638
1639 /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (before)
1640 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1641 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1642 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Const42>>,<<Arg>>]
1643
1644 /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (after)
1645 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1646 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1647 /// CHECK-DAG: <<GE:z\d+>> GreaterThanOrEqual [<<Arg>>,<<Const42>>]
1648
intReverseCondition(int i)1649 public static int intReverseCondition(int i) {
1650 return (42 > i) ? 13 : 54;
1651 }
1652
1653 /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (before)
1654 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42
1655 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect
1656 /// CHECK-DAG: <<CMP:i\d+>> Compare [<<Const42>>,<<Result>>]
1657
1658 /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (after)
1659 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42
1660 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect
1661 /// CHECK-DAG: <<EQ:z\d+>> Equal [<<Result>>,<<Const42>>]
1662
intReverseConditionNaN(int i)1663 public static int intReverseConditionNaN(int i) {
1664 return (42 != Math.sqrt(i)) ? 13 : 54;
1665 }
1666
runSmaliTest(String name, boolean input)1667 public static int runSmaliTest(String name, boolean input) {
1668 try {
1669 Class<?> c = Class.forName("SmaliTests");
1670 Method m = c.getMethod(name, new Class[] { boolean.class });
1671 return (Integer) m.invoke(null, input);
1672 } catch (Exception ex) {
1673 throw new Error(ex);
1674 }
1675 }
1676
main(String[] args)1677 public static void main(String[] args) {
1678 int arg = 123456;
1679
1680 assertLongEquals(Add0(arg), arg);
1681 assertIntEquals(AndAllOnes(arg), arg);
1682 assertLongEquals(Div1(arg), arg);
1683 assertIntEquals(DivN1(arg), -arg);
1684 assertLongEquals(Mul1(arg), arg);
1685 assertIntEquals(MulN1(arg), -arg);
1686 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
1687 assertIntEquals(Or0(arg), arg);
1688 assertLongEquals(OrSame(arg), arg);
1689 assertIntEquals(Shl0(arg), arg);
1690 assertLongEquals(Shr0(arg), arg);
1691 assertLongEquals(Shr64(arg), arg);
1692 assertLongEquals(Sub0(arg), arg);
1693 assertIntEquals(SubAliasNeg(arg), -arg);
1694 assertLongEquals(UShr0(arg), arg);
1695 assertIntEquals(Xor0(arg), arg);
1696 assertIntEquals(XorAllOnes(arg), ~arg);
1697 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
1698 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
1699 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
1700 assertLongEquals(AddNeg1(arg, arg + 1), 1);
1701 assertLongEquals(AddNeg2(arg, arg + 1), -1);
1702 assertLongEquals(NegNeg1(arg), arg);
1703 assertIntEquals(NegNeg2(arg), 0);
1704 assertLongEquals(NegNeg3(arg), arg);
1705 assertIntEquals(NegSub1(arg, arg + 1), 1);
1706 assertIntEquals(NegSub2(arg, arg + 1), 1);
1707 assertLongEquals(NotNot1(arg), arg);
1708 assertIntEquals(NotNot2(arg), -1);
1709 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
1710 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
1711 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
1712 assertBooleanEquals(EqualBoolVsIntConst(true), true);
1713 assertBooleanEquals(EqualBoolVsIntConst(true), true);
1714 assertBooleanEquals(NotEqualBoolVsIntConst(false), false);
1715 assertBooleanEquals(NotEqualBoolVsIntConst(false), false);
1716 assertBooleanEquals(NotNotBool(true), true);
1717 assertBooleanEquals(NotNotBool(false), false);
1718 assertFloatEquals(Div2(100.0f), 50.0f);
1719 assertDoubleEquals(Div2(150.0), 75.0);
1720 assertFloatEquals(DivMP25(100.0f), -400.0f);
1721 assertDoubleEquals(DivMP25(150.0), -600.0);
1722 assertIntEquals(UShr28And15(0xc1234567), 0xc);
1723 assertLongEquals(UShr60And15(0xc123456787654321L), 0xcL);
1724 assertIntEquals(UShr28And7(0xc1234567), 0x4);
1725 assertLongEquals(UShr60And7(0xc123456787654321L), 0x4L);
1726 assertIntEquals(Shr24And255(0xc1234567), 0xc1);
1727 assertLongEquals(Shr56And255(0xc123456787654321L), 0xc1L);
1728 assertIntEquals(Shr24And127(0xc1234567), 0x41);
1729 assertLongEquals(Shr56And127(0xc123456787654321L), 0x41L);
1730 assertIntEquals(0, mulPow2Plus1(0));
1731 assertIntEquals(9, mulPow2Plus1(1));
1732 assertIntEquals(18, mulPow2Plus1(2));
1733 assertIntEquals(900, mulPow2Plus1(100));
1734 assertIntEquals(111105, mulPow2Plus1(12345));
1735 assertLongEquals(0, mulPow2Minus1(0));
1736 assertLongEquals(31, mulPow2Minus1(1));
1737 assertLongEquals(62, mulPow2Minus1(2));
1738 assertLongEquals(3100, mulPow2Minus1(100));
1739 assertLongEquals(382695, mulPow2Minus1(12345));
1740
1741 booleanField = false;
1742 assertIntEquals(booleanFieldNotEqualOne(), 54);
1743 assertIntEquals(booleanFieldEqualZero(), 54);
1744 booleanField = true;
1745 assertIntEquals(booleanFieldNotEqualOne(), 13);
1746 assertIntEquals(booleanFieldEqualZero(), 13);
1747 assertIntEquals(intConditionNotEqualOne(6), 54);
1748 assertIntEquals(intConditionNotEqualOne(43), 13);
1749 assertIntEquals(intConditionEqualZero(6), 54);
1750 assertIntEquals(intConditionEqualZero(43), 13);
1751 assertIntEquals(floatConditionNotEqualOne(6.0f), 54);
1752 assertIntEquals(floatConditionNotEqualOne(43.0f), 13);
1753 assertIntEquals(doubleConditionEqualZero(6.0), 54);
1754 assertIntEquals(doubleConditionEqualZero(43.0), 13);
1755
1756 assertIntEquals(1234567, intToDoubleToInt(1234567));
1757 assertIntEquals(Integer.MIN_VALUE, intToDoubleToInt(Integer.MIN_VALUE));
1758 assertIntEquals(Integer.MAX_VALUE, intToDoubleToInt(Integer.MAX_VALUE));
1759 assertStringEquals("d=7654321.0, i=7654321", intToDoubleToIntPrint(7654321));
1760 assertIntEquals(12, byteToDoubleToInt((byte) 12));
1761 assertIntEquals(Byte.MIN_VALUE, byteToDoubleToInt(Byte.MIN_VALUE));
1762 assertIntEquals(Byte.MAX_VALUE, byteToDoubleToInt(Byte.MAX_VALUE));
1763 assertIntEquals(11, floatToDoubleToInt(11.3f));
1764 assertStringEquals("d=12.25, i=12", floatToDoubleToIntPrint(12.25f));
1765 assertIntEquals(123, byteToDoubleToShort((byte) 123));
1766 assertIntEquals(Byte.MIN_VALUE, byteToDoubleToShort(Byte.MIN_VALUE));
1767 assertIntEquals(Byte.MAX_VALUE, byteToDoubleToShort(Byte.MAX_VALUE));
1768 assertIntEquals(1234, charToDoubleToShort((char) 1234));
1769 assertIntEquals(Character.MIN_VALUE, charToDoubleToShort(Character.MIN_VALUE));
1770 assertIntEquals(/* sign-extended */ -1, charToDoubleToShort(Character.MAX_VALUE));
1771 assertIntEquals(12345, floatToIntToShort(12345.75f));
1772 assertIntEquals(Short.MAX_VALUE, floatToIntToShort((float)(Short.MIN_VALUE - 1)));
1773 assertIntEquals(Short.MIN_VALUE, floatToIntToShort((float)(Short.MAX_VALUE + 1)));
1774 assertIntEquals(-54321, intToFloatToInt(-54321));
1775 assertDoubleEquals((double) 0x12345678, longToIntToDouble(0x1234567812345678L));
1776 assertDoubleEquals(0.0, longToIntToDouble(Long.MIN_VALUE));
1777 assertDoubleEquals(-1.0, longToIntToDouble(Long.MAX_VALUE));
1778 assertLongEquals(0x0000000012345678L, longToIntToLong(0x1234567812345678L));
1779 assertLongEquals(0xffffffff87654321L, longToIntToLong(0x1234567887654321L));
1780 assertLongEquals(0L, longToIntToLong(Long.MIN_VALUE));
1781 assertLongEquals(-1L, longToIntToLong(Long.MAX_VALUE));
1782 assertIntEquals((short) -5678, shortToCharToShort((short) -5678));
1783 assertIntEquals(Short.MIN_VALUE, shortToCharToShort(Short.MIN_VALUE));
1784 assertIntEquals(Short.MAX_VALUE, shortToCharToShort(Short.MAX_VALUE));
1785 assertIntEquals(5678, shortToLongToInt((short) 5678));
1786 assertIntEquals(Short.MIN_VALUE, shortToLongToInt(Short.MIN_VALUE));
1787 assertIntEquals(Short.MAX_VALUE, shortToLongToInt(Short.MAX_VALUE));
1788 assertIntEquals(0x34, shortToCharToByte((short) 0x1234));
1789 assertIntEquals(-0x10, shortToCharToByte((short) 0x12f0));
1790 assertIntEquals(0, shortToCharToByte(Short.MIN_VALUE));
1791 assertIntEquals(-1, shortToCharToByte(Short.MAX_VALUE));
1792 assertStringEquals("c=1025, b=1", shortToCharToBytePrint((short) 1025));
1793 assertStringEquals("c=1023, b=-1", shortToCharToBytePrint((short) 1023));
1794 assertStringEquals("c=65535, b=-1", shortToCharToBytePrint((short) -1));
1795
1796 assertIntEquals(0x21, longAnd0xffToByte(0x1234432112344321L));
1797 assertIntEquals(0, longAnd0xffToByte(Long.MIN_VALUE));
1798 assertIntEquals(-1, longAnd0xffToByte(Long.MAX_VALUE));
1799 assertIntEquals(0x1234, intAnd0x1ffffToChar(0x43211234));
1800 assertIntEquals(0, intAnd0x1ffffToChar(Integer.MIN_VALUE));
1801 assertIntEquals(Character.MAX_VALUE, intAnd0x1ffffToChar(Integer.MAX_VALUE));
1802 assertIntEquals(0x4321, intAnd0x17fffToShort(0x87654321));
1803 assertIntEquals(0x0888, intAnd0x17fffToShort(0x88888888));
1804 assertIntEquals(0, intAnd0x17fffToShort(Integer.MIN_VALUE));
1805 assertIntEquals(Short.MAX_VALUE, intAnd0x17fffToShort(Integer.MAX_VALUE));
1806
1807 assertDoubleEquals(0.0, shortAnd0xffffToShortToDouble((short) 0));
1808 assertDoubleEquals(1.0, shortAnd0xffffToShortToDouble((short) 1));
1809 assertDoubleEquals(-2.0, shortAnd0xffffToShortToDouble((short) -2));
1810 assertDoubleEquals(12345.0, shortAnd0xffffToShortToDouble((short) 12345));
1811 assertDoubleEquals((double)Short.MAX_VALUE, shortAnd0xffffToShortToDouble(Short.MAX_VALUE));
1812 assertDoubleEquals((double)Short.MIN_VALUE, shortAnd0xffffToShortToDouble(Short.MIN_VALUE));
1813
1814 assertIntEquals(intReverseCondition(41), 13);
1815 assertIntEquals(intReverseConditionNaN(-5), 13);
1816
1817 for (String condition : new String[] { "Equal", "NotEqual" }) {
1818 for (String constant : new String[] { "True", "False" }) {
1819 for (String side : new String[] { "Rhs", "Lhs" }) {
1820 String name = condition + constant + side;
1821 assertIntEquals(runSmaliTest(name, true), 5);
1822 assertIntEquals(runSmaliTest(name, false), 3);
1823 }
1824 }
1825 }
1826 }
1827
$inline$true()1828 private static boolean $inline$true() { return true; }
$inline$false()1829 private static boolean $inline$false() { return false; }
1830
1831 public static boolean booleanField;
1832 }
1833