Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index c3e45a1..19ea062 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -75,7 +75,9 @@
 
 
 Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) {
-  return graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+  Node* const node = graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+  Reduction const reduction = ReduceInt32Sub(node);
+  return reduction.Changed() ? reduction.replacement() : node;
 }
 
 
@@ -101,13 +103,19 @@
 
 
 Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
-  DCHECK_LT(0, divisor);
+  DCHECK_LT(0u, divisor);
+  // If the divisor is even, we can avoid using the expensive fixup by shifting
+  // the dividend upfront.
+  unsigned const shift = base::bits::CountTrailingZeros32(divisor);
+  dividend = Word32Shr(dividend, shift);
+  divisor >>= shift;
+  // Compute the magic number for the (shifted) divisor.
   base::MagicNumbersForDivision<uint32_t> const mag =
-      base::UnsignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+      base::UnsignedDivisionByConstant(divisor, shift);
   Node* quotient = graph()->NewNode(machine()->Uint32MulHigh(), dividend,
                                     Uint32Constant(mag.multiplier));
   if (mag.add) {
-    DCHECK_LE(1, mag.shift);
+    DCHECK_LE(1u, mag.shift);
     quotient = Word32Shr(
         Int32Add(Word32Shr(Int32Sub(dividend, quotient), 1), quotient),
         mag.shift - 1);
@@ -122,7 +130,7 @@
 Reduction MachineOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
     case IrOpcode::kProjection:
-      return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0));
+      return ReduceProjection(ProjectionIndexOf(node->op()), node->InputAt(0));
     case IrOpcode::kWord32And:
       return ReduceWord32And(node);
     case IrOpcode::kWord32Or:
@@ -152,29 +160,8 @@
       }
       return ReduceWord32Shifts(node);
     }
-    case IrOpcode::kWord32Sar: {
-      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.left().IsWord32Shl()) {
-        Int32BinopMatcher mleft(m.left().node());
-        if (mleft.left().IsLoad()) {
-          LoadRepresentation const rep =
-              OpParameter<LoadRepresentation>(mleft.left().node());
-          if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) {
-            // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
-            return Replace(mleft.left().node());
-          }
-          if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) {
-            // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
-            return Replace(mleft.left().node());
-          }
-        }
-      }
-      return ReduceWord32Shifts(node);
-    }
+    case IrOpcode::kWord32Sar:
+      return ReduceWord32Sar(node);
     case IrOpcode::kWord32Ror: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.left().node());  // x ror 0 => x
@@ -216,16 +203,8 @@
     }
     case IrOpcode::kInt32Add:
       return ReduceInt32Add(node);
-    case IrOpcode::kInt32Sub: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());  // x - 0 => x
-      if (m.IsFoldable()) {                                  // K - K => K
-        return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
-                            static_cast<uint32_t>(m.right().Value()));
-      }
-      if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
-      break;
-    }
+    case IrOpcode::kInt32Sub:
+      return ReduceInt32Sub(node);
     case IrOpcode::kInt32Mul: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.right().node());  // x * 0 => 0
@@ -234,14 +213,14 @@
         return ReplaceInt32(m.left().Value() * m.right().Value());
       }
       if (m.right().Is(-1)) {  // x * -1 => 0 - x
-        node->set_op(machine()->Int32Sub());
         node->ReplaceInput(0, Int32Constant(0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
         return Changed(node);
       }
       if (m.right().IsPowerOf2()) {  // x * 2^n => x << n
-        node->set_op(machine()->Word32Shl());
         node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
+        NodeProperties::ChangeOp(node, machine()->Word32Shl());
         Reduction reduction = ReduceWord32Shl(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -359,9 +338,9 @@
     case IrOpcode::kFloat64Mul: {
       Float64BinopMatcher m(node);
       if (m.right().Is(-1)) {  // x * -1.0 => -0.0 - x
-        node->set_op(machine()->Float64Sub());
         node->ReplaceInput(0, Float64Constant(-0.0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Float64Sub());
         return Changed(node);
       }
       if (m.right().Is(1)) return Replace(m.left().node());  // x * 1.0 => x
@@ -390,7 +369,7 @@
     case IrOpcode::kFloat64Mod: {
       Float64BinopMatcher m(node);
       if (m.right().Is(0)) {  // x % 0 => NaN
-        return ReplaceFloat64(base::OS::nan_value());
+        return ReplaceFloat64(std::numeric_limits<double>::quiet_NaN());
       }
       if (m.right().IsNaN()) {  // x % NaN => NaN
         return Replace(m.right().node());
@@ -454,8 +433,16 @@
       if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
       break;
     }
+    case IrOpcode::kFloat64InsertLowWord32:
+      return ReduceFloat64InsertLowWord32(node);
+    case IrOpcode::kFloat64InsertHighWord32:
+      return ReduceFloat64InsertHighWord32(node);
     case IrOpcode::kStore:
       return ReduceStore(node);
+    case IrOpcode::kFloat64Equal:
+    case IrOpcode::kFloat64LessThan:
+    case IrOpcode::kFloat64LessThanOrEqual:
+      return ReduceFloat64Compare(node);
     default:
       break;
   }
@@ -471,6 +458,44 @@
     return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) +
                          bit_cast<uint32_t>(m.right().Value()));
   }
+  if (m.left().IsInt32Sub()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.left().Is(0)) {  // (0 - x) + y => y - x
+      node->ReplaceInput(0, m.right().node());
+      node->ReplaceInput(1, mleft.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
+      Reduction const reduction = ReduceInt32Sub(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  if (m.right().IsInt32Sub()) {
+    Int32BinopMatcher mright(m.right().node());
+    if (mright.left().Is(0)) {  // y + (0 - x) => y - x
+      node->ReplaceInput(1, mright.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
+      Reduction const reduction = ReduceInt32Sub(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
+  DCHECK_EQ(IrOpcode::kInt32Sub, 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(static_cast<uint32_t>(m.left().Value()) -
+                        static_cast<uint32_t>(m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
+  if (m.right().HasValue()) {                       // x - K => x + -K
+    node->ReplaceInput(1, Int32Constant(-m.right().Value()));
+    NodeProperties::ChangeOp(node, machine()->Int32Add());
+    Reduction const reduction = ReduceInt32Add(node);
+    return reduction.Changed() ? reduction : Changed(node);
+  }
   return NoChange();
 }
 
@@ -489,10 +514,10 @@
     return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
   }
   if (m.right().Is(-1)) {  // x / -1 => 0 - x
-    node->set_op(machine()->Int32Sub());
     node->ReplaceInput(0, Int32Constant(0));
     node->ReplaceInput(1, m.left().node());
     node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, machine()->Int32Sub());
     return Changed(node);
   }
   if (m.right().HasValue()) {
@@ -501,7 +526,7 @@
     Node* quotient = dividend;
     if (base::bits::IsPowerOfTwo32(Abs(divisor))) {
       uint32_t const shift = WhichPowerOf2Abs(divisor);
-      DCHECK_NE(0, shift);
+      DCHECK_NE(0u, shift);
       if (shift > 1) {
         quotient = Word32Sar(quotient, 31);
       }
@@ -511,10 +536,10 @@
       quotient = Int32Div(quotient, Abs(divisor));
     }
     if (divisor < 0) {
-      node->set_op(machine()->Int32Sub());
       node->ReplaceInput(0, Int32Constant(0));
       node->ReplaceInput(1, quotient);
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
       return Changed(node);
     }
     return Replace(quotient);
@@ -540,9 +565,9 @@
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x / 2^n => x >> n
-      node->set_op(machine()->Word32Shr());
       node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32Shr());
       return Changed(node);
     } else {
       return Replace(Uint32Div(dividend, divisor));
@@ -569,18 +594,20 @@
     if (base::bits::IsPowerOfTwo32(divisor)) {
       uint32_t const mask = divisor - 1;
       Node* const zero = Int32Constant(0);
-      node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
       node->ReplaceInput(
           0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
       node->ReplaceInput(
           1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
       node->ReplaceInput(2, Word32And(dividend, mask));
+      NodeProperties::ChangeOp(
+          node,
+          common()->Select(MachineRepresentation::kWord32, BranchHint::kFalse));
     } else {
       Node* quotient = Int32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
     return Changed(node);
   }
@@ -602,15 +629,16 @@
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x % 2^n => x & 2^n-1
-      node->set_op(machine()->Word32And());
       node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32And());
     } else {
       Node* quotient = Uint32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
-    node->TrimInputCount(2);
     return Changed(node);
   }
   return NoChange();
@@ -623,23 +651,24 @@
   if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
   if (m.IsPhi()) {
     Node* const phi = m.node();
-    DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
+    DCHECK_EQ(MachineRepresentation::kFloat64, PhiRepresentationOf(phi->op()));
     if (phi->OwnedBy(node)) {
-      // TruncateFloat64ToInt32(Phi[Float64](x1,...,xn))
-      //   => Phi[Int32](TruncateFloat64ToInt32(x1),
+      // TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn))
+      //   => Phi[Int32](TruncateFloat64ToInt32[mode](x1),
       //                 ...,
-      //                 TruncateFloat64ToInt32(xn))
+      //                 TruncateFloat64ToInt32[mode](xn))
       const int value_input_count = phi->InputCount() - 1;
       for (int i = 0; i < value_input_count; ++i) {
-        Node* input = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
-                                       phi->InputAt(i));
+        Node* input = graph()->NewNode(node->op(), phi->InputAt(i));
         // TODO(bmeurer): Reschedule input for reduction once we have Revisit()
         // instead of recursing into ReduceTruncateFloat64ToInt32() here.
         Reduction reduction = ReduceTruncateFloat64ToInt32(input);
         if (reduction.Changed()) input = reduction.replacement();
         phi->ReplaceInput(i, input);
       }
-      phi->set_op(common()->Phi(kMachInt32, value_input_count));
+      NodeProperties::ChangeOp(
+          phi,
+          common()->Phi(MachineRepresentation::kWord32, value_input_count));
       return Replace(phi);
     }
   }
@@ -648,15 +677,16 @@
 
 
 Reduction MachineOperatorReducer::ReduceStore(Node* node) {
-  MachineType const rep =
-      RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
+  MachineRepresentation const rep =
+      StoreRepresentationOf(node->op()).representation();
   Node* const value = node->InputAt(2);
   switch (value->opcode()) {
     case IrOpcode::kWord32And: {
       Uint32BinopMatcher m(value);
-      if (m.right().HasValue() &&
-          ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
-           (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+      if (m.right().HasValue() && ((rep == MachineRepresentation::kWord8 &&
+                                    (m.right().Value() & 0xff) == 0xff) ||
+                                   (rep == MachineRepresentation::kWord16 &&
+                                    (m.right().Value() & 0xffff) == 0xffff))) {
         node->ReplaceInput(2, m.left().node());
         return Changed(node);
       }
@@ -664,9 +694,10 @@
     }
     case IrOpcode::kWord32Sar: {
       Int32BinopMatcher m(value);
-      if (m.left().IsWord32Shl() &&
-          ((rep == kRepWord8 && m.right().IsInRange(1, 24)) ||
-           (rep == kRepWord16 && m.right().IsInRange(1, 16)))) {
+      if (m.left().IsWord32Shl() && ((rep == MachineRepresentation::kWord8 &&
+                                      m.right().IsInRange(1, 24)) ||
+                                     (rep == MachineRepresentation::kWord16 &&
+                                      m.right().IsInRange(1, 16)))) {
         Int32BinopMatcher mleft(m.left().node());
         if (mleft.right().Is(m.right().Value())) {
           node->ReplaceInput(2, mleft.left().node());
@@ -752,10 +783,10 @@
     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)));
+        NodeProperties::ChangeOp(node, machine()->Word32And());
         Reduction reduction = ReduceWord32And(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -765,11 +796,50 @@
 }
 
 
+Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
+  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.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.left().IsComparison()) {
+      if (m.right().Is(31) && mleft.right().Is(31)) {
+        // Comparison << 31 >> 31 => 0 - Comparison
+        node->ReplaceInput(0, Int32Constant(0));
+        node->ReplaceInput(1, mleft.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
+        Reduction const reduction = ReduceInt32Sub(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    } else if (mleft.left().IsLoad()) {
+      LoadRepresentation const rep =
+          LoadRepresentationOf(mleft.left().node()->op());
+      if (m.right().Is(24) && mleft.right().Is(24) &&
+          rep == MachineType::Int8()) {
+        // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
+        return Replace(mleft.left().node());
+      }
+      if (m.right().Is(16) && mleft.right().Is(16) &&
+          rep == MachineType::Int16()) {
+        // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
+        return Replace(mleft.left().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.left().IsComparison() && m.right().Is(1)) {       // CMP & 1 => CMP
+    return Replace(m.left().node());
+  }
   if (m.IsFoldable()) {                                   // K & K  => K
     return ReplaceInt32(m.left().Value() & m.right().Value());
   }
@@ -784,63 +854,79 @@
       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 << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
-      node->set_op(machine()->Int32Add());
-      node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-      node->ReplaceInput(1, mleft.right().node());
-      Reduction const reduction = ReduceInt32Add(node);
-      return reduction.Changed() ? reduction : Changed(node);
-    }
-    if (mleft.left().IsInt32Mul()) {
-      Int32BinopMatcher mleftleft(mleft.left().node());
-      if (mleftleft.right().IsMultipleOf(-m.right().Value())) {
-        // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0,
-                           Word32And(mleft.right().node(), m.right().node()));
-        node->ReplaceInput(1, mleftleft.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+  if (m.right().IsNegativePowerOf2()) {
+    int32_t const mask = m.right().Value();
+    if (m.left().IsWord32Shl()) {
+      Uint32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue() &&
+          mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) {
+        // (x << L) & (-1 << K) => x << L iff K >= L
+        return Replace(mleft.node());
       }
-    }
-    if (mleft.right().IsInt32Mul()) {
-      Int32BinopMatcher mleftright(mleft.right().node());
-      if (mleftright.right().IsMultipleOf(-m.right().Value())) {
-        // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-        node->set_op(machine()->Int32Add());
+    } else if (m.left().IsInt32Add()) {
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue() &&
+          (mleft.right().Value() & mask) == mleft.right().Value()) {
+        // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
         node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-        node->ReplaceInput(1, mleftright.node());
+        node->ReplaceInput(1, mleft.right().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Add());
         Reduction const reduction = ReduceInt32Add(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
-    }
-    if (mleft.left().IsWord32Shl()) {
-      Int32BinopMatcher mleftleft(mleft.left().node());
-      if (mleftleft.right().Is(
-              base::bits::CountTrailingZeros32(m.right().Value()))) {
-        // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0,
-                           Word32And(mleft.right().node(), m.right().node()));
-        node->ReplaceInput(1, mleftleft.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+      if (mleft.left().IsInt32Mul()) {
+        Int32BinopMatcher mleftleft(mleft.left().node());
+        if (mleftleft.right().IsMultipleOf(-mask)) {
+          // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+          node->ReplaceInput(0,
+                             Word32And(mleft.right().node(), m.right().node()));
+          node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
       }
-    }
-    if (mleft.right().IsWord32Shl()) {
-      Int32BinopMatcher mleftright(mleft.right().node());
-      if (mleftright.right().Is(
-              base::bits::CountTrailingZeros32(m.right().Value()))) {
-        // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-        node->ReplaceInput(1, mleftright.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+      if (mleft.right().IsInt32Mul()) {
+        Int32BinopMatcher mleftright(mleft.right().node());
+        if (mleftright.right().IsMultipleOf(-mask)) {
+          // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+          node->ReplaceInput(0,
+                             Word32And(mleft.left().node(), m.right().node()));
+          node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+      if (mleft.left().IsWord32Shl()) {
+        Int32BinopMatcher mleftleft(mleft.left().node());
+        if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) {
+          // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
+          node->ReplaceInput(0,
+                             Word32And(mleft.right().node(), m.right().node()));
+          node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+      if (mleft.right().IsWord32Shl()) {
+        Int32BinopMatcher mleftright(mleft.right().node());
+        if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) {
+          // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
+          node->ReplaceInput(0,
+                             Word32And(mleft.left().node(), m.right().node()));
+          node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+    } else if (m.left().IsInt32Mul()) {
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsMultipleOf(-mask)) {
+        // (x * (K << L)) & (-1 << L) => x * (K << L)
+        return Replace(mleft.node());
       }
     }
   }
@@ -858,8 +944,8 @@
   }
   if (m.LeftEqualsRight()) return Replace(m.left().node());  // x | x => x
 
-  Node* shl = NULL;
-  Node* shr = NULL;
+  Node* shl = nullptr;
+  Node* shr = nullptr;
   // Recognize rotation, we are matching either:
   //  * x << y | x >>> (32 - y) => x ror (32 - y), i.e  x rol y
   //  * x << (32 - y) | x >>> y => x ror y
@@ -882,8 +968,8 @@
     // Case where y is a constant.
     if (mshl.right().Value() + mshr.right().Value() != 32) return NoChange();
   } else {
-    Node* sub = NULL;
-    Node* y = NULL;
+    Node* sub = nullptr;
+    Node* y = nullptr;
     if (mshl.right().IsInt32Sub()) {
       sub = mshl.right().node();
       y = mshr.right().node();
@@ -898,13 +984,96 @@
     if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
   }
 
-  node->set_op(machine()->Word32Ror());
   node->ReplaceInput(0, mshl.left().node());
   node->ReplaceInput(1, mshr.right().node());
+  NodeProperties::ChangeOp(node, machine()->Word32Ror());
   return Changed(node);
 }
 
 
+Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) {
+  DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode());
+  Float64Matcher mlhs(node->InputAt(0));
+  Uint32Matcher mrhs(node->InputAt(1));
+  if (mlhs.HasValue() && mrhs.HasValue()) {
+    return ReplaceFloat64(bit_cast<double>(
+        (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF00000000)) |
+        mrhs.Value()));
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceFloat64InsertHighWord32(Node* node) {
+  DCHECK_EQ(IrOpcode::kFloat64InsertHighWord32, node->opcode());
+  Float64Matcher mlhs(node->InputAt(0));
+  Uint32Matcher mrhs(node->InputAt(1));
+  if (mlhs.HasValue() && mrhs.HasValue()) {
+    return ReplaceFloat64(bit_cast<double>(
+        (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF)) |
+        (static_cast<uint64_t>(mrhs.Value()) << 32)));
+  }
+  return NoChange();
+}
+
+
+namespace {
+
+bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) {
+  if (m.HasValue()) {
+    double v = m.Value();
+    float fv = static_cast<float>(v);
+    return static_cast<double>(fv) == v;
+  }
+  return false;
+}
+
+}  // namespace
+
+
+Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
+  DCHECK((IrOpcode::kFloat64Equal == node->opcode()) ||
+         (IrOpcode::kFloat64LessThan == node->opcode()) ||
+         (IrOpcode::kFloat64LessThanOrEqual == node->opcode()));
+  // As all Float32 values have an exact representation in Float64, comparing
+  // two Float64 values both converted from Float32 is equivalent to comparing
+  // the original Float32s, so we can ignore the conversions. We can also reduce
+  // comparisons of converted Float64 values against constants that can be
+  // represented exactly as Float32.
+  Float64BinopMatcher m(node);
+  if ((m.left().IsChangeFloat32ToFloat64() &&
+       m.right().IsChangeFloat32ToFloat64()) ||
+      (m.left().IsChangeFloat32ToFloat64() &&
+       IsFloat64RepresentableAsFloat32(m.right())) ||
+      (IsFloat64RepresentableAsFloat32(m.left()) &&
+       m.right().IsChangeFloat32ToFloat64())) {
+    switch (node->opcode()) {
+      case IrOpcode::kFloat64Equal:
+        NodeProperties::ChangeOp(node, machine()->Float32Equal());
+        break;
+      case IrOpcode::kFloat64LessThan:
+        NodeProperties::ChangeOp(node, machine()->Float32LessThan());
+        break;
+      case IrOpcode::kFloat64LessThanOrEqual:
+        NodeProperties::ChangeOp(node, machine()->Float32LessThanOrEqual());
+        break;
+      default:
+        return NoChange();
+    }
+    node->ReplaceInput(
+        0, m.left().HasValue()
+               ? Float32Constant(static_cast<float>(m.left().Value()))
+               : m.left().InputAt(0));
+    node->ReplaceInput(
+        1, m.right().HasValue()
+               ? Float32Constant(static_cast<float>(m.right().Value()))
+               : m.right().InputAt(0));
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
 CommonOperatorBuilder* MachineOperatorReducer::common() const {
   return jsgraph()->common();
 }