blob: 9c86154bd4d3a48f55c166942167578ab2090ad2 [file] [log] [blame]
Alexandre Rames8626b742015-11-25 16:28:08 +00001/*
Roland Levillainfb7fc7b2016-02-24 15:41:20 +00002 * 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 */
Alexandre Rames8626b742015-11-25 16:28:08 +000016
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
Vladimir Markob52bbde2016-02-12 12:06:05 +0000244 /// CHECK-NOT: Arm64DataProcWithShifterOp
Alexandre Rames8626b742015-11-25 16:28:08 +0000245
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);
Vladimir Markob52bbde2016-02-12 12:06:05 +0000251 // Conversions byte->short and short->int are implicit; nothing to merge.
Alexandre Rames8626b742015-11-25 16:28:08 +0000252 assertIntEquals(a + $noinline$byteToShort(b), a + (short)b);
253 }
254
255 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm64 (after)
256 /// CHECK-NOT: Arm64DataProcWithShifterOp
257 /// CHECK-NOT: Arm64DataProcWithShifterOp
258
259 public static void $opt$validateExtendByteInt2(int a, byte b) {
260 // The conversion to `int` has been optimized away, so there is nothing to merge.
261 assertIntEquals (a + $noinline$byteToInt (b), a + (int)b);
262 // There is an environment use for `(long)b`, preventing the merge.
263 assertLongEquals(a + $noinline$byteToLong(b), a + (long)b);
264 }
265
266 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
267 /// CHECK: Arm64DataProcWithShifterOp
268 /// CHECK: Arm64DataProcWithShifterOp
269 /// CHECK: Arm64DataProcWithShifterOp
Vladimir Markob52bbde2016-02-12 12:06:05 +0000270 /// CHECK: Arm64DataProcWithShifterOp
271 /// CHECK: Arm64DataProcWithShifterOp
272 /// CHECK-NOT: Arm64DataProcWithShifterOp
Alexandre Rames8626b742015-11-25 16:28:08 +0000273
274 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
275 /// CHECK: TypeConversion
Alexandre Rames8626b742015-11-25 16:28:08 +0000276 /// CHECK-NOT: TypeConversion
277
278 public static void $opt$validateExtendByteLong(long a, byte b) {
Vladimir Markob52bbde2016-02-12 12:06:05 +0000279 // In each of the following tests, there will be a merge on the LHS.
280
281 // The first test has an explicit byte->char conversion on RHS,
282 // followed by a conversion that is merged with the Add.
Alexandre Rames8626b742015-11-25 16:28:08 +0000283 assertLongEquals(a + $noinline$byteToChar (b), a + (char)b);
Vladimir Markob52bbde2016-02-12 12:06:05 +0000284 // Since conversions byte->short and byte->int are implicit, the RHS
285 // for the two tests below is the same and one is eliminated by GVN.
286 // The other is then merged to a shifter operand instruction.
Alexandre Rames8626b742015-11-25 16:28:08 +0000287 assertLongEquals(a + $noinline$byteToShort(b), a + (short)b);
Alexandre Rames8626b742015-11-25 16:28:08 +0000288 assertLongEquals(a + $noinline$byteToInt (b), a + (int)b);
289 }
290
291 public static void $opt$validateExtendByte(long a, byte b) {
292 $opt$validateExtendByteInt1((int)a, b);
293 $opt$validateExtendByteInt2((int)a, b);
294 $opt$validateExtendByteLong(a, b);
295 }
296
297 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
298 /// CHECK: Arm64DataProcWithShifterOp
299 /// CHECK: Arm64DataProcWithShifterOp
300
301 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
302 /// CHECK-NOT: TypeConversion
303
304 public static void $opt$validateExtendCharInt1(int a, char b) {
305 assertIntEquals(a + $noinline$charToByte (b), a + (byte)b);
306 assertIntEquals(a + $noinline$charToShort(b), a + (short)b);
307 }
308
309 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after)
310 /// CHECK-NOT: Arm64DataProcWithShifterOp
311 /// CHECK-NOT: Arm64DataProcWithShifterOp
312
313 public static void $opt$validateExtendCharInt2(int a, char b) {
314 // The conversion to `int` has been optimized away, so there is nothing to merge.
315 assertIntEquals (a + $noinline$charToInt (b), a + (int)b);
316 // There is an environment use for `(long)b`, preventing the merge.
317 assertLongEquals(a + $noinline$charToLong(b), a + (long)b);
318 }
319
320 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
321 /// CHECK: Arm64DataProcWithShifterOp
322 /// CHECK: Arm64DataProcWithShifterOp
323 /// CHECK: Arm64DataProcWithShifterOp
324 /// CHECK: Arm64DataProcWithShifterOp
325
326 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
327 /// CHECK: TypeConversion
328 /// CHECK: TypeConversion
329 /// CHECK-NOT: TypeConversion
330
331 public static void $opt$validateExtendCharLong(long a, char b) {
332 // The first two tests have a type conversion.
333 assertLongEquals(a + $noinline$charToByte (b), a + (byte)b);
334 assertLongEquals(a + $noinline$charToShort(b), a + (short)b);
335 // This test does not because the conversion to `int` is optimized away.
336 assertLongEquals(a + $noinline$charToInt (b), a + (int)b);
337 }
338
339 public static void $opt$validateExtendChar(long a, char b) {
340 $opt$validateExtendCharInt1((int)a, b);
341 $opt$validateExtendCharInt2((int)a, b);
342 $opt$validateExtendCharLong(a, b);
343 }
344
345 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
346 /// CHECK: Arm64DataProcWithShifterOp
347 /// CHECK: Arm64DataProcWithShifterOp
348
349 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
350 /// CHECK-NOT: TypeConversion
351
352 public static void $opt$validateExtendShortInt1(int a, short b) {
353 assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b);
354 assertIntEquals(a + $noinline$shortToChar (b), a + (char)b);
355 }
356
357 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after)
358 /// CHECK-NOT: Arm64DataProcWithShifterOp
359 /// CHECK-NOT: Arm64DataProcWithShifterOp
360
361 public static void $opt$validateExtendShortInt2(int a, short b) {
362 // The conversion to `int` has been optimized away, so there is nothing to merge.
363 assertIntEquals (a + $noinline$shortToInt (b), a + (int)b);
364 // There is an environment use for `(long)b`, preventing the merge.
365 assertLongEquals(a + $noinline$shortToLong (b), a + (long)b);
366 }
367
368 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
369 /// CHECK: Arm64DataProcWithShifterOp
370 /// CHECK: Arm64DataProcWithShifterOp
371 /// CHECK: Arm64DataProcWithShifterOp
372
373 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
374 /// CHECK: TypeConversion
375 /// CHECK: TypeConversion
376 /// CHECK-NOT: TypeConversion
377
378 public static void $opt$validateExtendShortLong(long a, short b) {
379 // The first two tests have a type conversion.
380 assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b);
381 assertLongEquals(a + $noinline$shortToChar(b), a + (char)b);
382 // This test does not because the conversion to `int` is optimized away.
383 assertLongEquals(a + $noinline$shortToInt (b), a + (int)b);
384 }
385
386 public static void $opt$validateExtendShort(long a, short b) {
387 $opt$validateExtendShortInt1((int)a, b);
388 $opt$validateExtendShortInt2((int)a, b);
389 $opt$validateExtendShortLong(a, b);
390 }
391
392 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
393 /// CHECK: Arm64DataProcWithShifterOp
394 /// CHECK: Arm64DataProcWithShifterOp
395 /// CHECK: Arm64DataProcWithShifterOp
396 /// CHECK: Arm64DataProcWithShifterOp
397
398 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
399 /// CHECK: TypeConversion
400 /// CHECK: TypeConversion
401 /// CHECK: TypeConversion
402 /// CHECK-NOT: TypeConversion
403
404 public static void $opt$validateExtendInt(long a, int b) {
405 // All tests have a conversion to `long`. The first three tests also have a
406 // conversion from `int` to the specified type. For each test the conversion
407 // to `long` is merged into the shifter operand.
408 assertLongEquals(a + $noinline$intToByte (b), a + (byte)b);
409 assertLongEquals(a + $noinline$intToChar (b), a + (char)b);
410 assertLongEquals(a + $noinline$intToShort(b), a + (short)b);
411 assertLongEquals(a + $noinline$intToLong (b), a + (long)b);
412 }
413
414 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
415 /// CHECK: Arm64DataProcWithShifterOp
416 /// CHECK: Arm64DataProcWithShifterOp
417 /// CHECK: Arm64DataProcWithShifterOp
418 /// CHECK: Arm64DataProcWithShifterOp
419
420 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
421 /// CHECK: TypeConversion
422 /// CHECK: TypeConversion
423 /// CHECK: TypeConversion
424 /// CHECK: TypeConversion
425 /// CHECK-NOT: TypeConversion
426
427 public static void $opt$validateExtendLong(long a, long b) {
428 // Each test has two conversions, from `long` and then back to `long`. The
429 // conversions to `long` are merged.
430 assertLongEquals(a + $noinline$longToByte (b), a + (byte)b);
431 assertLongEquals(a + $noinline$longToChar (b), a + (char)b);
432 assertLongEquals(a + $noinline$longToShort(b), a + (short)b);
433 assertLongEquals(a + $noinline$longToInt (b), a + (int)b);
434 }
435
436
437 static int $noinline$IntShl(int b, int c) {
438 if (doThrow) throw new Error();
439 return b << c;
440 }
441 static int $noinline$IntShr(int b, int c) {
442 if (doThrow) throw new Error();
443 return b >> c;
444 }
445 static int $noinline$IntUshr(int b, int c) {
446 if (doThrow) throw new Error();
447 return b >>> c;
448 }
449
450
451 // Each test line below should see one merge.
452 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
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 /// CHECK: Arm64DataProcWithShifterOp
482 /// CHECK: Arm64DataProcWithShifterOp
483 /// CHECK: Arm64DataProcWithShifterOp
484 /// CHECK: Arm64DataProcWithShifterOp
485 /// CHECK: Arm64DataProcWithShifterOp
486 /// CHECK: Arm64DataProcWithShifterOp
487 /// CHECK: Arm64DataProcWithShifterOp
488 /// CHECK: Arm64DataProcWithShifterOp
489
490 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
491 /// CHECK-NOT: Shl
492 /// CHECK-NOT: Shr
493 /// CHECK-NOT: UShr
494
495 public static void $opt$validateShiftInt(int a, int b) {
496 assertIntEquals(a + $noinline$IntShl(b, 1), a + (b << 1));
497 assertIntEquals(a + $noinline$IntShl(b, 6), a + (b << 6));
498 assertIntEquals(a + $noinline$IntShl(b, 7), a + (b << 7));
499 assertIntEquals(a + $noinline$IntShl(b, 8), a + (b << 8));
500 assertIntEquals(a + $noinline$IntShl(b, 14), a + (b << 14));
501 assertIntEquals(a + $noinline$IntShl(b, 15), a + (b << 15));
502 assertIntEquals(a + $noinline$IntShl(b, 16), a + (b << 16));
503 assertIntEquals(a + $noinline$IntShl(b, 30), a + (b << 30));
504 assertIntEquals(a + $noinline$IntShl(b, 31), a + (b << 31));
505 assertIntEquals(a + $noinline$IntShl(b, 32), a + (b << 32));
506 assertIntEquals(a + $noinline$IntShl(b, 62), a + (b << 62));
507 assertIntEquals(a + $noinline$IntShl(b, 63), a + (b << 63));
508
509 assertIntEquals(a - $noinline$IntShr(b, 1), a - (b >> 1));
510 assertIntEquals(a - $noinline$IntShr(b, 6), a - (b >> 6));
511 assertIntEquals(a - $noinline$IntShr(b, 7), a - (b >> 7));
512 assertIntEquals(a - $noinline$IntShr(b, 8), a - (b >> 8));
513 assertIntEquals(a - $noinline$IntShr(b, 14), a - (b >> 14));
514 assertIntEquals(a - $noinline$IntShr(b, 15), a - (b >> 15));
515 assertIntEquals(a - $noinline$IntShr(b, 16), a - (b >> 16));
516 assertIntEquals(a - $noinline$IntShr(b, 30), a - (b >> 30));
517 assertIntEquals(a - $noinline$IntShr(b, 31), a - (b >> 31));
518 assertIntEquals(a - $noinline$IntShr(b, 32), a - (b >> 32));
519 assertIntEquals(a - $noinline$IntShr(b, 62), a - (b >> 62));
520 assertIntEquals(a - $noinline$IntShr(b, 63), a - (b >> 63));
521
522 assertIntEquals(a ^ $noinline$IntUshr(b, 1), a ^ (b >>> 1));
523 assertIntEquals(a ^ $noinline$IntUshr(b, 6), a ^ (b >>> 6));
524 assertIntEquals(a ^ $noinline$IntUshr(b, 7), a ^ (b >>> 7));
525 assertIntEquals(a ^ $noinline$IntUshr(b, 8), a ^ (b >>> 8));
526 assertIntEquals(a ^ $noinline$IntUshr(b, 14), a ^ (b >>> 14));
527 assertIntEquals(a ^ $noinline$IntUshr(b, 15), a ^ (b >>> 15));
528 assertIntEquals(a ^ $noinline$IntUshr(b, 16), a ^ (b >>> 16));
529 assertIntEquals(a ^ $noinline$IntUshr(b, 30), a ^ (b >>> 30));
530 assertIntEquals(a ^ $noinline$IntUshr(b, 31), a ^ (b >>> 31));
531 assertIntEquals(a ^ $noinline$IntUshr(b, 32), a ^ (b >>> 32));
532 assertIntEquals(a ^ $noinline$IntUshr(b, 62), a ^ (b >>> 62));
533 assertIntEquals(a ^ $noinline$IntUshr(b, 63), a ^ (b >>> 63));
534 }
535
536
537 static long $noinline$LongShl(long b, long c) {
538 if (doThrow) throw new Error();
539 return b << c;
540 }
541 static long $noinline$LongShr(long b, long c) {
542 if (doThrow) throw new Error();
543 return b >> c;
544 }
545 static long $noinline$LongUshr(long b, long c) {
546 if (doThrow) throw new Error();
547 return b >>> c;
548 }
549
550 // Each test line below should see one merge.
551 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
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 /// CHECK: Arm64DataProcWithShifterOp
581 /// CHECK: Arm64DataProcWithShifterOp
582 /// CHECK: Arm64DataProcWithShifterOp
583 /// CHECK: Arm64DataProcWithShifterOp
584 /// CHECK: Arm64DataProcWithShifterOp
585 /// CHECK: Arm64DataProcWithShifterOp
586 /// CHECK: Arm64DataProcWithShifterOp
587 /// CHECK: Arm64DataProcWithShifterOp
588
589 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
590 /// CHECK-NOT: Shl
591 /// CHECK-NOT: Shr
592 /// CHECK-NOT: UShr
593
594 public static void $opt$validateShiftLong(long a, long b) {
595 assertLongEquals(a + $noinline$LongShl(b, 1), a + (b << 1));
596 assertLongEquals(a + $noinline$LongShl(b, 6), a + (b << 6));
597 assertLongEquals(a + $noinline$LongShl(b, 7), a + (b << 7));
598 assertLongEquals(a + $noinline$LongShl(b, 8), a + (b << 8));
599 assertLongEquals(a + $noinline$LongShl(b, 14), a + (b << 14));
600 assertLongEquals(a + $noinline$LongShl(b, 15), a + (b << 15));
601 assertLongEquals(a + $noinline$LongShl(b, 16), a + (b << 16));
602 assertLongEquals(a + $noinline$LongShl(b, 30), a + (b << 30));
603 assertLongEquals(a + $noinline$LongShl(b, 31), a + (b << 31));
604 assertLongEquals(a + $noinline$LongShl(b, 32), a + (b << 32));
605 assertLongEquals(a + $noinline$LongShl(b, 62), a + (b << 62));
606 assertLongEquals(a + $noinline$LongShl(b, 63), a + (b << 63));
607
608 assertLongEquals(a - $noinline$LongShr(b, 1), a - (b >> 1));
609 assertLongEquals(a - $noinline$LongShr(b, 6), a - (b >> 6));
610 assertLongEquals(a - $noinline$LongShr(b, 7), a - (b >> 7));
611 assertLongEquals(a - $noinline$LongShr(b, 8), a - (b >> 8));
612 assertLongEquals(a - $noinline$LongShr(b, 14), a - (b >> 14));
613 assertLongEquals(a - $noinline$LongShr(b, 15), a - (b >> 15));
614 assertLongEquals(a - $noinline$LongShr(b, 16), a - (b >> 16));
615 assertLongEquals(a - $noinline$LongShr(b, 30), a - (b >> 30));
616 assertLongEquals(a - $noinline$LongShr(b, 31), a - (b >> 31));
617 assertLongEquals(a - $noinline$LongShr(b, 32), a - (b >> 32));
618 assertLongEquals(a - $noinline$LongShr(b, 62), a - (b >> 62));
619 assertLongEquals(a - $noinline$LongShr(b, 63), a - (b >> 63));
620
621 assertLongEquals(a ^ $noinline$LongUshr(b, 1), a ^ (b >>> 1));
622 assertLongEquals(a ^ $noinline$LongUshr(b, 6), a ^ (b >>> 6));
623 assertLongEquals(a ^ $noinline$LongUshr(b, 7), a ^ (b >>> 7));
624 assertLongEquals(a ^ $noinline$LongUshr(b, 8), a ^ (b >>> 8));
625 assertLongEquals(a ^ $noinline$LongUshr(b, 14), a ^ (b >>> 14));
626 assertLongEquals(a ^ $noinline$LongUshr(b, 15), a ^ (b >>> 15));
627 assertLongEquals(a ^ $noinline$LongUshr(b, 16), a ^ (b >>> 16));
628 assertLongEquals(a ^ $noinline$LongUshr(b, 30), a ^ (b >>> 30));
629 assertLongEquals(a ^ $noinline$LongUshr(b, 31), a ^ (b >>> 31));
630 assertLongEquals(a ^ $noinline$LongUshr(b, 32), a ^ (b >>> 32));
631 assertLongEquals(a ^ $noinline$LongUshr(b, 62), a ^ (b >>> 62));
632 assertLongEquals(a ^ $noinline$LongUshr(b, 63), a ^ (b >>> 63));
633 }
634
635
636 public static void main(String[] args) {
637 assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3));
638 assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3));
639
640 assertIntEquals(4096, $opt$noinline$sameInput(512));
641 assertIntEquals(-8192, $opt$noinline$sameInput(-1024));
642
643 assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1));
644 assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20));
645
646 long inputs[] = {
647 -((1L << 7) - 1L), -((1L << 7)), -((1L << 7) + 1L),
648 -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L),
649 -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L),
650 -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L),
651 -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L),
652 -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L),
653 -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L,
654 -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L,
655 0L,
656 1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L,
657 42L, 314L, 2718281828L, 0x123456789L, 0x987654321L,
658 (1L << 7) - 1L, (1L << 7), (1L << 7) + 1L,
659 (1L << 8) - 1L, (1L << 8), (1L << 8) + 1L,
660 (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L,
661 (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L,
662 (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L,
663 (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L,
664 (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L,
665 Long.MIN_VALUE, Long.MAX_VALUE
666 };
667 for (int i = 0; i < inputs.length; i++) {
668 $opt$noinline$testNeg((int)inputs[i]);
669 for (int j = 0; j < inputs.length; j++) {
670 $opt$noinline$testAnd(inputs[i], inputs[j]);
671 $opt$noinline$testOr((int)inputs[i], (int)inputs[j]);
672 $opt$noinline$testXor(inputs[i], inputs[j]);
673
674 $opt$validateExtendByte(inputs[i], (byte)inputs[j]);
675 $opt$validateExtendChar(inputs[i], (char)inputs[j]);
676 $opt$validateExtendShort(inputs[i], (short)inputs[j]);
677 $opt$validateExtendInt(inputs[i], (int)inputs[j]);
678 $opt$validateExtendLong(inputs[i], inputs[j]);
679
680 $opt$validateShiftInt((int)inputs[i], (int)inputs[j]);
681 $opt$validateShiftLong(inputs[i], inputs[j]);
682 }
683 }
684
685 }
686}