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 short[] 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] = (short) -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] = (short) ~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   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.sar2() loop_optimization (after)
    125   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    126   /// CHECK-DAG: VecShr   loop:<<Loop>>      outer_loop:none
    127   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    128   static void sar2() {
    129     for (int i = 0; i < 128; i++)
    130       a[i] >>= 2;
    131   }
    132 
    133   /// CHECK-START: void Main.shr2() loop_optimization (before)
    134   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    135   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    136   //
    137   // TODO: would need signess flip.
    138   /// CHECK-START: void Main.shr2() loop_optimization (after)
    139   /// CHECK-NOT: VecUShr
    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 
    165   static void shr33() {
    166     for (int i = 0; i < 128; i++)
    167       a[i] >>>= 33;  // 1, since & 31
    168   }
    169 
    170   //
    171   // Loop bounds.
    172   //
    173 
    174   static void add() {
    175     for (int i = 1; i < 127; i++)
    176       a[i] += 11;
    177   }
    178 
    179   //
    180   // Test Driver.
    181   //
    182 
    183   public static void main(String[] args) {
    184     // Set up.
    185     a = new short[128];
    186     for (int i = 0; i < 128; i++) {
    187       a[i] = (short) i;
    188     }
    189     // Arithmetic operations.
    190     add(2);
    191     for (int i = 0; i < 128; i++) {
    192       expectEquals(i + 2, a[i], "add");
    193     }
    194     sub(2);
    195     for (int i = 0; i < 128; i++) {
    196       expectEquals(i, a[i], "sub");
    197     }
    198     mul(2);
    199     for (int i = 0; i < 128; i++) {
    200       expectEquals(i + i, a[i], "mul");
    201     }
    202     div(2);
    203     for (int i = 0; i < 128; i++) {
    204       expectEquals(i, a[i], "div");
    205     }
    206     neg();
    207     for (int i = 0; i < 128; i++) {
    208       expectEquals(-i, a[i], "neg");
    209     }
    210     // Loop bounds.
    211     add();
    212     expectEquals(0, a[0], "bounds0");
    213     for (int i = 1; i < 127; i++) {
    214       expectEquals(11 - i, a[i], "bounds");
    215     }
    216     expectEquals(-127, a[127], "bounds127");
    217     // Shifts.
    218     for (int i = 0; i < 128; i++) {
    219       a[i] = (short) 0xffff;
    220     }
    221     shl4();
    222     for (int i = 0; i < 128; i++) {
    223       expectEquals((short) 0xfff0, a[i], "shl4");
    224     }
    225     sar2();
    226     for (int i = 0; i < 128; i++) {
    227       expectEquals((short) 0xfffc, a[i], "sar2");
    228     }
    229     shr2();
    230     for (int i = 0; i < 128; i++) {
    231       expectEquals((short) 0xffff, a[i], "shr2");  // sic!
    232     }
    233     sar31();
    234     for (int i = 0; i < 128; i++) {
    235       expectEquals((short) 0xffff, a[i], "sar31");
    236     }
    237     shr31();
    238     for (int i = 0; i < 128; i++) {
    239       expectEquals(0x0001, a[i], "shr31");
    240       a[i] = (short) 0x1200;  // reset
    241     }
    242     shr32();
    243     for (int i = 0; i < 128; i++) {
    244       expectEquals((short) 0x1200, a[i], "shr32");
    245     }
    246     shr33();
    247     for (int i = 0; i < 128; i++) {
    248       expectEquals((short) 0x0900, a[i], "shr33");
    249       a[i] = (short) 0xf0f1;  // reset
    250     }
    251     not();
    252     for (int i = 0; i < 128; i++) {
    253       expectEquals((short) 0x0f0e, a[i], "not");
    254     }
    255     // Done.
    256     System.out.println("passed");
    257   }
    258 
    259   private static void expectEquals(int expected, int result, String action) {
    260     if (expected != result) {
    261       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
    262     }
    263   }
    264 }
    265