1 /* 2 * Copyright (C) 2020 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 public class Main { expectEquals(long expected, long result)18 private static void expectEquals(long expected, long result) { 19 if (expected != result) { 20 throw new Error("Expected: " + expected + ", found: " + result); 21 } 22 } 23 remInt()24 private static void remInt() { 25 expectEquals(1L << 32, $noinline$IntRemBy3(3)); 26 expectEquals((3L << 32) | 6, $noinline$IntRemBy7(27)); 27 expectEquals((1L << 32) | 1, $noinline$IntRemBy12(13)); 28 expectEquals((1L << 32) | 1, $noinline$IntRemBy12A(13)); 29 } 30 31 // A test case to check: 32 // BCE detects the optimized 'v % 3' and eliminates bounds checks. 33 // 34 /// CHECK-START: long Main.$noinline$IntRemBy3(int) BCE (before) 35 /// CHECK: Div 36 /// CHECK-NEXT: Shl 37 /// CHECK-NEXT: Add 38 /// CHECK-NEXT: Sub 39 /// CHECK: BoundsCheck 40 /// CHECK-NEXT: ArrayGet 41 // 42 /// CHECK-START: long Main.$noinline$IntRemBy3(int) BCE (after) 43 /// CHECK: Div 44 /// CHECK-NEXT: Shl 45 /// CHECK-NEXT: Add 46 /// CHECK-NEXT: Sub 47 /// CHECK-NOT: BoundsCheck 48 /// CHECK: ArrayGet $noinline$IntRemBy3(int v)49 private static long $noinline$IntRemBy3(int v) { 50 int[] values = {0, 1, 2}; 51 if (v > 0) { 52 int q = v / 3; 53 int r = v % 3; 54 return ((long)q << 32) | values[r]; 55 } else { 56 return -1; 57 } 58 } 59 60 // A test case to check: 61 // BCE detects the optimized 'v % 7' and eliminates bounds checks. 62 // 63 /// CHECK-START: long Main.$noinline$IntRemBy7(int) BCE (before) 64 /// CHECK: Div 65 /// CHECK-NEXT: Shl 66 /// CHECK-NEXT: Sub 67 /// CHECK-NEXT: Sub 68 /// CHECK: BoundsCheck 69 /// CHECK-NEXT: ArrayGet 70 // 71 /// CHECK-START: long Main.$noinline$IntRemBy7(int) BCE (after) 72 /// CHECK: Div 73 /// CHECK-NEXT: Shl 74 /// CHECK-NEXT: Sub 75 /// CHECK-NEXT: Sub 76 /// CHECK-NOT: BoundsCheck 77 /// CHECK: ArrayGet $noinline$IntRemBy7(int v)78 private static long $noinline$IntRemBy7(int v) { 79 int[] values = {0, 1, 2, 3, 4, 5, 6}; 80 if (v > 0) { 81 int q = v / 7; 82 int r = v % 7; 83 return ((long)q << 32) | values[r]; 84 } else { 85 return -1; 86 } 87 } 88 89 // A test case to check: 90 // BCE detects the optimized 'v % 12' and eliminates bounds checks. 91 // 92 /// CHECK-START: long Main.$noinline$IntRemBy12(int) BCE (before) 93 /// CHECK: Div 94 /// CHECK-NEXT: Mul 95 /// CHECK-NEXT: Sub 96 /// CHECK: BoundsCheck 97 /// CHECK-NEXT: ArrayGet 98 // 99 /// CHECK-START: long Main.$noinline$IntRemBy12(int) BCE (after) 100 /// CHECK: Div 101 /// CHECK-NEXT: Mul 102 /// CHECK-NEXT: Sub 103 /// CHECK-NOT: BoundsCheck 104 /// CHECK: ArrayGet $noinline$IntRemBy12(int v)105 private static long $noinline$IntRemBy12(int v) { 106 int[] values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 107 if (v > 0) { 108 int q = v / 12; 109 int r = v % 12; 110 return ((long)q << 32) | values[r]; 111 } else { 112 return -1; 113 } 114 } 115 116 // A test case to check: 117 // BCE detects the optimized 'v % 12' and eliminates bounds checks. 118 // 119 /// CHECK-START: long Main.$noinline$IntRemBy12A(int) BCE (before) 120 /// CHECK: Div 121 /// CHECK-NEXT: Mul 122 /// CHECK-NEXT: Sub 123 /// CHECK: BoundsCheck 124 /// CHECK-NEXT: ArrayGet 125 // 126 /// CHECK-START: long Main.$noinline$IntRemBy12A(int) BCE (after) 127 /// CHECK: Div 128 /// CHECK-NEXT: Mul 129 /// CHECK-NEXT: Sub 130 /// CHECK-NOT: BoundsCheck 131 /// CHECK: ArrayGet $noinline$IntRemBy12A(int v)132 private static long $noinline$IntRemBy12A(int v) { 133 int[] values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 134 if (v > 0) { 135 int q = v / 12; 136 int t = q * 12; 137 int r = v - t; 138 return ((long)q << 32) | values[r]; 139 } else { 140 return -1; 141 } 142 } 143 144 // A test case to check: 145 // BCE detects the optimized 'v % Integer.MAX_VALUE' and eliminates bounds checks. 146 // 147 /// CHECK-START: int Main.$noinline$IntRemByMaxInt(int) BCE (before) 148 /// CHECK: Div 149 /// CHECK-NEXT: Shl 150 /// CHECK-NEXT: Sub 151 /// CHECK-NEXT: Sub 152 /// CHECK: BoundsCheck 153 /// CHECK-NEXT: ArrayGet 154 // 155 /// CHECK-START: int Main.$noinline$IntRemByMaxInt(int) BCE (after) 156 /// CHECK: Div 157 /// CHECK-NEXT: Shl 158 /// CHECK-NEXT: Sub 159 /// CHECK-NEXT: Sub 160 /// CHECK-NOT: BoundsCheck 161 /// CHECK: ArrayGet $noinline$IntRemByMaxInt(int v)162 private static int $noinline$IntRemByMaxInt(int v) { 163 int[] values = new int[Integer.MAX_VALUE]; 164 if (v > 0) { 165 int q = v / Integer.MAX_VALUE; 166 int r = v % Integer.MAX_VALUE; 167 return values[v % Integer.MAX_VALUE] + q; 168 } else { 169 return -1; 170 } 171 } 172 173 // A test case to check: 174 // BCE detects the optimized 'v % Integer.MIN_VALUE' and eliminates bounds checks. 175 // 176 /// CHECK-START: int Main.$noinline$IntRemByMinInt(int) BCE (before) 177 /// CHECK: Div 178 /// CHECK-NEXT: Mul 179 /// CHECK-NEXT: Sub 180 /// CHECK: BoundsCheck 181 /// CHECK-NEXT: ArrayGet 182 // 183 /// CHECK-START: int Main.$noinline$IntRemByMinInt(int) BCE (after) 184 /// CHECK: Div 185 /// CHECK-NEXT: Mul 186 /// CHECK-NEXT: Sub 187 /// CHECK-NOT: BoundsCheck 188 /// CHECK: ArrayGet $noinline$IntRemByMinInt(int v)189 private static int $noinline$IntRemByMinInt(int v) { 190 int[] values = new int[Integer.MAX_VALUE]; 191 if (v > 0) { 192 int q = v / Integer.MIN_VALUE; 193 int t = q * Integer.MIN_VALUE; 194 int r = v - t; 195 return values[r - 1]; 196 } else { 197 return -1; 198 } 199 } 200 201 // A test case to check: 202 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 203 // 204 /// CHECK-START: int Main.$noinline$NoRem01(int, int) BCE (before) 205 /// CHECK: Mul 206 /// CHECK-NEXT: Sub 207 /// CHECK-NEXT: BoundsCheck 208 /// CHECK-NEXT: ArrayGet 209 // 210 /// CHECK-START: int Main.$noinline$NoRem01(int, int) BCE (after) 211 /// CHECK: Mul 212 /// CHECK-NEXT: Sub 213 /// CHECK-NEXT: BoundsCheck 214 /// CHECK-NEXT: ArrayGet $noinline$NoRem01(int v, int s)215 private static int $noinline$NoRem01(int v, int s) { 216 int[] values = {0, 1, 2}; 217 if (v > 0) { 218 int a = v * 10; 219 int b = s - a; 220 return values[b]; 221 } else { 222 return -1; 223 } 224 } 225 226 // A test case to check: 227 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 228 // 229 /// CHECK-START: int Main.$noinline$NoRem02(int, int) BCE (before) 230 /// CHECK: Div 231 /// CHECK-NEXT: Mul 232 /// CHECK-NEXT: Sub 233 /// CHECK-NEXT: BoundsCheck 234 /// CHECK-NEXT: ArrayGet 235 // 236 /// CHECK-START: int Main.$noinline$NoRem02(int, int) BCE (after) 237 /// CHECK: Div 238 /// CHECK-NEXT: Mul 239 /// CHECK-NEXT: Sub 240 /// CHECK-NEXT: BoundsCheck 241 /// CHECK-NEXT: ArrayGet $noinline$NoRem02(int v, int s)242 private static int $noinline$NoRem02(int v, int s) { 243 int[] values = {0, 1, 2}; 244 if (v > 0) { 245 int q = v / 10; 246 int a = q * s; 247 int b = v - a; 248 return values[b]; 249 } else { 250 return -1; 251 } 252 } 253 254 // A test case to check: 255 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 256 // 257 /// CHECK-START: int Main.$noinline$NoRem03(int, int) BCE (before) 258 /// CHECK: Div 259 /// CHECK-NEXT: Add 260 /// CHECK-NEXT: Sub 261 /// CHECK-NEXT: BoundsCheck 262 /// CHECK-NEXT: ArrayGet 263 // 264 /// CHECK-START: int Main.$noinline$NoRem03(int, int) BCE (after) 265 /// CHECK: Div 266 /// CHECK-NEXT: Add 267 /// CHECK-NEXT: Sub 268 /// CHECK-NEXT: BoundsCheck 269 /// CHECK-NEXT: ArrayGet $noinline$NoRem03(int v, int s)270 private static int $noinline$NoRem03(int v, int s) { 271 int[] values = {0, 1, 2}; 272 if (v > 0) { 273 int q = v / 10; 274 int a = q + s; 275 int b = v - a; 276 return values[b]; 277 } else { 278 return -1; 279 } 280 } 281 282 // A test case to check: 283 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 284 // 285 /// CHECK-START: int Main.$noinline$NoRem04(int, int) BCE (before) 286 /// CHECK: Div 287 /// CHECK-NEXT: Shl 288 /// CHECK-NEXT: Add 289 /// CHECK-NEXT: Sub 290 /// CHECK-NEXT: BoundsCheck 291 /// CHECK-NEXT: ArrayGet 292 // 293 /// CHECK-START: int Main.$noinline$NoRem04(int, int) BCE (after) 294 /// CHECK: Div 295 /// CHECK-NEXT: Shl 296 /// CHECK-NEXT: Add 297 /// CHECK-NEXT: Sub 298 /// CHECK-NEXT: BoundsCheck 299 /// CHECK-NEXT: ArrayGet $noinline$NoRem04(int v, int s)300 private static int $noinline$NoRem04(int v, int s) { 301 int[] values = {0, 1, 2}; 302 if (v > 0) { 303 int q = v / 10; 304 int t = q << s; 305 int a = q + t; 306 int b = v - a; 307 return values[b]; 308 } else { 309 return -1; 310 } 311 } 312 313 // A test case to check: 314 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 315 // 316 /// CHECK-START: int Main.$noinline$NoRem05(int, int) BCE (before) 317 /// CHECK: Div 318 /// CHECK-NEXT: Shl 319 /// CHECK-NEXT: Add 320 /// CHECK-NEXT: Sub 321 /// CHECK-NEXT: BoundsCheck 322 /// CHECK-NEXT: ArrayGet 323 // 324 /// CHECK-START: int Main.$noinline$NoRem05(int, int) BCE (after) 325 /// CHECK: Div 326 /// CHECK-NEXT: Shl 327 /// CHECK-NEXT: Add 328 /// CHECK-NEXT: Sub 329 /// CHECK-NEXT: BoundsCheck 330 /// CHECK-NEXT: ArrayGet $noinline$NoRem05(int v, int s)331 private static int $noinline$NoRem05(int v, int s) { 332 int[] values = {0, 1, 2}; 333 if (v > 0) { 334 int q = v / 10; 335 int t = s << 1; 336 int a = q + t; 337 int b = v - a; 338 return values[b]; 339 } else { 340 return -1; 341 } 342 } 343 344 // A test case to check: 345 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 346 // 347 /// CHECK-START: int Main.$noinline$NoRem06(int, int) BCE (before) 348 /// CHECK: Div 349 /// CHECK-NEXT: Mul 350 /// CHECK-NEXT: Sub 351 /// CHECK-NEXT: BoundsCheck 352 /// CHECK-NEXT: ArrayGet 353 // 354 /// CHECK-START: int Main.$noinline$NoRem06(int, int) BCE (after) 355 /// CHECK: Div 356 /// CHECK-NEXT: Mul 357 /// CHECK-NEXT: Sub 358 /// CHECK-NEXT: BoundsCheck 359 /// CHECK-NEXT: ArrayGet $noinline$NoRem06(int v, int s)360 private static int $noinline$NoRem06(int v, int s) { 361 int[] values = {0, 1, 2}; 362 if (v > 0) { 363 int q = v / 10; 364 int a = q * 11; 365 int b = v - a; 366 return values[b]; 367 } else { 368 return -1; 369 } 370 } 371 372 // A test case to check: 373 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 374 // 375 /// CHECK-START: int Main.$noinline$NoRem07(int, int) BCE (before) 376 /// CHECK: Div 377 /// CHECK-NEXT: Shl 378 /// CHECK-NEXT: Add 379 /// CHECK-NEXT: Sub 380 /// CHECK-NEXT: BoundsCheck 381 /// CHECK-NEXT: ArrayGet 382 // 383 /// CHECK-START: int Main.$noinline$NoRem07(int, int) BCE (after) 384 /// CHECK: Div 385 /// CHECK-NEXT: Shl 386 /// CHECK-NEXT: Add 387 /// CHECK-NEXT: Sub 388 /// CHECK-NEXT: BoundsCheck 389 /// CHECK-NEXT: ArrayGet $noinline$NoRem07(int v, int s)390 private static int $noinline$NoRem07(int v, int s) { 391 int[] values = {0, 1, 2}; 392 if (v > 0) { 393 int q = v / 10; 394 int t = q << 1; 395 int a = s + t; 396 int b = v - a; 397 return values[b]; 398 } else { 399 return -1; 400 } 401 } 402 403 // A test case to check: 404 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 405 // 406 /// CHECK-START: int Main.$noinline$NoRem08(int, int) BCE (before) 407 /// CHECK: Div 408 /// CHECK-NEXT: Shl 409 /// CHECK-NEXT: Add 410 /// CHECK-NEXT: Sub 411 /// CHECK-NEXT: BoundsCheck 412 /// CHECK-NEXT: ArrayGet 413 // 414 /// CHECK-START: int Main.$noinline$NoRem08(int, int) BCE (after) 415 /// CHECK: Div 416 /// CHECK-NEXT: Shl 417 /// CHECK-NEXT: Add 418 /// CHECK-NEXT: Sub 419 /// CHECK-NEXT: BoundsCheck 420 /// CHECK-NEXT: ArrayGet $noinline$NoRem08(int v, int s)421 private static int $noinline$NoRem08(int v, int s) { 422 int[] values = {0, 1, 2}; 423 if (v > 0) { 424 int q = v / 10; 425 int t = q << 31; 426 int a = q + t; 427 int b = v - a; 428 return values[b]; 429 } else { 430 return -1; 431 } 432 } 433 434 // A test case to check: 435 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 436 // 437 /// CHECK-START: int Main.$noinline$NoRem09(int, int) BCE (before) 438 /// CHECK: Div 439 /// CHECK-NEXT: Shl 440 /// CHECK-NEXT: Add 441 /// CHECK-NEXT: Sub 442 /// CHECK-NEXT: BoundsCheck 443 /// CHECK-NEXT: ArrayGet 444 // 445 /// CHECK-START: int Main.$noinline$NoRem09(int, int) BCE (after) 446 /// CHECK: Div 447 /// CHECK-NEXT: Shl 448 /// CHECK-NEXT: Add 449 /// CHECK-NEXT: Sub 450 /// CHECK-NEXT: BoundsCheck 451 /// CHECK-NEXT: ArrayGet $noinline$NoRem09(int v, int s)452 private static int $noinline$NoRem09(int v, int s) { 453 int[] values = {0, 1, 2}; 454 if (v > 0) { 455 int q = v / 10; 456 int t = q << 1; 457 int a = q + t; 458 int b = v - a; 459 return values[b]; 460 } else { 461 return -1; 462 } 463 } 464 465 // A test case to check: 466 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 467 // 468 /// CHECK-START: int Main.$noinline$NoRem10(int, int) BCE (before) 469 /// CHECK: Div 470 /// CHECK-NEXT: Shl 471 /// CHECK-NEXT: Sub 472 /// CHECK-NEXT: Sub 473 /// CHECK-NEXT: BoundsCheck 474 /// CHECK-NEXT: ArrayGet 475 // 476 /// CHECK-START: int Main.$noinline$NoRem10(int, int) BCE (after) 477 /// CHECK: Div 478 /// CHECK-NEXT: Shl 479 /// CHECK-NEXT: Sub 480 /// CHECK-NEXT: Sub 481 /// CHECK-NEXT: BoundsCheck 482 /// CHECK-NEXT: ArrayGet $noinline$NoRem10(int v, int s)483 private static int $noinline$NoRem10(int v, int s) { 484 int[] values = {0, 1, 2}; 485 if (v > 0) { 486 int q = v / 10; 487 int t = q << s; 488 int a = t - q; 489 int b = v - a; 490 return values[b]; 491 } else { 492 return -1; 493 } 494 } 495 496 // A test case to check: 497 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 498 // 499 /// CHECK-START: int Main.$noinline$NoRem11(int, int) BCE (before) 500 /// CHECK: Div 501 /// CHECK-NEXT: Shl 502 /// CHECK-NEXT: Sub 503 /// CHECK-NEXT: Sub 504 /// CHECK-NEXT: BoundsCheck 505 /// CHECK-NEXT: ArrayGet 506 // 507 /// CHECK-START: int Main.$noinline$NoRem11(int, int) BCE (after) 508 /// CHECK: Div 509 /// CHECK-NEXT: Shl 510 /// CHECK-NEXT: Sub 511 /// CHECK-NEXT: Sub 512 /// CHECK-NEXT: BoundsCheck 513 /// CHECK-NEXT: ArrayGet $noinline$NoRem11(int v, int s)514 private static int $noinline$NoRem11(int v, int s) { 515 int[] values = {0, 1, 2}; 516 if (v > 0) { 517 int q = v / 10; 518 int t = s << 1; 519 int a = t - q; 520 int b = v - a; 521 return values[b]; 522 } else { 523 return -1; 524 } 525 } 526 527 // A test case to check: 528 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 529 // 530 /// CHECK-START: int Main.$noinline$NoRem12(int, int) BCE (before) 531 /// CHECK: Div 532 /// CHECK-NEXT: Shl 533 /// CHECK-NEXT: Sub 534 /// CHECK-NEXT: Sub 535 /// CHECK-NEXT: BoundsCheck 536 /// CHECK-NEXT: ArrayGet 537 // 538 /// CHECK-START: int Main.$noinline$NoRem12(int, int) BCE (after) 539 /// CHECK: Div 540 /// CHECK-NEXT: Shl 541 /// CHECK-NEXT: Sub 542 /// CHECK-NEXT: Sub 543 /// CHECK-NEXT: BoundsCheck 544 /// CHECK-NEXT: ArrayGet $noinline$NoRem12(int v, int s)545 private static int $noinline$NoRem12(int v, int s) { 546 int[] values = {0, 1, 2}; 547 if (v > 0) { 548 int q = v / 10; 549 int t = q << 1; 550 int a = t - s; 551 int b = v - a; 552 return values[b]; 553 } else { 554 return -1; 555 } 556 } 557 558 // A test case to check: 559 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 560 // 561 /// CHECK-START: int Main.$noinline$NoRem13(int, int) BCE (before) 562 /// CHECK: Div 563 /// CHECK-NEXT: Shl 564 /// CHECK-NEXT: Sub 565 /// CHECK-NEXT: Sub 566 /// CHECK-NEXT: BoundsCheck 567 /// CHECK-NEXT: ArrayGet 568 // 569 /// CHECK-START: int Main.$noinline$NoRem13(int, int) BCE (after) 570 /// CHECK: Div 571 /// CHECK-NEXT: Shl 572 /// CHECK-NEXT: Sub 573 /// CHECK-NEXT: Sub 574 /// CHECK-NEXT: BoundsCheck 575 /// CHECK-NEXT: ArrayGet $noinline$NoRem13(int v, int s)576 private static int $noinline$NoRem13(int v, int s) { 577 int[] values = {0, 1, 2}; 578 if (v > 0) { 579 int q = v / 10; 580 int t = q << 31; 581 int a = t - q; 582 int b = v - a; 583 return values[b]; 584 } else { 585 return -1; 586 } 587 } 588 589 // A test case to check: 590 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 591 // 592 /// CHECK-START: int Main.$noinline$NoRem14(int, int) BCE (before) 593 /// CHECK: Div 594 /// CHECK-NEXT: Sub 595 /// CHECK-NEXT: BoundsCheck 596 /// CHECK-NEXT: ArrayGet 597 // 598 /// CHECK-START: int Main.$noinline$NoRem14(int, int) BCE (after) 599 /// CHECK: Div 600 /// CHECK-NEXT: Sub 601 /// CHECK-NEXT: BoundsCheck 602 /// CHECK-NEXT: ArrayGet $noinline$NoRem14(int v, int s)603 private static int $noinline$NoRem14(int v, int s) { 604 int[] values = {0, 1, 2}; 605 if (v > 0) { 606 int a = v / 10; 607 int b = s - a; 608 return values[b]; 609 } else { 610 return -1; 611 } 612 } 613 614 // A test case to check: 615 // Bounds checks are not eliminated if the checked value is not an optimized HDiv+HRem. 616 // 617 /// CHECK-START: int Main.$noinline$NoRem15(int, int) BCE (before) 618 /// CHECK: Div 619 /// CHECK-NEXT: Mul 620 /// CHECK-NEXT: Sub 621 /// CHECK-NEXT: BoundsCheck 622 /// CHECK-NEXT: ArrayGet 623 // 624 /// CHECK-START: int Main.$noinline$NoRem15(int, int) BCE (after) 625 /// CHECK: Div 626 /// CHECK-NEXT: Mul 627 /// CHECK-NEXT: Sub 628 /// CHECK-NEXT: BoundsCheck 629 /// CHECK-NEXT: ArrayGet $noinline$NoRem15(int v, int s)630 private static int $noinline$NoRem15(int v, int s) { 631 int[] values = {0, 1, 2}; 632 if (v > 0) { 633 int q = v / 10; 634 int a = q * 10; 635 int b = s - a; 636 return values[b]; 637 } else { 638 return -1; 639 } 640 } 641 642 /// CHECK-START: int Main.$noinline$noRemNonConst(int, int) BCE (after) 643 /// CHECK: BoundsCheck $noinline$noRemNonConst(int v, int s)644 private static int $noinline$noRemNonConst(int v, int s) { 645 // Regression test for compiler crash, b/169669115. 646 int[] values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 647 if (v > 0) { 648 int q = v / s; // Non-constant divisor. 649 int a = q * 10; // Constant unrelated to the divisor above. 650 int b = s - a; 651 return values[b]; 652 } else { 653 return -1; 654 } 655 } 656 main(String args[])657 public static void main(String args[]) { 658 remInt(); 659 } 660 } 661