blob: decdd1f324c79a33e29cd2980403ced76c6bc847 [file] [log] [blame]
Alexandre Rames8626b742015-11-25 16:28:08 +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
19 // A dummy value to defeat inlining of these routines.
20 static boolean doThrow = false;
21
22 public static void assertByteEquals(byte expected, byte result) {
23 if (expected != result) {
24 throw new Error("Expected: " + expected + ", found: " + result);
25 }
26 }
27
28 public static void assertCharEquals(char expected, char result) {
29 if (expected != result) {
30 throw new Error("Expected: " + expected + ", found: " + result);
31 }
32 }
33
34 public static void assertShortEquals(short expected, short result) {
35 if (expected != result) {
36 throw new Error("Expected: " + expected + ", found: " + result);
37 }
38 }
39
40 public static void assertIntEquals(int expected, int result) {
41 if (expected != result) {
42 throw new Error("Expected: " + expected + ", found: " + result);
43 }
44 }
45
46 public static void assertLongEquals(long expected, long result) {
47 if (expected != result) {
48 throw new Error("Expected: " + expected + ", found: " + result);
49 }
50 }
51
52 // Non-inlinable type-casting helpers.
53 static char $noinline$byteToChar (byte v) { if (doThrow) throw new Error(); return (char)v; }
54 static short $noinline$byteToShort (byte v) { if (doThrow) throw new Error(); return (short)v; }
55 static int $noinline$byteToInt (byte v) { if (doThrow) throw new Error(); return (int)v; }
56 static long $noinline$byteToLong (byte v) { if (doThrow) throw new Error(); return (long)v; }
57 static byte $noinline$charToByte (char v) { if (doThrow) throw new Error(); return (byte)v; }
58 static short $noinline$charToShort (char v) { if (doThrow) throw new Error(); return (short)v; }
59 static int $noinline$charToInt (char v) { if (doThrow) throw new Error(); return (int)v; }
60 static long $noinline$charToLong (char v) { if (doThrow) throw new Error(); return (long)v; }
61 static byte $noinline$shortToByte (short v) { if (doThrow) throw new Error(); return (byte)v; }
62 static char $noinline$shortToChar (short v) { if (doThrow) throw new Error(); return (char)v; }
63 static int $noinline$shortToInt (short v) { if (doThrow) throw new Error(); return (int)v; }
64 static long $noinline$shortToLong (short v) { if (doThrow) throw new Error(); return (long)v; }
65 static byte $noinline$intToByte (int v) { if (doThrow) throw new Error(); return (byte)v; }
66 static char $noinline$intToChar (int v) { if (doThrow) throw new Error(); return (char)v; }
67 static short $noinline$intToShort (int v) { if (doThrow) throw new Error(); return (short)v; }
68 static long $noinline$intToLong (int v) { if (doThrow) throw new Error(); return (long)v; }
69 static byte $noinline$longToByte (long v) { if (doThrow) throw new Error(); return (byte)v; }
70 static char $noinline$longToChar (long v) { if (doThrow) throw new Error(); return (char)v; }
71 static short $noinline$longToShort (long v) { if (doThrow) throw new Error(); return (short)v; }
72 static int $noinline$longToInt (long v) { if (doThrow) throw new Error(); return (int)v; }
73
74 /**
75 * Basic test merging a bitfield move operation (here a type conversion) into
76 * the shifter operand.
77 */
78
79 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (before)
80 /// CHECK-DAG: <<l:j\d+>> ParameterValue
81 /// CHECK-DAG: <<b:b\d+>> ParameterValue
82 /// CHECK: <<tmp:j\d+>> TypeConversion [<<b>>]
83 /// CHECK: Sub [<<l>>,<<tmp>>]
84
85 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after)
86 /// CHECK-DAG: <<l:j\d+>> ParameterValue
87 /// CHECK-DAG: <<b:b\d+>> ParameterValue
88 /// CHECK: Arm64DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB
89
90 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after)
91 /// CHECK-NOT: TypeConversion
92 /// CHECK-NOT: Sub
93
94 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) disassembly (after)
95 /// CHECK: sub x{{\d+}}, x{{\d+}}, w{{\d+}}, sxtb
96
97 public static long $opt$noinline$translate(long l, byte b) {
98 if (doThrow) throw new Error();
99 long tmp = (long)b;
100 return l - tmp;
101 }
102
103
104 /**
105 * Test that we do not merge into the shifter operand when the left and right
106 * inputs are the the IR.
107 */
108
109 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (before)
110 /// CHECK: <<a:i\d+>> ParameterValue
111 /// CHECK: <<Const2:i\d+>> IntConstant 2
112 /// CHECK: <<tmp:i\d+>> Shl [<<a>>,<<Const2>>]
113 /// CHECK: Add [<<tmp>>,<<tmp>>]
114
115 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after)
116 /// CHECK-DAG: <<a:i\d+>> ParameterValue
117 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
118 /// CHECK: <<Shl:i\d+>> Shl [<<a>>,<<Const2>>]
119 /// CHECK: Add [<<Shl>>,<<Shl>>]
120
121 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after)
122 /// CHECK-NOT: Arm64DataProcWithShifterOp
123
124 public static int $opt$noinline$sameInput(int a) {
125 if (doThrow) throw new Error();
126 int tmp = a << 2;
127 return tmp + tmp;
128 }
129
130 /**
131 * Check that we perform the merge for multiple uses.
132 */
133
134 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (before)
135 /// CHECK: <<arg:i\d+>> ParameterValue
136 /// CHECK: <<Const23:i\d+>> IntConstant 23
137 /// CHECK: <<tmp:i\d+>> Shl [<<arg>>,<<Const23>>]
138 /// CHECK: Add [<<tmp>>,{{i\d+}}]
139 /// CHECK: Add [<<tmp>>,{{i\d+}}]
140 /// CHECK: Add [<<tmp>>,{{i\d+}}]
141 /// CHECK: Add [<<tmp>>,{{i\d+}}]
142 /// CHECK: Add [<<tmp>>,{{i\d+}}]
143
144 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after)
145 /// CHECK: <<arg:i\d+>> ParameterValue
146 /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
147 /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
148 /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
149 /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
150 /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
151
152 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after)
153 /// CHECK-NOT: Shl
154 /// CHECK-NOT: Add
155
156 public static int $opt$noinline$multipleUses(int arg) {
157 if (doThrow) throw new Error();
158 int tmp = arg << 23;
159 switch (arg) {
160 case 1: return (arg | 1) + tmp;
161 case 2: return (arg | 2) + tmp;
162 case 3: return (arg | 3) + tmp;
163 case 4: return (arg | 4) + tmp;
164 case (1 << 20): return (arg | 5) + tmp;
165 default: return 0;
166 }
167 }
168
169 /**
170 * Logical instructions cannot take 'extend' operations into the shift
171 * operand, so test that only the shifts are merged.
172 */
173
174 /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm64 (after)
175 /// CHECK: Arm64DataProcWithShifterOp
176 /// CHECK-NOT: Arm64DataProcWithShifterOp
177
178 /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) disassembly (after)
179 /// CHECK: and lsl
180 /// CHECK: sxtb
181 /// CHECK: and
182
183 static void $opt$noinline$testAnd(long a, long b) {
184 if (doThrow) throw new Error();
185 assertLongEquals((a & $noinline$LongShl(b, 5)) | (a & $noinline$longToByte(b)),
186 (a & (b << 5)) | (a & (byte)b));
187 }
188
189 /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm64 (after)
190 /// CHECK: Arm64DataProcWithShifterOp
191 /// CHECK-NOT: Arm64DataProcWithShifterOp
192
193 /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) disassembly (after)
194 /// CHECK: orr asr
195 /// CHECK: uxth
196 /// CHECK: orr
197
198 static void $opt$noinline$testOr(int a, int b) {
199 if (doThrow) throw new Error();
200 assertIntEquals((a | $noinline$IntShr(b, 6)) | (a | $noinline$intToChar(b)),
201 (a | (b >> 6)) | (a | (char)b));
202 }
203
204 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after)
205 /// CHECK: Arm64DataProcWithShifterOp
206 /// CHECK-NOT: Arm64DataProcWithShifterOp
207
208 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after)
209 /// CHECK: eor lsr
210 /// CHECK: sxtw
211 /// CHECK: eor
212
213 static void $opt$noinline$testXor(long a, long b) {
214 if (doThrow) throw new Error();
215 assertLongEquals((a ^ $noinline$LongUshr(b, 7)) | (a ^ $noinline$longToInt(b)),
216 (a ^ (b >>> 7)) | (a ^ (int)b));
217 }
218
219 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after)
220 /// CHECK: Arm64DataProcWithShifterOp
221 /// CHECK-NOT: Arm64DataProcWithShifterOp
222
223 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after)
224 /// CHECK: neg lsl
225 /// CHECK: sxth
226 /// CHECK: neg
227
228 static void $opt$noinline$testNeg(int a) {
229 if (doThrow) throw new Error();
230 assertIntEquals(-$noinline$IntShl(a, 8) | -$noinline$intToShort(a),
231 (-(a << 8)) | (-(short)a));
232 }
233
234 /**
235 * The functions below are used to compare the result of optimized operations
236 * to non-optimized operations.
237 * On the left-hand side we use a non-inlined function call to ensure the
238 * optimization does not occur. The checker tests ensure that the optimization
239 * does occur on the right-hand.
240 */
241
242 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after)
243 /// CHECK: Arm64DataProcWithShifterOp
244 /// CHECK: Arm64DataProcWithShifterOp
245
246 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after)
247 /// CHECK-NOT: TypeConversion
248
249 public static void $opt$validateExtendByteInt1(int a, byte b) {
250 assertIntEquals(a + $noinline$byteToChar (b), a + (char)b);
251 assertIntEquals(a + $noinline$byteToShort(b), a + (short)b);
252 }
253
254 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm64 (after)
255 /// CHECK-NOT: Arm64DataProcWithShifterOp
256 /// CHECK-NOT: Arm64DataProcWithShifterOp
257
258 public static void $opt$validateExtendByteInt2(int a, byte b) {
259 // The conversion to `int` has been optimized away, so there is nothing to merge.
260 assertIntEquals (a + $noinline$byteToInt (b), a + (int)b);
261 // There is an environment use for `(long)b`, preventing the merge.
262 assertLongEquals(a + $noinline$byteToLong(b), a + (long)b);
263 }
264
265 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
266 /// CHECK: Arm64DataProcWithShifterOp
267 /// CHECK: Arm64DataProcWithShifterOp
268 /// CHECK: Arm64DataProcWithShifterOp
269
270 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
271 /// CHECK: TypeConversion
272 /// CHECK: TypeConversion
273 /// CHECK-NOT: TypeConversion
274
275 public static void $opt$validateExtendByteLong(long a, byte b) {
276 // The first two tests have a type conversion.
277 assertLongEquals(a + $noinline$byteToChar (b), a + (char)b);
278 assertLongEquals(a + $noinline$byteToShort(b), a + (short)b);
279 // This test does not because the conversion to `int` is optimized away.
280 assertLongEquals(a + $noinline$byteToInt (b), a + (int)b);
281 }
282
283 public static void $opt$validateExtendByte(long a, byte b) {
284 $opt$validateExtendByteInt1((int)a, b);
285 $opt$validateExtendByteInt2((int)a, b);
286 $opt$validateExtendByteLong(a, b);
287 }
288
289 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
290 /// CHECK: Arm64DataProcWithShifterOp
291 /// CHECK: Arm64DataProcWithShifterOp
292
293 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
294 /// CHECK-NOT: TypeConversion
295
296 public static void $opt$validateExtendCharInt1(int a, char b) {
297 assertIntEquals(a + $noinline$charToByte (b), a + (byte)b);
298 assertIntEquals(a + $noinline$charToShort(b), a + (short)b);
299 }
300
301 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after)
302 /// CHECK-NOT: Arm64DataProcWithShifterOp
303 /// CHECK-NOT: Arm64DataProcWithShifterOp
304
305 public static void $opt$validateExtendCharInt2(int a, char b) {
306 // The conversion to `int` has been optimized away, so there is nothing to merge.
307 assertIntEquals (a + $noinline$charToInt (b), a + (int)b);
308 // There is an environment use for `(long)b`, preventing the merge.
309 assertLongEquals(a + $noinline$charToLong(b), a + (long)b);
310 }
311
312 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
313 /// CHECK: Arm64DataProcWithShifterOp
314 /// CHECK: Arm64DataProcWithShifterOp
315 /// CHECK: Arm64DataProcWithShifterOp
316 /// CHECK: Arm64DataProcWithShifterOp
317
318 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
319 /// CHECK: TypeConversion
320 /// CHECK: TypeConversion
321 /// CHECK-NOT: TypeConversion
322
323 public static void $opt$validateExtendCharLong(long a, char b) {
324 // The first two tests have a type conversion.
325 assertLongEquals(a + $noinline$charToByte (b), a + (byte)b);
326 assertLongEquals(a + $noinline$charToShort(b), a + (short)b);
327 // This test does not because the conversion to `int` is optimized away.
328 assertLongEquals(a + $noinline$charToInt (b), a + (int)b);
329 }
330
331 public static void $opt$validateExtendChar(long a, char b) {
332 $opt$validateExtendCharInt1((int)a, b);
333 $opt$validateExtendCharInt2((int)a, b);
334 $opt$validateExtendCharLong(a, b);
335 }
336
337 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
338 /// CHECK: Arm64DataProcWithShifterOp
339 /// CHECK: Arm64DataProcWithShifterOp
340
341 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
342 /// CHECK-NOT: TypeConversion
343
344 public static void $opt$validateExtendShortInt1(int a, short b) {
345 assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b);
346 assertIntEquals(a + $noinline$shortToChar (b), a + (char)b);
347 }
348
349 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after)
350 /// CHECK-NOT: Arm64DataProcWithShifterOp
351 /// CHECK-NOT: Arm64DataProcWithShifterOp
352
353 public static void $opt$validateExtendShortInt2(int a, short b) {
354 // The conversion to `int` has been optimized away, so there is nothing to merge.
355 assertIntEquals (a + $noinline$shortToInt (b), a + (int)b);
356 // There is an environment use for `(long)b`, preventing the merge.
357 assertLongEquals(a + $noinline$shortToLong (b), a + (long)b);
358 }
359
360 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
361 /// CHECK: Arm64DataProcWithShifterOp
362 /// CHECK: Arm64DataProcWithShifterOp
363 /// CHECK: Arm64DataProcWithShifterOp
364
365 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
366 /// CHECK: TypeConversion
367 /// CHECK: TypeConversion
368 /// CHECK-NOT: TypeConversion
369
370 public static void $opt$validateExtendShortLong(long a, short b) {
371 // The first two tests have a type conversion.
372 assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b);
373 assertLongEquals(a + $noinline$shortToChar(b), a + (char)b);
374 // This test does not because the conversion to `int` is optimized away.
375 assertLongEquals(a + $noinline$shortToInt (b), a + (int)b);
376 }
377
378 public static void $opt$validateExtendShort(long a, short b) {
379 $opt$validateExtendShortInt1((int)a, b);
380 $opt$validateExtendShortInt2((int)a, b);
381 $opt$validateExtendShortLong(a, b);
382 }
383
384 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
385 /// CHECK: Arm64DataProcWithShifterOp
386 /// CHECK: Arm64DataProcWithShifterOp
387 /// CHECK: Arm64DataProcWithShifterOp
388 /// CHECK: Arm64DataProcWithShifterOp
389
390 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
391 /// CHECK: TypeConversion
392 /// CHECK: TypeConversion
393 /// CHECK: TypeConversion
394 /// CHECK-NOT: TypeConversion
395
396 public static void $opt$validateExtendInt(long a, int b) {
397 // All tests have a conversion to `long`. The first three tests also have a
398 // conversion from `int` to the specified type. For each test the conversion
399 // to `long` is merged into the shifter operand.
400 assertLongEquals(a + $noinline$intToByte (b), a + (byte)b);
401 assertLongEquals(a + $noinline$intToChar (b), a + (char)b);
402 assertLongEquals(a + $noinline$intToShort(b), a + (short)b);
403 assertLongEquals(a + $noinline$intToLong (b), a + (long)b);
404 }
405
406 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
407 /// CHECK: Arm64DataProcWithShifterOp
408 /// CHECK: Arm64DataProcWithShifterOp
409 /// CHECK: Arm64DataProcWithShifterOp
410 /// CHECK: Arm64DataProcWithShifterOp
411
412 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
413 /// CHECK: TypeConversion
414 /// CHECK: TypeConversion
415 /// CHECK: TypeConversion
416 /// CHECK: TypeConversion
417 /// CHECK-NOT: TypeConversion
418
419 public static void $opt$validateExtendLong(long a, long b) {
420 // Each test has two conversions, from `long` and then back to `long`. The
421 // conversions to `long` are merged.
422 assertLongEquals(a + $noinline$longToByte (b), a + (byte)b);
423 assertLongEquals(a + $noinline$longToChar (b), a + (char)b);
424 assertLongEquals(a + $noinline$longToShort(b), a + (short)b);
425 assertLongEquals(a + $noinline$longToInt (b), a + (int)b);
426 }
427
428
429 static int $noinline$IntShl(int b, int c) {
430 if (doThrow) throw new Error();
431 return b << c;
432 }
433 static int $noinline$IntShr(int b, int c) {
434 if (doThrow) throw new Error();
435 return b >> c;
436 }
437 static int $noinline$IntUshr(int b, int c) {
438 if (doThrow) throw new Error();
439 return b >>> c;
440 }
441
442
443 // Each test line below should see one merge.
444 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
445 /// CHECK: Arm64DataProcWithShifterOp
446 /// CHECK: Arm64DataProcWithShifterOp
447 /// CHECK: Arm64DataProcWithShifterOp
448 /// CHECK: Arm64DataProcWithShifterOp
449 /// CHECK: Arm64DataProcWithShifterOp
450 /// CHECK: Arm64DataProcWithShifterOp
451 /// CHECK: Arm64DataProcWithShifterOp
452 /// CHECK: Arm64DataProcWithShifterOp
453 /// CHECK: Arm64DataProcWithShifterOp
454 /// CHECK: Arm64DataProcWithShifterOp
455 /// CHECK: Arm64DataProcWithShifterOp
456 /// CHECK: Arm64DataProcWithShifterOp
457 /// CHECK: Arm64DataProcWithShifterOp
458 /// CHECK: Arm64DataProcWithShifterOp
459 /// CHECK: Arm64DataProcWithShifterOp
460 /// CHECK: Arm64DataProcWithShifterOp
461 /// CHECK: Arm64DataProcWithShifterOp
462 /// CHECK: Arm64DataProcWithShifterOp
463 /// CHECK: Arm64DataProcWithShifterOp
464 /// CHECK: Arm64DataProcWithShifterOp
465 /// CHECK: Arm64DataProcWithShifterOp
466 /// CHECK: Arm64DataProcWithShifterOp
467 /// CHECK: Arm64DataProcWithShifterOp
468 /// CHECK: Arm64DataProcWithShifterOp
469 /// CHECK: Arm64DataProcWithShifterOp
470 /// CHECK: Arm64DataProcWithShifterOp
471 /// CHECK: Arm64DataProcWithShifterOp
472 /// CHECK: Arm64DataProcWithShifterOp
473 /// CHECK: Arm64DataProcWithShifterOp
474 /// CHECK: Arm64DataProcWithShifterOp
475 /// CHECK: Arm64DataProcWithShifterOp
476 /// CHECK: Arm64DataProcWithShifterOp
477 /// CHECK: Arm64DataProcWithShifterOp
478 /// CHECK: Arm64DataProcWithShifterOp
479 /// CHECK: Arm64DataProcWithShifterOp
480 /// CHECK: Arm64DataProcWithShifterOp
481
482 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
483 /// CHECK-NOT: Shl
484 /// CHECK-NOT: Shr
485 /// CHECK-NOT: UShr
486
487 public static void $opt$validateShiftInt(int a, int b) {
488 assertIntEquals(a + $noinline$IntShl(b, 1), a + (b << 1));
489 assertIntEquals(a + $noinline$IntShl(b, 6), a + (b << 6));
490 assertIntEquals(a + $noinline$IntShl(b, 7), a + (b << 7));
491 assertIntEquals(a + $noinline$IntShl(b, 8), a + (b << 8));
492 assertIntEquals(a + $noinline$IntShl(b, 14), a + (b << 14));
493 assertIntEquals(a + $noinline$IntShl(b, 15), a + (b << 15));
494 assertIntEquals(a + $noinline$IntShl(b, 16), a + (b << 16));
495 assertIntEquals(a + $noinline$IntShl(b, 30), a + (b << 30));
496 assertIntEquals(a + $noinline$IntShl(b, 31), a + (b << 31));
497 assertIntEquals(a + $noinline$IntShl(b, 32), a + (b << 32));
498 assertIntEquals(a + $noinline$IntShl(b, 62), a + (b << 62));
499 assertIntEquals(a + $noinline$IntShl(b, 63), a + (b << 63));
500
501 assertIntEquals(a - $noinline$IntShr(b, 1), a - (b >> 1));
502 assertIntEquals(a - $noinline$IntShr(b, 6), a - (b >> 6));
503 assertIntEquals(a - $noinline$IntShr(b, 7), a - (b >> 7));
504 assertIntEquals(a - $noinline$IntShr(b, 8), a - (b >> 8));
505 assertIntEquals(a - $noinline$IntShr(b, 14), a - (b >> 14));
506 assertIntEquals(a - $noinline$IntShr(b, 15), a - (b >> 15));
507 assertIntEquals(a - $noinline$IntShr(b, 16), a - (b >> 16));
508 assertIntEquals(a - $noinline$IntShr(b, 30), a - (b >> 30));
509 assertIntEquals(a - $noinline$IntShr(b, 31), a - (b >> 31));
510 assertIntEquals(a - $noinline$IntShr(b, 32), a - (b >> 32));
511 assertIntEquals(a - $noinline$IntShr(b, 62), a - (b >> 62));
512 assertIntEquals(a - $noinline$IntShr(b, 63), a - (b >> 63));
513
514 assertIntEquals(a ^ $noinline$IntUshr(b, 1), a ^ (b >>> 1));
515 assertIntEquals(a ^ $noinline$IntUshr(b, 6), a ^ (b >>> 6));
516 assertIntEquals(a ^ $noinline$IntUshr(b, 7), a ^ (b >>> 7));
517 assertIntEquals(a ^ $noinline$IntUshr(b, 8), a ^ (b >>> 8));
518 assertIntEquals(a ^ $noinline$IntUshr(b, 14), a ^ (b >>> 14));
519 assertIntEquals(a ^ $noinline$IntUshr(b, 15), a ^ (b >>> 15));
520 assertIntEquals(a ^ $noinline$IntUshr(b, 16), a ^ (b >>> 16));
521 assertIntEquals(a ^ $noinline$IntUshr(b, 30), a ^ (b >>> 30));
522 assertIntEquals(a ^ $noinline$IntUshr(b, 31), a ^ (b >>> 31));
523 assertIntEquals(a ^ $noinline$IntUshr(b, 32), a ^ (b >>> 32));
524 assertIntEquals(a ^ $noinline$IntUshr(b, 62), a ^ (b >>> 62));
525 assertIntEquals(a ^ $noinline$IntUshr(b, 63), a ^ (b >>> 63));
526 }
527
528
529 static long $noinline$LongShl(long b, long c) {
530 if (doThrow) throw new Error();
531 return b << c;
532 }
533 static long $noinline$LongShr(long b, long c) {
534 if (doThrow) throw new Error();
535 return b >> c;
536 }
537 static long $noinline$LongUshr(long b, long c) {
538 if (doThrow) throw new Error();
539 return b >>> c;
540 }
541
542 // Each test line below should see one merge.
543 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
544 /// CHECK: Arm64DataProcWithShifterOp
545 /// CHECK: Arm64DataProcWithShifterOp
546 /// CHECK: Arm64DataProcWithShifterOp
547 /// CHECK: Arm64DataProcWithShifterOp
548 /// CHECK: Arm64DataProcWithShifterOp
549 /// CHECK: Arm64DataProcWithShifterOp
550 /// CHECK: Arm64DataProcWithShifterOp
551 /// CHECK: Arm64DataProcWithShifterOp
552 /// CHECK: Arm64DataProcWithShifterOp
553 /// CHECK: Arm64DataProcWithShifterOp
554 /// CHECK: Arm64DataProcWithShifterOp
555 /// CHECK: Arm64DataProcWithShifterOp
556 /// CHECK: Arm64DataProcWithShifterOp
557 /// CHECK: Arm64DataProcWithShifterOp
558 /// CHECK: Arm64DataProcWithShifterOp
559 /// CHECK: Arm64DataProcWithShifterOp
560 /// CHECK: Arm64DataProcWithShifterOp
561 /// CHECK: Arm64DataProcWithShifterOp
562 /// CHECK: Arm64DataProcWithShifterOp
563 /// CHECK: Arm64DataProcWithShifterOp
564 /// CHECK: Arm64DataProcWithShifterOp
565 /// CHECK: Arm64DataProcWithShifterOp
566 /// CHECK: Arm64DataProcWithShifterOp
567 /// CHECK: Arm64DataProcWithShifterOp
568 /// CHECK: Arm64DataProcWithShifterOp
569 /// CHECK: Arm64DataProcWithShifterOp
570 /// CHECK: Arm64DataProcWithShifterOp
571 /// CHECK: Arm64DataProcWithShifterOp
572 /// CHECK: Arm64DataProcWithShifterOp
573 /// CHECK: Arm64DataProcWithShifterOp
574 /// CHECK: Arm64DataProcWithShifterOp
575 /// CHECK: Arm64DataProcWithShifterOp
576 /// CHECK: Arm64DataProcWithShifterOp
577 /// CHECK: Arm64DataProcWithShifterOp
578 /// CHECK: Arm64DataProcWithShifterOp
579 /// CHECK: Arm64DataProcWithShifterOp
580
581 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
582 /// CHECK-NOT: Shl
583 /// CHECK-NOT: Shr
584 /// CHECK-NOT: UShr
585
586 public static void $opt$validateShiftLong(long a, long b) {
587 assertLongEquals(a + $noinline$LongShl(b, 1), a + (b << 1));
588 assertLongEquals(a + $noinline$LongShl(b, 6), a + (b << 6));
589 assertLongEquals(a + $noinline$LongShl(b, 7), a + (b << 7));
590 assertLongEquals(a + $noinline$LongShl(b, 8), a + (b << 8));
591 assertLongEquals(a + $noinline$LongShl(b, 14), a + (b << 14));
592 assertLongEquals(a + $noinline$LongShl(b, 15), a + (b << 15));
593 assertLongEquals(a + $noinline$LongShl(b, 16), a + (b << 16));
594 assertLongEquals(a + $noinline$LongShl(b, 30), a + (b << 30));
595 assertLongEquals(a + $noinline$LongShl(b, 31), a + (b << 31));
596 assertLongEquals(a + $noinline$LongShl(b, 32), a + (b << 32));
597 assertLongEquals(a + $noinline$LongShl(b, 62), a + (b << 62));
598 assertLongEquals(a + $noinline$LongShl(b, 63), a + (b << 63));
599
600 assertLongEquals(a - $noinline$LongShr(b, 1), a - (b >> 1));
601 assertLongEquals(a - $noinline$LongShr(b, 6), a - (b >> 6));
602 assertLongEquals(a - $noinline$LongShr(b, 7), a - (b >> 7));
603 assertLongEquals(a - $noinline$LongShr(b, 8), a - (b >> 8));
604 assertLongEquals(a - $noinline$LongShr(b, 14), a - (b >> 14));
605 assertLongEquals(a - $noinline$LongShr(b, 15), a - (b >> 15));
606 assertLongEquals(a - $noinline$LongShr(b, 16), a - (b >> 16));
607 assertLongEquals(a - $noinline$LongShr(b, 30), a - (b >> 30));
608 assertLongEquals(a - $noinline$LongShr(b, 31), a - (b >> 31));
609 assertLongEquals(a - $noinline$LongShr(b, 32), a - (b >> 32));
610 assertLongEquals(a - $noinline$LongShr(b, 62), a - (b >> 62));
611 assertLongEquals(a - $noinline$LongShr(b, 63), a - (b >> 63));
612
613 assertLongEquals(a ^ $noinline$LongUshr(b, 1), a ^ (b >>> 1));
614 assertLongEquals(a ^ $noinline$LongUshr(b, 6), a ^ (b >>> 6));
615 assertLongEquals(a ^ $noinline$LongUshr(b, 7), a ^ (b >>> 7));
616 assertLongEquals(a ^ $noinline$LongUshr(b, 8), a ^ (b >>> 8));
617 assertLongEquals(a ^ $noinline$LongUshr(b, 14), a ^ (b >>> 14));
618 assertLongEquals(a ^ $noinline$LongUshr(b, 15), a ^ (b >>> 15));
619 assertLongEquals(a ^ $noinline$LongUshr(b, 16), a ^ (b >>> 16));
620 assertLongEquals(a ^ $noinline$LongUshr(b, 30), a ^ (b >>> 30));
621 assertLongEquals(a ^ $noinline$LongUshr(b, 31), a ^ (b >>> 31));
622 assertLongEquals(a ^ $noinline$LongUshr(b, 32), a ^ (b >>> 32));
623 assertLongEquals(a ^ $noinline$LongUshr(b, 62), a ^ (b >>> 62));
624 assertLongEquals(a ^ $noinline$LongUshr(b, 63), a ^ (b >>> 63));
625 }
626
627
628 public static void main(String[] args) {
629 assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3));
630 assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3));
631
632 assertIntEquals(4096, $opt$noinline$sameInput(512));
633 assertIntEquals(-8192, $opt$noinline$sameInput(-1024));
634
635 assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1));
636 assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20));
637
638 long inputs[] = {
639 -((1L << 7) - 1L), -((1L << 7)), -((1L << 7) + 1L),
640 -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L),
641 -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L),
642 -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L),
643 -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L),
644 -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L),
645 -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L,
646 -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L,
647 0L,
648 1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L,
649 42L, 314L, 2718281828L, 0x123456789L, 0x987654321L,
650 (1L << 7) - 1L, (1L << 7), (1L << 7) + 1L,
651 (1L << 8) - 1L, (1L << 8), (1L << 8) + 1L,
652 (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L,
653 (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L,
654 (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L,
655 (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L,
656 (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L,
657 Long.MIN_VALUE, Long.MAX_VALUE
658 };
659 for (int i = 0; i < inputs.length; i++) {
660 $opt$noinline$testNeg((int)inputs[i]);
661 for (int j = 0; j < inputs.length; j++) {
662 $opt$noinline$testAnd(inputs[i], inputs[j]);
663 $opt$noinline$testOr((int)inputs[i], (int)inputs[j]);
664 $opt$noinline$testXor(inputs[i], inputs[j]);
665
666 $opt$validateExtendByte(inputs[i], (byte)inputs[j]);
667 $opt$validateExtendChar(inputs[i], (char)inputs[j]);
668 $opt$validateExtendShort(inputs[i], (short)inputs[j]);
669 $opt$validateExtendInt(inputs[i], (int)inputs[j]);
670 $opt$validateExtendLong(inputs[i], inputs[j]);
671
672 $opt$validateShiftInt((int)inputs[i], (int)inputs[j]);
673 $opt$validateShiftLong(inputs[i], inputs[j]);
674 }
675 }
676
677 }
678}