Improved instruction + offset hunting.

Rationale:
This is generally useful for anything using this method
but in particular for deopting something like

 bs[  off] = (byte)(n >>> 24);
 bs[++off] = (byte)(n >>> 16);
 bs[++off] = (byte)(n >>>  8);
 bs[++off] = (byte)(n       );

where the base + offset is hidden in the increments.
Occurs quite often in real-life code.

Change-Id: I3fa7d285a7368a179a26e590e8eee37f3b64c25d
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index ba1b168..a7a1c0f 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -67,20 +67,28 @@
   static bool IsAddOrSubAConstant(HInstruction* instruction,
                                   /* out */ HInstruction** left_instruction,
                                   /* out */ int32_t* right_constant) {
-    if (instruction->IsAdd() || instruction->IsSub()) {
+    HInstruction* left_so_far = nullptr;
+    int32_t right_so_far = 0;
+    while (instruction->IsAdd() || instruction->IsSub()) {
       HBinaryOperation* bin_op = instruction->AsBinaryOperation();
       HInstruction* left = bin_op->GetLeft();
       HInstruction* right = bin_op->GetRight();
       if (right->IsIntConstant()) {
-        *left_instruction = left;
-        int32_t c = right->AsIntConstant()->GetValue();
-        *right_constant = instruction->IsAdd() ? c : -c;
-        return true;
+        int32_t v = right->AsIntConstant()->GetValue();
+        int32_t c = instruction->IsAdd() ? v : -v;
+        if (!WouldAddOverflowOrUnderflow(right_so_far, c)) {
+          instruction = left;
+          left_so_far = left;
+          right_so_far += c;
+          continue;
+        }
       }
+      break;
     }
-    *left_instruction = nullptr;
-    *right_constant = 0;
-    return false;
+    // Return result: either false and "null+0" or true and "instr+constant".
+    *left_instruction = left_so_far;
+    *right_constant = right_so_far;
+    return left_so_far != nullptr;
   }
 
   // Expresses any instruction as a value bound.