Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2018 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 /**
     18  * Functional tests for detecting min/max.
     19  */
     20 public class Main {
     21 
     22   //
     23   // Direct intrinsics.
     24   //
     25 
     26   /// CHECK-START: int Main.minI(int) instruction_simplifier (before)
     27   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
     28   /// CHECK-DAG: <<Con:i\d+>> IntConstant 20
     29   /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<Par>>,<<Con>>] intrinsic:MathMinIntInt
     30   /// CHECK-DAG:              Return [<<Min>>]
     31   //
     32   /// CHECK-START: int Main.minI(int) instruction_simplifier (after)
     33   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
     34   /// CHECK-DAG: <<Con:i\d+>> IntConstant 20
     35   /// CHECK-DAG: <<Min:i\d+>> Min [<<Par>>,<<Con>>]
     36   /// CHECK-DAG:              Return [<<Min>>]
     37   //
     38   /// CHECK-START: int Main.minI(int) instruction_simplifier (after)
     39   /// CHECK-NOT:              InvokeStaticOrDirect
     40   //
     41   /// CHECK-START-ARM64: int Main.minI(int) disassembly (after)
     42   /// CHECK-NOT:              mov {{w\d+}}, #0x14
     43   /// CHECK:                  cmp {{w\d+}}, #0x14
     44   //  Check that the constant generation was handled by VIXL.
     45   /// CHECK:                  mov w16, #0x14
     46   /// CHECK:                  csel {{w\d+}}, {{w\d+}}, w16, lt
     47   public static int minI(int a) {
     48     return Math.min(a, 20);
     49   }
     50 
     51   /// CHECK-START: long Main.minL(long) instruction_simplifier (before)
     52   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
     53   /// CHECK-DAG: <<Con:j\d+>> LongConstant 20
     54   /// CHECK-DAG: <<Min:j\d+>> InvokeStaticOrDirect [<<Par>>,<<Con>>] intrinsic:MathMinLongLong
     55   /// CHECK-DAG:              Return [<<Min>>]
     56   //
     57   /// CHECK-START: long Main.minL(long) instruction_simplifier (after)
     58   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
     59   /// CHECK-DAG: <<Con:j\d+>> LongConstant 20
     60   /// CHECK-DAG: <<Min:j\d+>> Min [<<Par>>,<<Con>>]
     61   /// CHECK-DAG:              Return [<<Min>>]
     62   //
     63   /// CHECK-START: long Main.minL(long) instruction_simplifier (after)
     64   /// CHECK-NOT:              InvokeStaticOrDirect
     65   //
     66   /// CHECK-START-ARM64: long Main.minL(long) disassembly (after)
     67   /// CHECK-NOT:              mov {{x\d+}}, #0x14
     68   /// CHECK:                  cmp {{x\d+}}, #0x14
     69   //  Check that the constant generation was handled by VIXL.
     70   /// CHECK:                  mov x16, #0x14
     71   /// CHECK:                  csel {{x\d+}}, {{x\d+}}, x16, lt
     72   public static long minL(long a) {
     73     return Math.min(a, 20L);
     74   }
     75 
     76   /// CHECK-START: int Main.maxI(int) instruction_simplifier (before)
     77   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
     78   /// CHECK-DAG: <<Con:i\d+>> IntConstant 20
     79   /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<Par>>,<<Con>>] intrinsic:MathMaxIntInt
     80   /// CHECK-DAG:              Return [<<Max>>]
     81   //
     82   /// CHECK-START: int Main.maxI(int) instruction_simplifier (after)
     83   /// CHECK-DAG: <<Par:i\d+>> ParameterValue
     84   /// CHECK-DAG: <<Con:i\d+>> IntConstant 20
     85   /// CHECK-DAG: <<Max:i\d+>> Max [<<Par>>,<<Con>>]
     86   /// CHECK-DAG:              Return [<<Max>>]
     87   //
     88   /// CHECK-START: int Main.maxI(int) instruction_simplifier (after)
     89   /// CHECK-NOT:              InvokeStaticOrDirect
     90   //
     91   /// CHECK-START-ARM64: int Main.maxI(int) disassembly (after)
     92   /// CHECK-NOT:              mov {{w\d+}}, #0x14
     93   /// CHECK:                  cmp {{w\d+}}, #0x14
     94   //  Check that the constant generation was handled by VIXL.
     95   /// CHECK:                  mov w16, #0x14
     96   /// CHECK:                  csel {{w\d+}}, {{w\d+}}, w16, gt
     97   public static int maxI(int a) {
     98     return Math.max(a, 20);
     99   }
    100 
    101   /// CHECK-START: long Main.maxL(long) instruction_simplifier (before)
    102   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
    103   /// CHECK-DAG: <<Con:j\d+>> LongConstant 20
    104   /// CHECK-DAG: <<Max:j\d+>> InvokeStaticOrDirect [<<Par>>,<<Con>>] intrinsic:MathMaxLongLong
    105   /// CHECK-DAG:              Return [<<Max>>]
    106   //
    107   /// CHECK-START: long Main.maxL(long) instruction_simplifier (after)
    108   /// CHECK-DAG: <<Par:j\d+>> ParameterValue
    109   /// CHECK-DAG: <<Con:j\d+>> LongConstant 20
    110   /// CHECK-DAG: <<Max:j\d+>> Max [<<Par>>,<<Con>>]
    111   /// CHECK-DAG:              Return [<<Max>>]
    112   //
    113   /// CHECK-START: long Main.maxL(long) instruction_simplifier (after)
    114   /// CHECK-NOT:              InvokeStaticOrDirect
    115   //
    116   /// CHECK-START-ARM64: long Main.maxL(long) disassembly (after)
    117   /// CHECK-NOT:              mov {{x\d+}}, #0x14
    118   /// CHECK:                  cmp {{x\d+}}, #0x14
    119   //  Check that the constant generation was handled by VIXL.
    120   /// CHECK:                  mov x16, #0x14
    121   /// CHECK:                  csel {{x\d+}}, {{x\d+}}, x16, gt
    122   public static long maxL(long a) {
    123     return Math.max(a, 20L);
    124   }
    125 
    126   //
    127   // Special Cases
    128   //
    129 
    130   /// CHECK-START-ARM64: int Main.minIntConstantZero(int) disassembly (after)
    131   /// CHECK-NOT:        InvokeStaticOrDirect
    132   /// CHECK-NOT:        mov {{w\d+}}, #0x0
    133   /// CHECK:            cmp {{w\d+}}, #0x0 (0)
    134   /// CHECK:            csel {{w\d+}}, {{w\d+}}, wzr, lt
    135   /// CHECK:            ret
    136   public static int minIntConstantZero(int a) {
    137     return Math.min(a, 0);
    138   }
    139 
    140   /// CHECK-START-ARM64: int Main.minIntConstantOne(int) disassembly (after)
    141   /// CHECK-NOT:        InvokeStaticOrDirect
    142   /// CHECK-NOT:        mov {{w\d+}}, #0x1
    143   /// CHECK:            cmp {{w\d+}}, #0x1 (1)
    144   /// CHECK:            csinc {{w\d+}}, {{w\d+}}, wzr, lt
    145   /// CHECK:            ret
    146   public static int minIntConstantOne(int a) {
    147     return Math.min(a, 1);
    148   }
    149 
    150   /// CHECK-START-ARM64: int Main.minIntConstantMinusOne(int) disassembly (after)
    151   /// CHECK-NOT:        InvokeStaticOrDirect
    152   /// CHECK-NOT:        mov {{w\d+}}, #0xffffffff
    153   /// CHECK:            cmn {{w\d+}}, #0x1 (1)
    154   /// CHECK:            csinv {{w\d+}}, {{w\d+}}, wzr, lt
    155   /// CHECK:            ret
    156   public static int minIntConstantMinusOne(int a) {
    157     return Math.min(a, -1);
    158   }
    159 
    160   /// CHECK-START-ARM64: long Main.minLongConstantZero(long) disassembly (after)
    161   /// CHECK-NOT:        InvokeStaticOrDirect
    162   /// CHECK-NOT:        mov {{x\d+}}, #0x0
    163   /// CHECK:            cmp {{x\d+}}, #0x0 (0)
    164   /// CHECK:            csel {{x\d+}}, {{x\d+}}, xzr, lt
    165   /// CHECK:            ret
    166   public static long minLongConstantZero(long a) {
    167     return Math.min(a, 0L);
    168   }
    169 
    170   /// CHECK-START-ARM64: long Main.minLongConstantOne(long) disassembly (after)
    171   /// CHECK-NOT:        InvokeStaticOrDirect
    172   /// CHECK-NOT:        mov {{x\d+}}, #0x1
    173   /// CHECK:            cmp {{x\d+}}, #0x1 (1)
    174   /// CHECK:            csinc {{x\d+}}, {{x\d+}}, xzr, lt
    175   /// CHECK:            ret
    176   public static long minLongConstantOne(long a) {
    177     return Math.min(a, 1L);
    178   }
    179 
    180   /// CHECK-START-ARM64: long Main.minLongConstantMinusOne(long) disassembly (after)
    181   /// CHECK-NOT:        InvokeStaticOrDirect
    182   /// CHECK-NOT:        mov {{x\d+}}, #0xffffffffffffffff
    183   /// CHECK:            cmn {{x\d+}}, #0x1 (1)
    184   /// CHECK:            csinv {{x\d+}}, {{x\d+}}, xzr, lt
    185   /// CHECK:            ret
    186   public static long minLongConstantMinusOne(long a) {
    187     return Math.min(a, -1L);
    188   }
    189 
    190   /// CHECK-START-ARM64: int Main.maxIntConstantZero(int) disassembly (after)
    191   /// CHECK-NOT:        InvokeStaticOrDirect
    192   /// CHECK-NOT:        mov {{w\d+}}, #0x0
    193   /// CHECK:            cmp {{w\d+}}, #0x0 (0)
    194   /// CHECK:            csel {{w\d+}}, {{w\d+}}, wzr, gt
    195   /// CHECK:            ret
    196   public static int maxIntConstantZero(int a) {
    197     return Math.max(a, 0);
    198   }
    199 
    200   /// CHECK-START-ARM64: int Main.maxIntConstantOne(int) disassembly (after)
    201   /// CHECK-NOT:        InvokeStaticOrDirect
    202   /// CHECK-NOT:        mov {{w\d+}}, #0x1
    203   /// CHECK:            cmp {{w\d+}}, #0x1 (1)
    204   /// CHECK:            csinc {{w\d+}}, {{w\d+}}, wzr, gt
    205   /// CHECK:            ret
    206   public static int maxIntConstantOne(int a) {
    207     return Math.max(a, 1);
    208   }
    209 
    210   /// CHECK-START-ARM64: int Main.maxIntConstantMinusOne(int) disassembly (after)
    211   /// CHECK-NOT:        InvokeStaticOrDirect
    212   /// CHECK-NOT:        mov {{w\d+}}, #0xffffffff
    213   /// CHECK:            cmn {{w\d+}}, #0x1 (1)
    214   /// CHECK:            csinv {{w\d+}}, {{w\d+}}, wzr, gt
    215   /// CHECK:            ret
    216   public static int maxIntConstantMinusOne(int a) {
    217     return Math.max(a, -1);
    218   }
    219 
    220   /// CHECK-START-ARM64: int Main.maxIntLargeConstant(int) disassembly (after)
    221   /// CHECK-NOT:        InvokeStaticOrDirect
    222   /// CHECK:            mov {{w\d+}}, #0x2001
    223   /// CHECK:            cmp {{w\d+}}, {{w\d+}}
    224   //  Check that constant generation was not handled by VIXL.
    225   /// CHECK-NOT:        mov {{w\d+}}, #0x2001
    226   /// CHECK:            csel {{w\d+}}, {{w\d+}}, {{w\d+}}, gt
    227   /// CHECK:            ret
    228   public static int maxIntLargeConstant(int a) {
    229     return Math.max(a, 8193);
    230   }
    231 
    232   /// CHECK-START-ARM64: long Main.maxLongConstantZero(long) disassembly (after)
    233   /// CHECK-NOT:        InvokeStaticOrDirect
    234   /// CHECK-NOT:        mov {{x\d+}}, #0x0
    235   /// CHECK:            cmp {{x\d+}}, #0x0 (0)
    236   /// CHECK:            csel {{x\d+}}, {{x\d+}}, xzr, gt
    237   /// CHECK:            ret
    238   public static long maxLongConstantZero(long a) {
    239     return Math.max(a, 0L);
    240   }
    241 
    242   /// CHECK-START-ARM64: long Main.maxLongConstantOne(long) disassembly (after)
    243   /// CHECK-NOT:        InvokeStaticOrDirect
    244   /// CHECK-NOT:        mov {{x\d+}}, #0x1
    245   /// CHECK:            cmp {{x\d+}}, #0x1 (1)
    246   /// CHECK:            csinc {{x\d+}}, {{x\d+}}, xzr, gt
    247   /// CHECK:            ret
    248   public static long maxLongConstantOne(long a) {
    249     return Math.max(a, 1L);
    250   }
    251 
    252   /// CHECK-START-ARM64: long Main.maxLongConstantMinusOne(long) disassembly (after)
    253   /// CHECK-NOT:        InvokeStaticOrDirect
    254   /// CHECK-NOT:        mov {{x\d+}}, #0xffffffffffffffff
    255   /// CHECK:            cmn {{x\d+}}, #0x1 (1)
    256   /// CHECK:            csinv {{x\d+}}, {{x\d+}}, xzr, gt
    257   /// CHECK:            ret
    258   public static long maxLongConstantMinusOne(long a) {
    259     return Math.max(a, -1L);
    260   }
    261 
    262   /// CHECK-START-ARM64: long Main.maxLongLargeConstant(long) disassembly (after)
    263   /// CHECK-NOT:        InvokeStaticOrDirect
    264   /// CHECK:            mov {{x\d+}}, #0x2001
    265   /// CHECK:            cmp {{x\d+}}, {{x\d+}}
    266   //  Check that constant generation was not handled by VIXL.
    267   /// CHECK-NOT:        mov {{x\d+}}, #0x2001
    268   /// CHECK:            csel {{x\d+}}, {{x\d+}}, {{x\d+}}, gt
    269   /// CHECK:            ret
    270   public static long maxLongLargeConstant(long a) {
    271     return Math.max(a, 8193L);
    272   }
    273 
    274   //
    275   // Different types.
    276   //
    277 
    278   /// CHECK-START: int Main.min1(int, int) instruction_simplifier$after_gvn (before)
    279   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThanOrEqual [<<Op1:i\d+>>,<<Op2:i\d+>>]
    280   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    281   /// CHECK-DAG:              Return [<<Sel>>]
    282   //
    283   /// CHECK-START: int Main.min1(int, int) instruction_simplifier$after_gvn (after)
    284   /// CHECK-DAG: <<Min:i\d+>> Min
    285   /// CHECK-DAG:              Return [<<Min>>]
    286   //
    287   /// CHECK-START: int Main.min1(int, int) instruction_simplifier$after_gvn (after)
    288   /// CHECK-NOT:              Select
    289   public static int min1(int a, int b) {
    290     return a < b ? a : b;
    291   }
    292 
    293   /// CHECK-START: int Main.min2(int, int) instruction_simplifier$after_gvn (before)
    294   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThan [<<Op1:i\d+>>,<<Op2:i\d+>>]
    295   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    296   /// CHECK-DAG:              Return [<<Sel>>]
    297   //
    298   /// CHECK-START: int Main.min2(int, int) instruction_simplifier$after_gvn (after)
    299   /// CHECK-DAG: <<Min:i\d+>> Min
    300   /// CHECK-DAG:              Return [<<Min>>]
    301   //
    302   /// CHECK-START: int Main.min2(int, int) instruction_simplifier$after_gvn (after)
    303   /// CHECK-NOT:              Select
    304   public static int min2(int a, int b) {
    305     return a <= b ? a : b;
    306   }
    307 
    308   /// CHECK-START: int Main.min3(int, int) instruction_simplifier$after_gvn (before)
    309   /// CHECK-DAG: <<Cnd:z\d+>> LessThanOrEqual [<<Op1:i\d+>>,<<Op2:i\d+>>]
    310   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    311   /// CHECK-DAG:              Return [<<Sel>>]
    312   //
    313   /// CHECK-START: int Main.min3(int, int) instruction_simplifier$after_gvn (after)
    314   /// CHECK-DAG: <<Min:i\d+>> Min
    315   /// CHECK-DAG:              Return [<<Min>>]
    316   //
    317   /// CHECK-START: int Main.min3(int, int) instruction_simplifier$after_gvn (after)
    318   /// CHECK-NOT:              Select
    319   public static int min3(int a, int b) {
    320     return a > b ? b : a;
    321   }
    322 
    323   /// CHECK-START: int Main.min4(int, int) instruction_simplifier$after_gvn (before)
    324   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:i\d+>>,<<Op2:i\d+>>]
    325   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    326   /// CHECK-DAG:              Return [<<Sel>>]
    327   //
    328   /// CHECK-START: int Main.min4(int, int) instruction_simplifier$after_gvn (after)
    329   /// CHECK-DAG: <<Min:i\d+>> Min
    330   /// CHECK-DAG:              Return [<<Min>>]
    331   //
    332   /// CHECK-START: int Main.min4(int, int) instruction_simplifier$after_gvn (after)
    333   /// CHECK-NOT:              Select
    334   public static int min4(int a, int b) {
    335     return a >= b ? b : a;
    336   }
    337 
    338   /// CHECK-START: int Main.min5(short, short) instruction_simplifier$after_gvn (before)
    339   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:s\d+>>,<<Op2:s\d+>>]
    340   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    341   /// CHECK-DAG:              Return [<<Sel>>]
    342   //
    343   /// CHECK-START: int Main.min5(short, short) instruction_simplifier$after_gvn (after)
    344   /// CHECK-DAG: <<Min:i\d+>> Min
    345   /// CHECK-DAG:              Return [<<Min>>]
    346   //
    347   /// CHECK-START: int Main.min5(short, short) instruction_simplifier$after_gvn (after)
    348   /// CHECK-NOT:              Select
    349   public static int min5(short a, short b) {
    350     return a >= b ? b : a;
    351   }
    352 
    353   /// CHECK-START: int Main.min6(byte, byte) instruction_simplifier$after_gvn (before)
    354   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:b\d+>>,<<Op2:b\d+>>]
    355   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    356   /// CHECK-DAG:              Return [<<Sel>>]
    357   //
    358   /// CHECK-START: int Main.min6(byte, byte) instruction_simplifier$after_gvn (after)
    359   /// CHECK-DAG: <<Min:i\d+>> Min
    360   /// CHECK-DAG:              Return [<<Min>>]
    361   //
    362   /// CHECK-START: int Main.min6(byte, byte) instruction_simplifier$after_gvn (after)
    363   /// CHECK-NOT:              Select
    364   public static int min6(byte a, byte b) {
    365     return a >= b ? b : a;
    366   }
    367 
    368   /// CHECK-START: long Main.min7(long, long) instruction_simplifier$after_gvn (before)
    369   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:j\d+>>,<<Op2:j\d+>>]
    370   /// CHECK-DAG: <<Sel:j\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    371   /// CHECK-DAG:              Return [<<Sel>>]
    372   //
    373   /// CHECK-START: long Main.min7(long, long) instruction_simplifier$after_gvn (after)
    374   /// CHECK-DAG: <<Min:j\d+>> Min
    375   /// CHECK-DAG:              Return [<<Min>>]
    376   //
    377   /// CHECK-START: long Main.min7(long, long) instruction_simplifier$after_gvn (after)
    378   /// CHECK-NOT:              Select
    379   public static long min7(long a, long b) {
    380     return a >= b ? b : a;
    381   }
    382 
    383   /// CHECK-START: int Main.max1(int, int) instruction_simplifier$after_gvn (before)
    384   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThanOrEqual [<<Op1:i\d+>>,<<Op2:i\d+>>]
    385   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    386   /// CHECK-DAG:              Return [<<Sel>>]
    387   //
    388   /// CHECK-START: int Main.max1(int, int) instruction_simplifier$after_gvn (after)
    389   /// CHECK-DAG: <<Max:i\d+>> Max
    390   /// CHECK-DAG:              Return [<<Max>>]
    391   //
    392   /// CHECK-START: int Main.max1(int, int) instruction_simplifier$after_gvn (after)
    393   /// CHECK-NOT:              Select
    394   public static int max1(int a, int b) {
    395     return a < b ? b : a;
    396   }
    397 
    398   /// CHECK-START: int Main.max2(int, int) instruction_simplifier$after_gvn (before)
    399   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThan [<<Op1:i\d+>>,<<Op2:i\d+>>]
    400   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op2>>,<<Op1>>,<<Cnd>>]
    401   /// CHECK-DAG:              Return [<<Sel>>]
    402   //
    403   /// CHECK-START: int Main.max2(int, int) instruction_simplifier$after_gvn (after)
    404   /// CHECK-DAG: <<Max:i\d+>> Max
    405   /// CHECK-DAG:              Return [<<Max>>]
    406   //
    407   /// CHECK-START: int Main.max2(int, int) instruction_simplifier$after_gvn (after)
    408   /// CHECK-NOT:              Select
    409   public static int max2(int a, int b) {
    410     return a <= b ? b : a;
    411   }
    412 
    413   /// CHECK-START: int Main.max3(int, int) instruction_simplifier$after_gvn (before)
    414   /// CHECK-DAG: <<Cnd:z\d+>> LessThanOrEqual [<<Op1:i\d+>>,<<Op2:i\d+>>]
    415   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    416   /// CHECK-DAG:              Return [<<Sel>>]
    417   //
    418   /// CHECK-START: int Main.max3(int, int) instruction_simplifier$after_gvn (after)
    419   /// CHECK-DAG: <<Max:i\d+>> Max
    420   /// CHECK-DAG:              Return [<<Max>>]
    421   //
    422   /// CHECK-START: int Main.max3(int, int) instruction_simplifier$after_gvn (after)
    423   /// CHECK-NOT:              Select
    424   public static int max3(int a, int b) {
    425     return a > b ? a : b;
    426   }
    427 
    428   /// CHECK-START: int Main.max4(int, int) instruction_simplifier$after_gvn (before)
    429   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:i\d+>>,<<Op2:i\d+>>]
    430   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    431   /// CHECK-DAG:              Return [<<Sel>>]
    432   //
    433   /// CHECK-START: int Main.max4(int, int) instruction_simplifier$after_gvn (after)
    434   /// CHECK-DAG: <<Max:i\d+>> Max
    435   /// CHECK-DAG:              Return [<<Max>>]
    436   //
    437   /// CHECK-START: int Main.max4(int, int) instruction_simplifier$after_gvn (after)
    438   /// CHECK-NOT:              Select
    439   public static int max4(int a, int b) {
    440     return a >= b ? a : b;
    441   }
    442 
    443   /// CHECK-START: int Main.max5(short, short) instruction_simplifier$after_gvn (before)
    444   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:s\d+>>,<<Op2:s\d+>>]
    445   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    446   /// CHECK-DAG:              Return [<<Sel>>]
    447   //
    448   /// CHECK-START: int Main.max5(short, short) instruction_simplifier$after_gvn (after)
    449   /// CHECK-DAG: <<Max:i\d+>> Max
    450   /// CHECK-DAG:              Return [<<Max>>]
    451   //
    452   /// CHECK-START: int Main.max5(short, short) instruction_simplifier$after_gvn (after)
    453   /// CHECK-NOT:              Select
    454   public static int max5(short a, short b) {
    455     return a >= b ? a : b;
    456   }
    457 
    458   /// CHECK-START: int Main.max6(byte, byte) instruction_simplifier$after_gvn (before)
    459   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:b\d+>>,<<Op2:b\d+>>]
    460   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    461   /// CHECK-DAG:              Return [<<Sel>>]
    462   //
    463   /// CHECK-START: int Main.max6(byte, byte) instruction_simplifier$after_gvn (after)
    464   /// CHECK-DAG: <<Max:i\d+>> Max
    465   /// CHECK-DAG:              Return [<<Max>>]
    466   //
    467   /// CHECK-START: int Main.max6(byte, byte) instruction_simplifier$after_gvn (after)
    468   /// CHECK-NOT:              Select
    469   public static int max6(byte a, byte b) {
    470     return a >= b ? a : b;
    471   }
    472 
    473   /// CHECK-START: long Main.max7(long, long) instruction_simplifier$after_gvn (before)
    474   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Op1:j\d+>>,<<Op2:j\d+>>]
    475   /// CHECK-DAG: <<Sel:j\d+>> Select [<<Op1>>,<<Op2>>,<<Cnd>>]
    476   /// CHECK-DAG:              Return [<<Sel>>]
    477   //
    478   /// CHECK-START: long Main.max7(long, long) instruction_simplifier$after_gvn (after)
    479   /// CHECK-DAG: <<Max:j\d+>> Max
    480   /// CHECK-DAG:              Return [<<Max>>]
    481   //
    482   /// CHECK-START: long Main.max7(long, long) instruction_simplifier$after_gvn (after)
    483   /// CHECK-NOT:              Select
    484   public static long max7(long a, long b) {
    485     return a >= b ? a : b;
    486   }
    487 
    488   //
    489   // Complications.
    490   //
    491 
    492   /// CHECK-START: int Main.min0(int[], int[]) instruction_simplifier$after_gvn (before)
    493   /// CHECK-DAG: <<Ar1:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
    494   /// CHECK-DAG: <<Ar2:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
    495   /// CHECK-DAG: <<Cnd:z\d+>> GreaterThan [<<Ar1>>,<<Ar2>>]
    496   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Ar1>>,<<Ar2>>,<<Cnd>>]
    497   /// CHECK-DAG:              Return [<<Sel>>]
    498   //
    499   /// CHECK-START: int Main.min0(int[], int[]) instruction_simplifier$after_gvn (after)
    500   /// CHECK-DAG: <<Min:i\d+>> Min
    501   /// CHECK-DAG:              Return [<<Min>>]
    502   //
    503   /// CHECK-START: int Main.min0(int[], int[]) instruction_simplifier$after_gvn (after)
    504   /// CHECK-NOT:              Select
    505   public static int min0(int[] a, int[] b) {
    506     // Repeat of array references needs finding the common subexpressions
    507     // prior to doing the select and min/max recognition.
    508     return a[0] <= b[0] ? a[0] : b[0];
    509   }
    510 
    511   /// CHECK-START: int Main.max0(int[], int[]) instruction_simplifier$after_gvn (before)
    512   /// CHECK-DAG: <<Ar1:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
    513   /// CHECK-DAG: <<Ar2:i\d+>> ArrayGet [{{l\d+}},{{i\d+}}]
    514   /// CHECK-DAG: <<Cnd:z\d+>> LessThan [<<Ar1>>,<<Ar2>>]
    515   /// CHECK-DAG: <<Sel:i\d+>> Select [<<Ar1>>,<<Ar2>>,<<Cnd>>]
    516   /// CHECK-DAG:              Return [<<Sel>>]
    517   //
    518   /// CHECK-START: int Main.max0(int[], int[]) instruction_simplifier$after_gvn (after)
    519   /// CHECK-DAG: <<Max:i\d+>> Max
    520   /// CHECK-DAG:              Return [<<Max>>]
    521   //
    522   /// CHECK-START: int Main.max0(int[], int[]) instruction_simplifier$after_gvn (after)
    523   /// CHECK-NOT:              Select
    524   public static int max0(int[] a, int[] b) {
    525     // Repeat of array references needs finding the common subexpressions
    526     // prior to doing the select and min/max recognition.
    527     return a[0] >= b[0] ? a[0] : b[0];
    528   }
    529 
    530   /// CHECK-START: int Main.minmax1(int) instruction_simplifier$after_gvn (before)
    531   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    532   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    533   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    534   /// CHECK-DAG: <<Cnd1:z\d+>> LessThanOrEqual [<<Par>>,<<P100>>]
    535   /// CHECK-DAG: <<Sel1:i\d+>> Select [<<P100>>,<<Par>>,<<Cnd1>>]
    536   /// CHECK-DAG: <<Cnd2:z\d+>> GreaterThanOrEqual [<<Sel1>>,<<M100>>]
    537   /// CHECK-DAG: <<Sel2:i\d+>> Select [<<M100>>,<<Sel1>>,<<Cnd2>>]
    538   /// CHECK-DAG:               Return [<<Sel2>>]
    539   //
    540   /// CHECK-START: int Main.minmax1(int) instruction_simplifier$after_gvn (after)
    541   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    542   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    543   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    544   /// CHECK-DAG: <<Min:i\d+>>  Min [<<Par>>,<<P100>>]
    545   /// CHECK-DAG: <<Max:i\d+>>  Max [<<Min>>,<<M100>>]
    546   /// CHECK-DAG:               Return [<<Max>>]
    547   //
    548   /// CHECK-START: int Main.minmax1(int) instruction_simplifier$after_gvn (after)
    549   /// CHECK-NOT:               Select
    550   public static int minmax1(int x) {
    551     // Simple if-if gives clean select sequence.
    552     if (x > 100) {
    553       x = 100;
    554     }
    555     if (x < -100) {
    556       x = -100;
    557     }
    558     return x;
    559   }
    560 
    561   /// CHECK-START: int Main.minmax2(int) instruction_simplifier$after_gvn (before)
    562   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    563   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    564   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    565   /// CHECK-DAG: <<Cnd1:z\d+>> LessThanOrEqual [<<Par>>,<<P100>>]
    566   /// CHECK-DAG: <<Cnd2:z\d+>> GreaterThanOrEqual [<<Par>>,<<M100>>]
    567   /// CHECK-DAG: <<Sel1:i\d+>> Select [<<M100>>,<<Par>>,<<Cnd2>>]
    568   /// CHECK-DAG: <<Sel2:i\d+>> Select [<<P100>>,<<Sel1>>,<<Cnd1>>]
    569   /// CHECK-DAG:               Return [<<Sel2>>]
    570   //
    571   /// CHECK-START: int Main.minmax2(int) instruction_simplifier$after_gvn (after)
    572   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    573   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    574   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    575   /// CHECK-DAG: <<Max:i\d+>>  Max [<<Par>>,<<M100>>]
    576   /// CHECK-DAG: <<Min:i\d+>>  Min [<<Max>>,<<P100>>]
    577   /// CHECK-DAG:               Return [<<Min>>]
    578   //
    579   /// CHECK-START: int Main.minmax2(int) instruction_simplifier$after_gvn (after)
    580   /// CHECK-NOT:               Select
    581   public static int minmax2(int x) {
    582     // Simple if-else requires inspecting bounds of resulting selects.
    583     if (x > 100) {
    584       x = 100;
    585     } else if (x < -100) {
    586       x = -100;
    587     }
    588     return x;
    589   }
    590 
    591   /// CHECK-START: int Main.minmax3(int) instruction_simplifier$after_gvn (after)
    592   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    593   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    594   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    595   /// CHECK-DAG: <<Max:i\d+>>  Max [<<Par>>,<<M100>>]
    596   /// CHECK-DAG: <<Min:i\d+>>  Min [<<Max>>,<<P100>>]
    597   /// CHECK-DAG:               Return [<<Min>>]
    598   //
    599   /// CHECK-START: int Main.minmax3(int) instruction_simplifier$after_gvn (after)
    600   /// CHECK-NOT:               Select
    601   public static int minmax3(int x) {
    602     return (x > 100) ? 100 : ((x < -100) ? -100 : x);
    603   }
    604 
    605   /// CHECK-START: int Main.minmax4(int) instruction_simplifier$after_gvn (after)
    606   /// CHECK-DAG: <<Par:i\d+>>  ParameterValue
    607   /// CHECK-DAG: <<P100:i\d+>> IntConstant 100
    608   /// CHECK-DAG: <<M100:i\d+>> IntConstant -100
    609   /// CHECK-DAG: <<Min:i\d+>>  Min [<<Par>>,<<P100>>]
    610   /// CHECK-DAG: <<Max:i\d+>>  Max [<<Min>>,<<M100>>]
    611   /// CHECK-DAG:               Return [<<Max>>]
    612   //
    613   /// CHECK-START: int Main.minmax4(int) instruction_simplifier$after_gvn (after)
    614   /// CHECK-NOT:               Select
    615   public static int minmax4(int x) {
    616     return (x < -100) ? -100 : ((x > 100) ? 100 : x);
    617   }
    618 
    619   /// CHECK-START: int Main.minmaxCSEScalar(int, int) select_generator (after)
    620   /// CHECK-DAG: <<Par1:i\d+>> ParameterValue
    621   /// CHECK-DAG: <<Par2:i\d+>> ParameterValue
    622   /// CHECK-DAG: <<Cnd1:z\d+>> LessThanOrEqual    [<<Par1>>,<<Par2>>]
    623   /// CHECK-DAG: <<Sel1:i\d+>> Select             [<<Par1>>,<<Par2>>,<<Cnd1>>]
    624   /// CHECK-DAG: <<Cnd2:z\d+>> GreaterThanOrEqual [<<Par1>>,<<Par2>>]
    625   /// CHECK-DAG: <<Sel2:i\d+>> Select             [<<Par1>>,<<Par2>>,<<Cnd2>>]
    626   /// CHECK-DAG: <<Add1:i\d+>> Add                [<<Sel1>>,<<Sel2>>]
    627   /// CHECK-DAG: <<Add2:i\d+>> Add                [<<Sel1>>,<<Add1>>]
    628   /// CHECK-DAG: <<Add3:i\d+>> Add                [<<Sel2>>,<<Add2>>]
    629   /// CHECK-DAG: <<Add4:i\d+>> Add                [<<Sel1>>,<<Add3>>]
    630   /// CHECK-DAG: <<Add5:i\d+>> Add                [<<Sel2>>,<<Add4>>]
    631   /// CHECK-DAG:               Return             [<<Add5>>]
    632   //
    633   /// CHECK-START: int Main.minmaxCSEScalar(int, int) instruction_simplifier$after_gvn (after)
    634   /// CHECK-DAG: <<Par1:i\d+>> ParameterValue
    635   /// CHECK-DAG: <<Par2:i\d+>> ParameterValue
    636   /// CHECK-DAG: <<Max:i\d+>>  Max    [<<Par1>>,<<Par2>>]
    637   /// CHECK-DAG: <<Min:i\d+>>  Min    [<<Par1>>,<<Par2>>]
    638   /// CHECK-DAG: <<Add1:i\d+>> Add    [<<Max>>,<<Min>>]
    639   /// CHECK-DAG: <<Add2:i\d+>> Add    [<<Max>>,<<Add1>>]
    640   /// CHECK-DAG: <<Add3:i\d+>> Add    [<<Min>>,<<Add2>>]
    641   /// CHECK-DAG: <<Add4:i\d+>> Add    [<<Max>>,<<Add3>>]
    642   /// CHECK-DAG: <<Add5:i\d+>> Add    [<<Min>>,<<Add4>>]
    643   /// CHECK-DAG:               Return [<<Add5>>]
    644   public static int minmaxCSEScalar(int x, int y) {
    645     int t1 = (x > y) ? x : y;
    646     int t2 = (x < y) ? x : y;
    647     int t3 = (x > y) ? x : y;
    648     int t4 = (x < y) ? x : y;
    649     int t5 = (x > y) ? x : y;
    650     int t6 = (x < y) ? x : y;
    651     // Make sure min/max is CSEed.
    652     return t1 + t2 + t3 + t4 + t5 + t6;
    653   }
    654 
    655   /// CHECK-START: int Main.minmaxCSEArray(int[], int[]) select_generator (after)
    656   /// CHECK-DAG: <<Arr1:i\d+>> ArrayGet
    657   /// CHECK-DAG: <<Arr2:i\d+>> ArrayGet
    658   /// CHECK-DAG: <<Cnd1:z\d+>> LessThanOrEqual    [<<Arr1>>,<<Arr2>>]
    659   /// CHECK-DAG: <<Sel1:i\d+>> Select             [<<Arr1>>,<<Arr2>>,<<Cnd1>>]
    660   /// CHECK-DAG: <<Cnd2:z\d+>> GreaterThanOrEqual [<<Arr1>>,<<Arr2>>]
    661   /// CHECK-DAG: <<Sel2:i\d+>> Select             [<<Arr1>>,<<Arr2>>,<<Cnd2>>]
    662   /// CHECK-DAG: <<Add1:i\d+>> Add                [<<Sel1>>,<<Sel2>>]
    663   /// CHECK-DAG: <<Add2:i\d+>> Add                [<<Sel1>>,<<Add1>>]
    664   /// CHECK-DAG: <<Add3:i\d+>> Add                [<<Sel2>>,<<Add2>>]
    665   /// CHECK-DAG: <<Add4:i\d+>> Add                [<<Sel1>>,<<Add3>>]
    666   /// CHECK-DAG: <<Add5:i\d+>> Add                [<<Sel2>>,<<Add4>>]
    667   /// CHECK-DAG:               Return             [<<Add5>>]
    668   //
    669   /// CHECK-START: int Main.minmaxCSEArray(int[], int[]) instruction_simplifier$after_gvn (after)
    670   /// CHECK-DAG: <<Arr1:i\d+>> ArrayGet
    671   /// CHECK-DAG: <<Arr2:i\d+>> ArrayGet
    672   /// CHECK-DAG: <<Max:i\d+>>  Max    [<<Arr1>>,<<Arr2>>]
    673   /// CHECK-DAG: <<Min:i\d+>>  Min    [<<Arr1>>,<<Arr2>>]
    674   /// CHECK-DAG: <<Add1:i\d+>> Add    [<<Max>>,<<Min>>]
    675   /// CHECK-DAG: <<Add2:i\d+>> Add    [<<Max>>,<<Add1>>]
    676   /// CHECK-DAG: <<Add3:i\d+>> Add    [<<Min>>,<<Add2>>]
    677   /// CHECK-DAG: <<Add4:i\d+>> Add    [<<Max>>,<<Add3>>]
    678   /// CHECK-DAG: <<Add5:i\d+>> Add    [<<Min>>,<<Add4>>]
    679   /// CHECK-DAG:               Return [<<Add5>>]
    680   public static int minmaxCSEArray(int[] x, int[] y) {
    681     int t1 = (x[0] > y[0]) ? x[0] : y[0];
    682     int t2 = (x[0] < y[0]) ? x[0] : y[0];
    683     int t3 = (x[0] > y[0]) ? x[0] : y[0];
    684     int t4 = (x[0] < y[0]) ? x[0] : y[0];
    685     int t5 = (x[0] > y[0]) ? x[0] : y[0];
    686     int t6 = (x[0] < y[0]) ? x[0] : y[0];
    687     // Make sure min/max is CSEed.
    688     return t1 + t2 + t3 + t4 + t5 + t6;
    689   }
    690 
    691   /// CHECK-START: int Main.minmaxCSEScalarAndCond(int, int) instruction_simplifier$after_gvn (after)
    692   /// CHECK-DAG: <<Par1:i\d+>> ParameterValue
    693   /// CHECK-DAG: <<Par2:i\d+>> ParameterValue
    694   /// CHECK-DAG: <<Max:i\d+>>  Max    [<<Par1>>,<<Par2>>]
    695   /// CHECK-DAG: <<Min:i\d+>>  Min    [<<Par1>>,<<Par2>>]
    696   /// CHECK-DAG: <<Add:i\d+>>  Add    [<<Max>>,<<Min>>]
    697   /// CHECK-DAG:               Return [<<Add>>]
    698   /// CHECK-DAG: <<Add1:i\d+>> Add    [<<Max>>,<<Min>>]
    699   /// CHECK-DAG: <<Add2:i\d+>> Add    [<<Max>>,<<Add1>>]
    700   /// CHECK-DAG: <<Add3:i\d+>> Add    [<<Min>>,<<Add2>>]
    701   /// CHECK-DAG:               Return [<<Add3>>]
    702   public static int minmaxCSEScalarAndCond(int x, int y) {
    703     int t1 = (x > y) ? x : y;
    704     int t2 = (x < y) ? x : y;
    705     if (x == y)
    706       return t1 + t2;
    707     int t3 = (x > y) ? x : y;
    708     int t4 = (x < y) ? x : y;
    709     // Make sure min/max is CSEed.
    710     return t1 + t2 + t3 + t4;
    711   }
    712 
    713   public static void main(String[] args) {
    714     // Intrinsics.
    715     expectEquals(10, minI(10));
    716     expectEquals(20, minI(25));
    717     expectEquals(-1, minIntConstantZero(-1));
    718     expectEquals(0, minIntConstantZero(1));
    719     expectEquals(0, minIntConstantOne(0));
    720     expectEquals(1, minIntConstantOne(2));
    721     expectEquals(-2, minIntConstantMinusOne(-2));
    722     expectEquals(-1, minIntConstantMinusOne(0));
    723     expectEquals(10L, minL(10L));
    724     expectEquals(20L, minL(25L));
    725     expectEquals(-1L, minLongConstantZero(-1L));
    726     expectEquals(0L, minLongConstantZero(1L));
    727     expectEquals(0L, minLongConstantOne(0L));
    728     expectEquals(1L, minLongConstantOne(2L));
    729     expectEquals(-2L, minLongConstantMinusOne(-2L));
    730     expectEquals(-1L, minLongConstantMinusOne(0L));
    731     expectEquals(20, maxI(10));
    732     expectEquals(25, maxI(25));
    733     expectEquals(0, maxIntConstantZero(-1));
    734     expectEquals(1, maxIntConstantZero(1));
    735     expectEquals(1, maxIntConstantOne(0));
    736     expectEquals(2, maxIntConstantOne(2));
    737     expectEquals(-1, maxIntConstantMinusOne(-2));
    738     expectEquals(0, maxIntConstantMinusOne(0));
    739     expectEquals(8193, maxIntLargeConstant(8192));
    740     expectEquals(9000, maxIntLargeConstant(9000));
    741     expectEquals(20L, maxL(10L));
    742     expectEquals(25L, maxL(25L));
    743     expectEquals(0L, maxLongConstantZero(-1L));
    744     expectEquals(1L, maxLongConstantZero(1L));
    745     expectEquals(1L, maxLongConstantOne(0L));
    746     expectEquals(2L, maxLongConstantOne(2L));
    747     expectEquals(-1L, maxLongConstantMinusOne(-2L));
    748     expectEquals(0L, maxLongConstantMinusOne(0L));
    749     expectEquals(8193L, maxLongLargeConstant(8192L));
    750     expectEquals(9000L, maxLongLargeConstant(9000L));
    751     // Types.
    752     expectEquals(10, min1(10, 20));
    753     expectEquals(10, min2(10, 20));
    754     expectEquals(10, min3(10, 20));
    755     expectEquals(10, min4(10, 20));
    756     expectEquals(10, min5((short) 10, (short) 20));
    757     expectEquals(10, min6((byte) 10, (byte) 20));
    758     expectEquals(10L, min7(10L, 20L));
    759     expectEquals(20, max1(10, 20));
    760     expectEquals(20, max2(10, 20));
    761     expectEquals(20, max3(10, 20));
    762     expectEquals(20, max4(10, 20));
    763     expectEquals(20, max5((short) 10, (short) 20));
    764     expectEquals(20, max6((byte) 10, (byte) 20));
    765     expectEquals(20L, max7(10L, 20L));
    766     // Complications.
    767     int[] a = { 10 };
    768     int[] b = { 20 };
    769     expectEquals(10, min0(a, b));
    770     expectEquals(20, max0(a, b));
    771     expectEquals(-100, minmax1(-200));
    772     expectEquals(10, minmax1(10));
    773     expectEquals(100, minmax1(200));
    774     expectEquals(-100, minmax2(-200));
    775     expectEquals(10, minmax2(10));
    776     expectEquals(100, minmax2(200));
    777     expectEquals(-100, minmax3(-200));
    778     expectEquals(10, minmax3(10));
    779     expectEquals(100, minmax3(200));
    780     expectEquals(-100, minmax4(-200));
    781     expectEquals(10, minmax4(10));
    782     expectEquals(100, minmax4(200));
    783     expectEquals(90, minmaxCSEScalar(10, 20));
    784     expectEquals(90, minmaxCSEArray(a, b));
    785     expectEquals(20, minmaxCSEScalarAndCond(10, 10));
    786     expectEquals(60, minmaxCSEScalarAndCond(10, 20));
    787     System.out.println("passed");
    788   }
    789 
    790   private static void expectEquals(int expected, int result) {
    791     if (expected != result) {
    792       throw new Error("Expected: " + expected + ", found: " + result);
    793     }
    794   }
    795 
    796   private static void expectEquals(long expected, long result) {
    797     if (expected != result) {
    798       throw new Error("Expected: " + expected + ", found: " + result);
    799     }
    800   }
    801 }
    802