| Index: src/compiler/machine-operator-reducer.cc | 
| diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc | 
| index fe579689bf9ccca7015bb395c5788859ebe7ddd4..00c998d81a04be79a8606a74d9657d238714d4e4 100644 | 
| --- a/src/compiler/machine-operator-reducer.cc | 
| +++ b/src/compiler/machine-operator-reducer.cc | 
| @@ -119,38 +119,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { | 
| switch (node->opcode()) { | 
| case IrOpcode::kProjection: | 
| return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0)); | 
| -    case IrOpcode::kWord32And: { | 
| -      Int32BinopMatcher m(node); | 
| -      if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0 | 
| -      if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x | 
| -      if (m.IsFoldable()) {                                   // K & K  => K | 
| -        return ReplaceInt32(m.left().Value() & m.right().Value()); | 
| -      } | 
| -      if (m.LeftEqualsRight()) return Replace(m.left().node());  // x & x => x | 
| -      if (m.left().IsWord32And() && m.right().HasValue()) { | 
| -        Int32BinopMatcher mleft(m.left().node()); | 
| -        if (mleft.right().HasValue()) {  // (x & K) & K => x & K | 
| -          node->ReplaceInput(0, mleft.left().node()); | 
| -          node->ReplaceInput( | 
| -              1, Int32Constant(m.right().Value() & mleft.right().Value())); | 
| -          return Changed(node); | 
| -        } | 
| -      } | 
| -      if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) { | 
| -        Int32BinopMatcher mleft(m.left().node()); | 
| -        if (mleft.right().HasValue() && | 
| -            (mleft.right().Value() & m.right().Value()) == | 
| -                mleft.right().Value()) { | 
| -          // (x + K) & K => (x & K) + K | 
| -          return Replace(graph()->NewNode( | 
| -              machine()->Int32Add(), | 
| -              graph()->NewNode(machine()->Word32And(), mleft.left().node(), | 
| -                               m.right().node()), | 
| -              mleft.right().node())); | 
| -        } | 
| -      } | 
| -      break; | 
| -    } | 
| +    case IrOpcode::kWord32And: | 
| +      return ReduceWord32And(node); | 
| case IrOpcode::kWord32Or: | 
| return ReduceWord32Or(node); | 
| case IrOpcode::kWord32Xor: { | 
| @@ -168,28 +138,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { | 
| } | 
| break; | 
| } | 
| -    case IrOpcode::kWord32Shl: { | 
| -      Int32BinopMatcher m(node); | 
| -      if (m.right().Is(0)) return Replace(m.left().node());  // x << 0 => x | 
| -      if (m.IsFoldable()) {                                  // K << K => K | 
| -        return ReplaceInt32(m.left().Value() << m.right().Value()); | 
| -      } | 
| -      if (m.right().IsInRange(1, 31)) { | 
| -        // (x >>> K) << K => x & ~(2^K - 1) | 
| -        // (x >> K) << K => x & ~(2^K - 1) | 
| -        if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) { | 
| -          Int32BinopMatcher mleft(m.left().node()); | 
| -          if (mleft.right().Is(m.right().Value())) { | 
| -            node->set_op(machine()->Word32And()); | 
| -            node->ReplaceInput(0, mleft.left().node()); | 
| -            node->ReplaceInput( | 
| -                1, Uint32Constant(~((1U << m.right().Value()) - 1U))); | 
| -            return Changed(node); | 
| -          } | 
| -        } | 
| -      } | 
| -      return ReduceWord32Shifts(node); | 
| -    } | 
| +    case IrOpcode::kWord32Shl: | 
| +      return ReduceWord32Shl(node); | 
| case IrOpcode::kWord32Shr: { | 
| Uint32BinopMatcher m(node); | 
| if (m.right().Is(0)) return Replace(m.left().node());  // x >>> 0 => x | 
| @@ -295,7 +245,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { | 
| if (m.right().IsPowerOf2()) {  // x * 2^n => x << n | 
| node->set_op(machine()->Word32Shl()); | 
| node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); | 
| -        return Changed(node); | 
| +        Reduction reduction = ReduceWord32Shl(node); | 
| +        return reduction.Changed() ? reduction : Changed(node); | 
| } | 
| break; | 
| } | 
| @@ -763,7 +714,6 @@ Reduction MachineOperatorReducer::ReduceWord32Shifts(Node* node) { | 
| DCHECK((node->opcode() == IrOpcode::kWord32Shl) || | 
| (node->opcode() == IrOpcode::kWord32Shr) || | 
| (node->opcode() == IrOpcode::kWord32Sar)); | 
| - | 
| if (machine()->Word32ShiftIsSafe()) { | 
| // Remove the explicit 'and' with 0x1f if the shift provided by the machine | 
| // instruction matches that required by JavaScript. | 
| @@ -780,9 +730,69 @@ Reduction MachineOperatorReducer::ReduceWord32Shifts(Node* node) { | 
| } | 
|  | 
|  | 
| -Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { | 
| -  DCHECK(node->opcode() == IrOpcode::kWord32Or); | 
| +Reduction MachineOperatorReducer::ReduceWord32Shl(Node* node) { | 
| +  DCHECK_EQ(IrOpcode::kWord32Shl, node->opcode()); | 
| +  Int32BinopMatcher m(node); | 
| +  if (m.right().Is(0)) return Replace(m.left().node());  // x << 0 => x | 
| +  if (m.IsFoldable()) {                                  // K << K => K | 
| +    return ReplaceInt32(m.left().Value() << m.right().Value()); | 
| +  } | 
| +  if (m.right().IsInRange(1, 31)) { | 
| +    // (x >>> K) << K => x & ~(2^K - 1) | 
| +    // (x >> K) << K => x & ~(2^K - 1) | 
| +    if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) { | 
| +      Int32BinopMatcher mleft(m.left().node()); | 
| +      if (mleft.right().Is(m.right().Value())) { | 
| +        node->set_op(machine()->Word32And()); | 
| +        node->ReplaceInput(0, mleft.left().node()); | 
| +        node->ReplaceInput(1, | 
| +                           Uint32Constant(~((1U << m.right().Value()) - 1U))); | 
| +        Reduction reduction = ReduceWord32And(node); | 
| +        return reduction.Changed() ? reduction : Changed(node); | 
| +      } | 
| +    } | 
| +  } | 
| +  return ReduceWord32Shifts(node); | 
| +} | 
| + | 
|  | 
| +Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { | 
| +  DCHECK_EQ(IrOpcode::kWord32And, node->opcode()); | 
| +  Int32BinopMatcher m(node); | 
| +  if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0 | 
| +  if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x | 
| +  if (m.IsFoldable()) {                                   // K & K  => K | 
| +    return ReplaceInt32(m.left().Value() & m.right().Value()); | 
| +  } | 
| +  if (m.LeftEqualsRight()) return Replace(m.left().node());  // x & x => x | 
| +  if (m.left().IsWord32And() && m.right().HasValue()) { | 
| +    Int32BinopMatcher mleft(m.left().node()); | 
| +    if (mleft.right().HasValue()) {  // (x & K) & K => x & K | 
| +      node->ReplaceInput(0, mleft.left().node()); | 
| +      node->ReplaceInput( | 
| +          1, Int32Constant(m.right().Value() & mleft.right().Value())); | 
| +      Reduction reduction = ReduceWord32And(node); | 
| +      return reduction.Changed() ? reduction : Changed(node); | 
| +    } | 
| +  } | 
| +  if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) { | 
| +    Int32BinopMatcher mleft(m.left().node()); | 
| +    if (mleft.right().HasValue() && | 
| +        (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) { | 
| +      // (x + K) & K => (x & K) + K | 
| +      return Replace(graph()->NewNode( | 
| +          machine()->Int32Add(), | 
| +          graph()->NewNode(machine()->Word32And(), mleft.left().node(), | 
| +                           m.right().node()), | 
| +          mleft.right().node())); | 
| +    } | 
| +  } | 
| +  return NoChange(); | 
| +} | 
| + | 
| + | 
| +Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { | 
| +  DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); | 
| Int32BinopMatcher m(node); | 
| if (m.right().Is(0)) return Replace(m.left().node());    // x | 0  => x | 
| if (m.right().Is(-1)) return Replace(m.right().node());  // x | -1 => -1 | 
|  |