| Index: src/arm64/lithium-arm64.cc
|
| diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
|
| index c6f547f6284db0dcccc091f52f21b02f3f9c8688..3d3ae97b0caab0f3c79e9d030a0737502b137a18 100644
|
| --- a/src/arm64/lithium-arm64.cc
|
| +++ b/src/arm64/lithium-arm64.cc
|
| @@ -1891,29 +1891,36 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| HValue* least_const = instr->BetterLeftOperand();
|
| HValue* most_const = instr->BetterRightOperand();
|
|
|
| - LOperand* left = UseRegisterAtStart(least_const);
|
| + LOperand* left;
|
|
|
| // LMulConstI can handle a subset of constants:
|
| // With support for overflow detection:
|
| // -1, 0, 1, 2
|
| - // Without support for overflow detection:
|
| // 2^n, -(2^n)
|
| + // Without support for overflow detection:
|
| // 2^n + 1, -(2^n - 1)
|
| if (most_const->IsConstant()) {
|
| int32_t constant = HConstant::cast(most_const)->Integer32Value();
|
| - int32_t constant_abs = (constant >= 0) ? constant : -constant;
|
| -
|
| - if (((constant >= -1) && (constant <= 2)) ||
|
| - (!can_overflow && (IsPowerOf2(constant_abs) ||
|
| - IsPowerOf2(constant_abs + 1) ||
|
| - IsPowerOf2(constant_abs - 1)))) {
|
| + bool small_constant = (constant >= -1) && (constant <= 2);
|
| + bool end_range_constant = (constant <= -kMaxInt) || (constant == kMaxInt);
|
| + int32_t constant_abs = Abs(constant);
|
| +
|
| + if (!end_range_constant &&
|
| + (small_constant ||
|
| + (IsPowerOf2(constant_abs)) ||
|
| + (!can_overflow && (IsPowerOf2(constant_abs + 1) ||
|
| + IsPowerOf2(constant_abs - 1))))) {
|
| LConstantOperand* right = UseConstant(most_const);
|
| + bool need_register = IsPowerOf2(constant_abs) && !small_constant;
|
| + left = need_register ? UseRegister(least_const)
|
| + : UseRegisterAtStart(least_const);
|
| LMulConstIS* mul = new(zone()) LMulConstIS(left, right);
|
| if (needs_environment) AssignEnvironment(mul);
|
| return DefineAsRegister(mul);
|
| }
|
| }
|
|
|
| + left = UseRegisterAtStart(least_const);
|
| // LMulI/S can handle all cases, but it requires that a register is
|
| // allocated for the second operand.
|
| LInstruction* result;
|
|
|