Index: runtime/vm/intermediate_language_arm64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_arm64.cc (revision 36182) |
+++ runtime/vm/intermediate_language_arm64.cc (working copy) |
@@ -2608,20 +2608,28 @@ |
if (locs()->in(1).IsConstant()) { |
const Object& constant = locs()->in(1).constant(); |
ASSERT(constant.IsSmi()); |
- int64_t imm = reinterpret_cast<int64_t>(constant.raw()); |
+ const int64_t imm = reinterpret_cast<int64_t>(constant.raw()); |
switch (op_kind()) { |
- case Token::kSUB: { |
- imm = -imm; // TODO(regis): What if deopt != NULL && imm == 0x80000000? |
- // Fall through. |
- } |
case Token::kADD: { |
if (deopt == NULL) { |
__ AddImmediate(result, left, imm, PP); |
} else { |
__ AddImmediateSetFlags(result, left, imm, PP); |
- __ b(deopt, VS); } |
+ __ b(deopt, VS); |
+ } |
break; |
} |
+ case Token::kSUB: { |
+ if (deopt == NULL) { |
+ __ AddImmediate(result, left, -imm, PP); |
+ } else { |
+ // Negating imm and using AddImmediateSetFlags would not detect the |
+ // overflow when imm == kMinInt64. |
+ __ SubImmediateSetFlags(result, left, imm, PP); |
+ __ b(deopt, VS); |
+ } |
+ break; |
+ } |
case Token::kMUL: { |
// Keep left value tagged and untag right value. |
const intptr_t value = Smi::Cast(constant).Value(); |