| Index: src/compiler/arm64/instruction-selector-arm64.cc
 | 
| diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
 | 
| index b32ccf58cd22a17216a65db35fcf24c21ae26474..4be5c8371e70b4416741daae11c3535b2c03c52b 100644
 | 
| --- a/src/compiler/arm64/instruction-selector-arm64.cc
 | 
| +++ b/src/compiler/arm64/instruction-selector-arm64.cc
 | 
| @@ -841,6 +841,34 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  if (m.left().IsInt32Add() && m.right().HasValue() &&
 | 
| +      CanCover(node, node->InputAt(0))) {
 | 
| +    Node* add_node = m.left().node();
 | 
| +    Int32BinopMatcher madd_node(add_node);
 | 
| +    if (madd_node.left().IsInt32MulHigh() &&
 | 
| +        CanCover(add_node, madd_node.left().node())) {
 | 
| +      // Combine the shift that would be generated by Int32MulHigh with the add
 | 
| +      // on the left of this Sar operation. We do it here, as the result of the
 | 
| +      // add potentially has 33 bits, so we have to ensure the result is
 | 
| +      // truncated by being the input to this 32-bit Sar operation.
 | 
| +      Arm64OperandGenerator g(this);
 | 
| +      Node* mul_node = madd_node.left().node();
 | 
| +
 | 
| +      InstructionOperand const smull_operand = g.TempRegister();
 | 
| +      Emit(kArm64Smull, smull_operand, g.UseRegister(mul_node->InputAt(0)),
 | 
| +           g.UseRegister(mul_node->InputAt(1)));
 | 
| +
 | 
| +      InstructionOperand const add_operand = g.TempRegister();
 | 
| +      Emit(kArm64Add | AddressingModeField::encode(kMode_Operand2_R_ASR_I),
 | 
| +           add_operand, g.UseRegister(add_node->InputAt(1)), smull_operand,
 | 
| +           g.TempImmediate(32));
 | 
| +
 | 
| +      Emit(kArm64Asr32, g.DefineAsRegister(node), add_operand,
 | 
| +           g.UseImmediate(node->InputAt(1)));
 | 
| +      return;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|    VisitRRO(this, kArm64Asr32, node, kShift32Imm);
 | 
|  }
 | 
|  
 | 
| 
 |