• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class Main {
18 
19   // A dummy value to defeat inlining of these routines.
20   static boolean doThrow = false;
21 
assertByteEquals(byte expected, byte result)22   public static void assertByteEquals(byte expected, byte result) {
23     if (expected != result) {
24       throw new Error("Expected: " + expected + ", found: " + result);
25     }
26   }
27 
assertCharEquals(char expected, char result)28   public static void assertCharEquals(char expected, char result) {
29     if (expected != result) {
30       throw new Error("Expected: " + expected + ", found: " + result);
31     }
32   }
33 
assertShortEquals(short expected, short result)34   public static void assertShortEquals(short expected, short result) {
35     if (expected != result) {
36       throw new Error("Expected: " + expected + ", found: " + result);
37     }
38   }
39 
assertIntEquals(int expected, int result)40   public static void assertIntEquals(int expected, int result) {
41     if (expected != result) {
42       throw new Error("Expected: " + expected + ", found: " + result);
43     }
44   }
45 
assertLongEquals(long expected, long result)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.
$noinline$byteToChar(byte v)53   static  char $noinline$byteToChar   (byte v) { if (doThrow) throw new Error(); return  (char)v; }
$noinline$byteToShort(byte v)54   static short $noinline$byteToShort  (byte v) { if (doThrow) throw new Error(); return (short)v; }
$noinline$byteToInt(byte v)55   static   int $noinline$byteToInt    (byte v) { if (doThrow) throw new Error(); return   (int)v; }
$noinline$byteToLong(byte v)56   static  long $noinline$byteToLong   (byte v) { if (doThrow) throw new Error(); return  (long)v; }
$noinline$charToByte(char v)57   static  byte $noinline$charToByte   (char v) { if (doThrow) throw new Error(); return  (byte)v; }
$noinline$charToShort(char v)58   static short $noinline$charToShort  (char v) { if (doThrow) throw new Error(); return (short)v; }
$noinline$charToInt(char v)59   static   int $noinline$charToInt    (char v) { if (doThrow) throw new Error(); return   (int)v; }
$noinline$charToLong(char v)60   static  long $noinline$charToLong   (char v) { if (doThrow) throw new Error(); return  (long)v; }
$noinline$shortToByte(short v)61   static  byte $noinline$shortToByte (short v) { if (doThrow) throw new Error(); return  (byte)v; }
$noinline$shortToChar(short v)62   static  char $noinline$shortToChar (short v) { if (doThrow) throw new Error(); return  (char)v; }
$noinline$shortToInt(short v)63   static   int $noinline$shortToInt  (short v) { if (doThrow) throw new Error(); return   (int)v; }
$noinline$shortToLong(short v)64   static  long $noinline$shortToLong (short v) { if (doThrow) throw new Error(); return  (long)v; }
$noinline$intToByte(int v)65   static  byte $noinline$intToByte     (int v) { if (doThrow) throw new Error(); return  (byte)v; }
$noinline$intToChar(int v)66   static  char $noinline$intToChar     (int v) { if (doThrow) throw new Error(); return  (char)v; }
$noinline$intToShort(int v)67   static short $noinline$intToShort    (int v) { if (doThrow) throw new Error(); return (short)v; }
$noinline$intToLong(int v)68   static  long $noinline$intToLong     (int v) { if (doThrow) throw new Error(); return  (long)v; }
$noinline$longToByte(long v)69   static  byte $noinline$longToByte   (long v) { if (doThrow) throw new Error(); return  (byte)v; }
$noinline$longToChar(long v)70   static  char $noinline$longToChar   (long v) { if (doThrow) throw new Error(); return  (char)v; }
$noinline$longToShort(long v)71   static short $noinline$longToShort  (long v) { if (doThrow) throw new Error(); return (short)v; }
$noinline$longToInt(long 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 
$opt$noinline$translate(long l, byte b)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 
$opt$noinline$sameInput(int a)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 
$opt$noinline$multipleUses(int arg)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
238   /// CHECK:                            and
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 
$opt$noinline$testAnd(long a, long b)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
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 
$opt$noinline$testOr(int a, int b)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:                            mov
286   /// CHECK:                            asr
287   /// CHECK:                            eor
288 
289   /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after)
290   /// CHECK:                            DataProcWithShifterOp
291   /// CHECK-NOT:                        DataProcWithShifterOp
292 
293   /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after)
294   /// CHECK:                            eor lsr
295   /// CHECK:                            sxtw
296   /// CHECK:                            eor
297 
$opt$noinline$testXor(long a, long b)298   static void $opt$noinline$testXor(long a, long b) {
299     if (doThrow) throw new Error();
300     assertLongEquals((a ^ $noinline$LongUshr(b, 7)) | (a ^ $noinline$longToInt(b)),
301                      (a ^ (b >>> 7)) | (a ^ (int)b));
302   }
303 
304   /// CHECK-START-ARM: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm (after)
305   /// CHECK-NOT:                            DataProcWithShifterOp
306 
307   /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after)
308   /// CHECK:                            DataProcWithShifterOp
309   /// CHECK-NOT:                        DataProcWithShifterOp
310 
311   /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after)
312   /// CHECK:                            neg lsl
313   /// CHECK:                            sxth
314   /// CHECK:                            neg
315 
$opt$noinline$testNeg(int a)316   static void $opt$noinline$testNeg(int a) {
317     if (doThrow) throw new Error();
318     assertIntEquals(-$noinline$IntShl(a, 8) | -$noinline$intToShort(a),
319                     (-(a << 8)) | (-(short)a));
320   }
321 
322   /**
323    * The functions below are used to compare the result of optimized operations
324    * to non-optimized operations.
325    * On the left-hand side we use a non-inlined function call to ensure the
326    * optimization does not occur. The checker tests ensure that the optimization
327    * does occur on the right-hand.
328    */
329 
330   /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after)
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 
$opt$validateExtendByteInt1(int a, byte b)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 
$opt$validateExtendByteInt2(int a, byte b)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 
$opt$validateExtendByteLong(long a, byte b)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 
$opt$validateExtendByte(long a, byte b)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-NOT:                        DataProcWithShifterOp
404 
405   /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
406   /// CHECK:                            DataProcWithShifterOp
407   /// CHECK:                            DataProcWithShifterOp
408 
409   /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after)
410   /// CHECK-NOT:                        TypeConversion
411 
$opt$validateExtendCharInt1(int a, char b)412   public static void $opt$validateExtendCharInt1(int a, char b) {
413     assertIntEquals(a + $noinline$charToByte (b), a +  (byte)b);
414     assertIntEquals(a + $noinline$charToShort(b), a + (short)b);
415   }
416 
417   /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm (after)
418   /// CHECK-NOT:                        DataProcWithShifterOp
419 
420   /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after)
421   /// CHECK-NOT:                        DataProcWithShifterOp
422 
$opt$validateExtendCharInt2(int a, char b)423   public static void $opt$validateExtendCharInt2(int a, char b) {
424     // The conversion to `int` has been optimized away, so there is nothing to merge.
425     assertIntEquals (a + $noinline$charToInt (b), a +  (int)b);
426     // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge.
427     assertLongEquals(a + $noinline$charToLong(b), a + (long)b);
428   }
429 
430   /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after)
431   /// CHECK:                            DataProcWithShifterOp
432   /// CHECK:                            DataProcWithShifterOp
433   /// CHECK:                            DataProcWithShifterOp
434   /// CHECK:                            DataProcWithShifterOp
435   /// CHECK:                            DataProcWithShifterOp
436   /// CHECK:                            DataProcWithShifterOp
437   /// CHECK-NOT:                        DataProcWithShifterOp
438 
439   /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after)
440   /// CHECK:                            TypeConversion
441   /// CHECK:                            TypeConversion
442   /// CHECK-NOT:                        TypeConversion
443 
444   /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
445   /// CHECK:                            DataProcWithShifterOp
446   /// CHECK:                            DataProcWithShifterOp
447   /// CHECK:                            DataProcWithShifterOp
448   /// CHECK:                            DataProcWithShifterOp
449   /// CHECK:                            DataProcWithShifterOp
450   /// CHECK:                            DataProcWithShifterOp
451   /// CHECK-NOT:                        DataProcWithShifterOp
452 
453   /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after)
454   /// CHECK:                            TypeConversion
455   /// CHECK:                            TypeConversion
456   /// CHECK-NOT:                        TypeConversion
457 
$opt$validateExtendCharLong(long a, char b)458   public static void $opt$validateExtendCharLong(long a, char b) {
459     // The first two tests have a type conversion.
460     assertLongEquals(a + $noinline$charToByte (b), a +  (byte)b);
461     assertLongEquals(a + $noinline$charToShort(b), a + (short)b);
462     // On ARM64 this test does not because the conversion to `int` is optimized away.
463     assertLongEquals(a + $noinline$charToInt  (b), a +   (int)b);
464   }
465 
$opt$validateExtendChar(long a, char b)466   public static void $opt$validateExtendChar(long a, char b) {
467     $opt$validateExtendCharInt1((int)a, b);
468     $opt$validateExtendCharInt2((int)a, b);
469     $opt$validateExtendCharLong(a, b);
470   }
471 
472   /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after)
473   /// CHECK-NOT:                        DataProcWithShifterOp
474 
475   /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
476   /// CHECK:                            DataProcWithShifterOp
477   /// CHECK:                            DataProcWithShifterOp
478 
479   /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after)
480   /// CHECK-NOT:                        TypeConversion
481 
$opt$validateExtendShortInt1(int a, short b)482   public static void $opt$validateExtendShortInt1(int a, short b) {
483     assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b);
484     assertIntEquals(a + $noinline$shortToChar (b), a + (char)b);
485   }
486 
487   /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm (after)
488   /// CHECK-NOT:                        DataProcWithShifterOp
489 
490   /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after)
491   /// CHECK-NOT:                        DataProcWithShifterOp
492 
$opt$validateExtendShortInt2(int a, short b)493   public static void $opt$validateExtendShortInt2(int a, short b) {
494     // The conversion to `int` has been optimized away, so there is nothing to merge.
495     assertIntEquals (a + $noinline$shortToInt  (b), a +  (int)b);
496     // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge.
497     assertLongEquals(a + $noinline$shortToLong (b), a + (long)b);
498   }
499 
500   /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after)
501   /// CHECK:                            DataProcWithShifterOp
502   /// CHECK:                            DataProcWithShifterOp
503   /// CHECK:                            DataProcWithShifterOp
504   /// CHECK:                            DataProcWithShifterOp
505   /// CHECK:                            DataProcWithShifterOp
506   /// CHECK:                            DataProcWithShifterOp
507   /// CHECK-NOT:                        DataProcWithShifterOp
508 
509   /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after)
510   /// CHECK:                            TypeConversion
511   /// CHECK:                            TypeConversion
512   /// CHECK-NOT:                        TypeConversion
513 
514   /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
515   /// CHECK:                            DataProcWithShifterOp
516   /// CHECK:                            DataProcWithShifterOp
517   /// CHECK:                            DataProcWithShifterOp
518   /// CHECK:                            DataProcWithShifterOp
519   /// CHECK:                            DataProcWithShifterOp
520   /// CHECK:                            DataProcWithShifterOp
521   /// CHECK-NOT:                        DataProcWithShifterOp
522 
523   /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after)
524   /// CHECK:                            TypeConversion
525   /// CHECK:                            TypeConversion
526   /// CHECK-NOT:                        TypeConversion
527 
$opt$validateExtendShortLong(long a, short b)528   public static void $opt$validateExtendShortLong(long a, short b) {
529     // The first two tests have a type conversion.
530     assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b);
531     assertLongEquals(a + $noinline$shortToChar(b), a + (char)b);
532     // On ARM64 this test does not because the conversion to `int` is optimized away.
533     assertLongEquals(a + $noinline$shortToInt (b), a +  (int)b);
534   }
535 
$opt$validateExtendShort(long a, short b)536   public static void $opt$validateExtendShort(long a, short b) {
537     $opt$validateExtendShortInt1((int)a, b);
538     $opt$validateExtendShortInt2((int)a, b);
539     $opt$validateExtendShortLong(a, b);
540   }
541 
542   /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after)
543   /// CHECK:                            DataProcWithShifterOp
544   /// CHECK:                            DataProcWithShifterOp
545   /// CHECK:                            DataProcWithShifterOp
546   /// CHECK:                            DataProcWithShifterOp
547   /// CHECK:                            DataProcWithShifterOp
548   /// CHECK:                            DataProcWithShifterOp
549   /// CHECK:                            DataProcWithShifterOp
550   /// CHECK-NOT:                        DataProcWithShifterOp
551 
552   /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after)
553   /// CHECK:                            TypeConversion
554   /// CHECK:                            TypeConversion
555   /// CHECK:                            TypeConversion
556   /// CHECK-NOT:                        TypeConversion
557 
558   /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
559   /// CHECK:                            DataProcWithShifterOp
560   /// CHECK:                            DataProcWithShifterOp
561   /// CHECK:                            DataProcWithShifterOp
562   /// CHECK:                            DataProcWithShifterOp
563   /// CHECK:                            DataProcWithShifterOp
564   /// CHECK:                            DataProcWithShifterOp
565   /// CHECK:                            DataProcWithShifterOp
566   /// CHECK-NOT:                        DataProcWithShifterOp
567 
568   /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after)
569   /// CHECK:                            TypeConversion
570   /// CHECK:                            TypeConversion
571   /// CHECK:                            TypeConversion
572   /// CHECK-NOT:                        TypeConversion
573 
$opt$validateExtendInt(long a, int b)574   public static void $opt$validateExtendInt(long a, int b) {
575     // All tests have a conversion to `long`. The first three tests also have a
576     // conversion from `int` to the specified type. For each test the conversion
577     // to `long` is merged into the shifter operand.
578     assertLongEquals(a + $noinline$intToByte (b), a +  (byte)b);
579     assertLongEquals(a + $noinline$intToChar (b), a +  (char)b);
580     assertLongEquals(a + $noinline$intToShort(b), a + (short)b);
581     assertLongEquals(a + $noinline$intToLong (b), a +  (long)b);
582   }
583 
584   /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after)
585   /// CHECK:                            DataProcWithShifterOp
586   /// CHECK:                            DataProcWithShifterOp
587   /// CHECK:                            DataProcWithShifterOp
588   /// CHECK:                            DataProcWithShifterOp
589   /// CHECK:                            DataProcWithShifterOp
590   /// CHECK:                            DataProcWithShifterOp
591   /// CHECK:                            DataProcWithShifterOp
592   /// CHECK:                            DataProcWithShifterOp
593   /// CHECK-NOT:                        DataProcWithShifterOp
594 
595   /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after)
596   /// CHECK:                            TypeConversion
597   /// CHECK:                            TypeConversion
598   /// CHECK:                            TypeConversion
599   /// CHECK:                            TypeConversion
600   /// CHECK-NOT:                        TypeConversion
601 
602   /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
603   /// CHECK:                            DataProcWithShifterOp
604   /// CHECK:                            DataProcWithShifterOp
605   /// CHECK:                            DataProcWithShifterOp
606   /// CHECK:                            DataProcWithShifterOp
607   /// CHECK:                            DataProcWithShifterOp
608   /// CHECK:                            DataProcWithShifterOp
609   /// CHECK:                            DataProcWithShifterOp
610   /// CHECK:                            DataProcWithShifterOp
611   /// CHECK-NOT:                        DataProcWithShifterOp
612 
613   /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after)
614   /// CHECK:                            TypeConversion
615   /// CHECK:                            TypeConversion
616   /// CHECK:                            TypeConversion
617   /// CHECK:                            TypeConversion
618   /// CHECK-NOT:                        TypeConversion
619 
$opt$validateExtendLong(long a, long b)620   public static void $opt$validateExtendLong(long a, long b) {
621     // Each test has two conversions, from `long` and then back to `long`. The
622     // conversions to `long` are merged.
623     assertLongEquals(a + $noinline$longToByte (b), a +  (byte)b);
624     assertLongEquals(a + $noinline$longToChar (b), a +  (char)b);
625     assertLongEquals(a + $noinline$longToShort(b), a + (short)b);
626     assertLongEquals(a + $noinline$longToInt  (b), a +   (int)b);
627   }
628 
629 
$noinline$IntShl(int b, int c)630   static int $noinline$IntShl(int b, int c) {
631     if (doThrow) throw new Error();
632     return b << c;
633   }
$noinline$IntShr(int b, int c)634   static int $noinline$IntShr(int b, int c) {
635     if (doThrow) throw new Error();
636     return b >> c;
637   }
$noinline$IntUshr(int b, int c)638   static int $noinline$IntUshr(int b, int c) {
639     if (doThrow) throw new Error();
640     return b >>> c;
641   }
642 
643 
644   // Each test line below should see one merge.
645   /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
646   /// CHECK:                            DataProcWithShifterOp
647   /// CHECK:                            DataProcWithShifterOp
648   /// CHECK:                            DataProcWithShifterOp
649   /// CHECK:                            DataProcWithShifterOp
650   /// CHECK:                            DataProcWithShifterOp
651   /// CHECK:                            DataProcWithShifterOp
652   /// CHECK:                            DataProcWithShifterOp
653   /// CHECK:                            DataProcWithShifterOp
654   /// CHECK:                            DataProcWithShifterOp
655   /// CHECK:                            DataProcWithShifterOp
656   /// CHECK:                            DataProcWithShifterOp
657   /// CHECK:                            DataProcWithShifterOp
658   /// CHECK:                            DataProcWithShifterOp
659   /// CHECK:                            DataProcWithShifterOp
660   /// CHECK:                            DataProcWithShifterOp
661   /// CHECK:                            DataProcWithShifterOp
662   /// CHECK:                            DataProcWithShifterOp
663   /// CHECK:                            DataProcWithShifterOp
664   /// CHECK:                            DataProcWithShifterOp
665   /// CHECK:                            DataProcWithShifterOp
666   /// CHECK:                            DataProcWithShifterOp
667   /// CHECK:                            DataProcWithShifterOp
668   /// CHECK:                            DataProcWithShifterOp
669   /// CHECK:                            DataProcWithShifterOp
670   /// CHECK:                            DataProcWithShifterOp
671   /// CHECK:                            DataProcWithShifterOp
672   /// CHECK:                            DataProcWithShifterOp
673   /// CHECK:                            DataProcWithShifterOp
674   /// CHECK:                            DataProcWithShifterOp
675   /// CHECK:                            DataProcWithShifterOp
676   /// CHECK:                            DataProcWithShifterOp
677   /// CHECK:                            DataProcWithShifterOp
678   /// CHECK:                            DataProcWithShifterOp
679   /// CHECK-NOT:                        DataProcWithShifterOp
680   // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier.
681 
682   /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after)
683   /// CHECK-NOT:                        Shl
684   /// CHECK-NOT:                        Shr
685   /// CHECK-NOT:                        UShr
686 
687   /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
688   /// CHECK:                            DataProcWithShifterOp
689   /// CHECK:                            DataProcWithShifterOp
690   /// CHECK:                            DataProcWithShifterOp
691   /// CHECK:                            DataProcWithShifterOp
692   /// CHECK:                            DataProcWithShifterOp
693   /// CHECK:                            DataProcWithShifterOp
694   /// CHECK:                            DataProcWithShifterOp
695   /// CHECK:                            DataProcWithShifterOp
696   /// CHECK:                            DataProcWithShifterOp
697   /// CHECK:                            DataProcWithShifterOp
698   /// CHECK:                            DataProcWithShifterOp
699   /// CHECK:                            DataProcWithShifterOp
700   /// CHECK:                            DataProcWithShifterOp
701   /// CHECK:                            DataProcWithShifterOp
702   /// CHECK:                            DataProcWithShifterOp
703   /// CHECK:                            DataProcWithShifterOp
704   /// CHECK:                            DataProcWithShifterOp
705   /// CHECK:                            DataProcWithShifterOp
706   /// CHECK:                            DataProcWithShifterOp
707   /// CHECK:                            DataProcWithShifterOp
708   /// CHECK:                            DataProcWithShifterOp
709   /// CHECK:                            DataProcWithShifterOp
710   /// CHECK:                            DataProcWithShifterOp
711   /// CHECK:                            DataProcWithShifterOp
712   /// CHECK:                            DataProcWithShifterOp
713   /// CHECK:                            DataProcWithShifterOp
714   /// CHECK:                            DataProcWithShifterOp
715   /// CHECK:                            DataProcWithShifterOp
716   /// CHECK:                            DataProcWithShifterOp
717   /// CHECK:                            DataProcWithShifterOp
718   /// CHECK:                            DataProcWithShifterOp
719   /// CHECK:                            DataProcWithShifterOp
720   /// CHECK:                            DataProcWithShifterOp
721   /// CHECK-NOT:                        DataProcWithShifterOp
722   // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier.
723 
724   /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after)
725   /// CHECK-NOT:                        Shl
726   /// CHECK-NOT:                        Shr
727   /// CHECK-NOT:                        UShr
728 
$opt$validateShiftInt(int a, int b)729   public static void $opt$validateShiftInt(int a, int b) {
730     assertIntEquals(a + $noinline$IntShl(b, 1),   a + (b <<  1));
731     assertIntEquals(a + $noinline$IntShl(b, 6),   a + (b <<  6));
732     assertIntEquals(a + $noinline$IntShl(b, 7),   a + (b <<  7));
733     assertIntEquals(a + $noinline$IntShl(b, 8),   a + (b <<  8));
734     assertIntEquals(a + $noinline$IntShl(b, 14),  a + (b << 14));
735     assertIntEquals(a + $noinline$IntShl(b, 15),  a + (b << 15));
736     assertIntEquals(a + $noinline$IntShl(b, 16),  a + (b << 16));
737     assertIntEquals(a + $noinline$IntShl(b, 30),  a + (b << 30));
738     assertIntEquals(a + $noinline$IntShl(b, 31),  a + (b << 31));
739     assertIntEquals(a + $noinline$IntShl(b, 32),  a + (b << $opt$inline$IntConstant32()));
740     assertIntEquals(a + $noinline$IntShl(b, 62),  a + (b << $opt$inline$IntConstant62()));
741     assertIntEquals(a + $noinline$IntShl(b, 63),  a + (b << $opt$inline$IntConstant63()));
742 
743     assertIntEquals(a - $noinline$IntShr(b, 1),   a - (b >>  1));
744     assertIntEquals(a - $noinline$IntShr(b, 6),   a - (b >>  6));
745     assertIntEquals(a - $noinline$IntShr(b, 7),   a - (b >>  7));
746     assertIntEquals(a - $noinline$IntShr(b, 8),   a - (b >>  8));
747     assertIntEquals(a - $noinline$IntShr(b, 14),  a - (b >> 14));
748     assertIntEquals(a - $noinline$IntShr(b, 15),  a - (b >> 15));
749     assertIntEquals(a - $noinline$IntShr(b, 16),  a - (b >> 16));
750     assertIntEquals(a - $noinline$IntShr(b, 30),  a - (b >> 30));
751     assertIntEquals(a - $noinline$IntShr(b, 31),  a - (b >> 31));
752     assertIntEquals(a - $noinline$IntShr(b, 32),  a - (b >> $opt$inline$IntConstant32()));
753     assertIntEquals(a - $noinline$IntShr(b, 62),  a - (b >> $opt$inline$IntConstant62()));
754     assertIntEquals(a - $noinline$IntShr(b, 63),  a - (b >> $opt$inline$IntConstant63()));
755 
756     assertIntEquals(a ^ $noinline$IntUshr(b, 1),   a ^ (b >>>  1));
757     assertIntEquals(a ^ $noinline$IntUshr(b, 6),   a ^ (b >>>  6));
758     assertIntEquals(a ^ $noinline$IntUshr(b, 7),   a ^ (b >>>  7));
759     assertIntEquals(a ^ $noinline$IntUshr(b, 8),   a ^ (b >>>  8));
760     assertIntEquals(a ^ $noinline$IntUshr(b, 14),  a ^ (b >>> 14));
761     assertIntEquals(a ^ $noinline$IntUshr(b, 15),  a ^ (b >>> 15));
762     assertIntEquals(a ^ $noinline$IntUshr(b, 16),  a ^ (b >>> 16));
763     assertIntEquals(a ^ $noinline$IntUshr(b, 30),  a ^ (b >>> 30));
764     assertIntEquals(a ^ $noinline$IntUshr(b, 31),  a ^ (b >>> 31));
765     assertIntEquals(a ^ $noinline$IntUshr(b, 32),  a ^ (b >>> $opt$inline$IntConstant32()));
766     assertIntEquals(a ^ $noinline$IntUshr(b, 62),  a ^ (b >>> $opt$inline$IntConstant62()));
767     assertIntEquals(a ^ $noinline$IntUshr(b, 63),  a ^ (b >>> $opt$inline$IntConstant63()));
768   }
769 
770   // Hiding constants outside the range [0, 32) used for int shifts from Jack.
771   // (Jack extracts only the low 5 bits.)
$opt$inline$IntConstant32()772   public static int $opt$inline$IntConstant32() { return 32; }
$opt$inline$IntConstant62()773   public static int $opt$inline$IntConstant62() { return 62; }
$opt$inline$IntConstant63()774   public static int $opt$inline$IntConstant63() { return 63; }
775 
776 
$noinline$LongShl(long b, long c)777   static long $noinline$LongShl(long b, long c) {
778     if (doThrow) throw new Error();
779     return b << c;
780   }
$noinline$LongShr(long b, long c)781   static long $noinline$LongShr(long b, long c) {
782     if (doThrow) throw new Error();
783     return b >> c;
784   }
$noinline$LongUshr(long b, long c)785   static long $noinline$LongUshr(long b, long c) {
786     if (doThrow) throw new Error();
787     return b >>> c;
788   }
789 
790   // Each test line below should see one merge.
791   /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after)
792   /// CHECK:                            DataProcWithShifterOp
793   /// CHECK:                            DataProcWithShifterOp
794   /// CHECK:                            DataProcWithShifterOp
795   /// CHECK:                            DataProcWithShifterOp
796   /// CHECK:                            DataProcWithShifterOp
797   /// CHECK:                            DataProcWithShifterOp
798   /// CHECK:                            DataProcWithShifterOp
799   /// CHECK:                            DataProcWithShifterOp
800   /// CHECK:                            DataProcWithShifterOp
801   /// CHECK:                            DataProcWithShifterOp
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-NOT:                        DataProcWithShifterOp
826 
827   // On ARM shifts by 1 are not merged.
828   /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after)
829   /// CHECK:                            Shl
830   /// CHECK-NOT:                        Shl
831   /// CHECK:                            Shr
832   /// CHECK-NOT:                        Shr
833   /// CHECK:                            UShr
834   /// CHECK-NOT:                        UShr
835 
836   /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
837   /// CHECK:                            DataProcWithShifterOp
838   /// CHECK:                            DataProcWithShifterOp
839   /// CHECK:                            DataProcWithShifterOp
840   /// CHECK:                            DataProcWithShifterOp
841   /// CHECK:                            DataProcWithShifterOp
842   /// CHECK:                            DataProcWithShifterOp
843   /// CHECK:                            DataProcWithShifterOp
844   /// CHECK:                            DataProcWithShifterOp
845   /// CHECK:                            DataProcWithShifterOp
846   /// CHECK:                            DataProcWithShifterOp
847   /// CHECK:                            DataProcWithShifterOp
848   /// CHECK:                            DataProcWithShifterOp
849   /// CHECK:                            DataProcWithShifterOp
850   /// CHECK:                            DataProcWithShifterOp
851   /// CHECK:                            DataProcWithShifterOp
852   /// CHECK:                            DataProcWithShifterOp
853   /// CHECK:                            DataProcWithShifterOp
854   /// CHECK:                            DataProcWithShifterOp
855   /// CHECK:                            DataProcWithShifterOp
856   /// CHECK:                            DataProcWithShifterOp
857   /// CHECK:                            DataProcWithShifterOp
858   /// CHECK:                            DataProcWithShifterOp
859   /// CHECK:                            DataProcWithShifterOp
860   /// CHECK:                            DataProcWithShifterOp
861   /// CHECK:                            DataProcWithShifterOp
862   /// CHECK:                            DataProcWithShifterOp
863   /// CHECK:                            DataProcWithShifterOp
864   /// CHECK:                            DataProcWithShifterOp
865   /// CHECK:                            DataProcWithShifterOp
866   /// CHECK:                            DataProcWithShifterOp
867   /// CHECK:                            DataProcWithShifterOp
868   /// CHECK:                            DataProcWithShifterOp
869   /// CHECK:                            DataProcWithShifterOp
870   /// CHECK:                            DataProcWithShifterOp
871   /// CHECK:                            DataProcWithShifterOp
872   /// CHECK:                            DataProcWithShifterOp
873   /// CHECK-NOT:                        DataProcWithShifterOp
874 
875   /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after)
876   /// CHECK-NOT:                        Shl
877   /// CHECK-NOT:                        Shr
878   /// CHECK-NOT:                        UShr
879 
$opt$validateShiftLong(long a, long b)880   public static void $opt$validateShiftLong(long a, long b) {
881     assertLongEquals(a + $noinline$LongShl(b, 1),   a + (b <<  1));
882     assertLongEquals(a + $noinline$LongShl(b, 6),   a + (b <<  6));
883     assertLongEquals(a + $noinline$LongShl(b, 7),   a + (b <<  7));
884     assertLongEquals(a + $noinline$LongShl(b, 8),   a + (b <<  8));
885     assertLongEquals(a + $noinline$LongShl(b, 14),  a + (b << 14));
886     assertLongEquals(a + $noinline$LongShl(b, 15),  a + (b << 15));
887     assertLongEquals(a + $noinline$LongShl(b, 16),  a + (b << 16));
888     assertLongEquals(a + $noinline$LongShl(b, 30),  a + (b << 30));
889     assertLongEquals(a + $noinline$LongShl(b, 31),  a + (b << 31));
890     assertLongEquals(a + $noinline$LongShl(b, 32),  a + (b << 32));
891     assertLongEquals(a + $noinline$LongShl(b, 62),  a + (b << 62));
892     assertLongEquals(a + $noinline$LongShl(b, 63),  a + (b << 63));
893 
894     assertLongEquals(a - $noinline$LongShr(b, 1),   a - (b >>  1));
895     assertLongEquals(a - $noinline$LongShr(b, 6),   a - (b >>  6));
896     assertLongEquals(a - $noinline$LongShr(b, 7),   a - (b >>  7));
897     assertLongEquals(a - $noinline$LongShr(b, 8),   a - (b >>  8));
898     assertLongEquals(a - $noinline$LongShr(b, 14),  a - (b >> 14));
899     assertLongEquals(a - $noinline$LongShr(b, 15),  a - (b >> 15));
900     assertLongEquals(a - $noinline$LongShr(b, 16),  a - (b >> 16));
901     assertLongEquals(a - $noinline$LongShr(b, 30),  a - (b >> 30));
902     assertLongEquals(a - $noinline$LongShr(b, 31),  a - (b >> 31));
903     assertLongEquals(a - $noinline$LongShr(b, 32),  a - (b >> 32));
904     assertLongEquals(a - $noinline$LongShr(b, 62),  a - (b >> 62));
905     assertLongEquals(a - $noinline$LongShr(b, 63),  a - (b >> 63));
906 
907     assertLongEquals(a ^ $noinline$LongUshr(b, 1),   a ^ (b >>>  1));
908     assertLongEquals(a ^ $noinline$LongUshr(b, 6),   a ^ (b >>>  6));
909     assertLongEquals(a ^ $noinline$LongUshr(b, 7),   a ^ (b >>>  7));
910     assertLongEquals(a ^ $noinline$LongUshr(b, 8),   a ^ (b >>>  8));
911     assertLongEquals(a ^ $noinline$LongUshr(b, 14),  a ^ (b >>> 14));
912     assertLongEquals(a ^ $noinline$LongUshr(b, 15),  a ^ (b >>> 15));
913     assertLongEquals(a ^ $noinline$LongUshr(b, 16),  a ^ (b >>> 16));
914     assertLongEquals(a ^ $noinline$LongUshr(b, 30),  a ^ (b >>> 30));
915     assertLongEquals(a ^ $noinline$LongUshr(b, 31),  a ^ (b >>> 31));
916     assertLongEquals(a ^ $noinline$LongUshr(b, 32),  a ^ (b >>> 32));
917     assertLongEquals(a ^ $noinline$LongUshr(b, 62),  a ^ (b >>> 62));
918     assertLongEquals(a ^ $noinline$LongUshr(b, 63),  a ^ (b >>> 63));
919   }
920 
921 
main(String[] args)922   public static void main(String[] args) {
923     assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3));
924     assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3));
925 
926     assertIntEquals(4096, $opt$noinline$sameInput(512));
927     assertIntEquals(-8192, $opt$noinline$sameInput(-1024));
928 
929     assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1));
930     assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20));
931 
932     long inputs[] = {
933       -((1L <<  7) - 1L), -((1L <<  7)), -((1L <<  7) + 1L),
934       -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L),
935       -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L),
936       -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L),
937       -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L),
938       -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L),
939       -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L,
940       -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L,
941       0L,
942       1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L,
943       42L,  314L,  2718281828L,  0x123456789L,  0x987654321L,
944       (1L <<  7) - 1L, (1L <<  7), (1L <<  7) + 1L,
945       (1L <<  8) - 1L, (1L <<  8), (1L <<  8) + 1L,
946       (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L,
947       (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L,
948       (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L,
949       (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L,
950       (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L,
951       Long.MIN_VALUE, Long.MAX_VALUE
952     };
953     for (int i = 0; i < inputs.length; i++) {
954       $opt$noinline$testNeg((int)inputs[i]);
955       for (int j = 0; j < inputs.length; j++) {
956         $opt$noinline$testAnd(inputs[i], inputs[j]);
957         $opt$noinline$testOr((int)inputs[i], (int)inputs[j]);
958         $opt$noinline$testXor(inputs[i], inputs[j]);
959 
960         $opt$validateExtendByte(inputs[i], (byte)inputs[j]);
961         $opt$validateExtendChar(inputs[i], (char)inputs[j]);
962         $opt$validateExtendShort(inputs[i], (short)inputs[j]);
963         $opt$validateExtendInt(inputs[i], (int)inputs[j]);
964         $opt$validateExtendLong(inputs[i], inputs[j]);
965 
966         $opt$validateShiftInt((int)inputs[i], (int)inputs[j]);
967         $opt$validateShiftLong(inputs[i], inputs[j]);
968       }
969     }
970 
971   }
972 }
973