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 SimdDouble { 22 23 static double[] a; 24 25 // 26 // Arithmetic operations. 27 // 28 29 /// CHECK-START: void SimdDouble.add(double) loop_optimization (before) 30 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none 31 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 32 // 33 /// CHECK-START-ARM64: void SimdDouble.add(double) loop_optimization (after) 34 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 35 /// CHECK-DAG: VecAdd loop:<<Loop>> outer_loop:none 36 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none add(double x)37 static void add(double x) { 38 for (int i = 0; i < 128; i++) 39 a[i] += x; 40 } 41 42 /// CHECK-START: void SimdDouble.sub(double) loop_optimization (before) 43 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none 44 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 45 // 46 /// CHECK-START-ARM64: void SimdDouble.sub(double) loop_optimization (after) 47 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 48 /// CHECK-DAG: VecSub loop:<<Loop>> outer_loop:none 49 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none sub(double x)50 static void sub(double x) { 51 for (int i = 0; i < 128; i++) 52 a[i] -= x; 53 } 54 55 /// CHECK-START: void SimdDouble.mul(double) loop_optimization (before) 56 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none 57 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 58 // 59 /// CHECK-START-ARM64: void SimdDouble.mul(double) loop_optimization (after) 60 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 61 /// CHECK-DAG: VecMul loop:<<Loop>> outer_loop:none 62 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none mul(double x)63 static void mul(double x) { 64 for (int i = 0; i < 128; i++) 65 a[i] *= x; 66 } 67 68 /// CHECK-START: void SimdDouble.div(double) loop_optimization (before) 69 /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none 70 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 71 // 72 /// CHECK-START-ARM64: void SimdDouble.div(double) loop_optimization (after) 73 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 74 /// CHECK-DAG: VecDiv loop:<<Loop>> outer_loop:none 75 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none div(double x)76 static void div(double x) { 77 for (int i = 0; i < 128; i++) 78 a[i] /= x; 79 } 80 81 /// CHECK-START: void SimdDouble.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-ARM64: void SimdDouble.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 neg()89 static void neg() { 90 for (int i = 0; i < 128; i++) 91 a[i] = -a[i]; 92 } 93 94 /// CHECK-START: void SimdDouble.abs() 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-ARM64: void SimdDouble.abs() loop_optimization (after) 99 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 100 /// CHECK-DAG: VecAbs loop:<<Loop>> outer_loop:none 101 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none abs()102 static void abs() { 103 for (int i = 0; i < 128; i++) 104 a[i] = Math.abs(a[i]); 105 } 106 107 /// CHECK-START: void SimdDouble.conv(long[]) 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: void SimdDouble.conv(long[]) loop_optimization (after) 112 /// CHECK-NOT: VecLoad 113 /// CHECK-NOT: VecStore 114 // 115 // TODO: fill in when long2double is supported conv(long[] b)116 static void conv(long[] b) { 117 for (int i = 0; i < 128; i++) 118 a[i] = b[i]; 119 } 120 121 // 122 // Loop bounds. 123 // 124 bounds()125 static void bounds() { 126 for (int i = 1; i < 127; i++) 127 a[i] += 11; 128 } 129 130 // 131 // Test Driver. 132 // 133 main()134 public static void main() { 135 // Set up. 136 a = new double[128]; 137 for (int i = 0; i < 128; i++) { 138 a[i] = i; 139 } 140 // Arithmetic operations. 141 add(2.0); 142 for (int i = 0; i < 128; i++) { 143 expectEquals(i + 2, a[i], "add"); 144 } 145 sub(2.0); 146 for (int i = 0; i < 128; i++) { 147 expectEquals(i, a[i], "sub"); 148 } 149 mul(2.0); 150 for (int i = 0; i < 128; i++) { 151 expectEquals(i + i, a[i], "mul"); 152 } 153 div(2.0); 154 for (int i = 0; i < 128; i++) { 155 expectEquals(i, a[i], "div"); 156 } 157 neg(); 158 for (int i = 0; i < 128; i++) { 159 expectEquals(-i, a[i], "neg"); 160 } 161 // Loop bounds. 162 bounds(); 163 expectEquals(0, a[0], "bounds0"); 164 for (int i = 1; i < 127; i++) { 165 expectEquals(11 - i, a[i], "bounds"); 166 } 167 expectEquals(-127, a[127], "bounds127"); 168 // Abs. 169 abs(); 170 expectEquals(0, a[0], "abs0"); 171 for (int i = 1; i <= 11; i++) { 172 expectEquals(11 - i, a[i], "abs_lo"); 173 } 174 for (int i = 12; i < 127; i++) { 175 expectEquals(i - 11, a[i], "abs_hi"); 176 } 177 expectEquals(127, a[127], "abs127"); 178 // Conversion. 179 long[] b = new long[128]; 180 for (int i = 0; i < 128; i++) { 181 b[i] = 1000 * i; 182 } 183 conv(b); 184 for (int i = 1; i < 127; i++) { 185 expectEquals(1000.0 * i, a[i], "conv"); 186 } 187 // Done. 188 System.out.println("SimdDouble passed"); 189 } 190 expectEquals(double expected, double result, String action)191 private static void expectEquals(double expected, double result, String action) { 192 if (expected != result) { 193 throw new Error("Expected: " + expected + ", found: " + result + " for " + action); 194 } 195 } 196 } 197