Fix bug in BCE remainder handling.
Rationale:
(1) code was looking up index in wrong block
(2) code was merging monotonic (rather than the other way around).
This
(a) caused DCHECK failure, reproduced and fixed with new test
(b) missed cases, reproduced and fixed with new test
Bug: 65551926
Test: test-art-host
Change-Id: I9991635bf8b04925b6929b73abf659717639a78b
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 2f96cfa..6b832da 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -1143,9 +1143,9 @@
ValueBound(nullptr, 1 - right_const),
ValueBound(nullptr, right_const - 1));
- ValueRange* left_range = LookupValueRange(left, left->GetBlock());
+ ValueRange* left_range = LookupValueRange(left, instruction->GetBlock());
if (left_range != nullptr) {
- right_range = left_range->Narrow(right_range);
+ right_range = right_range->Narrow(left_range);
}
AssignRange(instruction->GetBlock(), instruction, right_range);
return;
@@ -1172,9 +1172,9 @@
GetGraph()->GetArena(),
lower,
upper);
- ValueRange* left_range = LookupValueRange(left, left->GetBlock());
+ ValueRange* left_range = LookupValueRange(left, instruction->GetBlock());
if (left_range != nullptr) {
- right_range = left_range->Narrow(right_range);
+ right_range = right_range->Narrow(left_range);
}
AssignRange(instruction->GetBlock(), instruction, right_range);
return;
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index f466eea..60e653c 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -962,6 +962,25 @@
}
}
+ /// CHECK-START: void Main.modArrayIndex5(int[], int) BCE (before)
+ /// CHECK-DAG: BoundsCheck
+ /// CHECK-DAG: ArraySet
+ //
+ /// CHECK-START: void Main.modArrayIndex5(int[], int) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK-DAG: ArraySet
+ public static void modArrayIndex5(int[] x, int i) {
+ while (true) {
+ int xi = i % x.length;
+ if (xi < 0)
+ break;
+ if (i >= x.length)
+ break;
+ x[xi] = i;
+ i++;
+ }
+ }
+
/// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
/// CHECK: BoundsCheck
/// CHECK: ArrayGet
@@ -1690,6 +1709,21 @@
sieve(20);
+ int[] x1 = new int[10];
+ int[] x2 = new int[10];
+ int[] x3 = new int[10];
+ modArrayIndex5(x1, -1);
+ modArrayIndex5(x2, 0);
+ modArrayIndex5(x3, 5);
+ for (int i = 0; i < 10; i++) {
+ int e1 = 0;
+ int e2 = i;
+ int e3 = i < 5 ? 0 : i;
+ if (x1[i] != e1 || x2[i] != e2 || x3[i] != e3) {
+ System.out.println("modarray failed!");
+ }
+ }
+
int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
bubbleSort(array);
for (int i = 0; i < 8; i++) {