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 SimdFloat { 22 23 static float[] a; 24 25 // 26 // Arithmetic operations. 27 // 28 29 /// CHECK-START: void SimdFloat.add(float) 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 SimdFloat.add(float) 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(float x)37 static void add(float x) { 38 for (int i = 0; i < 128; i++) 39 a[i] += x; 40 } 41 42 /// CHECK-START: void SimdFloat.sub(float) 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 SimdFloat.sub(float) 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(float x)50 static void sub(float x) { 51 for (int i = 0; i < 128; i++) 52 a[i] -= x; 53 } 54 55 /// CHECK-START: void SimdFloat.mul(float) 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 SimdFloat.mul(float) 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(float x)63 static void mul(float x) { 64 for (int i = 0; i < 128; i++) 65 a[i] *= x; 66 } 67 68 /// CHECK-START: void SimdFloat.div(float) 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 SimdFloat.div(float) 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(float x)76 static void div(float x) { 77 for (int i = 0; i < 128; i++) 78 a[i] /= x; 79 } 80 81 /// CHECK-START: void SimdFloat.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 SimdFloat.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 SimdFloat.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 SimdFloat.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 SimdFloat.conv(int[]) 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-ARM64: void SimdFloat.conv(int[]) loop_optimization (after) 112 /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none 113 /// CHECK-DAG: VecCnv loop:<<Loop>> outer_loop:none 114 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none conv(int[] b)115 static void conv(int[] b) { 116 for (int i = 0; i < 128; i++) 117 a[i] = b[i]; 118 } 119 120 // 121 // Loop bounds. 122 // 123 bounds()124 static void bounds() { 125 for (int i = 1; i < 127; i++) 126 a[i] += 11; 127 } 128 129 // 130 // Test Driver. 131 // 132 main()133 public static void main() { 134 // Set up. 135 a = new float[128]; 136 for (int i = 0; i < 128; i++) { 137 a[i] = i; 138 } 139 // Arithmetic operations. 140 add(2.0f); 141 for (int i = 0; i < 128; i++) { 142 expectEquals(i + 2, a[i], "add"); 143 } 144 sub(2.0f); 145 for (int i = 0; i < 128; i++) { 146 expectEquals(i, a[i], "sub"); 147 } 148 mul(2.0f); 149 for (int i = 0; i < 128; i++) { 150 expectEquals(i + i, a[i], "mul"); 151 } 152 div(2.0f); 153 for (int i = 0; i < 128; i++) { 154 expectEquals(i, a[i], "div"); 155 } 156 neg(); 157 for (int i = 0; i < 128; i++) { 158 expectEquals(-i, a[i], "neg"); 159 } 160 // Loop bounds. 161 bounds(); 162 expectEquals(0, a[0], "bounds0"); 163 for (int i = 1; i < 127; i++) { 164 expectEquals(11 - i, a[i], "bounds"); 165 } 166 expectEquals(-127, a[127], "bounds127"); 167 // Abs. 168 abs(); 169 expectEquals(0, a[0], "abs0"); 170 for (int i = 1; i <= 11; i++) { 171 expectEquals(11 - i, a[i], "abs_lo"); 172 } 173 for (int i = 12; i < 127; i++) { 174 expectEquals(i - 11, a[i], "abs_hi"); 175 } 176 expectEquals(127, a[127], "abs127"); 177 // Conversion. 178 int[] b = new int[128]; 179 for (int i = 0; i < 128; i++) { 180 b[i] = 1000 * i; 181 } 182 conv(b); 183 for (int i = 1; i < 127; i++) { 184 expectEquals(1000.0f * i, a[i], "conv"); 185 } 186 // Done. 187 System.out.println("SimdFloat passed"); 188 } 189 expectEquals(float expected, float result, String action)190 private static void expectEquals(float expected, float result, String action) { 191 if (expected != result) { 192 throw new Error("Expected: " + expected + ", found: " + result + " for " + action); 193 } 194 } 195 } 196