Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 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 SIMD vectorization.
     19  */
     20 public class Main {
     21 
     22   static char[] a;
     23 
     24   //
     25   // Arithmetic operations.
     26   //
     27 
     28   /// CHECK-START: void Main.add(int) loop_optimization (before)
     29   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     30   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     31   //
     32   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.add(int) loop_optimization (after)
     33   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     34   /// CHECK-DAG: VecAdd   loop:<<Loop>>      outer_loop:none
     35   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     36   static void add(int x) {
     37     for (int i = 0; i < 128; i++)
     38       a[i] += x;
     39   }
     40 
     41   /// CHECK-START: void Main.sub(int) loop_optimization (before)
     42   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     43   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     44   //
     45   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.sub(int) loop_optimization (after)
     46   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     47   /// CHECK-DAG: VecSub   loop:<<Loop>>      outer_loop:none
     48   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     49   static void sub(int x) {
     50     for (int i = 0; i < 128; i++)
     51       a[i] -= x;
     52   }
     53 
     54   /// CHECK-START: void Main.mul(int) loop_optimization (before)
     55   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     56   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     57   //
     58   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.mul(int) loop_optimization (after)
     59   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     60   /// CHECK-DAG: VecMul   loop:<<Loop>>      outer_loop:none
     61   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     62   static void mul(int x) {
     63     for (int i = 0; i < 128; i++)
     64       a[i] *= x;
     65   }
     66 
     67   /// CHECK-START: void Main.div(int) loop_optimization (before)
     68   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     69   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     70   //
     71   /// CHECK-START: void Main.div(int) loop_optimization (after)
     72   /// CHECK-NOT: VecDiv
     73   //
     74   //  Not supported on any architecture.
     75   //
     76   static void div(int x) {
     77     for (int i = 0; i < 128; i++)
     78       a[i] /= x;
     79   }
     80 
     81   /// CHECK-START: void Main.neg() loop_optimization (before)
     82   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     83   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     84   //
     85   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.neg() loop_optimization (after)
     86   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     87   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
     88   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     89   static void neg() {
     90     for (int i = 0; i < 128; i++)
     91       a[i] = (char) -a[i];
     92   }
     93 
     94   /// CHECK-START: void Main.not() loop_optimization (before)
     95   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     96   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     97   //
     98   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.not() loop_optimization (after)
     99   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    100   /// CHECK-DAG: VecNot   loop:<<Loop>>      outer_loop:none
    101   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    102   static void not() {
    103     for (int i = 0; i < 128; i++)
    104       a[i] = (char) ~a[i];
    105   }
    106 
    107   /// CHECK-START: void Main.shl4() loop_optimization (before)
    108   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    109   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    110   //
    111   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.shl4() loop_optimization (after)
    112   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    113   /// CHECK-DAG: VecShl   loop:<<Loop>>      outer_loop:none
    114   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    115   static void shl4() {
    116     for (int i = 0; i < 128; i++)
    117       a[i] <<= 4;
    118   }
    119 
    120   /// CHECK-START: void Main.sar2() loop_optimization (before)
    121   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    122   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    123   //
    124   // TODO: would need signess flip.
    125   /// CHECK-START: void Main.sar2() loop_optimization (after)
    126   /// CHECK-NOT: VecShr
    127   static void sar2() {
    128     for (int i = 0; i < 128; i++)
    129       a[i] >>= 2;
    130   }
    131 
    132   /// CHECK-START: void Main.shr2() loop_optimization (before)
    133   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    134   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    135   //
    136   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.shr2() loop_optimization (after)
    137   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    138   /// CHECK-DAG: VecUShr  loop:<<Loop>>      outer_loop:none
    139   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    140   static void shr2() {
    141     for (int i = 0; i < 128; i++)
    142       a[i] >>>= 2;
    143   }
    144 
    145   //
    146   // Shift sanity.
    147   //
    148 
    149   static void sar31() {
    150     for (int i = 0; i < 128; i++)
    151       a[i] >>= 31;
    152   }
    153 
    154   static void shr31() {
    155     for (int i = 0; i < 128; i++)
    156       a[i] >>>= 31;
    157   }
    158 
    159   static void shr32() {
    160     for (int i = 0; i < 128; i++)
    161       a[i] >>>= 32;  // 0, since & 31
    162   }
    163 
    164   static void shr33() {
    165     for (int i = 0; i < 128; i++)
    166       a[i] >>>= 33;  // 1, since & 31
    167   }
    168 
    169   //
    170   // Loop bounds.
    171   //
    172 
    173   static void bounds() {
    174     for (int i = 1; i < 127; i++)
    175       a[i] += 11;
    176   }
    177 
    178   //
    179   // Test Driver.
    180   //
    181 
    182   public static void main(String[] args) {
    183     // Set up.
    184     a = new char[128];
    185     for (int i = 0; i < 128; i++) {
    186       a[i] = (char) i;
    187     }
    188     // Arithmetic operations.
    189     add(2);
    190     for (int i = 0; i < 128; i++) {
    191       expectEquals(i + 2, a[i], "add");
    192     }
    193     sub(2);
    194     for (int i = 0; i < 128; i++) {
    195       expectEquals(i, a[i], "sub");
    196     }
    197     mul(2);
    198     for (int i = 0; i < 128; i++) {
    199       expectEquals(i + i, a[i], "mul");
    200     }
    201     div(2);
    202     for (int i = 0; i < 128; i++) {
    203       expectEquals(i, a[i], "div");
    204     }
    205     neg();
    206     for (int i = 0; i < 128; i++) {
    207       expectEquals((char)-i, a[i], "neg");
    208     }
    209     // Loop bounds.
    210     bounds();
    211     expectEquals(0, a[0], "bounds0");
    212     for (int i = 1; i < 127; i++) {
    213       expectEquals((char)(11 - i), a[i], "bounds");
    214     }
    215     expectEquals((char)-127, a[127], "bounds127");
    216     // Shifts.
    217     for (int i = 0; i < 128; i++) {
    218       a[i] = (char) 0xffff;
    219     }
    220     shl4();
    221     for (int i = 0; i < 128; i++) {
    222       expectEquals((char) 0xfff0, a[i], "shl4");
    223     }
    224     sar2();
    225     for (int i = 0; i < 128; i++) {
    226       expectEquals((char) 0x3ffc, a[i], "sar2");
    227     }
    228     shr2();
    229     for (int i = 0; i < 128; i++) {
    230       expectEquals((char) 0x0fff, a[i], "shr2");
    231       a[i] = (char) 0xffff;  // reset
    232     }
    233     sar31();
    234     for (int i = 0; i < 128; i++) {
    235       expectEquals(0, a[i], "sar31");
    236       a[i] = (char) 0xffff;  // reset
    237     }
    238     shr31();
    239     for (int i = 0; i < 128; i++) {
    240       expectEquals(0, a[i], "shr31");
    241       a[i] = (char) 0x1200;  // reset
    242     }
    243     shr32();
    244     for (int i = 0; i < 128; i++) {
    245       expectEquals((char) 0x1200, a[i], "shr32");
    246     }
    247     shr33();
    248     for (int i = 0; i < 128; i++) {
    249       expectEquals((char) 0x0900, a[i], "shr33");
    250       a[i] = (char) 0xf1f0;  // reset
    251     }
    252     not();
    253     for (int i = 0; i < 128; i++) {
    254       expectEquals((char) 0x0e0f, a[i], "not");
    255     }
    256     // Done.
    257     System.out.println("passed");
    258   }
    259 
    260   private static void expectEquals(int expected, int result, String action) {
    261     if (expected != result) {
    262       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
    263     }
    264   }
    265 }
    266