1 /* 2 * Copyright (C) 2023 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 autovectorization of loops with control flow. 19 */ 20 public class Main { 21 22 public static final int ARRAY_LENGTH = 128; 23 public static final int USED_ARRAY_LENGTH = ARRAY_LENGTH - 1; 24 25 public static boolean[] booleanArray = new boolean[ARRAY_LENGTH]; 26 public static boolean[] booleanArray2 = new boolean[ARRAY_LENGTH]; 27 public static byte[] byteArray = new byte[ARRAY_LENGTH]; 28 public static short[] shortArray = new short[ARRAY_LENGTH]; 29 public static char[] charArray = new char[ARRAY_LENGTH]; 30 public static int[] intArray = new int[ARRAY_LENGTH]; 31 public static long[] longArray = new long[ARRAY_LENGTH]; 32 public static float[] floatArray = new float[ARRAY_LENGTH]; 33 public static double[] doubleArray = new double[ARRAY_LENGTH]; 34 35 public static final int MAGIC_VALUE_A = 2; 36 public static final int MAGIC_VALUE_B = 10; 37 public static final int MAGIC_VALUE_C = 100; 38 39 public static final int MAGIC_ADD_CONST = 99; 40 41 public static final float MAGIC_FLOAT_VALUE_A = 2.0f; 42 public static final float MAGIC_FLOAT_VALUE_B = 10.0f; 43 public static final float MAGIC_FLOAT_VALUE_C = 100.0f; 44 45 public static final float MAGIC_FLOAT_ADD_CONST = 99.0f; 46 47 /// CHECK-START-ARM64: int Main.$compile$noinline$FullDiamond(int[]) loop_optimization (after) 48 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 49 // 50 /// CHECK-DAG: <<C0:i\d+>> IntConstant 0 loop:none 51 /// CHECK-DAG: <<C4:i\d+>> IntConstant 4 loop:none 52 /// CHECK-DAG: <<C99:i\d+>> IntConstant 99 loop:none 53 /// CHECK-DAG: <<C100:i\d+>> IntConstant 100 loop:none 54 /// CHECK-DAG: <<Vec4:d\d+>> VecReplicateScalar [<<C4>>,{{j\d+}}] loop:none 55 /// CHECK-DAG: <<Vec99:d\d+>> VecReplicateScalar [<<C99>>,{{j\d+}}] loop:none 56 /// CHECK-DAG: <<Vec100:d\d+>> VecReplicateScalar [<<C100>>,{{j\d+}}] loop:none 57 // 58 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<C0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 59 /// CHECK-DAG: <<LoopP:j\d+>> VecPredWhile [<<Phi>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 60 // 61 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [<<Arr:l\d+>>,<<Phi>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 62 /// CHECK-DAG: <<Cond:j\d+>> VecCondition [<<Load1>>,<<Vec100>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 63 /// CHECK-DAG: <<CondR:j\d+>> VecPredNot [<<Cond>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 64 /// CHECK-DAG: <<AddT:d\d+>> VecAdd [<<Load1>>,<<Vec99>>,<<CondR>>] loop:<<Loop>> outer_loop:none 65 /// CHECK-DAG: <<StT:d\d+>> VecStore [<<Arr>>,<<Phi>>,<<AddT>>,<<CondR>>] loop:<<Loop>> outer_loop:none 66 /// CHECK-DAG: <<StF:d\d+>> VecStore [<<Arr>>,<<Phi>>,{{d\d+}},<<Cond>>] loop:<<Loop>> outer_loop:none 67 /// CHECK-DAG: <<Ld2:d\d+>> VecLoad [<<Arr>>,<<Phi>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 68 /// CHECK-DAG: <<Add2:d\d+>> VecAdd [<<Ld2>>,<<Vec4>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 69 /// CHECK-DAG: <<St21:d\d+>> VecStore [<<Arr>>,<<Phi>>,<<Add2>>,<<LoopP>>] loop:<<Loop>> outer_loop:none 70 // 71 /// CHECK-ELSE: 72 // 73 /// CHECK-NOT: VecLoad 74 // 75 /// CHECK-FI: $compile$noinline$FullDiamond(int[] x)76 public static int $compile$noinline$FullDiamond(int[] x) { 77 int i = 0; 78 for (; i < USED_ARRAY_LENGTH; i++) { 79 int val = x[i]; 80 if (val != MAGIC_VALUE_C) { 81 x[i] += MAGIC_ADD_CONST; 82 } else { 83 x[i] += 3; 84 } 85 x[i] += 4; 86 } 87 return i; 88 } 89 90 // 91 // Test various types. 92 // 93 94 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleBoolean(boolean[], boolean[]) loop_optimization (after) 95 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 96 // 97 /// CHECK-NOT: VecLoad 98 // 99 /// CHECK-FI: 100 // 101 // TODO: Support extra condition types and boolean comparisons. $compile$noinline$SimpleBoolean(boolean[] x, boolean[] y)102 public static void $compile$noinline$SimpleBoolean(boolean[] x, boolean[] y) { 103 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 104 boolean val = x[i]; 105 if (val != y[i]) { 106 x[i] |= y[i]; 107 } 108 } 109 } 110 111 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleByte(byte[]) loop_optimization (after) 112 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 113 // 114 /// CHECK-DAG: VecLoad 115 // 116 /// CHECK-FI: $compile$noinline$SimpleByte(byte[] x)117 public static void $compile$noinline$SimpleByte(byte[] x) { 118 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 119 byte val = x[i]; 120 if (val != MAGIC_VALUE_C) { 121 x[i] += MAGIC_ADD_CONST; 122 } 123 } 124 } 125 126 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleUByte(byte[]) loop_optimization (after) 127 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 128 // 129 /// CHECK-DAG: VecLoad 130 // 131 /// CHECK-FI: $compile$noinline$SimpleUByte(byte[] x)132 public static void $compile$noinline$SimpleUByte(byte[] x) { 133 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 134 if ((x[i] & 0xFF) != MAGIC_VALUE_C) { 135 x[i] += MAGIC_ADD_CONST; 136 } 137 } 138 } 139 140 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleShort(short[]) loop_optimization (after) 141 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 142 // 143 /// CHECK-DAG: VecLoad 144 // 145 /// CHECK-FI: $compile$noinline$SimpleShort(short[] x)146 public static void $compile$noinline$SimpleShort(short[] x) { 147 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 148 short val = x[i]; 149 if (val != MAGIC_VALUE_C) { 150 x[i] += MAGIC_ADD_CONST; 151 } 152 } 153 } 154 155 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleChar(char[]) loop_optimization (after) 156 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 157 // 158 /// CHECK-DAG: VecLoad 159 // 160 /// CHECK-FI: $compile$noinline$SimpleChar(char[] x)161 public static void $compile$noinline$SimpleChar(char[] x) { 162 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 163 char val = x[i]; 164 if (val != MAGIC_VALUE_C) { 165 x[i] += MAGIC_ADD_CONST; 166 } 167 } 168 } 169 170 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleInt(int[]) loop_optimization (after) 171 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 172 // 173 /// CHECK-DAG: VecLoad 174 // 175 /// CHECK-FI: $compile$noinline$SimpleInt(int[] x)176 public static void $compile$noinline$SimpleInt(int[] x) { 177 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 178 int val = x[i]; 179 if (val != MAGIC_VALUE_C) { 180 x[i] += MAGIC_ADD_CONST; 181 } 182 } 183 } 184 185 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleLong(long[]) loop_optimization (after) 186 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 187 // 188 /// CHECK-NOT: VecLoad 189 // 190 /// CHECK-FI: 191 // 192 // TODO: Support long comparisons. $compile$noinline$SimpleLong(long[] x)193 public static void $compile$noinline$SimpleLong(long[] x) { 194 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 195 long val = x[i]; 196 if (val != MAGIC_VALUE_C) { 197 x[i] += MAGIC_ADD_CONST; 198 } 199 } 200 } 201 202 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleFloat(float[]) loop_optimization (after) 203 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 204 // 205 /// CHECK-NOT: VecLoad 206 // 207 /// CHECK-FI: 208 // 209 // TODO: Support FP comparisons. $compile$noinline$SimpleFloat(float[] x)210 public static void $compile$noinline$SimpleFloat(float[] x) { 211 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 212 float val = x[i]; 213 if (val > 10.0f) { 214 x[i] += 99.1f; 215 } 216 } 217 } 218 219 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleDouble(double[]) loop_optimization (after) 220 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 221 // 222 /// CHECK-NOT: VecLoad 223 // 224 /// CHECK-FI: 225 // 226 // TODO: Support FP comparisons. $compile$noinline$SimpleDouble(double[] x)227 public static void $compile$noinline$SimpleDouble(double[] x) { 228 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 229 double val = x[i]; 230 if (val != 10.0) { 231 x[i] += 99.1; 232 } 233 } 234 } 235 236 // 237 // Narrowing types. 238 // 239 240 /// CHECK-START-ARM64: void Main.$compile$noinline$ByteConv(byte[], byte[]) loop_optimization (after) 241 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 242 // 243 /// CHECK-DAG: VecLoad 244 // 245 /// CHECK-FI: $compile$noinline$ByteConv(byte[] x, byte[] y)246 public static void $compile$noinline$ByteConv(byte[] x, byte[] y) { 247 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 248 byte val = (byte)(x[i] + 1); 249 if (val != y[i]) { 250 x[i] += MAGIC_ADD_CONST; 251 } 252 } 253 } 254 255 /// CHECK-START-ARM64: void Main.$compile$noinline$UByteAndWrongConst(byte[]) loop_optimization (after) 256 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 257 // 258 /// CHECK-NOT: VecLoad 259 // 260 /// CHECK-FI: 261 // 262 // 'NarrowerOperands' not met: the constant is not a ubyte one. $compile$noinline$UByteAndWrongConst(byte[] x)263 public static void $compile$noinline$UByteAndWrongConst(byte[] x) { 264 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 265 if ((x[i] & 0xFF) != (MAGIC_VALUE_C | 0x100)) { 266 x[i] += MAGIC_ADD_CONST; 267 } 268 } 269 } 270 271 /// CHECK-START-ARM64: void Main.$compile$noinline$ByteNoHiBits(byte[], byte[]) loop_optimization (after) 272 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 273 // 274 /// CHECK-NOT: VecLoad 275 // 276 /// CHECK-FI: 277 // 278 // Check kNoHiBits case when "wider" operations cannot bring in higher order bits. $compile$noinline$ByteNoHiBits(byte[] x, byte[] y)279 public static void $compile$noinline$ByteNoHiBits(byte[] x, byte[] y) { 280 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 281 byte val = x[i]; 282 if ((val >>> 3) != y[i]) { 283 x[i] += MAGIC_ADD_CONST; 284 } 285 } 286 } 287 288 // 289 // Test condition types. 290 // 291 292 /// CHECK-START-ARM64: void Main.$compile$noinline$SimpleBelow(int[]) loop_optimization (after) 293 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 294 // 295 /// CHECK-NOT: VecLoad 296 // 297 /// CHECK-FI: 298 // 299 // TODO: Support other conditions. $compile$noinline$SimpleBelow(int[] x)300 public static void $compile$noinline$SimpleBelow(int[] x) { 301 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 302 int val = x[i]; 303 if (val < MAGIC_VALUE_C) { 304 x[i] += MAGIC_ADD_CONST; 305 } 306 } 307 } 308 309 // 310 // Test vectorization idioms. 311 // 312 313 /// CHECK-START-ARM64: void Main.$compile$noinline$Select(int[]) loop_optimization (after) 314 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 315 // 316 /// CHECK-NOT: VecLoad 317 // 318 /// CHECK-FI: 319 // 320 // TODO: vectorize loops with select in the body. $compile$noinline$Select(int[] x)321 public static void $compile$noinline$Select(int[] x) { 322 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 323 int val = x[i]; 324 if (val != MAGIC_VALUE_C) { 325 val += MAGIC_ADD_CONST; 326 } 327 x[i] = val; 328 } 329 } 330 331 /// CHECK-START-ARM64: void Main.$compile$noinline$Phi(int[]) loop_optimization (after) 332 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 333 // 334 /// CHECK-NOT: VecLoad 335 // 336 /// CHECK-FI: 337 // 338 // TODO: vectorize loops with phis in the body. $compile$noinline$Phi(int[] x)339 public static void $compile$noinline$Phi(int[] x) { 340 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 341 int val = x[i]; 342 if (val != MAGIC_VALUE_C) { 343 val += MAGIC_ADD_CONST; 344 x[i] += val; 345 } 346 x[i] += val; 347 } 348 } 349 350 // TODO: when Phis are supported, test dotprod and sad idioms. 351 352 /// CHECK-START-ARM64: int Main.$compile$noinline$Reduction(int[]) loop_optimization (after) 353 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 354 // 355 /// CHECK-NOT: VecLoad 356 // 357 /// CHECK-FI: 358 // 359 // TODO: vectorize loops with phis and reductions in the body. $compile$noinline$Reduction(int[] x)360 private static int $compile$noinline$Reduction(int[] x) { 361 int sum = 0; 362 for (int i = 0; i < ARRAY_LENGTH; i++) { 363 int val = x[i]; 364 if (val != MAGIC_VALUE_C) { 365 sum += val + x[i]; 366 } 367 } 368 return sum; 369 } 370 371 /// CHECK-START-ARM64: int Main.$compile$noinline$ReductionBackEdge(int[]) loop_optimization (after) 372 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 373 // 374 /// CHECK-DAG: VecLoad 375 // 376 /// CHECK-FI: 377 // 378 // Reduction in the back edge block, non-CF-dependent. $compile$noinline$ReductionBackEdge(int[] x)379 public static int $compile$noinline$ReductionBackEdge(int[] x) { 380 int sum = 0; 381 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 382 int val = x[i]; 383 if (val != MAGIC_VALUE_C) { 384 x[i] += MAGIC_ADD_CONST; 385 } 386 sum += x[i]; 387 } 388 return sum; 389 } 390 391 // 392 // Negative compile tests. 393 // 394 395 public static final int STENCIL_ARRAY_SIZE = 130; 396 397 /// CHECK-START-ARM64: void Main.$compile$noinline$stencilAlike(int[], int[]) loop_optimization (after) 398 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 399 // 400 /// CHECK-NOT: VecLoad 401 // 402 /// CHECK-FI: 403 // 404 // This loop needs a runtime test for array references disambiguation and a scalar cleanup loop. 405 // Currently we can't generate a scalar clean up loop with control flow. $compile$noinline$stencilAlike(int[] a, int[] b)406 private static void $compile$noinline$stencilAlike(int[] a, int[] b) { 407 for (int i = 1; i < STENCIL_ARRAY_SIZE - 1; i++) { 408 int val0 = b[i - 1]; 409 int val1 = b[i]; 410 int val2 = b[i + 1]; 411 int un = a[i]; 412 if (val1 != MAGIC_VALUE_C) { 413 a[i] = val0 + val1 + val2; 414 } 415 } 416 } 417 418 /// CHECK-START-ARM64: void Main.$compile$noinline$NotDiamondCf(int[]) loop_optimization (after) 419 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 420 // 421 /// CHECK-NOT: VecLoad 422 // 423 /// CHECK-FI: 424 // 425 // Loops with complex CF are not supported. $compile$noinline$NotDiamondCf(int[] x)426 public static void $compile$noinline$NotDiamondCf(int[] x) { 427 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 428 int val = x[i]; 429 if (val != MAGIC_VALUE_C) { 430 if (val != 1234) { 431 x[i] += MAGIC_ADD_CONST; 432 } 433 } 434 } 435 } 436 437 /// CHECK-START-ARM64: void Main.$compile$noinline$BrokenInduction(int[]) loop_optimization (after) 438 /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' 439 // 440 /// CHECK-NOT: VecLoad 441 // 442 /// CHECK-FI: $compile$noinline$BrokenInduction(int[] x)443 public static void $compile$noinline$BrokenInduction(int[] x) { 444 for (int i = 0; i < USED_ARRAY_LENGTH; i++) { 445 int val = x[i]; 446 if (val != MAGIC_VALUE_C) { 447 x[i] += MAGIC_ADD_CONST; 448 i++; 449 } 450 } 451 } 452 453 // 454 // Main driver. 455 // 456 main(String[] args)457 public static void main(String[] args) { 458 initIntArray(intArray); 459 int final_ind_value = $compile$noinline$FullDiamond(intArray); 460 expectIntEquals(23755, IntArraySum(intArray)); 461 expectIntEquals(USED_ARRAY_LENGTH, final_ind_value); 462 463 // Types. 464 initBooleanArray(booleanArray); 465 booleanArray2[12] = true; 466 $compile$noinline$SimpleBoolean(booleanArray, booleanArray2); 467 expectIntEquals(86, BooleanArraySum(booleanArray)); 468 469 initByteArray(byteArray); 470 $compile$noinline$SimpleByte(byteArray); 471 expectIntEquals(-64, ByteArraySum(byteArray)); 472 473 initByteArray(byteArray); 474 $compile$noinline$SimpleUByte(byteArray); 475 expectIntEquals(-64, ByteArraySum(byteArray)); 476 477 initShortArray(shortArray); 478 $compile$noinline$SimpleShort(shortArray); 479 expectIntEquals(23121, ShortArraySum(shortArray)); 480 481 initCharArray(charArray); 482 $compile$noinline$SimpleChar(charArray); 483 expectIntEquals(23121, CharArraySum(charArray)); 484 485 initIntArray(intArray); 486 $compile$noinline$SimpleInt(intArray); 487 expectIntEquals(23121, IntArraySum(intArray)); 488 489 initLongArray(longArray); 490 $compile$noinline$SimpleLong(longArray); 491 expectLongEquals(23121, LongArraySum(longArray)); 492 493 initFloatArray(floatArray); 494 $compile$noinline$SimpleFloat(floatArray); 495 expectFloatEquals(18868.2f, FloatArraySum(floatArray)); 496 497 initDoubleArray(doubleArray); 498 $compile$noinline$SimpleDouble(doubleArray); 499 expectDoubleEquals(23129.5, DoubleArraySum(doubleArray)); 500 501 // Narrowing types. 502 initByteArray(byteArray); 503 $compile$noinline$ByteConv(byteArray, byteArray); 504 expectIntEquals(-2, ByteArraySum(byteArray)); 505 506 initByteArray(byteArray); 507 $compile$noinline$UByteAndWrongConst(byteArray); 508 expectIntEquals(-2, ByteArraySum(byteArray)); 509 510 initByteArray(byteArray); 511 $compile$noinline$ByteNoHiBits(byteArray, byteArray); 512 expectIntEquals(-2, ByteArraySum(byteArray)); 513 514 // Conditions. 515 initIntArray(intArray); 516 $compile$noinline$SimpleBelow(intArray); 517 expectIntEquals(23121, IntArraySum(intArray)); 518 519 // Idioms. 520 initIntArray(intArray); 521 $compile$noinline$Select(intArray); 522 expectIntEquals(23121, IntArraySum(intArray)); 523 524 initIntArray(intArray); 525 $compile$noinline$Phi(intArray); 526 expectIntEquals(36748, IntArraySum(intArray)); 527 528 int reduction_result = 0; 529 530 initIntArray(intArray); 531 reduction_result = $compile$noinline$Reduction(intArray); 532 expectIntEquals(14706, IntArraySum(intArray)); 533 expectIntEquals(21012, reduction_result); 534 535 initIntArray(intArray); 536 reduction_result = $compile$noinline$ReductionBackEdge(intArray); 537 expectIntEquals(23121, IntArraySum(intArray)); 538 expectIntEquals(13121, reduction_result); 539 540 int[] stencilArrayA = new int[STENCIL_ARRAY_SIZE]; 541 int[] stencilArrayB = new int[STENCIL_ARRAY_SIZE]; 542 initIntArray(stencilArrayA); 543 initIntArray(stencilArrayB); 544 $compile$noinline$stencilAlike(stencilArrayA, stencilArrayB); 545 expectIntEquals(43602, IntArraySum(stencilArrayA)); 546 547 initIntArray(intArray); 548 $compile$noinline$NotDiamondCf(intArray); 549 expectIntEquals(23121, IntArraySum(intArray)); 550 551 initIntArray(intArray); 552 $compile$noinline$BrokenInduction(intArray); 553 expectIntEquals(18963, IntArraySum(intArray)); 554 555 System.out.println("passed"); 556 } 557 initBooleanArray(boolean[] a)558 public static void initBooleanArray(boolean[] a) { 559 for (int i = 0; i < ARRAY_LENGTH; i++) { 560 if (i % 3 != 0) { 561 a[i] = true; 562 } 563 } 564 } 565 initByteArray(byte[] a)566 public static void initByteArray(byte[] a) { 567 for (int i = 0; i < ARRAY_LENGTH; i++) { 568 if (i % 3 == 0) { 569 a[i] = (byte)MAGIC_VALUE_A; 570 } else if (i % 3 == 1) { 571 a[i] = (byte)MAGIC_VALUE_B; 572 } else { 573 a[i] = (byte)MAGIC_VALUE_C; 574 } 575 } 576 a[USED_ARRAY_LENGTH] = 127; 577 } 578 initShortArray(short[] a)579 public static void initShortArray(short[] a) { 580 for (int i = 0; i < ARRAY_LENGTH; i++) { 581 if (i % 3 == 0) { 582 a[i] = (short)MAGIC_VALUE_A; 583 } else if (i % 3 == 1) { 584 a[i] = (short)MAGIC_VALUE_B; 585 } else { 586 a[i] = (short)MAGIC_VALUE_C; 587 } 588 } 589 a[USED_ARRAY_LENGTH] = 10000; 590 } 591 initCharArray(char[] a)592 public static void initCharArray(char[] a) { 593 for (int i = 0; i < ARRAY_LENGTH; i++) { 594 if (i % 3 == 0) { 595 a[i] = (char)MAGIC_VALUE_A; 596 } else if (i % 3 == 1) { 597 a[i] = (char)MAGIC_VALUE_B; 598 } else { 599 a[i] = (char)MAGIC_VALUE_C; 600 } 601 } 602 a[USED_ARRAY_LENGTH] = 10000; 603 } 604 initIntArray(int[] a)605 public static void initIntArray(int[] a) { 606 for (int i = 0; i < ARRAY_LENGTH; i++) { 607 if (i % 3 == 0) { 608 a[i] = MAGIC_VALUE_A; 609 } else if (i % 3 == 1) { 610 a[i] = MAGIC_VALUE_B; 611 } else { 612 a[i] = MAGIC_VALUE_C; 613 } 614 } 615 a[USED_ARRAY_LENGTH] = 10000; 616 } 617 initLongArray(long[] a)618 public static void initLongArray(long[] a) { 619 for (int i = 0; i < ARRAY_LENGTH; i++) { 620 if (i % 3 == 0) { 621 a[i] = MAGIC_VALUE_A; 622 } else if (i % 3 == 1) { 623 a[i] = MAGIC_VALUE_B; 624 } else { 625 a[i] = MAGIC_VALUE_C; 626 } 627 } 628 a[USED_ARRAY_LENGTH] = 10000; 629 } 630 initFloatArray(float[] a)631 public static void initFloatArray(float[] a) { 632 for (int i = 0; i < ARRAY_LENGTH; i++) { 633 if (i % 3 == 0) { 634 a[i] = MAGIC_FLOAT_VALUE_A; 635 } else if (i % 3 == 1) { 636 a[i] = MAGIC_FLOAT_VALUE_B; 637 } else { 638 a[i] = MAGIC_FLOAT_VALUE_C; 639 } 640 } 641 a[USED_ARRAY_LENGTH] = 10000.0f; 642 } 643 initDoubleArray(double[] a)644 public static void initDoubleArray(double[] a) { 645 for (int i = 0; i < ARRAY_LENGTH; i++) { 646 if (i % 3 == 0) { 647 a[i] = MAGIC_FLOAT_VALUE_A; 648 } else if (i % 3 == 1) { 649 a[i] = MAGIC_FLOAT_VALUE_B; 650 } else { 651 a[i] = MAGIC_FLOAT_VALUE_C; 652 } 653 } 654 a[USED_ARRAY_LENGTH] = 10000.0f; 655 } 656 BooleanArraySum(boolean[] a)657 public static byte BooleanArraySum(boolean[] a) { 658 byte sum = 0; 659 for (int i = 0; i < a.length; i++) { 660 sum += a[i] ? 1 : 0; 661 } 662 return sum; 663 } 664 ByteArraySum(byte[] a)665 public static byte ByteArraySum(byte[] a) { 666 byte sum = 0; 667 for (int i = 0; i < a.length; i++) { 668 sum += a[i]; 669 } 670 return sum; 671 } 672 ShortArraySum(short[] a)673 public static short ShortArraySum(short[] a) { 674 short sum = 0; 675 for (int i = 0; i < a.length; i++) { 676 sum += a[i]; 677 } 678 return sum; 679 } 680 CharArraySum(char[] a)681 public static char CharArraySum(char[] a) { 682 char sum = 0; 683 for (int i = 0; i < a.length; i++) { 684 sum += a[i]; 685 } 686 return sum; 687 } 688 IntArraySum(int[] a)689 public static int IntArraySum(int[] a) { 690 int sum = 0; 691 for (int i = 0; i < a.length; i++) { 692 sum += a[i]; 693 } 694 return sum; 695 } 696 LongArraySum(long[] a)697 public static long LongArraySum(long[] a) { 698 long sum = 0; 699 for (int i = 0; i < a.length; i++) { 700 sum += a[i]; 701 } 702 return sum; 703 } 704 FloatArraySum(float[] a)705 public static float FloatArraySum(float[] a) { 706 float sum = 0.0f; 707 for (int i = 0; i < a.length; i++) { 708 sum += a[i]; 709 } 710 return sum; 711 } 712 DoubleArraySum(double[] a)713 public static double DoubleArraySum(double[] a) { 714 double sum = 0.0; 715 for (int i = 0; i < a.length; i++) { 716 sum += a[i]; 717 } 718 return sum; 719 } 720 expectIntEquals(int expected, int result)721 private static void expectIntEquals(int expected, int result) { 722 if (expected != result) { 723 throw new Error("Expected: " + expected + ", found: " + result); 724 } 725 } 726 expectLongEquals(long expected, long result)727 private static void expectLongEquals(long expected, long result) { 728 if (expected != result) { 729 throw new Error("Expected: " + expected + ", found: " + result); 730 } 731 } 732 expectFloatEquals(float expected, float result)733 private static void expectFloatEquals(float expected, float result) { 734 final float THRESHOLD = .1f; 735 if (Math.abs(expected - result) >= THRESHOLD) { 736 throw new Error("Expected: " + expected + ", found: " + result); 737 } 738 } 739 expectDoubleEquals(double expected, double result)740 private static void expectDoubleEquals(double expected, double result) { 741 final double THRESHOLD = .1; 742 if (Math.abs(expected - result) >= THRESHOLD) { 743 throw new Error("Expected: " + expected + ", found: " + result); 744 } 745 } 746 } 747