| Index: src/arm64/lithium-arm64.cc
|
| diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
|
| index 7bb66dbd7018afcd7bf6a3579565cc60a7597b34..90ee0054f043f3c09a36db6c6839c6cffbd9e024 100644
|
| --- a/src/arm64/lithium-arm64.cc
|
| +++ b/src/arm64/lithium-arm64.cc
|
| @@ -2203,8 +2203,7 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
|
| return DoArithmeticT(op, instr);
|
| }
|
|
|
| - DCHECK(instr->representation().IsInteger32() ||
|
| - instr->representation().IsSmi());
|
| + DCHECK(instr->representation().IsSmiOrInteger32());
|
| DCHECK(instr->left()->representation().Equals(instr->representation()));
|
| DCHECK(instr->right()->representation().Equals(instr->representation()));
|
|
|
| @@ -2215,42 +2214,30 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
|
| LOperand* left = instr->representation().IsSmi()
|
| ? UseRegister(instr->left())
|
| : UseRegisterAtStart(instr->left());
|
| + LOperand* right = UseRegisterOrConstantAtStart(instr->right());
|
|
|
| - HValue* right_value = instr->right();
|
| - LOperand* right = NULL;
|
| - LOperand* temp = NULL;
|
| - int constant_value = 0;
|
| - if (right_value->IsConstant()) {
|
| - right = UseConstant(right_value);
|
| - constant_value = JSShiftAmountFromHConstant(right_value);
|
| - } else {
|
| - right = UseRegisterAtStart(right_value);
|
| - if (op == Token::ROR) {
|
| - temp = TempRegister();
|
| - }
|
| - }
|
| -
|
| - // Shift operations can only deoptimize if we do a logical shift by 0 and the
|
| - // result cannot be truncated to int32.
|
| - bool does_deopt = false;
|
| - if ((op == Token::SHR) && (constant_value == 0)) {
|
| + // The only shift that can deoptimize is `left >>> 0`, where left is negative.
|
| + // In these cases, the result is a uint32 that is too large for an int32.
|
| + bool right_can_be_zero = !instr->right()->IsConstant() ||
|
| + (JSShiftAmountFromHConstant(instr->right()) == 0);
|
| + bool can_deopt = false;
|
| + if ((op == Token::SHR) && right_can_be_zero) {
|
| if (FLAG_opt_safe_uint32_operations) {
|
| - does_deopt = !instr->CheckFlag(HInstruction::kUint32);
|
| + can_deopt = !instr->CheckFlag(HInstruction::kUint32);
|
| } else {
|
| - does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
|
| + can_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
|
| }
|
| }
|
|
|
| LInstruction* result;
|
| if (instr->representation().IsInteger32()) {
|
| - result = DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt));
|
| + result = DefineAsRegister(new (zone()) LShiftI(op, left, right, can_deopt));
|
| } else {
|
| DCHECK(instr->representation().IsSmi());
|
| - result = DefineAsRegister(
|
| - new(zone()) LShiftS(op, left, right, temp, does_deopt));
|
| + result = DefineAsRegister(new (zone()) LShiftS(op, left, right, can_deopt));
|
| }
|
|
|
| - return does_deopt ? AssignEnvironment(result) : result;
|
| + return can_deopt ? AssignEnvironment(result) : result;
|
| }
|
|
|
|
|
|
|