17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/machine-operator-reducer.h"
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
75e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/base/bits.h"
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/generic-node-inl.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph.h"
10ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#include "src/compiler/js-graph.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h"
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
17ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgMachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph)
186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    : jsgraph_(jsgraph) {}
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
21ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgMachineOperatorReducer::~MachineOperatorReducer() {}
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgNode* MachineOperatorReducer::Float32Constant(volatile float value) {
2506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  return graph()->NewNode(common()->Float32Constant(value));
2606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org}
2706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
2806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
29a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgNode* MachineOperatorReducer::Float64Constant(volatile double value) {
30ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  return jsgraph()->Float64Constant(value);
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
34a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgNode* MachineOperatorReducer::Int32Constant(int32_t value) {
35ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  return jsgraph()->Int32Constant(value);
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
39a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgNode* MachineOperatorReducer::Int64Constant(int64_t value) {
40ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  return graph()->NewNode(common()->Int64Constant(value));
41a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
42a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
43a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Perform constant folding and strength reduction on machine operators.
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgReduction MachineOperatorReducer::Reduce(Node* node) {
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (node->opcode()) {
472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    case IrOpcode::kProjection:
482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0));
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32And: {
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                   // K & K  => K
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() & m.right().Value());
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return Replace(m.left().node());  // x & x => x
577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Or: {
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());    // x | 0  => x
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(-1)) return Replace(m.right().node());  // x | -1 => -1
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                    // K | K  => K
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() | m.right().Value());
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return Replace(m.left().node());  // x | x => x
675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) {
685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Int32BinopMatcher mleft(m.left().node());
695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Int32BinopMatcher mright(m.right().node());
705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (mleft.left().node() == mright.left().node()) {
715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          // (x << y) | (x >> (32 - y)) => x ror y
725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (mright.right().IsInt32Sub()) {
735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Int32BinopMatcher mrightright(mright.right().node());
745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (mrightright.left().Is(32) &&
755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                mrightright.right().node() == mleft.right().node()) {
761af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              node->set_op(machine()->Word32Ror());
775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              node->ReplaceInput(0, mleft.left().node());
785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              node->ReplaceInput(1, mleft.right().node());
795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              return Changed(node);
805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          // (x << K) | (x >> (32 - K)) => x ror K
835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (mleft.right().IsInRange(0, 31) &&
845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              mright.right().Is(32 - mleft.right().Value())) {
851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            node->set_op(machine()->Word32Ror());
865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            node->ReplaceInput(0, mleft.left().node());
875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            node->ReplaceInput(1, mleft.right().node());
885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            return Changed(node);
895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) {
935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // (x >> (32 - y)) | (x << y)  => x ror y
945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Int32BinopMatcher mleft(m.left().node());
955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Int32BinopMatcher mright(m.right().node());
965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (mleft.left().node() == mright.left().node()) {
975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (mleft.right().IsInt32Sub()) {
985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Int32BinopMatcher mleftright(mleft.right().node());
995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (mleftright.left().Is(32) &&
1005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                mleftright.right().node() == mright.right().node()) {
1011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org              node->set_op(machine()->Word32Ror());
1025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              node->ReplaceInput(0, mright.left().node());
1035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              node->ReplaceInput(1, mright.right().node());
1045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              return Changed(node);
1055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
1065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
1075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          // (x >> (32 - K)) | (x << K) => x ror K
1085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (mright.right().IsInRange(0, 31) &&
1095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              mleft.right().Is(32 - mright.right().Value())) {
1101af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org            node->set_op(machine()->Word32Ror());
1115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            node->ReplaceInput(0, mright.left().node());
1125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            node->ReplaceInput(1, mright.right().node());
1135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            return Changed(node);
1145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
1155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
1165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Xor: {
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x ^ 0 => x
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K ^ K => K
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() ^ m.right().Value());
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x ^ x => 0
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Shl: {
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x << 0 => x
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K << K => K
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() << m.right().Value());
1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Shr: {
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Uint32BinopMatcher m(node);
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x >>> 0 => x
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K >>> K => K
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() >> m.right().Value());
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Sar: {
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x >> 0 => x
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K >> K => K
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() >> m.right().Value());
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kWord32Ror: {
1535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      Int32BinopMatcher m(node);
1545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x ror 0 => x
1555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (m.IsFoldable()) {                                  // K ror K => K
1565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return ReplaceInt32(
1575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            base::bits::RotateRight32(m.left().Value(), m.right().Value()));
1585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
1595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
1605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    }
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Equal: {
1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K == K => K
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceBool(m.left().Value() == m.right().Value());
1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().IsInt32Sub() && m.right().Is(0)) {  // x - y == 0 => x == y
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Int32BinopMatcher msub(m.left().node());
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, msub.left().node());
1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, msub.right().node());
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceBool(true);  // x == x => true
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Add: {
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x + 0 => x
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K + K => K
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) +
1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                            static_cast<uint32_t>(m.right().Value()));
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Sub: {
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.left().node());  // x - 0 => x
1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                  // K - K => K
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                            static_cast<uint32_t>(m.right().Value()));
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Mul: {
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return Replace(m.right().node());  // x * 0 => 0
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return Replace(m.left().node());   // x * 1 => x
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                   // K * K => K
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() * m.right().Value());
2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(-1)) {  // x * -1 => 0 - x
2031af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        node->set_op(machine()->Int32Sub());
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, Int32Constant(0));
2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, m.left().node());
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsPowerOf2()) {  // x * 2^n => x << n
2091af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        node->set_op(machine()->Word32Shl());
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Div: {
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1 => x
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.left().Is(0))
2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().IsPowerOf2())
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().Is(0))
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.LeftEqualsRight())
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value());
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() / m.right().Value());
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(-1)) {  // x / -1 => 0 - x
2271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        node->set_op(machine()->Int32Sub());
2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, Int32Constant(0));
2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, m.left().node());
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32UDiv: {
2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Uint32BinopMatcher m(node);
2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1 => x
2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.left().Is(0))
2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().Is(0))
2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.LeftEqualsRight())
2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() / m.right().Value());
2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsPowerOf2()) {  // x / 2^n => x >> n
2441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        node->set_op(machine()->Word32Shr());
2457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Mod: {
2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return ReplaceInt32(0);   // x % 1  => 0
2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(-1)) return ReplaceInt32(0);  // x % -1 => 0
2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.left().Is(0))
2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().IsPowerOf2())
2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().Is(0))
2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.LeftEqualsRight())
2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() % m.right().Value());
2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32UMod: {
2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Uint32BinopMatcher m(node);
2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return ReplaceInt32(0);  // x % 1 => 0
2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.left().Is(0))
2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.right().Is(0))
2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): if (m.LeftEqualsRight())
2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceInt32(m.left().Value() % m.right().Value());
2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsPowerOf2()) {  // x % 2^n => x & 2^n-1
2731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        node->set_op(machine()->Word32And());
2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, Int32Constant(m.right().Value() - 1));
2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32LessThan: {
2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K < K => K
2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceBool(m.left().Value() < m.right().Value());
2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().IsInt32Sub() && m.right().Is(0)) {  // x - y < 0 => x < y
2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Int32BinopMatcher msub(m.left().node());
2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, msub.left().node());
2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, msub.right().node());
2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().Is(0) && m.right().IsInt32Sub()) {  // 0 < x - y => y < x
2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Int32BinopMatcher msub(m.right().node());
2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, msub.right().node());
2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, msub.left().node());
2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceBool(false);  // x < x => false
2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32LessThanOrEqual: {
3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(node);
3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K <= K => K
3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceBool(m.left().Value() <= m.right().Value());
3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().IsInt32Sub() && m.right().Is(0)) {  // x - y <= 0 => x <= y
3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Int32BinopMatcher msub(m.left().node());
3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, msub.left().node());
3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, msub.right().node());
3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().Is(0) && m.right().IsInt32Sub()) {  // 0 <= x - y => y <= x
3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Int32BinopMatcher msub(m.right().node());
3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(0, msub.right().node());
3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        node->ReplaceInput(1, msub.left().node());
3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Changed(node);
3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceBool(true);  // x <= x => true
3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kUint32LessThan: {
3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Uint32BinopMatcher m(node);
3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().Is(kMaxUInt32)) return ReplaceBool(false);  // M < x => false
3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) return ReplaceBool(false);          // x < 0 => false
3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                    // K < K => K
3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceBool(m.left().Value() < m.right().Value());
3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceBool(false);  // x < x => false
3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kUint32LessThanOrEqual: {
3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Uint32BinopMatcher m(node);
3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().Is(0)) return ReplaceBool(true);            // 0 <= x => true
3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(kMaxUInt32)) return ReplaceBool(true);  // x <= M => true
3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {                                    // K <= K => K
3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceBool(m.left().Value() <= m.right().Value());
3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.LeftEqualsRight()) return ReplaceBool(true);  // x <= x => true
3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Add: {
3407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Float64BinopMatcher m(node);
3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K + K => K
3427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceFloat64(m.left().Value() + m.right().Value());
3437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Sub: {
3477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Float64BinopMatcher m(node);
3487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K - K => K
3497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceFloat64(m.left().Value() - m.right().Value());
3507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Mul: {
3547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Float64BinopMatcher m(node);
3557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return Replace(m.left().node());  // x * 1.0 => x
3567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsNaN()) {                               // x * NaN => NaN
3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Replace(m.right().node());
3587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K * K => K
3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceFloat64(m.left().Value() * m.right().Value());
3617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Div: {
3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Float64BinopMatcher m(node);
3667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1.0 => x
3677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsNaN()) {                               // x / NaN => NaN
3687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Replace(m.right().node());
3697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().IsNaN()) {  // NaN / x => NaN
3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Replace(m.left().node());
3727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K / K => K
3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceFloat64(m.left().Value() / m.right().Value());
3757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Mod: {
3797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Float64BinopMatcher m(node);
3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().IsNaN()) {  // x % NaN => NaN
3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Replace(m.right().node());
3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.left().IsNaN()) {  // NaN % x => NaN
3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Replace(m.left().node());
3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.IsFoldable()) {  // K % K => K
3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return ReplaceFloat64(modulo(m.left().Value(), m.right().Value()));
3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
39106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    case IrOpcode::kChangeFloat32ToFloat64: {
39206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Float32Matcher m(node->InputAt(0));
39306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      if (m.HasValue()) return ReplaceFloat64(m.Value());
39406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      break;
39506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    }
396a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeFloat64ToInt32: {
397a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Float64Matcher m(node->InputAt(0));
398a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt32(FastD2I(m.Value()));
399a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
400a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
401a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
402a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeFloat64ToUint32: {
403a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Float64Matcher m(node->InputAt(0));
404a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt32(FastD2UI(m.Value()));
405a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.IsChangeUint32ToFloat64()) return Replace(m.node()->InputAt(0));
406a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
407a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
408a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeInt32ToFloat64: {
409a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Int32Matcher m(node->InputAt(0));
410a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceFloat64(FastI2D(m.Value()));
411a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
412a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
413a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeInt32ToInt64: {
414a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Int32Matcher m(node->InputAt(0));
415a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt64(m.Value());
416a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
417a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
418a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeUint32ToFloat64: {
419a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Uint32Matcher m(node->InputAt(0));
420a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceFloat64(FastUI2D(m.Value()));
421a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
422a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
423a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kChangeUint32ToUint64: {
424a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Uint32Matcher m(node->InputAt(0));
425a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt64(static_cast<uint64_t>(m.Value()));
426a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
427a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
428a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kTruncateFloat64ToInt32: {
429a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Float64Matcher m(node->InputAt(0));
430a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
431a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
432a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
433a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
434a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kTruncateInt64ToInt32: {
435a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Int64Matcher m(node->InputAt(0));
436a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.HasValue()) return ReplaceInt32(static_cast<int32_t>(m.Value()));
437a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (m.IsChangeInt32ToInt64()) return Replace(m.node()->InputAt(0));
438a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      break;
439a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
44006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    case IrOpcode::kTruncateFloat64ToFloat32: {
44106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Float64Matcher m(node->InputAt(0));
44206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      if (m.HasValue()) return ReplaceFloat32(DoubleToFloat32(m.Value()));
44306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
44406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      break;
44506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    }
4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return NoChange();
4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
451ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
452ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
4532c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.orgReduction MachineOperatorReducer::ReduceProjection(size_t index, Node* node) {
4542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  switch (node->opcode()) {
4552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    case IrOpcode::kInt32AddWithOverflow: {
4562c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      DCHECK(index == 0 || index == 1);
4572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      Int32BinopMatcher m(node);
4582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      if (m.IsFoldable()) {
4592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        int32_t val;
4602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        bool ovf = base::bits::SignedAddOverflow32(m.left().Value(),
4612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                   m.right().Value(), &val);
4622c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        return ReplaceInt32((index == 0) ? val : ovf);
4632c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      }
4642c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      if (m.right().Is(0)) {
4652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        return (index == 0) ? Replace(m.left().node()) : ReplaceInt32(0);
4662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      }
4672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      break;
4682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    }
4692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    case IrOpcode::kInt32SubWithOverflow: {
4702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      DCHECK(index == 0 || index == 1);
4712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      Int32BinopMatcher m(node);
4722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      if (m.IsFoldable()) {
4732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        int32_t val;
4742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        bool ovf = base::bits::SignedSubOverflow32(m.left().Value(),
4752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                   m.right().Value(), &val);
4762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        return ReplaceInt32((index == 0) ? val : ovf);
4772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      }
4782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      if (m.right().Is(0)) {
4792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org        return (index == 0) ? Replace(m.left().node()) : ReplaceInt32(0);
4802c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      }
4812c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      break;
4822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    }
4832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    default:
4842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      break;
4852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  }
4862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  return NoChange();
4872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org}
4882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org
4892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org
490ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgCommonOperatorBuilder* MachineOperatorReducer::common() const {
491ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  return jsgraph()->common();
4927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
493ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
494ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
495d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.orgMachineOperatorBuilder* MachineOperatorReducer::machine() const {
496d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  return jsgraph()->machine();
497d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org}
498d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
499d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org
500ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgGraph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); }
501ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
502ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org}  // namespace compiler
503ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org}  // namespace internal
504ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org}  // namespace v8
505