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
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-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (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-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after)
86  /// CHECK-DAG:   <<l:j\d+>>           ParameterValue
87  /// CHECK-DAG:   <<b:b\d+>>           ParameterValue
88  /// CHECK:                            DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB
89
90  /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after)
91  /// CHECK-NOT:                        TypeConversion
92  /// CHECK-NOT:                        Sub
93
94  /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) disassembly (after)
95  /// CHECK:                            subs r{{\d+}}, r{{\d+}}, r{{\d+}}
96  /// CHECK:                            sbc r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31
97
98  /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (before)
99  /// CHECK-DAG:   <<l:j\d+>>           ParameterValue
100  /// CHECK-DAG:   <<b:b\d+>>           ParameterValue
101  /// CHECK:       <<tmp:j\d+>>         TypeConversion [<<b>>]
102  /// CHECK:                            Sub [<<l>>,<<tmp>>]
103
104  /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after)
105  /// CHECK-DAG:   <<l:j\d+>>           ParameterValue
106  /// CHECK-DAG:   <<b:b\d+>>           ParameterValue
107  /// CHECK:                            DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB
108
109  /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after)
110  /// CHECK-NOT:                        TypeConversion
111  /// CHECK-NOT:                        Sub
112
113  /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) disassembly (after)
114  /// CHECK:                            sub x{{\d+}}, x{{\d+}}, w{{\d+}}, sxtb
115
116  public static long $opt$noinline$translate(long l, byte b) {
117    if (doThrow) throw new Error();
118    long tmp = (long)b;
119    return l - tmp;
120  }
121
122
123  /**
124   * Test that we do not merge into the shifter operand when the left and right
125   * inputs are the the IR.
126   */
127
128  /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (before)
129  /// CHECK:       <<a:i\d+>>           ParameterValue
130  /// CHECK:       <<Const2:i\d+>>      IntConstant 2
131  /// CHECK:       <<tmp:i\d+>>         Shl [<<a>>,<<Const2>>]
132  /// CHECK:                            Add [<<tmp>>,<<tmp>>]
133
134  /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after)
135  /// CHECK-DAG:   <<a:i\d+>>           ParameterValue
136  /// CHECK-DAG:   <<Const2:i\d+>>      IntConstant 2
137  /// CHECK:       <<Shl:i\d+>>         Shl [<<a>>,<<Const2>>]
138  /// CHECK:                            Add [<<Shl>>,<<Shl>>]
139
140  /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after)
141  /// CHECK-NOT:                        DataProcWithShifterOp
142
143  /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (before)
144  /// CHECK:       <<a:i\d+>>           ParameterValue
145  /// CHECK:       <<Const2:i\d+>>      IntConstant 2
146  /// CHECK:       <<tmp:i\d+>>         Shl [<<a>>,<<Const2>>]
147  /// CHECK:                            Add [<<tmp>>,<<tmp>>]
148
149  /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after)
150  /// CHECK-DAG:   <<a:i\d+>>           ParameterValue
151  /// CHECK-DAG:   <<Const2:i\d+>>      IntConstant 2
152  /// CHECK:       <<Shl:i\d+>>         Shl [<<a>>,<<Const2>>]
153  /// CHECK:                            Add [<<Shl>>,<<Shl>>]
154
155  /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after)
156  /// CHECK-NOT:                        DataProcWithShifterOp
157
158  public static int $opt$noinline$sameInput(int a) {
159    if (doThrow) throw new Error();
160    int tmp = a << 2;
161    return tmp + tmp;
162  }
163
164  /**
165   * Check that we perform the merge for multiple uses.
166   */
167
168  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (before)
169  /// CHECK:       <<arg:i\d+>>         ParameterValue
170  /// CHECK:       <<Const23:i\d+>>     IntConstant 23
171  /// CHECK:       <<tmp:i\d+>>         Shl [<<arg>>,<<Const23>>]
172  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
173  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
174  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
175  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
176  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
177
178  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after)
179  /// CHECK:       <<arg:i\d+>>         ParameterValue
180  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
181  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
182  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
183  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
184  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
185
186  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after)
187  /// CHECK-NOT:                        Shl
188  /// CHECK-NOT:                        Add
189
190  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (before)
191  /// CHECK:       <<arg:i\d+>>         ParameterValue
192  /// CHECK:       <<Const23:i\d+>>     IntConstant 23
193  /// CHECK:       <<tmp:i\d+>>         Shl [<<arg>>,<<Const23>>]
194  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
195  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
196  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
197  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
198  /// CHECK:                            Add [<<tmp>>,{{i\d+}}]
199
200  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after)
201  /// CHECK:       <<arg:i\d+>>         ParameterValue
202  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
203  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
204  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
205  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
206  /// CHECK:                            DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23
207
208  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after)
209  /// CHECK-NOT:                        Shl
210  /// CHECK-NOT:                        Add
211
212  public static int $opt$noinline$multipleUses(int arg) {
213    if (doThrow) throw new Error();
214    int tmp = arg << 23;
215    switch (arg) {
216      case 1:  return (arg | 1) + tmp;
217      case 2:  return (arg | 2) + tmp;
218      case 3:  return (arg | 3) + tmp;
219      case 4:  return (arg | 4) + tmp;
220      case (1 << 20):  return (arg | 5) + tmp;
221      default: return 0;
222    }
223  }
224
225  /**
226   * Logical instructions cannot take 'extend' operations into the shift
227   * operand, so test that only the shifts are merged.
228   */
229
230  /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm (after)
231  /// CHECK:                            DataProcWithShifterOp
232  /// CHECK-NOT:                        DataProcWithShifterOp
233
234  /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) disassembly (after)
235  /// CHECK:                            and lsl
236  /// CHECK:                            sbfx
237  /// CHECK:                            asr{{s?}}
238  /// CHECK:                            and{{s?}}
239
240  /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm64 (after)
241  /// CHECK:                            DataProcWithShifterOp
242  /// CHECK-NOT:                        DataProcWithShifterOp
243
244  /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) disassembly (after)
245  /// CHECK:                            and lsl
246  /// CHECK:                            sxtb
247  /// CHECK:                            and
248
249  static void $opt$noinline$testAnd(long a, long b) {
250    if (doThrow) throw new Error();
251    assertLongEquals((a & $noinline$LongShl(b, 5)) | (a & $noinline$longToByte(b)),
252                     (a & (b << 5)) | (a & (byte)b));
253  }
254
255  /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm (after)
256  /// CHECK:                            DataProcWithShifterOp
257  /// CHECK-NOT:                        DataProcWithShifterOp
258
259  /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) disassembly (after)
260  /// CHECK:                            orr asr
261  /// CHECK:                            ubfx
262  /// CHECK:                            orr{{s?}}
263
264  /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm64 (after)
265  /// CHECK:                            DataProcWithShifterOp
266  /// CHECK-NOT:                        DataProcWithShifterOp
267
268  /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) disassembly (after)
269  /// CHECK:                            orr asr
270  /// CHECK:                            uxth
271  /// CHECK:                            orr
272
273  static void $opt$noinline$testOr(int a, int b) {
274    if (doThrow) throw new Error();
275    assertIntEquals((a | $noinline$IntShr(b, 6)) | (a | $noinline$intToChar(b)),
276                    (a | (b >> 6)) | (a | (char)b));
277  }
278
279  /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm (after)
280  /// CHECK:                            DataProcWithShifterOp
281  /// CHECK-NOT:                        DataProcWithShifterOp
282
283  /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) disassembly (after)
284  /// CHECK:                            eor lsr
285  /// CHECK:                            asr{{s?}}
286  /// CHECK:                            eor{{s?}}
287
288  /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after)
289  /// CHECK:                            DataProcWithShifterOp
290  /// CHECK-NOT:                        DataProcWithShifterOp
291
292  /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after)
293  /// CHECK:                            eor lsr
294  /// CHECK:                            sxtw
295  /// CHECK:                            eor
296
297  static void $opt$noinline$testXor(long a, long b) {
298    if (doThrow) throw new Error();
299    assertLongEquals((a ^ $noinline$LongUshr(b, 7)) | (a ^ $noinline$longToInt(b)),
300                     (a ^ (b >>> 7)) | (a ^ (int)b));
301  }
302
303  /// CHECK-START-ARM: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm (after)
304  /// CHECK-NOT:                            DataProcWithShifterOp
305
306  /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after)
307  /// CHECK:                            DataProcWithShifterOp
308  /// CHECK-NOT:                        DataProcWithShifterOp
309
310  /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after)
311  /// CHECK:                            neg lsl
312  /// CHECK:                            sxth
313  /// CHECK:                            neg
314
315  static void $opt$noinline$testNeg(int a) {
316    if (doThrow) throw new Error();
317    assertIntEquals(-$noinline$IntShl(a, 8) | -$noinline$intToShort(a),
318                    (-(a << 8)) | (-(short)a));
319  }
320
321  /**
322   * The functions below are used to compare the result of optimized operations
323   * to non-optimized operations.
324   * On the left-hand side we use a non-inlined function call to ensure the
325   * optimization does not occur. The checker tests ensure that the optimization
326   * does occur on the right-hand.
327   */
328
329  /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after)
330  /// CHECK:                            DataProcWithShifterOp
331  /// CHECK-NOT:                        DataProcWithShifterOp
332
333  /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after)
334  /// CHECK:                            DataProcWithShifterOp
335  /// CHECK-NOT:                        DataProcWithShifterOp
336
337  /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after)
338  /// CHECK-NOT:                        TypeConversion
339
340  public static void $opt$validateExtendByteInt1(int a, byte b) {
341    assertIntEquals(a + $noinline$byteToChar (b), a +  (char)b);
342    // Conversions byte->short and short->int are implicit; nothing to merge.
343    assertIntEquals(a + $noinline$byteToShort(b), a + (short)b);
344  }
345
346  /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm (after)
347  /// CHECK-NOT:                        DataProcWithShifterOp
348
349  /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm64 (after)
350  /// CHECK-NOT:                        DataProcWithShifterOp
351
352  public static void $opt$validateExtendByteInt2(int a, byte b) {
353    // The conversion to `int` has been optimized away, so there is nothing to merge.
354    assertIntEquals (a + $noinline$byteToInt (b), a +  (int)b);
355    // There is an environment use for `(long)b`, preventing the merge.
356    assertLongEquals(a + $noinline$byteToLong(b), a + (long)b);
357  }
358
359  /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after)
360  /// CHECK:                            DataProcWithShifterOp
361  /// CHECK:                            DataProcWithShifterOp
362  /// CHECK:                            DataProcWithShifterOp
363  /// CHECK:                            DataProcWithShifterOp
364  /// CHECK:                            DataProcWithShifterOp
365  /// CHECK-NOT:                        DataProcWithShifterOp
366
367  /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after)
368  /// CHECK:                            TypeConversion
369  /// CHECK-NOT:                        TypeConversion
370
371  /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
372  /// CHECK:                            DataProcWithShifterOp
373  /// CHECK:                            DataProcWithShifterOp
374  /// CHECK:                            DataProcWithShifterOp
375  /// CHECK:                            DataProcWithShifterOp
376  /// CHECK:                            DataProcWithShifterOp
377  /// CHECK-NOT:                        DataProcWithShifterOp
378
379  /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after)
380  /// CHECK:                            TypeConversion
381  /// CHECK-NOT:                        TypeConversion
382
383  public static void $opt$validateExtendByteLong(long a, byte b) {
384    // In each of the following tests, there will be a merge on the LHS.
385
386    // The first test has an explicit byte->char conversion on RHS,
387    // followed by a conversion that is merged with the Add.
388    assertLongEquals(a + $noinline$byteToChar (b), a +  (char)b);
389    // Since conversions byte->short and byte->int are implicit, the RHS
390    // for the two tests below is the same and one is eliminated by GVN.
391    // The other is then merged to a shifter operand instruction.
392    assertLongEquals(a + $noinline$byteToShort(b), a + (short)b);
393    assertLongEquals(a + $noinline$byteToInt  (b), a +  (int)b);
394  }
395
396  public static void $opt$validateExtendByte(long a, byte b) {
397    $opt$validateExtendByteInt1((int)a, b);
398    $opt$validateExtendByteInt2((int)a, b);
399    $opt$validateExtendByteLong(a, b);
400  }
401
402  /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm (after)
403  /// CHECK:                            DataProcWithShifterOp
404  /// CHECK:                            DataProcWithShifterOp
405  /// CHECK-NOT:                        DataProcWithShifterOp
406
407  /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
408  /// CHECK:                            DataProcWithShifterOp
409  /// CHECK:                            DataProcWithShifterOp
410
411  /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
412  /// CHECK-NOT:                        TypeConversion
413
414  public static void $opt$validateExtendCharInt1(int a, char b) {
415    assertIntEquals(a + $noinline$charToByte (b), a +  (byte)b);
416    assertIntEquals(a + $noinline$charToShort(b), a + (short)b);
417  }
418
419  /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm (after)
420  /// CHECK-NOT:                        DataProcWithShifterOp
421
422  /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after)
423  /// CHECK-NOT:                        DataProcWithShifterOp
424
425  public static void $opt$validateExtendCharInt2(int a, char b) {
426    // The conversion to `int` has been optimized away, so there is nothing to merge.
427    assertIntEquals (a + $noinline$charToInt (b), a +  (int)b);
428    // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge.
429    assertLongEquals(a + $noinline$charToLong(b), a + (long)b);
430  }
431
432  /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after)
433  /// CHECK:                            DataProcWithShifterOp
434  /// CHECK:                            DataProcWithShifterOp
435  /// CHECK:                            DataProcWithShifterOp
436  /// CHECK:                            DataProcWithShifterOp
437  /// CHECK:                            DataProcWithShifterOp
438  /// CHECK:                            DataProcWithShifterOp
439  /// CHECK-NOT:                        DataProcWithShifterOp
440
441  /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after)
442  /// CHECK:                            TypeConversion
443  /// CHECK:                            TypeConversion
444  /// CHECK-NOT:                        TypeConversion
445
446  /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
447  /// CHECK:                            DataProcWithShifterOp
448  /// CHECK:                            DataProcWithShifterOp
449  /// CHECK:                            DataProcWithShifterOp
450  /// CHECK:                            DataProcWithShifterOp
451  /// CHECK:                            DataProcWithShifterOp
452  /// CHECK:                            DataProcWithShifterOp
453  /// CHECK-NOT:                        DataProcWithShifterOp
454
455  /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
456  /// CHECK:                            TypeConversion
457  /// CHECK:                            TypeConversion
458  /// CHECK-NOT:                        TypeConversion
459
460  public static void $opt$validateExtendCharLong(long a, char b) {
461    // The first two tests have a type conversion.
462    assertLongEquals(a + $noinline$charToByte (b), a +  (byte)b);
463    assertLongEquals(a + $noinline$charToShort(b), a + (short)b);
464    // On ARM64 this test does not because the conversion to `int` is optimized away.
465    assertLongEquals(a + $noinline$charToInt  (b), a +   (int)b);
466  }
467
468  public static void $opt$validateExtendChar(long a, char b) {
469    $opt$validateExtendCharInt1((int)a, b);
470    $opt$validateExtendCharInt2((int)a, b);
471    $opt$validateExtendCharLong(a, b);
472  }
473
474  /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after)
475  /// CHECK:                            DataProcWithShifterOp
476  /// CHECK:                            DataProcWithShifterOp
477  /// CHECK-NOT:                        DataProcWithShifterOp
478
479  /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
480  /// CHECK:                            DataProcWithShifterOp
481  /// CHECK:                            DataProcWithShifterOp
482
483  /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
484  /// CHECK-NOT:                        TypeConversion
485
486  public static void $opt$validateExtendShortInt1(int a, short b) {
487    assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b);
488    assertIntEquals(a + $noinline$shortToChar (b), a + (char)b);
489  }
490
491  /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm (after)
492  /// CHECK-NOT:                        DataProcWithShifterOp
493
494  /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after)
495  /// CHECK-NOT:                        DataProcWithShifterOp
496
497  public static void $opt$validateExtendShortInt2(int a, short b) {
498    // The conversion to `int` has been optimized away, so there is nothing to merge.
499    assertIntEquals (a + $noinline$shortToInt  (b), a +  (int)b);
500    // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge.
501    assertLongEquals(a + $noinline$shortToLong (b), a + (long)b);
502  }
503
504  /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after)
505  /// CHECK:                            DataProcWithShifterOp
506  /// CHECK:                            DataProcWithShifterOp
507  /// CHECK:                            DataProcWithShifterOp
508  /// CHECK:                            DataProcWithShifterOp
509  /// CHECK:                            DataProcWithShifterOp
510  /// CHECK:                            DataProcWithShifterOp
511  /// CHECK-NOT:                        DataProcWithShifterOp
512
513  /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after)
514  /// CHECK:                            TypeConversion
515  /// CHECK:                            TypeConversion
516  /// CHECK-NOT:                        TypeConversion
517
518  /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
519  /// CHECK:                            DataProcWithShifterOp
520  /// CHECK:                            DataProcWithShifterOp
521  /// CHECK:                            DataProcWithShifterOp
522  /// CHECK:                            DataProcWithShifterOp
523  /// CHECK:                            DataProcWithShifterOp
524  /// CHECK:                            DataProcWithShifterOp
525  /// CHECK-NOT:                        DataProcWithShifterOp
526
527  /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
528  /// CHECK:                            TypeConversion
529  /// CHECK:                            TypeConversion
530  /// CHECK-NOT:                        TypeConversion
531
532  public static void $opt$validateExtendShortLong(long a, short b) {
533    // The first two tests have a type conversion.
534    assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b);
535    assertLongEquals(a + $noinline$shortToChar(b), a + (char)b);
536    // On ARM64 this test does not because the conversion to `int` is optimized away.
537    assertLongEquals(a + $noinline$shortToInt (b), a +  (int)b);
538  }
539
540  public static void $opt$validateExtendShort(long a, short b) {
541    $opt$validateExtendShortInt1((int)a, b);
542    $opt$validateExtendShortInt2((int)a, b);
543    $opt$validateExtendShortLong(a, b);
544  }
545
546  /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after)
547  /// CHECK:                            DataProcWithShifterOp
548  /// CHECK:                            DataProcWithShifterOp
549  /// CHECK:                            DataProcWithShifterOp
550  /// CHECK:                            DataProcWithShifterOp
551  /// CHECK:                            DataProcWithShifterOp
552  /// CHECK:                            DataProcWithShifterOp
553  /// CHECK:                            DataProcWithShifterOp
554  /// CHECK-NOT:                        DataProcWithShifterOp
555
556  /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after)
557  /// CHECK:                            TypeConversion
558  /// CHECK:                            TypeConversion
559  /// CHECK:                            TypeConversion
560  /// CHECK-NOT:                        TypeConversion
561
562  /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
563  /// CHECK:                            DataProcWithShifterOp
564  /// CHECK:                            DataProcWithShifterOp
565  /// CHECK:                            DataProcWithShifterOp
566  /// CHECK:                            DataProcWithShifterOp
567  /// CHECK:                            DataProcWithShifterOp
568  /// CHECK:                            DataProcWithShifterOp
569  /// CHECK:                            DataProcWithShifterOp
570  /// CHECK-NOT:                        DataProcWithShifterOp
571
572  /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
573  /// CHECK:                            TypeConversion
574  /// CHECK:                            TypeConversion
575  /// CHECK:                            TypeConversion
576  /// CHECK-NOT:                        TypeConversion
577
578  public static void $opt$validateExtendInt(long a, int b) {
579    // All tests have a conversion to `long`. The first three tests also have a
580    // conversion from `int` to the specified type. For each test the conversion
581    // to `long` is merged into the shifter operand.
582    assertLongEquals(a + $noinline$intToByte (b), a +  (byte)b);
583    assertLongEquals(a + $noinline$intToChar (b), a +  (char)b);
584    assertLongEquals(a + $noinline$intToShort(b), a + (short)b);
585    assertLongEquals(a + $noinline$intToLong (b), a +  (long)b);
586  }
587
588  /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after)
589  /// CHECK:                            DataProcWithShifterOp
590  /// CHECK:                            DataProcWithShifterOp
591  /// CHECK:                            DataProcWithShifterOp
592  /// CHECK:                            DataProcWithShifterOp
593  /// CHECK:                            DataProcWithShifterOp
594  /// CHECK:                            DataProcWithShifterOp
595  /// CHECK:                            DataProcWithShifterOp
596  /// CHECK:                            DataProcWithShifterOp
597  /// CHECK-NOT:                        DataProcWithShifterOp
598
599  /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after)
600  /// CHECK:                            TypeConversion
601  /// CHECK:                            TypeConversion
602  /// CHECK:                            TypeConversion
603  /// CHECK:                            TypeConversion
604  /// CHECK-NOT:                        TypeConversion
605
606  /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
607  /// CHECK:                            DataProcWithShifterOp
608  /// CHECK:                            DataProcWithShifterOp
609  /// CHECK:                            DataProcWithShifterOp
610  /// CHECK:                            DataProcWithShifterOp
611  /// CHECK:                            DataProcWithShifterOp
612  /// CHECK:                            DataProcWithShifterOp
613  /// CHECK:                            DataProcWithShifterOp
614  /// CHECK:                            DataProcWithShifterOp
615  /// CHECK-NOT:                        DataProcWithShifterOp
616
617  /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
618  /// CHECK:                            TypeConversion
619  /// CHECK:                            TypeConversion
620  /// CHECK:                            TypeConversion
621  /// CHECK:                            TypeConversion
622  /// CHECK-NOT:                        TypeConversion
623
624  public static void $opt$validateExtendLong(long a, long b) {
625    // Each test has two conversions, from `long` and then back to `long`. The
626    // conversions to `long` are merged.
627    assertLongEquals(a + $noinline$longToByte (b), a +  (byte)b);
628    assertLongEquals(a + $noinline$longToChar (b), a +  (char)b);
629    assertLongEquals(a + $noinline$longToShort(b), a + (short)b);
630    assertLongEquals(a + $noinline$longToInt  (b), a +   (int)b);
631  }
632
633
634  static int $noinline$IntShl(int b, int c) {
635    if (doThrow) throw new Error();
636    return b << c;
637  }
638  static int $noinline$IntShr(int b, int c) {
639    if (doThrow) throw new Error();
640    return b >> c;
641  }
642  static int $noinline$IntUshr(int b, int c) {
643    if (doThrow) throw new Error();
644    return b >>> c;
645  }
646
647
648  // Each test line below should see one merge.
649  //
650  /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (before)
651  /// CHECK:                            Shl
652  /// CHECK:                            Shl
653  /// CHECK:                            Shl
654  /// CHECK:                            Shl
655  /// CHECK:                            Shl
656  /// CHECK:                            Shl
657  /// CHECK:                            Shl
658  /// CHECK:                            Shl
659  /// CHECK:                            Shl
660  /// CHECK:                            Shl
661  /// CHECK:                            Shl
662  /// CHECK:                            Shl
663  /// CHECK-NOT:                        Shl
664  /// CHECK:                            Shr
665  /// CHECK:                            Shr
666  /// CHECK:                            Shr
667  /// CHECK:                            Shr
668  /// CHECK:                            Shr
669  /// CHECK:                            Shr
670  /// CHECK:                            Shr
671  /// CHECK:                            Shr
672  /// CHECK:                            Shr
673  /// CHECK:                            Shr
674  /// CHECK:                            Shr
675  /// CHECK:                            Shr
676  /// CHECK-NOT:                        Shl
677  /// CHECK:                            UShr
678  /// CHECK:                            UShr
679  /// CHECK:                            UShr
680  /// CHECK:                            UShr
681  /// CHECK:                            UShr
682  /// CHECK:                            UShr
683  /// CHECK:                            UShr
684  /// CHECK:                            UShr
685  /// CHECK:                            UShr
686  /// CHECK:                            UShr
687  /// CHECK:                            UShr
688  /// CHECK:                            UShr
689  /// CHECK-NOT:                        UShr
690  //
691  // Note: simplification after inlining removes `b << 32`, `b >> 32` and `b >>> 32`.
692  //
693  /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (after)
694  /// CHECK:                            Shl
695  /// CHECK:                            Shl
696  /// CHECK:                            Shl
697  /// CHECK:                            Shl
698  /// CHECK:                            Shl
699  /// CHECK:                            Shl
700  /// CHECK:                            Shl
701  /// CHECK:                            Shl
702  /// CHECK:                            Shl
703  /// CHECK:                            Shl
704  /// CHECK:                            Shl
705  /// CHECK-NOT:                        Shl
706  /// CHECK:                            Shr
707  /// CHECK:                            Shr
708  /// CHECK:                            Shr
709  /// CHECK:                            Shr
710  /// CHECK:                            Shr
711  /// CHECK:                            Shr
712  /// CHECK:                            Shr
713  /// CHECK:                            Shr
714  /// CHECK:                            Shr
715  /// CHECK:                            Shr
716  /// CHECK:                            Shr
717  /// CHECK-NOT:                        Shl
718  /// CHECK:                            UShr
719  /// CHECK:                            UShr
720  /// CHECK:                            UShr
721  /// CHECK:                            UShr
722  /// CHECK:                            UShr
723  /// CHECK:                            UShr
724  /// CHECK:                            UShr
725  /// CHECK:                            UShr
726  /// CHECK:                            UShr
727  /// CHECK:                            UShr
728  /// CHECK:                            UShr
729  /// CHECK-NOT:                        UShr
730  //
731  // Note: simplification followed by GVN exposes the common subexpressions between shifts with larger distance
732  //       `b << 62`, `b << 63` etc. and the equivalent smaller distances.
733  //
734  /// CHECK-START: void Main.$opt$validateShiftInt(int, int) GVN (after)
735  /// CHECK:                            Shl
736  /// CHECK:                            Shl
737  /// CHECK:                            Shl
738  /// CHECK:                            Shl
739  /// CHECK:                            Shl
740  /// CHECK:                            Shl
741  /// CHECK:                            Shl
742  /// CHECK:                            Shl
743  /// CHECK:                            Shl
744  /// CHECK-NOT:                        Shl
745  /// CHECK:                            Shr
746  /// CHECK:                            Shr
747  /// CHECK:                            Shr
748  /// CHECK:                            Shr
749  /// CHECK:                            Shr
750  /// CHECK:                            Shr
751  /// CHECK:                            Shr
752  /// CHECK:                            Shr
753  /// CHECK:                            Shr
754  /// CHECK-NOT:                        Shl
755  /// CHECK:                            UShr
756  /// CHECK:                            UShr
757  /// CHECK:                            UShr
758  /// CHECK:                            UShr
759  /// CHECK:                            UShr
760  /// CHECK:                            UShr
761  /// CHECK:                            UShr
762  /// CHECK:                            UShr
763  /// CHECK:                            UShr
764  /// CHECK-NOT:                        UShr
765  //
766  /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
767  /// CHECK:                            DataProcWithShifterOp
768  /// CHECK:                            DataProcWithShifterOp
769  /// CHECK:                            DataProcWithShifterOp
770  /// CHECK:                            DataProcWithShifterOp
771  /// CHECK:                            DataProcWithShifterOp
772  /// CHECK:                            DataProcWithShifterOp
773  /// CHECK:                            DataProcWithShifterOp
774  /// CHECK:                            DataProcWithShifterOp
775  /// CHECK:                            DataProcWithShifterOp
776  /// CHECK:                            DataProcWithShifterOp
777  /// CHECK:                            DataProcWithShifterOp
778  /// CHECK:                            DataProcWithShifterOp
779  /// CHECK:                            DataProcWithShifterOp
780  /// CHECK:                            DataProcWithShifterOp
781  /// CHECK:                            DataProcWithShifterOp
782  /// CHECK:                            DataProcWithShifterOp
783  /// CHECK:                            DataProcWithShifterOp
784  /// CHECK:                            DataProcWithShifterOp
785  /// CHECK:                            DataProcWithShifterOp
786  /// CHECK:                            DataProcWithShifterOp
787  /// CHECK:                            DataProcWithShifterOp
788  /// CHECK:                            DataProcWithShifterOp
789  /// CHECK:                            DataProcWithShifterOp
790  /// CHECK:                            DataProcWithShifterOp
791  /// CHECK:                            DataProcWithShifterOp
792  /// CHECK:                            DataProcWithShifterOp
793  /// CHECK:                            DataProcWithShifterOp
794  /// CHECK-NOT:                        DataProcWithShifterOp
795
796  /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
797  /// CHECK-NOT:                        Shl
798  /// CHECK-NOT:                        Shr
799  /// CHECK-NOT:                        UShr
800
801  /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
802  /// CHECK:                            DataProcWithShifterOp
803  /// CHECK:                            DataProcWithShifterOp
804  /// CHECK:                            DataProcWithShifterOp
805  /// CHECK:                            DataProcWithShifterOp
806  /// CHECK:                            DataProcWithShifterOp
807  /// CHECK:                            DataProcWithShifterOp
808  /// CHECK:                            DataProcWithShifterOp
809  /// CHECK:                            DataProcWithShifterOp
810  /// CHECK:                            DataProcWithShifterOp
811  /// CHECK:                            DataProcWithShifterOp
812  /// CHECK:                            DataProcWithShifterOp
813  /// CHECK:                            DataProcWithShifterOp
814  /// CHECK:                            DataProcWithShifterOp
815  /// CHECK:                            DataProcWithShifterOp
816  /// CHECK:                            DataProcWithShifterOp
817  /// CHECK:                            DataProcWithShifterOp
818  /// CHECK:                            DataProcWithShifterOp
819  /// CHECK:                            DataProcWithShifterOp
820  /// CHECK:                            DataProcWithShifterOp
821  /// CHECK:                            DataProcWithShifterOp
822  /// CHECK:                            DataProcWithShifterOp
823  /// CHECK:                            DataProcWithShifterOp
824  /// CHECK:                            DataProcWithShifterOp
825  /// CHECK:                            DataProcWithShifterOp
826  /// CHECK:                            DataProcWithShifterOp
827  /// CHECK:                            DataProcWithShifterOp
828  /// CHECK:                            DataProcWithShifterOp
829  /// CHECK-NOT:                        DataProcWithShifterOp
830
831  /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
832  /// CHECK-NOT:                        Shl
833  /// CHECK-NOT:                        Shr
834  /// CHECK-NOT:                        UShr
835
836  public static void $opt$validateShiftInt(int a, int b) {
837    assertIntEquals(a + $noinline$IntShl(b, 1),   a + (b <<  1));
838    assertIntEquals(a + $noinline$IntShl(b, 6),   a + (b <<  6));
839    assertIntEquals(a + $noinline$IntShl(b, 7),   a + (b <<  7));
840    assertIntEquals(a + $noinline$IntShl(b, 8),   a + (b <<  8));
841    assertIntEquals(a + $noinline$IntShl(b, 14),  a + (b << 14));
842    assertIntEquals(a + $noinline$IntShl(b, 15),  a + (b << 15));
843    assertIntEquals(a + $noinline$IntShl(b, 16),  a + (b << 16));
844    assertIntEquals(a + $noinline$IntShl(b, 30),  a + (b << 30));
845    assertIntEquals(a + $noinline$IntShl(b, 31),  a + (b << 31));
846    assertIntEquals(a + $noinline$IntShl(b, 32),  a + (b << $opt$inline$IntConstant32()));
847    assertIntEquals(a + $noinline$IntShl(b, 62),  a + (b << $opt$inline$IntConstant62()));
848    assertIntEquals(a + $noinline$IntShl(b, 63),  a + (b << $opt$inline$IntConstant63()));
849
850    assertIntEquals(a - $noinline$IntShr(b, 1),   a - (b >>  1));
851    assertIntEquals(a - $noinline$IntShr(b, 6),   a - (b >>  6));
852    assertIntEquals(a - $noinline$IntShr(b, 7),   a - (b >>  7));
853    assertIntEquals(a - $noinline$IntShr(b, 8),   a - (b >>  8));
854    assertIntEquals(a - $noinline$IntShr(b, 14),  a - (b >> 14));
855    assertIntEquals(a - $noinline$IntShr(b, 15),  a - (b >> 15));
856    assertIntEquals(a - $noinline$IntShr(b, 16),  a - (b >> 16));
857    assertIntEquals(a - $noinline$IntShr(b, 30),  a - (b >> 30));
858    assertIntEquals(a - $noinline$IntShr(b, 31),  a - (b >> 31));
859    assertIntEquals(a - $noinline$IntShr(b, 32),  a - (b >> $opt$inline$IntConstant32()));
860    assertIntEquals(a - $noinline$IntShr(b, 62),  a - (b >> $opt$inline$IntConstant62()));
861    assertIntEquals(a - $noinline$IntShr(b, 63),  a - (b >> $opt$inline$IntConstant63()));
862
863    assertIntEquals(a ^ $noinline$IntUshr(b, 1),   a ^ (b >>>  1));
864    assertIntEquals(a ^ $noinline$IntUshr(b, 6),   a ^ (b >>>  6));
865    assertIntEquals(a ^ $noinline$IntUshr(b, 7),   a ^ (b >>>  7));
866    assertIntEquals(a ^ $noinline$IntUshr(b, 8),   a ^ (b >>>  8));
867    assertIntEquals(a ^ $noinline$IntUshr(b, 14),  a ^ (b >>> 14));
868    assertIntEquals(a ^ $noinline$IntUshr(b, 15),  a ^ (b >>> 15));
869    assertIntEquals(a ^ $noinline$IntUshr(b, 16),  a ^ (b >>> 16));
870    assertIntEquals(a ^ $noinline$IntUshr(b, 30),  a ^ (b >>> 30));
871    assertIntEquals(a ^ $noinline$IntUshr(b, 31),  a ^ (b >>> 31));
872    assertIntEquals(a ^ $noinline$IntUshr(b, 32),  a ^ (b >>> $opt$inline$IntConstant32()));
873    assertIntEquals(a ^ $noinline$IntUshr(b, 62),  a ^ (b >>> $opt$inline$IntConstant62()));
874    assertIntEquals(a ^ $noinline$IntUshr(b, 63),  a ^ (b >>> $opt$inline$IntConstant63()));
875  }
876
877  // Hiding constants outside the range [0, 32) used for int shifts from Jack.
878  // (Jack extracts only the low 5 bits.)
879  public static int $opt$inline$IntConstant32() { return 32; }
880  public static int $opt$inline$IntConstant62() { return 62; }
881  public static int $opt$inline$IntConstant63() { return 63; }
882
883
884  static long $noinline$LongShl(long b, long c) {
885    if (doThrow) throw new Error();
886    return b << c;
887  }
888  static long $noinline$LongShr(long b, long c) {
889    if (doThrow) throw new Error();
890    return b >> c;
891  }
892  static long $noinline$LongUshr(long b, long c) {
893    if (doThrow) throw new Error();
894    return b >>> c;
895  }
896
897  // Each test line below should see one merge.
898  /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after)
899  /// CHECK:                            DataProcWithShifterOp
900  /// CHECK:                            DataProcWithShifterOp
901  /// CHECK:                            DataProcWithShifterOp
902  /// CHECK:                            DataProcWithShifterOp
903  /// CHECK:                            DataProcWithShifterOp
904  /// CHECK:                            DataProcWithShifterOp
905  /// CHECK:                            DataProcWithShifterOp
906  /// CHECK:                            DataProcWithShifterOp
907  /// CHECK:                            DataProcWithShifterOp
908  /// CHECK:                            DataProcWithShifterOp
909  /// CHECK:                            DataProcWithShifterOp
910  /// CHECK:                            DataProcWithShifterOp
911  /// CHECK:                            DataProcWithShifterOp
912  /// CHECK:                            DataProcWithShifterOp
913  /// CHECK:                            DataProcWithShifterOp
914  /// CHECK:                            DataProcWithShifterOp
915  /// CHECK:                            DataProcWithShifterOp
916  /// CHECK:                            DataProcWithShifterOp
917  /// CHECK:                            DataProcWithShifterOp
918  /// CHECK:                            DataProcWithShifterOp
919  /// CHECK:                            DataProcWithShifterOp
920  /// CHECK:                            DataProcWithShifterOp
921  /// CHECK:                            DataProcWithShifterOp
922  /// CHECK:                            DataProcWithShifterOp
923  /// CHECK:                            DataProcWithShifterOp
924  /// CHECK:                            DataProcWithShifterOp
925  /// CHECK:                            DataProcWithShifterOp
926  /// CHECK:                            DataProcWithShifterOp
927  /// CHECK:                            DataProcWithShifterOp
928  /// CHECK:                            DataProcWithShifterOp
929  /// CHECK:                            DataProcWithShifterOp
930  /// CHECK:                            DataProcWithShifterOp
931  /// CHECK:                            DataProcWithShifterOp
932  /// CHECK-NOT:                        DataProcWithShifterOp
933
934  // On ARM shifts by 1 are not merged.
935  /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after)
936  /// CHECK:                            Shl
937  /// CHECK-NOT:                        Shl
938  /// CHECK:                            Shr
939  /// CHECK-NOT:                        Shr
940  /// CHECK:                            UShr
941  /// CHECK-NOT:                        UShr
942
943  /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
944  /// CHECK:                            DataProcWithShifterOp
945  /// CHECK:                            DataProcWithShifterOp
946  /// CHECK:                            DataProcWithShifterOp
947  /// CHECK:                            DataProcWithShifterOp
948  /// CHECK:                            DataProcWithShifterOp
949  /// CHECK:                            DataProcWithShifterOp
950  /// CHECK:                            DataProcWithShifterOp
951  /// CHECK:                            DataProcWithShifterOp
952  /// CHECK:                            DataProcWithShifterOp
953  /// CHECK:                            DataProcWithShifterOp
954  /// CHECK:                            DataProcWithShifterOp
955  /// CHECK:                            DataProcWithShifterOp
956  /// CHECK:                            DataProcWithShifterOp
957  /// CHECK:                            DataProcWithShifterOp
958  /// CHECK:                            DataProcWithShifterOp
959  /// CHECK:                            DataProcWithShifterOp
960  /// CHECK:                            DataProcWithShifterOp
961  /// CHECK:                            DataProcWithShifterOp
962  /// CHECK:                            DataProcWithShifterOp
963  /// CHECK:                            DataProcWithShifterOp
964  /// CHECK:                            DataProcWithShifterOp
965  /// CHECK:                            DataProcWithShifterOp
966  /// CHECK:                            DataProcWithShifterOp
967  /// CHECK:                            DataProcWithShifterOp
968  /// CHECK:                            DataProcWithShifterOp
969  /// CHECK:                            DataProcWithShifterOp
970  /// CHECK:                            DataProcWithShifterOp
971  /// CHECK:                            DataProcWithShifterOp
972  /// CHECK:                            DataProcWithShifterOp
973  /// CHECK:                            DataProcWithShifterOp
974  /// CHECK:                            DataProcWithShifterOp
975  /// CHECK:                            DataProcWithShifterOp
976  /// CHECK:                            DataProcWithShifterOp
977  /// CHECK:                            DataProcWithShifterOp
978  /// CHECK:                            DataProcWithShifterOp
979  /// CHECK:                            DataProcWithShifterOp
980  /// CHECK-NOT:                        DataProcWithShifterOp
981
982  /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
983  /// CHECK-NOT:                        Shl
984  /// CHECK-NOT:                        Shr
985  /// CHECK-NOT:                        UShr
986
987  public static void $opt$validateShiftLong(long a, long b) {
988    assertLongEquals(a + $noinline$LongShl(b, 1),   a + (b <<  1));
989    assertLongEquals(a + $noinline$LongShl(b, 6),   a + (b <<  6));
990    assertLongEquals(a + $noinline$LongShl(b, 7),   a + (b <<  7));
991    assertLongEquals(a + $noinline$LongShl(b, 8),   a + (b <<  8));
992    assertLongEquals(a + $noinline$LongShl(b, 14),  a + (b << 14));
993    assertLongEquals(a + $noinline$LongShl(b, 15),  a + (b << 15));
994    assertLongEquals(a + $noinline$LongShl(b, 16),  a + (b << 16));
995    assertLongEquals(a + $noinline$LongShl(b, 30),  a + (b << 30));
996    assertLongEquals(a + $noinline$LongShl(b, 31),  a + (b << 31));
997    assertLongEquals(a + $noinline$LongShl(b, 32),  a + (b << 32));
998    assertLongEquals(a + $noinline$LongShl(b, 62),  a + (b << 62));
999    assertLongEquals(a + $noinline$LongShl(b, 63),  a + (b << 63));
1000
1001    assertLongEquals(a - $noinline$LongShr(b, 1),   a - (b >>  1));
1002    assertLongEquals(a - $noinline$LongShr(b, 6),   a - (b >>  6));
1003    assertLongEquals(a - $noinline$LongShr(b, 7),   a - (b >>  7));
1004    assertLongEquals(a - $noinline$LongShr(b, 8),   a - (b >>  8));
1005    assertLongEquals(a - $noinline$LongShr(b, 14),  a - (b >> 14));
1006    assertLongEquals(a - $noinline$LongShr(b, 15),  a - (b >> 15));
1007    assertLongEquals(a - $noinline$LongShr(b, 16),  a - (b >> 16));
1008    assertLongEquals(a - $noinline$LongShr(b, 30),  a - (b >> 30));
1009    assertLongEquals(a - $noinline$LongShr(b, 31),  a - (b >> 31));
1010    assertLongEquals(a - $noinline$LongShr(b, 32),  a - (b >> 32));
1011    assertLongEquals(a - $noinline$LongShr(b, 62),  a - (b >> 62));
1012    assertLongEquals(a - $noinline$LongShr(b, 63),  a - (b >> 63));
1013
1014    assertLongEquals(a ^ $noinline$LongUshr(b, 1),   a ^ (b >>>  1));
1015    assertLongEquals(a ^ $noinline$LongUshr(b, 6),   a ^ (b >>>  6));
1016    assertLongEquals(a ^ $noinline$LongUshr(b, 7),   a ^ (b >>>  7));
1017    assertLongEquals(a ^ $noinline$LongUshr(b, 8),   a ^ (b >>>  8));
1018    assertLongEquals(a ^ $noinline$LongUshr(b, 14),  a ^ (b >>> 14));
1019    assertLongEquals(a ^ $noinline$LongUshr(b, 15),  a ^ (b >>> 15));
1020    assertLongEquals(a ^ $noinline$LongUshr(b, 16),  a ^ (b >>> 16));
1021    assertLongEquals(a ^ $noinline$LongUshr(b, 30),  a ^ (b >>> 30));
1022    assertLongEquals(a ^ $noinline$LongUshr(b, 31),  a ^ (b >>> 31));
1023    assertLongEquals(a ^ $noinline$LongUshr(b, 32),  a ^ (b >>> 32));
1024    assertLongEquals(a ^ $noinline$LongUshr(b, 62),  a ^ (b >>> 62));
1025    assertLongEquals(a ^ $noinline$LongUshr(b, 63),  a ^ (b >>> 63));
1026  }
1027
1028
1029  public static void main(String[] args) {
1030    assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3));
1031    assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3));
1032
1033    assertIntEquals(4096, $opt$noinline$sameInput(512));
1034    assertIntEquals(-8192, $opt$noinline$sameInput(-1024));
1035
1036    assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1));
1037    assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20));
1038
1039    long inputs[] = {
1040      -((1L <<  7) - 1L), -((1L <<  7)), -((1L <<  7) + 1L),
1041      -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L),
1042      -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L),
1043      -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L),
1044      -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L),
1045      -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L),
1046      -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L,
1047      -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L,
1048      0L,
1049      1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L,
1050      42L,  314L,  2718281828L,  0x123456789L,  0x987654321L,
1051      (1L <<  7) - 1L, (1L <<  7), (1L <<  7) + 1L,
1052      (1L <<  8) - 1L, (1L <<  8), (1L <<  8) + 1L,
1053      (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L,
1054      (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L,
1055      (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L,
1056      (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L,
1057      (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L,
1058      Long.MIN_VALUE, Long.MAX_VALUE
1059    };
1060    for (int i = 0; i < inputs.length; i++) {
1061      $opt$noinline$testNeg((int)inputs[i]);
1062      for (int j = 0; j < inputs.length; j++) {
1063        $opt$noinline$testAnd(inputs[i], inputs[j]);
1064        $opt$noinline$testOr((int)inputs[i], (int)inputs[j]);
1065        $opt$noinline$testXor(inputs[i], inputs[j]);
1066
1067        $opt$validateExtendByte(inputs[i], (byte)inputs[j]);
1068        $opt$validateExtendChar(inputs[i], (char)inputs[j]);
1069        $opt$validateExtendShort(inputs[i], (short)inputs[j]);
1070        $opt$validateExtendInt(inputs[i], (int)inputs[j]);
1071        $opt$validateExtendLong(inputs[i], inputs[j]);
1072
1073        $opt$validateShiftInt((int)inputs[i], (int)inputs[j]);
1074        $opt$validateShiftLong(inputs[i], inputs[j]);
1075      }
1076    }
1077
1078  }
1079}
1080