Quick compiler: aarch64 codegen & long_min literal

Int64 overflow during instruction selection caused incorrect
code patterns to emitted in some cases of long operations with
an immediate value of 0x8000000000000000.

The code in question was attempting to determine if the immediate
operand would fit in aarch64 immediate instruction variants.

Internal b/17630605

Change-Id: I8177021b73e51302bc1032387d83b1dd567ed6db
diff --git a/compiler/dex/quick/arm64/utility_arm64.cc b/compiler/dex/quick/arm64/utility_arm64.cc
index 5326e74..f58f830 100644
--- a/compiler/dex/quick/arm64/utility_arm64.cc
+++ b/compiler/dex/quick/arm64/utility_arm64.cc
@@ -345,7 +345,7 @@
   case Instruction::SUB_INT_2ADDR:
     // The code below is consistent with the implementation of OpRegRegImm().
     {
-      int32_t abs_value = std::abs(value);
+      uint32_t abs_value = (value == INT_MIN) ? value : std::abs(value);
       if (abs_value < 0x1000) {
         return true;
       } else if ((abs_value & UINT64_C(0xfff)) == 0 && ((abs_value >> 12) < 0x1000)) {
@@ -809,7 +809,7 @@
 LIR* Arm64Mir2Lir::OpRegRegImm64(OpKind op, RegStorage r_dest, RegStorage r_src1, int64_t value) {
   LIR* res;
   bool neg = (value < 0);
-  int64_t abs_value = (neg) ? -value : value;
+  uint64_t abs_value = (neg & !(value == LLONG_MIN)) ? -value : value;
   ArmOpcode opcode = kA64Brk1d;
   ArmOpcode alt_opcode = kA64Brk1d;
   bool is_logical = false;
@@ -942,7 +942,7 @@
   ArmOpcode neg_opcode = kA64Brk1d;
   bool shift;
   bool neg = (value < 0);
-  uint64_t abs_value = (neg) ? -value : value;
+  uint64_t abs_value = (neg & !(value == LLONG_MIN)) ? -value : value;
 
   if (LIKELY(abs_value < 0x1000)) {
     // abs_value is a 12-bit immediate.