| Index: src/compiler/instruction-selector.cc | 
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc | 
| index e8a52a61e12213577b48711ba768ad36ac117252..c170a01d4a2bebbfe51e246254c2d86600c96ce2 100644 | 
| --- a/src/compiler/instruction-selector.cc | 
| +++ b/src/compiler/instruction-selector.cc | 
| @@ -4,6 +4,8 @@ | 
|  | 
| #include "src/compiler/instruction-selector.h" | 
|  | 
| +#include <limits> | 
| + | 
| #include "src/compiler/instruction-selector-impl.h" | 
| #include "src/compiler/node-matchers.h" | 
| #include "src/compiler/node-properties.h" | 
| @@ -519,15 +521,33 @@ void InstructionSelector::VisitControl(BasicBlock* block) { | 
| } | 
| case BasicBlock::kSwitch: { | 
| DCHECK_EQ(IrOpcode::kSwitch, input->opcode()); | 
| -      BasicBlock** const branches = &block->successors().front(); | 
| -      size_t const branch_count = block->SuccessorCount(); | 
| -      DCHECK_LE(2u, branch_count); | 
| +      // Last successor must be Default. | 
| +      BasicBlock* default_branch = block->successors().back(); | 
| +      DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode()); | 
| // SSA deconstruction requires targets of branches not to have phis. | 
| // Edge split form guarantees this property, but is more strict. | 
| -      for (size_t index = 0; index < branch_count; ++index) { | 
| -        CheckNoPhis(branches[index]); | 
| +      CheckNoPhis(default_branch); | 
| +      // All other successors must be cases. | 
| +      size_t case_count = block->SuccessorCount() - 1; | 
| +      DCHECK_LE(1u, case_count); | 
| +      BasicBlock** case_branches = &block->successors().front(); | 
| +      // Determine case values and their min/max. | 
| +      int32_t* case_values = zone()->NewArray<int32_t>(case_count); | 
| +      int32_t min_value = std::numeric_limits<int32_t>::max(); | 
| +      int32_t max_value = std::numeric_limits<int32_t>::min(); | 
| +      for (size_t index = 0; index < case_count; ++index) { | 
| +        BasicBlock* branch = case_branches[index]; | 
| +        int32_t value = OpParameter<int32_t>(branch->front()->op()); | 
| +        case_values[index] = value; | 
| +        if (min_value > value) min_value = value; | 
| +        if (max_value < value) max_value = value; | 
| +        // SSA deconstruction requires targets of branches not to have phis. | 
| +        // Edge split form guarantees this property, but is more strict. | 
| +        CheckNoPhis(branch); | 
| } | 
| -      return VisitSwitch(input, branches, branch_count); | 
| +      DCHECK_LE(min_value, max_value); | 
| +      return VisitSwitch(input, default_branch, case_branches, case_values, | 
| +                         case_count, min_value, max_value); | 
| } | 
| case BasicBlock::kReturn: { | 
| // If the result itself is a return, return its input. | 
| @@ -561,7 +581,8 @@ MachineType InstructionSelector::GetMachineType(Node* node) { | 
| case IrOpcode::kIfTrue: | 
| case IrOpcode::kIfFalse: | 
| case IrOpcode::kSwitch: | 
| -    case IrOpcode::kCase: | 
| +    case IrOpcode::kIfValue: | 
| +    case IrOpcode::kIfDefault: | 
| case IrOpcode::kEffectPhi: | 
| case IrOpcode::kEffectSet: | 
| case IrOpcode::kMerge: | 
| @@ -701,7 +722,8 @@ void InstructionSelector::VisitNode(Node* node) { | 
| case IrOpcode::kIfTrue: | 
| case IrOpcode::kIfFalse: | 
| case IrOpcode::kSwitch: | 
| -    case IrOpcode::kCase: | 
| +    case IrOpcode::kIfValue: | 
| +    case IrOpcode::kIfDefault: | 
| case IrOpcode::kEffectPhi: | 
| case IrOpcode::kMerge: | 
| // No code needed for these graph artifacts. | 
| @@ -1058,22 +1080,6 @@ void InstructionSelector::VisitGoto(BasicBlock* target) { | 
| } | 
|  | 
|  | 
| -void InstructionSelector::VisitSwitch(Node* node, BasicBlock** branches, | 
| -                                      size_t branch_count) { | 
| -  OperandGenerator g(this); | 
| -  Node* const value = node->InputAt(0); | 
| -  size_t const input_count = branch_count + 1; | 
| -  InstructionOperand* const inputs = | 
| -      zone()->NewArray<InstructionOperand>(input_count); | 
| -  inputs[0] = g.UseRegister(value); | 
| -  for (size_t index = 0; index < branch_count; ++index) { | 
| -    inputs[index + 1] = g.Label(branches[index]); | 
| -  } | 
| -  Emit(kArchSwitch, 0, nullptr, input_count, inputs, 0, nullptr) | 
| -      ->MarkAsControl(); | 
| -} | 
| - | 
| - | 
| void InstructionSelector::VisitReturn(Node* value) { | 
| OperandGenerator g(this); | 
| if (value != NULL) { | 
|  |