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. Note that this class provides a mere
     19  * functional test, not a precise numerical verifier.
     20  */
     21 public class Main {
     22 
     23   static double[] a;
     24 
     25   //
     26   // Arithmetic operations.
     27   //
     28 
     29   /// CHECK-START: void Main.add(double) loop_optimization (before)
     30   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     31   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
     32   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     33   //
     34   /// CHECK-START-ARM64: void Main.add(double) loop_optimization (after)
     35   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     36   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     37   /// CHECK-DAG: VecAdd   loop:<<Loop>>      outer_loop:none
     38   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     39   //
     40   /// CHECK-START-MIPS64: void Main.add(double) loop_optimization (after)
     41   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     42   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     43   /// CHECK-DAG: VecAdd   loop:<<Loop>>      outer_loop:none
     44   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     45   static void add(double x) {
     46     for (int i = 0; i < 128; i++)
     47       a[i] += x;
     48   }
     49 
     50   /// CHECK-START: void Main.sub(double) loop_optimization (before)
     51   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     52   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
     53   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     54   //
     55   /// CHECK-START-ARM64: void Main.sub(double) loop_optimization (after)
     56   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     57   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     58   /// CHECK-DAG: VecSub   loop:<<Loop>>      outer_loop:none
     59   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     60   //
     61   /// CHECK-START-MIPS64: void Main.sub(double) loop_optimization (after)
     62   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     63   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     64   /// CHECK-DAG: VecSub   loop:<<Loop>>      outer_loop:none
     65   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     66   static void sub(double x) {
     67     for (int i = 0; i < 128; i++)
     68       a[i] -= x;
     69   }
     70 
     71   /// CHECK-START: void Main.mul(double) loop_optimization (before)
     72   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     73   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
     74   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     75   //
     76   /// CHECK-START-ARM64: void Main.mul(double) loop_optimization (after)
     77   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     78   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     79   /// CHECK-DAG: VecMul   loop:<<Loop>>      outer_loop:none
     80   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     81   //
     82   /// CHECK-START-MIPS64: void Main.mul(double) loop_optimization (after)
     83   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     84   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
     85   /// CHECK-DAG: VecMul   loop:<<Loop>>      outer_loop:none
     86   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
     87   static void mul(double x) {
     88     for (int i = 0; i < 128; i++)
     89       a[i] *= x;
     90   }
     91 
     92   /// CHECK-START: void Main.div(double) loop_optimization (before)
     93   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     94   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
     95   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
     96   //
     97   /// CHECK-START-ARM64: void Main.div(double) loop_optimization (after)
     98   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
     99   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    100   /// CHECK-DAG: VecDiv   loop:<<Loop>>      outer_loop:none
    101   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    102   //
    103   /// CHECK-START-MIPS64: void Main.div(double) loop_optimization (after)
    104   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    105   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    106   /// CHECK-DAG: VecDiv   loop:<<Loop>>      outer_loop:none
    107   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    108   static void div(double x) {
    109     for (int i = 0; i < 128; i++)
    110       a[i] /= x;
    111   }
    112 
    113   /// CHECK-START: void Main.neg() loop_optimization (before)
    114   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    115   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
    116   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    117   //
    118   /// CHECK-START-ARM64: void Main.neg() loop_optimization (after)
    119   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    120   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    121   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
    122   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    123   //
    124   /// CHECK-START-MIPS64: void Main.neg() loop_optimization (after)
    125   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    126   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    127   /// CHECK-DAG: VecNeg   loop:<<Loop>>      outer_loop:none
    128   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    129   static void neg() {
    130     for (int i = 0; i < 128; i++)
    131       a[i] = -a[i];
    132   }
    133 
    134   /// CHECK-START: void Main.abs() loop_optimization (before)
    135   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    136   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
    137   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    138   //
    139   /// CHECK-START-ARM64: void Main.abs() loop_optimization (after)
    140   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    141   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    142   /// CHECK-DAG: VecAbs   loop:<<Loop>>      outer_loop:none
    143   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    144   //
    145   /// CHECK-START-MIPS64: void Main.abs() loop_optimization (after)
    146   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    147   /// CHECK-DAG: VecLoad  loop:<<Loop>>      outer_loop:none
    148   /// CHECK-DAG: VecAbs   loop:<<Loop>>      outer_loop:none
    149   /// CHECK-DAG: VecStore loop:<<Loop>>      outer_loop:none
    150   static void abs() {
    151     for (int i = 0; i < 128; i++)
    152       a[i] = Math.abs(a[i]);
    153   }
    154 
    155   /// CHECK-START: void Main.conv(long[]) loop_optimization (before)
    156   /// CHECK-DAG: Phi      loop:<<Loop:B\d+>> outer_loop:none
    157   /// CHECK-DAG: ArrayGet loop:<<Loop>>      outer_loop:none
    158   /// CHECK-DAG: ArraySet loop:<<Loop>>      outer_loop:none
    159   //
    160   /// CHECK-START-ARM64: void Main.conv(long[]) loop_optimization (after)
    161   /// CHECK-NOT: VecLoad
    162   /// CHECK-NOT: VecStore
    163   //
    164   /// CHECK-START-MIPS64: void Main.conv(long[]) loop_optimization (after)
    165   /// CHECK-NOT: VecLoad
    166   /// CHECK-NOT: VecStore
    167   //
    168   // TODO: fill in when long2double is supported
    169   static void conv(long[] b) {
    170     for (int i = 0; i < 128; i++)
    171       a[i] = b[i];
    172   }
    173 
    174   //
    175   // Loop bounds.
    176   //
    177 
    178   static void bounds() {
    179     for (int i = 1; i < 127; i++)
    180       a[i] += 11;
    181   }
    182 
    183   //
    184   // Test Driver.
    185   //
    186 
    187   public static void main(String[] args) {
    188     // Set up.
    189     a = new double[128];
    190     for (int i = 0; i < 128; i++) {
    191       a[i] = i;
    192     }
    193     // Arithmetic operations.
    194     add(2.0);
    195     for (int i = 0; i < 128; i++) {
    196       expectEquals(i + 2, a[i], "add");
    197     }
    198     sub(2.0);
    199     for (int i = 0; i < 128; i++) {
    200       expectEquals(i, a[i], "sub");
    201     }
    202     mul(2.0);
    203     for (int i = 0; i < 128; i++) {
    204       expectEquals(i + i, a[i], "mul");
    205     }
    206     div(2.0);
    207     for (int i = 0; i < 128; i++) {
    208       expectEquals(i, a[i], "div");
    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     // Abs.
    222     abs();
    223     expectEquals(0, a[0], "abs0");
    224     for (int i = 1; i <= 11; i++) {
    225       expectEquals(11 - i, a[i], "abs_lo");
    226     }
    227     for (int i = 12; i < 127; i++) {
    228       expectEquals(i - 11, a[i], "abs_hi");
    229     }
    230     expectEquals(127, a[127], "abs127");
    231     // Conversion.
    232     long[] b = new long[128];
    233     for (int i = 0; i < 128; i++) {
    234       b[i] = 1000 * i;
    235     }
    236     conv(b);
    237     for (int i = 1; i < 127; i++) {
    238       expectEquals(1000.0 * i, a[i], "conv");
    239     }
    240     // Done.
    241     System.out.println("passed");
    242   }
    243 
    244   private static void expectEquals(double expected, double result, String action) {
    245     if (expected != result) {
    246       throw new Error("Expected: " + expected + ", found: " + result + " for " + action);
    247     }
    248   }
    249 }
    250