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 * Tests for simple integral reductions: same type for accumulator and data. 19 */ 20 public class Main { 21 22 static final int N = 500; 23 static final int M = 100; 24 25 // 26 // Basic reductions in loops. 27 // 28 29 // TODO: vectorize these (second step of b/64091002 plan) 30 reductionByte(byte[] x)31 private static byte reductionByte(byte[] x) { 32 byte sum = 0; 33 for (int i = 0; i < x.length; i++) { 34 sum += x[i]; 35 } 36 return sum; 37 } 38 reductionShort(short[] x)39 private static short reductionShort(short[] x) { 40 short sum = 0; 41 for (int i = 0; i < x.length; i++) { 42 sum += x[i]; 43 } 44 return sum; 45 } 46 reductionChar(char[] x)47 private static char reductionChar(char[] x) { 48 char sum = 0; 49 for (int i = 0; i < x.length; i++) { 50 sum += x[i]; 51 } 52 return sum; 53 } 54 55 /// CHECK-START: int Main.reductionInt(int[]) loop_optimization (before) 56 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 57 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 58 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 59 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 60 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 61 /// CHECK-DAG: Add [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 62 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 63 /// CHECK-DAG: Return [<<Phi2>>] loop:none 64 // 65 /// CHECK-START-{ARM,ARM64}: int Main.reductionInt(int[]) loop_optimization (after) 66 /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none 67 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{i\d+}}] loop:none 68 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 69 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 70 /// CHECK-DAG: VecAdd [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 71 /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop>> outer_loop:none 72 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 73 /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none 74 75 // Check that full 128-bit Q-Register are saved across SuspendCheck slow path. 76 /// CHECK-START-ARM64: int Main.reductionInt(int[]) disassembly (after) 77 /// CHECK: SuspendCheckSlowPathARM64 78 /// CHECK: stur q<<RegNo:\d+>>, [sp, #<<Offset:\d+>>] 79 /// CHECK: ldur q<<RegNo>>, [sp, #<<Offset>>] reductionInt(int[] x)80 private static int reductionInt(int[] x) { 81 int sum = 0; 82 for (int i = 0; i < x.length; i++) { 83 sum += x[i]; 84 } 85 return sum; 86 } 87 88 /// CHECK-START: int Main.reductionIntChain() loop_optimization (before) 89 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 90 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 91 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons1>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 92 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop1>> outer_loop:none 93 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [{{l\d+}},<<Phi2>>] loop:<<Loop1>> outer_loop:none 94 /// CHECK-DAG: Add [<<Phi1>>,<<Get1>>] loop:<<Loop1>> outer_loop:none 95 /// CHECK-DAG: Add [<<Phi2>>,<<Cons1>>] loop:<<Loop1>> outer_loop:none 96 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:none 97 /// CHECK-DAG: <<Phi4:i\d+>> Phi [<<Phi1>>,{{i\d+}}] loop:<<Loop2>> outer_loop:none 98 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [{{l\d+}},<<Phi3>>] loop:<<Loop2>> outer_loop:none 99 /// CHECK-DAG: Add [<<Phi4>>,<<Get2>>] loop:<<Loop2>> outer_loop:none 100 /// CHECK-DAG: Add [<<Phi3>>,<<Cons1>>] loop:<<Loop2>> outer_loop:none 101 /// CHECK-DAG: Return [<<Phi4>>] loop:none 102 // 103 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 104 // 105 /// CHECK-START-{ARM,ARM64}: int Main.reductionIntChain() loop_optimization (after) 106 /// CHECK-DAG: <<Set1:d\d+>> VecSetScalars [{{i\d+}}] loop:none 107 /// CHECK-DAG: <<Phi1:d\d+>> Phi [<<Set1>>,{{d\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 108 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<I1:i\d+>>] loop:<<Loop1>> outer_loop:none 109 /// CHECK-DAG: VecAdd [<<Phi1>>,<<Load1>>] loop:<<Loop1>> outer_loop:none 110 /// CHECK-DAG: Add [<<I1>>,{{i\d+}}] loop:<<Loop1>> outer_loop:none 111 /// CHECK-DAG: <<Red1:d\d+>> VecReduce [<<Phi1>>] loop:none 112 /// CHECK-DAG: <<Extr1:i\d+>> VecExtractScalar [<<Red1>>] loop:none 113 /// CHECK-DAG: <<Set2:d\d+>> VecSetScalars [{{i\d+}}] loop:none 114 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set2>>,{{d\d+}}] loop:<<Loop2:B\d+>> outer_loop:none 115 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<I2:i\d+>>] loop:<<Loop2>> outer_loop:none 116 /// CHECK-DAG: VecAdd [<<Phi2>>,<<Load2>>] loop:<<Loop2>> outer_loop:none 117 /// CHECK-DAG: Add [<<I2>>,{{i\d+}}] loop:<<Loop2>> outer_loop:none 118 /// CHECK-DAG: <<Red2:d\d+>> VecReduce [<<Phi2>>] loop:none 119 /// CHECK-DAG: <<Extr2:i\d+>> VecExtractScalar [<<Red2>>] loop:none 120 // 121 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 122 // 123 // NOTE: pattern is robust with respect to vector loop unrolling and peeling. reductionIntChain()124 private static int reductionIntChain() { 125 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 126 int r = 1; 127 for (int i = 0; i < 16; i++) { 128 r += x[i]; 129 } 130 for (int i = 0; i < 16; i++) { 131 r += x[i]; 132 } 133 return r; 134 } 135 136 /// CHECK-START: int Main.reductionIntToLoop(int[]) loop_optimization (before) 137 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 138 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 139 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 140 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop1>> outer_loop:none 141 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop1>> outer_loop:none 142 /// CHECK-DAG: Add [<<Phi2>>,<<Get>>] loop:<<Loop1>> outer_loop:none 143 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop1>> outer_loop:none 144 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Phi2>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:none 145 /// CHECK-DAG: <<Phi4:i\d+>> Phi [<<Phi2>>,{{i\d+}}] loop:<<Loop2>> outer_loop:none 146 // 147 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 148 // 149 /// CHECK-START-{ARM,ARM64}: int Main.reductionIntToLoop(int[]) loop_optimization (after) 150 /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none 151 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{i\d+}}] loop:none 152 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 153 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop1>> outer_loop:none 154 /// CHECK-DAG: VecAdd [<<Phi>>,<<Load>>] loop:<<Loop1>> outer_loop:none 155 /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop1>> outer_loop:none 156 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 157 /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none reductionIntToLoop(int[] x)158 private static int reductionIntToLoop(int[] x) { 159 int r = 0; 160 for (int i = 0; i < 8; i++) { 161 r += x[i]; 162 } 163 for (int i = r; i < 16; i++) { 164 r += i; 165 } 166 return r; 167 } 168 169 /// CHECK-START: long Main.reductionLong(long[]) loop_optimization (before) 170 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 171 /// CHECK-DAG: <<Long0:j\d+>> LongConstant 0 loop:none 172 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 173 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 174 /// CHECK-DAG: <<Phi2:j\d+>> Phi [<<Long0>>,{{j\d+}}] loop:<<Loop>> outer_loop:none 175 /// CHECK-DAG: <<Get:j\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 176 /// CHECK-DAG: Add [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 177 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 178 /// CHECK-DAG: Return [<<Phi2>>] loop:none 179 // 180 /// CHECK-START-ARM64: long Main.reductionLong(long[]) loop_optimization (after) 181 /// CHECK-DAG: <<Cons2:i\d+>> IntConstant 2 loop:none 182 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{j\d+}}] loop:none 183 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 184 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 185 /// CHECK-DAG: VecAdd [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 186 /// CHECK-DAG: Add [<<I>>,<<Cons2>>] loop:<<Loop>> outer_loop:none 187 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 188 /// CHECK-DAG: <<Extr:j\d+>> VecExtractScalar [<<Red>>] loop:none reductionLong(long[] x)189 private static long reductionLong(long[] x) { 190 long sum = 0; 191 for (int i = 0; i < x.length; i++) { 192 sum += x[i]; 193 } 194 return sum; 195 } 196 reductionByteM1(byte[] x)197 private static byte reductionByteM1(byte[] x) { 198 byte sum = -1; 199 for (int i = 0; i < x.length; i++) { 200 sum += x[i]; 201 } 202 return sum; 203 } 204 reductionShortM1(short[] x)205 private static short reductionShortM1(short[] x) { 206 short sum = -1; 207 for (int i = 0; i < x.length; i++) { 208 sum += x[i]; 209 } 210 return sum; 211 } 212 reductionCharM1(char[] x)213 private static char reductionCharM1(char[] x) { 214 char sum = 0xffff; 215 for (int i = 0; i < x.length; i++) { 216 sum += x[i]; 217 } 218 return sum; 219 } 220 221 /// CHECK-START: int Main.reductionIntM1(int[]) loop_optimization (before) 222 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 223 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 224 /// CHECK-DAG: <<ConsM1:i\d+>> IntConstant -1 loop:none 225 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 226 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<ConsM1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 227 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 228 /// CHECK-DAG: Add [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 229 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 230 /// CHECK-DAG: Return [<<Phi2>>] loop:none 231 // 232 /// CHECK-START-{ARM,ARM64}: int Main.reductionIntM1(int[]) loop_optimization (after) 233 /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none 234 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{i\d+}}] loop:none 235 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 236 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 237 /// CHECK-DAG: VecAdd [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 238 /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop>> outer_loop:none 239 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 240 /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none reductionIntM1(int[] x)241 private static int reductionIntM1(int[] x) { 242 int sum = -1; 243 for (int i = 0; i < x.length; i++) { 244 sum += x[i]; 245 } 246 return sum; 247 } 248 249 /// CHECK-START: long Main.reductionLongM1(long[]) loop_optimization (before) 250 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 251 /// CHECK-DAG: <<LongM1:j\d+>> LongConstant -1 loop:none 252 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 253 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 254 /// CHECK-DAG: <<Phi2:j\d+>> Phi [<<LongM1>>,{{j\d+}}] loop:<<Loop>> outer_loop:none 255 /// CHECK-DAG: <<Get:j\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 256 /// CHECK-DAG: Add [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 257 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 258 /// CHECK-DAG: Return [<<Phi2>>] loop:none 259 // 260 /// CHECK-START-ARM64: long Main.reductionLongM1(long[]) loop_optimization (after) 261 /// CHECK-DAG: <<Cons2:i\d+>> IntConstant 2 loop:none 262 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{j\d+}}] loop:none 263 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 264 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 265 /// CHECK-DAG: VecAdd [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 266 /// CHECK-DAG: Add [<<I>>,<<Cons2>>] loop:<<Loop>> outer_loop:none 267 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 268 /// CHECK-DAG: <<Extr:j\d+>> VecExtractScalar [<<Red>>] loop:none reductionLongM1(long[] x)269 private static long reductionLongM1(long[] x) { 270 long sum = -1L; 271 for (int i = 0; i < x.length; i++) { 272 sum += x[i]; 273 } 274 return sum; 275 } 276 reductionMinusByte(byte[] x)277 private static byte reductionMinusByte(byte[] x) { 278 byte sum = 0; 279 for (int i = 0; i < x.length; i++) { 280 sum -= x[i]; 281 } 282 return sum; 283 } 284 reductionMinusShort(short[] x)285 private static short reductionMinusShort(short[] x) { 286 short sum = 0; 287 for (int i = 0; i < x.length; i++) { 288 sum -= x[i]; 289 } 290 return sum; 291 } 292 reductionMinusChar(char[] x)293 private static char reductionMinusChar(char[] x) { 294 char sum = 0; 295 for (int i = 0; i < x.length; i++) { 296 sum -= x[i]; 297 } 298 return sum; 299 } 300 301 /// CHECK-START: int Main.reductionMinusInt(int[]) loop_optimization (before) 302 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 303 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 304 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 305 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 306 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 307 /// CHECK-DAG: Sub [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 308 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 309 /// CHECK-DAG: Return [<<Phi2>>] loop:none 310 // 311 /// CHECK-START-{ARM,ARM64}: int Main.reductionMinusInt(int[]) loop_optimization (after) 312 /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none 313 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{i\d+}}] loop:none 314 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 315 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 316 /// CHECK-DAG: VecSub [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 317 /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop>> outer_loop:none 318 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 319 /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none reductionMinusInt(int[] x)320 private static int reductionMinusInt(int[] x) { 321 int sum = 0; 322 for (int i = 0; i < x.length; i++) { 323 sum -= x[i]; 324 } 325 return sum; 326 } 327 328 /// CHECK-START: long Main.reductionMinusLong(long[]) loop_optimization (before) 329 /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none 330 /// CHECK-DAG: <<Long0:j\d+>> LongConstant 0 loop:none 331 /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none 332 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 333 /// CHECK-DAG: <<Phi2:j\d+>> Phi [<<Long0>>,{{j\d+}}] loop:<<Loop>> outer_loop:none 334 /// CHECK-DAG: <<Get:j\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 335 /// CHECK-DAG: Sub [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none 336 /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none 337 /// CHECK-DAG: Return [<<Phi2>>] loop:none 338 // 339 /// CHECK-START-ARM64: long Main.reductionMinusLong(long[]) loop_optimization (after) 340 /// CHECK-DAG: <<Cons2:i\d+>> IntConstant 2 loop:none 341 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [{{j\d+}}] loop:none 342 /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none 343 /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none 344 /// CHECK-DAG: VecSub [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none 345 /// CHECK-DAG: Add [<<I>>,<<Cons2>>] loop:<<Loop>> outer_loop:none 346 /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none 347 /// CHECK-DAG: <<Extr:j\d+>> VecExtractScalar [<<Red>>] loop:none reductionMinusLong(long[] x)348 private static long reductionMinusLong(long[] x) { 349 long sum = 0; 350 for (int i = 0; i < x.length; i++) { 351 sum -= x[i]; 352 } 353 return sum; 354 } 355 356 // 357 // A few special cases. 358 // 359 360 // TODO: consider unrolling 361 reductionInt10(int[] x)362 private static int reductionInt10(int[] x) { 363 int sum = 0; 364 // Amenable to complete unrolling. 365 for (int i = 10; i <= 10; i++) { 366 sum += x[i]; 367 } 368 return sum; 369 } 370 reductionMinusInt10(int[] x)371 private static int reductionMinusInt10(int[] x) { 372 int sum = 0; 373 // Amenable to complete unrolling. 374 for (int i = 10; i <= 10; i++) { 375 sum -= x[i]; 376 } 377 return sum; 378 } 379 380 // 381 // Main driver. 382 // 383 main(String[] args)384 public static void main(String[] args) { 385 byte[] xb = new byte[N]; 386 short[] xs = new short[N]; 387 char[] xc = new char[N]; 388 int[] xi = new int[N]; 389 long[] xl = new long[N]; 390 for (int i = 0, k = -17; i < N; i++, k += 3) { 391 xb[i] = (byte) k; 392 xs[i] = (short) k; 393 xc[i] = (char) k; 394 xi[i] = k; 395 xl[i] = k; 396 } 397 398 // Arrays with all positive elements. 399 byte[] xpb = new byte[M]; 400 short[] xps = new short[M]; 401 char[] xpc = new char[M]; 402 int[] xpi = new int[M]; 403 long[] xpl = new long[M]; 404 for (int i = 0, k = 3; i < M; i++, k++) { 405 xpb[i] = (byte) k; 406 xps[i] = (short) k; 407 xpc[i] = (char) k; 408 xpi[i] = k; 409 xpl[i] = k; 410 } 411 412 // Arrays with all negative elements. 413 byte[] xnb = new byte[M]; 414 short[] xns = new short[M]; 415 int[] xni = new int[M]; 416 long[] xnl = new long[M]; 417 for (int i = 0, k = -103; i < M; i++, k++) { 418 xnb[i] = (byte) k; 419 xns[i] = (short) k; 420 xni[i] = k; 421 xnl[i] = k; 422 } 423 424 // Test various reductions in loops. 425 int[] x0 = { 0, 0, 0, 0, 0, 0, 0, 0 }; 426 int[] x1 = { 0, 0, 0, 1, 0, 0, 0, 0 }; 427 int[] x2 = { 1, 1, 1, 1, 0, 0, 0, 0 }; 428 expectEquals(-74, reductionByte(xb)); 429 expectEquals(-27466, reductionShort(xs)); 430 expectEquals(38070, reductionChar(xc)); 431 expectEquals(365750, reductionInt(xi)); 432 expectEquals(273, reductionIntChain()); 433 expectEquals(120, reductionIntToLoop(x0)); 434 expectEquals(121, reductionIntToLoop(x1)); 435 expectEquals(118, reductionIntToLoop(x2)); 436 expectEquals(-1310, reductionIntToLoop(xi)); 437 expectEquals(365750L, reductionLong(xl)); 438 expectEquals(-75, reductionByteM1(xb)); 439 expectEquals(-27467, reductionShortM1(xs)); 440 expectEquals(38069, reductionCharM1(xc)); 441 expectEquals(365749, reductionIntM1(xi)); 442 expectEquals(365749L, reductionLongM1(xl)); 443 expectEquals(74, reductionMinusByte(xb)); 444 expectEquals(27466, reductionMinusShort(xs)); 445 expectEquals(27466, reductionMinusChar(xc)); 446 expectEquals(-365750, reductionMinusInt(xi)); 447 expectEquals(365750L, reductionLong(xl)); 448 expectEquals(-75, reductionByteM1(xb)); 449 expectEquals(-27467, reductionShortM1(xs)); 450 expectEquals(38069, reductionCharM1(xc)); 451 expectEquals(365749, reductionIntM1(xi)); 452 expectEquals(365749L, reductionLongM1(xl)); 453 expectEquals(74, reductionMinusByte(xb)); 454 expectEquals(27466, reductionMinusShort(xs)); 455 expectEquals(27466, reductionMinusChar(xc)); 456 expectEquals(-365750, reductionMinusInt(xi)); 457 expectEquals(-365750L, reductionMinusLong(xl)); 458 459 // Test special cases. 460 expectEquals(13, reductionInt10(xi)); 461 expectEquals(-13, reductionMinusInt10(xi)); 462 463 System.out.println("passed"); 464 } 465 expectEquals(int expected, int result)466 private static void expectEquals(int expected, int result) { 467 if (expected != result) { 468 throw new Error("Expected: " + expected + ", found: " + result); 469 } 470 } 471 expectEquals(long expected, long result)472 private static void expectEquals(long expected, long result) { 473 if (expected != result) { 474 throw new Error("Expected: " + expected + ", found: " + result); 475 } 476 } 477 } 478