Improve bound analysis on constant range.

Rationale:
A low hanging fruit basedon the first CL
that addressed b/70688025 (when the method
is inlined, BCE did not kick in due to
missing the now constant range).

Bug: b/70688025

Test: test-art-host test-art-target
Change-Id: Ic317d5a0920e654b5158694a1dfa1ea359e0a839
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 147df1e..d893cc8 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -836,9 +836,23 @@
       ValueRange array_range(&allocator_, lower, upper);
       // Try index range obtained by dominator-based analysis.
       ValueRange* index_range = LookupValueRange(index, block);
-      if (index_range != nullptr && index_range->FitsIn(&array_range)) {
-        ReplaceInstruction(bounds_check, index);
-        return;
+      if (index_range != nullptr) {
+        if (index_range->FitsIn(&array_range)) {
+          ReplaceInstruction(bounds_check, index);
+          return;
+        } else if (index_range->IsConstantValueRange()) {
+          // If the non-constant index turns out to have a constant range,
+          // make one more attempt to get a constant in the array range.
+          ValueRange* existing_range = LookupValueRange(array_length, block);
+          if (existing_range != nullptr &&
+              existing_range->IsConstantValueRange()) {
+            ValueRange constant_array_range(&allocator_, lower, existing_range->GetLower());
+            if (index_range->FitsIn(&constant_array_range)) {
+              ReplaceInstruction(bounds_check, index);
+              return;
+            }
+          }
+        }
       }
       // Try index range obtained by induction variable analysis.
       // Disables dynamic bce if OOB is certain.
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index 3506649..4868355 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -1068,6 +1068,7 @@
   //
   /// CHECK-START: void Main.lengthAlias1(int[], int) BCE (after)
   /// CHECK-NOT:              BoundsCheck
+  /// CHECK-NOT:              Deoptimize
   public static void lengthAlias1(int[] a, int len) {
     if (len == a.length) {
       for (int i = 0; i < len; i++) {
@@ -1087,6 +1088,7 @@
   //
   /// CHECK-START: void Main.lengthAlias2(int[], int) BCE (after)
   /// CHECK-NOT:              BoundsCheck
+  /// CHECK-NOT:              Deoptimize
   public static void lengthAlias2(int[] a, int len) {
     if (len != a.length) {
       return;
@@ -1107,6 +1109,7 @@
   //
   /// CHECK-START: void Main.lengthAlias3(int[], int) BCE (after)
   /// CHECK-NOT:              BoundsCheck
+  /// CHECK-NOT:              Deoptimize
   public static void lengthAlias3(int[] a, int len) {
     if (a.length == len) {
       for (int i = 0; i < len; i++) {
@@ -1115,6 +1118,27 @@
     }
   }
 
+  /// CHECK-START: void Main.lengthAlias4(int[]) BCE (before)
+  /// CHECK-DAG: <<Arr:l\d+>> ParameterValue                loop:none
+  /// CHECK-DAG: <<Val:i\d+>> IntConstant 8                 loop:none
+  /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>]           loop:none
+  /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>]         loop:none
+  /// CHECK-DAG:              Equal [<<Len>>,<<Val>>]       loop:none
+  /// CHECK-DAG: <<Idx:i\d+>> Phi                           loop:<<Loop:B\d+>>
+  /// CHECK-DAG:              BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>>
+  //
+  /// CHECK-START: void Main.lengthAlias4(int[]) BCE (after)
+  /// CHECK-NOT:              BoundsCheck
+  /// CHECK-NOT:              Deoptimize
+  public static void lengthAlias4(int[] a) {
+    if (8 != a.length) {
+      return;
+    }
+    for (int i = 0; i < 8; i++) {
+      a[i] = 4;
+    }
+  }
+
   static int[][] mA;
 
   /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
@@ -1824,10 +1848,20 @@
         System.out.println("alias3 failed!");
       }
     }
-
-    lengthAlias1(array, /*mismatched value*/ 32);
+    lengthAlias4(array);
     for (int i = 0; i < 8; i++) {
-      if (array[i] != 3) {
+      if (array[i] != 4) {
+        System.out.println("alias4 failed!");
+      }
+    }
+
+    array = new int[10];
+    lengthAlias1(array, /*mismatched value*/ 8);
+    lengthAlias2(array, /*mismatched value*/ 8);
+    lengthAlias3(array, /*mismatched value*/ 8);
+    lengthAlias4(array);  // implicit mismatch
+    for (int i = 0; i < 10; i++) {
+      if (array[i] != 0) {
         System.out.println("mismatch failed!");
       }
     }