| Index: src/arm/lithium-arm.cc
 | 
| diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
 | 
| index 65abecaf1879caf3a59d6b7ff2e3309aa4f7656c..ae0b874fc68c4cc1421cbbe42be9b97d743fc629 100644
 | 
| --- a/src/arm/lithium-arm.cc
 | 
| +++ b/src/arm/lithium-arm.cc
 | 
| @@ -708,9 +708,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
 | 
|  
 | 
|  LInstruction* LChunkBuilder::DoShift(Token::Value op,
 | 
|                                       HBitwiseBinaryOperation* instr) {
 | 
| -  if (instr->representation().IsSmiOrTagged()) {
 | 
| -    ASSERT(instr->left()->representation().IsSmiOrTagged());
 | 
| -    ASSERT(instr->right()->representation().IsSmiOrTagged());
 | 
| +  if (instr->representation().IsTagged()) {
 | 
| +    ASSERT(instr->left()->representation().IsTagged());
 | 
| +    ASSERT(instr->right()->representation().IsTagged());
 | 
|  
 | 
|      LOperand* left = UseFixed(instr->left(), r1);
 | 
|      LOperand* right = UseFixed(instr->right(), r0);
 | 
| @@ -718,25 +718,35 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
 | 
|      return MarkAsCall(DefineFixed(result, r0), instr);
 | 
|    }
 | 
|  
 | 
| -  ASSERT(instr->representation().IsInteger32());
 | 
| -  ASSERT(instr->left()->representation().IsInteger32());
 | 
| -  ASSERT(instr->right()->representation().IsInteger32());
 | 
| +  ASSERT(instr->representation().IsSmiOrInteger32());
 | 
| +  ASSERT(instr->left()->representation().Equals(instr->representation()));
 | 
| +  ASSERT(instr->right()->representation().Equals(instr->representation()));
 | 
|    LOperand* left = UseRegisterAtStart(instr->left());
 | 
|  
 | 
|    HValue* right_value = instr->right();
 | 
|    LOperand* right = NULL;
 | 
|    int constant_value = 0;
 | 
| +  bool does_deopt = false;
 | 
|    if (right_value->IsConstant()) {
 | 
|      HConstant* constant = HConstant::cast(right_value);
 | 
|      right = chunk_->DefineConstantOperand(constant);
 | 
|      constant_value = constant->Integer32Value() & 0x1f;
 | 
| +    // Left shifts can deoptimize if we shift by > 0 and the result cannot be
 | 
| +    // truncated to smi.
 | 
| +    if (instr->representation().IsSmi() && constant_value > 0) {
 | 
| +      for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
 | 
| +        if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
 | 
| +          does_deopt = true;
 | 
| +          break;
 | 
| +        }
 | 
| +      }
 | 
| +    }
 | 
|    } else {
 | 
|      right = UseRegisterAtStart(right_value);
 | 
|    }
 | 
|  
 | 
|    // 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) {
 | 
|      if (FLAG_opt_safe_uint32_operations) {
 | 
|        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
 | 
| 
 |