Index: src/arm64/lithium-codegen-arm64.cc |
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc |
index 5b0b018ab9f148a2cdb77768e42d2779525249ef..d61151eec3824aac9b725a31aef1c8cc61548d93 100644 |
--- a/src/arm64/lithium-codegen-arm64.cc |
+++ b/src/arm64/lithium-codegen-arm64.cc |
@@ -4253,7 +4253,6 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
Register left = |
is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; |
int32_t right = ToInteger32(instr->right()); |
- ASSERT((right > -kMaxInt) || (right < kMaxInt)); |
bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
bool bailout_on_minus_zero = |
@@ -4297,40 +4296,20 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
} |
break; |
+ // All other cases cannot detect overflow, because it would probably be no |
+ // faster than using the smull method in LMulI. |
+ // TODO(jbramley): Investigate this, and add overflow support if it would |
+ // be useful. |
default: |
- // Multiplication by constant powers of two (and some related values) |
- // can be done efficiently with shifted operands. |
- int32_t right_abs = Abs(right); |
- |
- if (IsPowerOf2(right_abs)) { |
- int right_log2 = WhichPowerOf2(right_abs); |
- |
- if (can_overflow) { |
- Register scratch = result; |
- ASSERT(!AreAliased(scratch, left)); |
- __ Cls(scratch, left); |
- __ Cmp(scratch, right_log2); |
- DeoptimizeIf(lt, instr->environment()); |
- } |
- |
- if (right >= 0) { |
- // result = left << log2(right) |
- __ Lsl(result, left, right_log2); |
- } else { |
- // result = -left << log2(-right) |
- __ Neg(result, Operand(left, LSL, right_log2)); |
- } |
- return; |
- } |
- |
- |
- // For the following cases, we could perform a conservative overflow check |
- // with CLS as above. However the few cycles saved are likely not worth |
- // the risk of deoptimizing more often than required. |
ASSERT(!can_overflow); |
+ // Multiplication by constant powers of two (and some related values) |
+ // can be done efficiently with shifted operands. |
if (right >= 0) { |
- if (IsPowerOf2(right - 1)) { |
+ if (IsPowerOf2(right)) { |
+ // result = left << log2(right) |
+ __ Lsl(result, left, WhichPowerOf2(right)); |
+ } else if (IsPowerOf2(right - 1)) { |
// result = left + left << log2(right - 1) |
__ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); |
} else if (IsPowerOf2(right + 1)) { |
@@ -4341,7 +4320,10 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
UNREACHABLE(); |
} |
} else { |
- if (IsPowerOf2(-right + 1)) { |
+ if (IsPowerOf2(-right)) { |
+ // result = -left << log2(-right) |
+ __ Neg(result, Operand(left, LSL, WhichPowerOf2(-right))); |
+ } else if (IsPowerOf2(-right + 1)) { |
// result = left - left << log2(-right + 1) |
__ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); |
} else if (IsPowerOf2(-right - 1)) { |
@@ -4352,6 +4334,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
UNREACHABLE(); |
} |
} |
+ break; |
} |
} |