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