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