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 byte[] 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   //
     73   //  Not supported on any architecture.
     74   //
     75   static void div(int x) {
     76     for (int i = 0; i < 128; i++)
     77       a[i] /= x;
     78   }
     79 
     80   /// CHECK-START: void Main.neg() loop_optimization (before)
     81   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     82   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     83   //
     84   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.neg() loop_optimization (after)
     85   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     86   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
     87   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     88   static void neg() {
     89     for (int i = 0; i < 128; i++)
     90       a[i] = (byte) -a[i];
     91   }
     92 
     93   /// CHECK-START: void Main.not() loop_optimization (before)
     94   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
     95   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     96   //
     97   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.not() loop_optimization (after)
     98   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
     99   /// CHECK-DAG: VecNot   loop:<<Loop>>      outer_loop:none
    100   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    101   static void not() {
    102     for (int i = 0; i < 128; i++)
    103       a[i] = (byte) ~a[i];
    104   }
    105 
    106   /// CHECK-START: void Main.shl4() loop_optimization (before)
    107   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    108   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    109   //
    110   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.shl4() loop_optimization (after)
    111   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    112   /// CHECK-DAG: VecShl   loop:<<Loop>>      outer_loop:none
    113   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    114   static void shl4() {
    115     for (int i = 0; i < 128; i++)
    116       a[i] <<= 4;
    117   }
    118 
    119   /// CHECK-START: void Main.sar2() loop_optimization (before)
    120   /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none
    121   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    122   //
    123   /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.sar2() loop_optimization (after)
    124   /// CHECK-DAG: VecLoad  loop:<<Loop:B\d+>> outer_loop:none
    125   /// CHECK-DAG: VecShr   loop:<<Loop>>      outer_loop:none
    126   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    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   // TODO: would need signess flip.
    137   /// CHECK-START: void Main.shr2() loop_optimization (after)
    138   /// CHECK-NOT: VecUShr
    139   static void shr2() {
    140     for (int i = 0; i < 128; i++)
    141       a[i] >>>= 2;
    142   }
    143 
    144   //
    145   // Shift sanity.
    146   //
    147 
    148   static void sar31() {
    149     for (int i = 0; i < 128; i++)
    150       a[i] >>= 31;
    151   }
    152 
    153   static void shr31() {
    154     for (int i = 0; i < 128; i++)
    155       a[i] >>>= 31;
    156   }
    157 
    158   static void shr32() {
    159     for (int i = 0; i < 128; i++)
    160       a[i] >>>= 32;  // 0, since & 31
    161   }
    162 
    163   static void shr33() {
    164     for (int i = 0; i < 128; i++)
    165       a[i] >>>= 33;  // 1, since & 31
    166   }
    167 
    168   static void shl9() {
    169     for (int i = 0; i < 128; i++)
    170       a[i] <<= 9;  // yields all-zeros
    171   }
    172 
    173   //
    174   // Loop bounds.
    175   //
    176 
    177   static void bounds() {
    178     for (int i = 1; i < 127; i++)
    179       a[i] += 11;
    180   }
    181 
    182   //
    183   // Test Driver.
    184   //
    185 
    186   public static void main(String[] args) {
    187     // Set up.
    188     a = new byte[128];
    189     for (int i = 0; i < 128; i++) {
    190       a[i] = (byte) i;
    191     }
    192     // Arithmetic operations.
    193     add(2);
    194     for (int i = 0; i < 128; i++) {
    195       expectEquals((byte)(i + 2), a[i], "add");
    196     }
    197     sub(2);
    198     for (int i = 0; i < 128; i++) {
    199       expectEquals(i, a[i], "sub");
    200     }
    201     mul(2);
    202     for (int i = 0; i < 128; i++) {
    203       expectEquals((byte)(i + i), a[i], "mul");
    204     }
    205     div(2);
    206     for (int i = 0; i < 128; i++) {
    207       expectEquals(((byte)(i + i)) >> 1, a[i], "div");
    208       a[i] = (byte) i;  // undo arithmetic wrap-around effects
    209     }
    210     neg();
    211     for (int i = 0; i < 128; i++) {
    212       expectEquals(-i, a[i], "neg");
    213     }
    214     // Loop bounds.
    215     bounds();
    216     expectEquals(0, a[0], "bounds0");
    217     for (int i = 1; i < 127; i++) {
    218       expectEquals(11 - i, a[i], "bounds");
    219     }
    220     expectEquals(-127, a[127], "bounds127");
    221     // Shifts.
    222     for (int i = 0; i < 128; i++) {
    223       a[i] = (byte) 0xff;
    224     }
    225     shl4();
    226     for (int i = 0; i < 128; i++) {
    227       expectEquals((byte) 0xf0, a[i], "shl4");
    228     }
    229     sar2();
    230     for (int i = 0; i < 128; i++) {
    231       expectEquals((byte) 0xfc, a[i], "sar2");
    232     }
    233     shr2();
    234     for (int i = 0; i < 128; i++) {
    235       expectEquals((byte) 0xff, a[i], "shr2");  // sic!
    236     }
    237     sar31();
    238     for (int i = 0; i < 128; i++) {
    239       expectEquals((byte) 0xff, a[i], "sar31");
    240     }
    241     shr31();
    242     for (int i = 0; i < 128; i++) {
    243       expectEquals(0x01, a[i], "shr31");
    244       a[i] = (byte) 0x12;  // reset
    245     }
    246     shr32();
    247     for (int i = 0; i < 128; i++) {
    248       expectEquals((byte) 0x12, a[i], "shr32");
    249     }
    250     shr33();
    251     for (int i = 0; i < 128; i++) {
    252       expectEquals((byte) 0x09, a[i], "shr33");
    253     }
    254     shl9();
    255     for (int i = 0; i < 128; i++) {
    256       expectEquals((byte) 0x00, a[i], "shl9");
    257       a[i] = (byte) 0xf0;  // reset
    258     }
    259     not();
    260     for (int i = 0; i < 128; i++) {
    261       expectEquals((byte) 0x0f, a[i], "not");
    262     }
    263     // Done.
    264     System.out.println("passed");
    265   }
    266 
    267   private static void expectEquals(int expected, int result, String action) {
    268     if (expected != result) {
    269       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
    270     }
    271   }
    272 }
    273