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