| Index: runtime/vm/flow_graph_optimizer.cc
 | 
| ===================================================================
 | 
| --- runtime/vm/flow_graph_optimizer.cc	(revision 13286)
 | 
| +++ runtime/vm/flow_graph_optimizer.cc	(working copy)
 | 
| @@ -148,7 +148,8 @@
 | 
|      if (join_entry->phis() != NULL) {
 | 
|        for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
 | 
|          PhiInstr* phi = (*join_entry->phis())[i];
 | 
| -        if ((phi != NULL) && (phi->GetPropagatedCid() == kDoubleCid)) {
 | 
| +        if (phi == NULL) continue;
 | 
| +        if (phi->GetPropagatedCid() == kDoubleCid) {
 | 
|            phi->set_representation(kUnboxedDouble);
 | 
|          }
 | 
|        }
 | 
| @@ -268,7 +269,7 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| -static bool HasOnlyTwoSmi(const ICData& ic_data) {
 | 
| +static bool HasOnlyTwoSmis(const ICData& ic_data) {
 | 
|    return (ic_data.NumberOfChecks() == 1) &&
 | 
|        ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
 | 
|  }
 | 
| @@ -474,7 +475,7 @@
 | 
|    switch (op_kind) {
 | 
|      case Token::kADD:
 | 
|      case Token::kSUB:
 | 
| -      if (HasOnlyTwoSmi(ic_data)) {
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
|          operands_type = kSmiCid;
 | 
|        } else if (HasTwoMintOrSmi(ic_data) &&
 | 
|                   FlowGraphCompiler::SupportsUnboxedMints()) {
 | 
| @@ -486,7 +487,7 @@
 | 
|        }
 | 
|        break;
 | 
|      case Token::kMUL:
 | 
| -      if (HasOnlyTwoSmi(ic_data)) {
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
|          operands_type = kSmiCid;
 | 
|        } else if (ShouldSpecializeForDouble(ic_data)) {
 | 
|          operands_type = kDoubleCid;
 | 
| @@ -502,7 +503,7 @@
 | 
|        }
 | 
|        break;
 | 
|      case Token::kMOD:
 | 
| -      if (HasOnlyTwoSmi(ic_data)) {
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
|          operands_type = kSmiCid;
 | 
|        } else {
 | 
|          return false;
 | 
| @@ -511,7 +512,7 @@
 | 
|      case Token::kBIT_AND:
 | 
|      case Token::kBIT_OR:
 | 
|      case Token::kBIT_XOR:
 | 
| -      if (HasOnlyTwoSmi(ic_data)) {
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
|          operands_type = kSmiCid;
 | 
|        } else if (HasTwoMintOrSmi(ic_data) &&
 | 
|                   FlowGraphCompiler::SupportsUnboxedMints()) {
 | 
| @@ -520,10 +521,19 @@
 | 
|          return false;
 | 
|        }
 | 
|        break;
 | 
| +    case Token::kSHR:
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
| +        operands_type = kSmiCid;
 | 
| +      } else if (HasTwoMintOrSmi(ic_data) &&
 | 
| +                 FlowGraphCompiler::SupportsUnboxedMints()) {
 | 
| +        operands_type = kMintCid;
 | 
| +      } else {
 | 
| +        return false;
 | 
| +      }
 | 
| +      break;
 | 
|      case Token::kTRUNCDIV:
 | 
| -    case Token::kSHR:
 | 
|      case Token::kSHL:
 | 
| -      if (HasOnlyTwoSmi(ic_data)) {
 | 
| +      if (HasOnlyTwoSmis(ic_data)) {
 | 
|          operands_type = kSmiCid;
 | 
|        } else {
 | 
|          return false;
 | 
| @@ -554,9 +564,15 @@
 | 
|    } else if (operands_type == kMintCid) {
 | 
|      Value* left = call->ArgumentAt(0)->value();
 | 
|      Value* right = call->ArgumentAt(1)->value();
 | 
| -    BinaryMintOpInstr* bin_op =
 | 
| -        new BinaryMintOpInstr(op_kind, left, right, call);
 | 
| -    call->ReplaceWith(bin_op, current_iterator());
 | 
| +    if (op_kind == Token::kSHR) {
 | 
| +      ShiftMintOpInstr* shift_op =
 | 
| +          new ShiftMintOpInstr(op_kind, left, right, call);
 | 
| +      call->ReplaceWith(shift_op, current_iterator());
 | 
| +    } else {
 | 
| +      BinaryMintOpInstr* bin_op =
 | 
| +          new BinaryMintOpInstr(op_kind, left, right, call);
 | 
| +      call->ReplaceWith(bin_op, current_iterator());
 | 
| +    }
 | 
|      RemovePushArguments(call);
 | 
|    } else if (op_kind == Token::kMOD) {
 | 
|      // TODO(vegorov): implement fast path code for modulo.
 | 
| @@ -1042,7 +1058,7 @@
 | 
|    if (ic_data.NumberOfChecks() != 1) return;
 | 
|    ASSERT(ic_data.HasOneTarget());
 | 
|  
 | 
| -  if (HasOnlyTwoSmi(ic_data)) {
 | 
| +  if (HasOnlyTwoSmis(ic_data)) {
 | 
|      optimizer->InsertBefore(
 | 
|          instr,
 | 
|          new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
 | 
| @@ -2983,6 +2999,13 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void ConstantPropagator::VisitShiftMintOp(
 | 
| +    ShiftMintOpInstr* instr) {
 | 
| +  // TODO(kmillikin): Handle shift operations.
 | 
| +  SetValue(instr, non_constant_);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void ConstantPropagator::VisitUnaryMintOp(
 | 
|      UnaryMintOpInstr* instr) {
 | 
|    // TODO(kmillikin): Handle unary operations.
 | 
| 
 |