Refined range rule for ABS(x)
Rationale;
ABS(minint) = minint prevents assuming >=0 always.
With a fail-before(sig11)/pass-after regression test.
Test: 623
Change-Id: If5fb1580b207c7cdd964f7498849d1768bb1589d
diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc
index f35aace..089340e 100644
--- a/compiler/optimizing/induction_var_range.cc
+++ b/compiler/optimizing/induction_var_range.cc
@@ -87,8 +87,10 @@
IsGEZero(instruction->InputAt(1));
case Intrinsics::kMathAbsInt:
case Intrinsics::kMathAbsLong:
- // Instruction ABS(x) is >= 0.
- return true;
+ // Instruction ABS(>=0) is >= 0.
+ // NOTE: ABS(minint) = minint prevents assuming
+ // >= 0 without looking at the argument.
+ return IsGEZero(instruction->InputAt(0));
default:
break;
}
diff --git a/test/620-checker-bce-intrinsics/src/Main.java b/test/620-checker-bce-intrinsics/src/Main.java
index afc3c65..e0b5986 100644
--- a/test/620-checker-bce-intrinsics/src/Main.java
+++ b/test/620-checker-bce-intrinsics/src/Main.java
@@ -34,15 +34,15 @@
return x;
}
- /// CHECK-START: int Main.oneArrayAbs(int[], int) BCE (before)
+ /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (before)
/// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none
//
- /// CHECK-START: int Main.oneArrayAbs(int[], int) BCE (after)
+ /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (after)
/// CHECK-NOT: BoundsCheck
/// CHECK-NOT: Deoptimize
- static int oneArrayAbs(int[] a, int lo) {
+ static int oneArrayAbs(int[] a, int[] b) {
int x = 0;
- for (int i = Math.abs(lo); i < a.length; i++) {
+ for (int i = Math.abs(b.length); i < a.length; i++) {
x += a[i];
}
return x;
@@ -221,15 +221,15 @@
int[] b = { 6, 7, 8, 9, 4, 2 };
int[] c = { 1, 2, 3 };
int[] d = { 8, 5, 3, 2 };
+ int[] e = { };
expectEquals(15, oneArray(a));
expectEquals(36, oneArray(b));
expectEquals(6, oneArray(c));
expectEquals(18, oneArray(d));
- expectEquals(5, oneArrayAbs(a, -4));
- expectEquals(15, oneArrayAbs(a, 0));
- expectEquals(5, oneArrayAbs(a, 4));
+ expectEquals(15, oneArrayAbs(a, e));
+ expectEquals(5, oneArrayAbs(a, d));
expectEquals(30, twoArrays(a, a));
expectEquals(49, twoArrays(a, b));
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index 0e85612..056ed91 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -464,6 +464,15 @@
return r;
}
+ static int absCanBeNegative(int x) {
+ int a[] = { 1, 2, 3 };
+ int y = 0;
+ for (int i = Math.abs(x); i < a.length; i++) {
+ y += a[i];
+ }
+ return y;
+ }
+
public static void main(String[] args) {
expectEquals(10, earlyExitFirst(-1));
for (int i = 0; i <= 10; i++) {
@@ -586,6 +595,24 @@
expectEquals(11, f[i]);
}
+ expectEquals(0, absCanBeNegative(-3));
+ expectEquals(3, absCanBeNegative(-2));
+ expectEquals(5, absCanBeNegative(-1));
+ expectEquals(6, absCanBeNegative(0));
+ expectEquals(5, absCanBeNegative(1));
+ expectEquals(3, absCanBeNegative(2));
+ expectEquals(0, absCanBeNegative(3));
+ expectEquals(0, absCanBeNegative(Integer.MAX_VALUE));
+ // Abs(min_int) = min_int.
+ int verify = 0;
+ try {
+ absCanBeNegative(Integer.MIN_VALUE);
+ verify = 1;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ verify = 2;
+ }
+ expectEquals(2, verify);
+
System.out.println("passed");
}