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